This is the mail archive of the mailing list for the GDB project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

breakpoint at address on Atmel AVR - parsing


It seems GDB-7.4.91 badly parses program-space addresses given to
`break' and `disassemble' at Atmel AVR architecture: an "0x4d2"
becomes 0x8004d2.

(gdb) disassemble 0x4d2,0x4dc
Dump of assembler code from 0x8004d2 to 0x8004dc:
   0x008004d2 <Fatfs+682>:      rjmp    .-1126          ;  0x80006e
   0x008004d4 <Fatfs+684>:      rjmp    .-1126          ;  0x800070
   0x008004d6 <Fatfs+686>:      rjmp    .-1126          ;  0x800072
   0x008004d8 <Fatfs+688>:      rjmp    .-1126          ;  0x800074
   0x008004da <Fatfs+690>:      rjmp    .-1126          ;  0x800076
(gdb) p & Fatfs
$4 = (FATFS (*)[2]) 0x800228 <Fatfs>

On Atmel AVR chips 0x8004d2 is an address in data RAM, not in a
program memory (harward arch). Program space addresses are in range 0
to 0x007fffff.
The disassembly command incorectly parses the input range and decodes
random data as instructions. In this example the `Fatfs' hapens to be
a static variable at that address (static FATFS* Fatfs[2]).
Using a function name instead of an address (e.g. `break main' and
`disassemble main') works correctly.

This also affects `break' command:
(gdb) break *0x20
Breakpoint 1 at 0x8000020
(Note: this will be rejected by a remote target when user attempts to
continue because only data breakpoints are accepted in RAM range.)

GDB understands that program counter (PC) points to a code
(__trampolines_start is a C runtime initialization), however it
incorrectly thinks that stack pointer (SP) points to code (__vectors
is interrupt vector table):

(gdb) info registers
r30            0xcd     205
r31            0xcd     205
SREG           0x0      0
SP             0x0      0x0 <__vectors>
PC2            0x4e6    1254
pc             0x4e6    0x4e6 <__trampolines_start>

I debugged GDB and the 0x4d2 -> 0x008004d2 transformation happens at
avr_make_saddr(), at this place:
#0  avr_make_saddr (x=0) at avr-tdep.c:256
#1  avr_integer_to_address () at avr-tdep.c:338
#2  gdbarch_integer_to_address () at gdbarch.c:2531
#3  value_as_address () at value.c:2392
#4  disassemble_command (arg=0x47331b7 ", 0x4", from_tty=1)
#5  do_cfunc (c=0x5e9d130, args=0x47331b4 "0x0, 0x4", from_tty=1)
#6  cmd_func (cmd=..., args="0x0, 0x4", from_tty=1) at ./cli/cli-decode.c:1758
#7  execute_command (p= "4", from_tty=1) at top.c:484
#8  command_handler (command= "disassemble 0x0, 0x4")

The  value_as_address () contains a lot of comments explaining the
desired behavior [1]:

  /* Some architectures (e.g. Harvard), map instruction and data
     addresses onto a single large unified address space.  For
     instance: An architecture may consider a large integer in the
     range 0x10000000 .. 0x1000ffff to already represent a data
     addresses (hence not need a pointer to address conversion) while
     a small integer would still need to be converted integer to
     pointer to address.  Just assume such architectures handle all
     integer conversions in a single function.  */

  /* JimB writes:
     AndrewC pointed out that users aren't complaining about how GDB
     casts integers to pointers; they are complaining that they can't
     take an address from a disassembly listing and give it to `x/i'.
     This is certainly important.

     Adding an architecture method like integer_to_address() certainly
     makes it possible for GDB to "get it right" in all circumstances
     --- the target has complete control over how things get done, so
     people can Do The Right Thing for their target without breaking
     anyone else.  The standard doesn't specify how integers get
     converted to pointers; usually, the ABI doesn't either, but
     ABI-specific code is a more reasonable place to handle it.  */

On this harward architrecture this is what GCC does:

void * p = 0x42; // compiles to 0x8000042
void (*func)() = 0x42; // compiles to 0x42

In case of `break' and `disassemble' commands an argument 0x42 should
be recognized as a code address. This is how GDB show register values
and what is a system ABI custom. (Personally I would prefer different
address space layout.)

How should avr_integer_to_address() handle integers?

The current behavior makes breakpoint-at-address impossible and breaks
IDEs (at least Qt Creator). There are many callers of value_as_address
(), I failed to deduce its contract.


Petr Hluzin

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]