Bug 9511 - avr gdb accessing ram instead of eeprom
Summary: avr gdb accessing ram instead of eeprom
Status: ASSIGNED
Alias: None
Product: gdb
Classification: Unclassified
Component: gdb (show other bugs)
Version: 6.7
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-01-17 09:58 UTC by tomas.vanek
Modified: 2008-12-19 19:15 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
avr-gdb-eeprom.patch (885 bytes, application/octet-stream)
, tomas.vanek
Details

Note You need to log in before you can comment on or make changes to this bug.
Description tomas.vanek 2008-01-17 09:58:01 UTC
[Converted from Gnats 2406]

AVR uses concept of different gdbarch_ptr_bit and gdbarch_addr_bit.
gdbarch_ptr_bit is set to 16 and represents the size of a pointer on the target.
gdbarch_addr_bit is set to 32 and as the size of a target address as represented in gdb.

If gdb is accessing a pointer on the target the avr_address_to_pointer() or avr_pointer_to_address() conversion is the only way. The problem is that gdb cuts the address to pointer size even for internal purposes, in expression evaluator. Evaluating a reference operator (&) should store full target address, however it builds internal struct value typed as pointer filled by only 16 bit of address.

EEPROM segment is on AVR normally at 0x810000, RAM is from 0x800000.

Release:
from at least gdb 6.6 up to 6.7.50.20080117-cvs

Environment:
not dependent on host system
from at least gdb 6.6 up to current cvs
GDB was configured as "--host=i686-pc-linux-gnu --target=avr"

How-To-Repeat:
Lets have the code:

int eeVar __attribute__((section(".eeprom"))) = 123;
int eeArray[2] __attribute__((section(".eeprom"))) = { 34, 56 };
int main() {}


avr-nm shows the addresses:
00810002 D eeArray
00810000 D eeVar

Now inspect variables in gdb:

(gdb) p eeVar
$1 = 123

Good.


(gdb) p &eeVar
$2 = (int *) 0x800000

Wrong. It's a RAM address. 0x800000 prefix is added in avr_pointer_to_address()


(gdb) p *&eeVar
$3 = 0

Wrong. Value is read from RAM instead form EEPROM.

Of course there is no point in using *& construction. But wait. gdb uses similar technique to access array elements:

(gdb) p eeArray
$4 = {34, 56}

Good.


(gdb) p eeArray [1]
$5= 0

Wrong. Value goes from RAM again.

Same problem is for writing values, they go to RAM, not to EEPROM.
Comment 1 tomas.vanek 2008-01-17 09:58:01 UTC
Fix:
Store gdbarch_addr_bit() bits of address instead gdbarch_ptr_bit() to any struct value representing a pointer. The size of the pointer type in type info have to stay unchanged! We should just treat internal data value.aliner.contents as gdbarch_addr_bit() long, instead of gdbarch_ptr_bit() long. It looks weird but it is exactly what we need:

p sizeof(&eeVar) returns 2, as appropriate on the target.
p &eeVar returns 0x810000, right address in EEPROM.

The attached patch should not have any influence on targets with gdbarch_addr_bit() equal to gdbarch_ptr_bit().
There are more architectures using different gdbarch_ptr_bit() and gdbarch_addr_bit():
Reneas H8/300, M32C
Motorola 68hc11
Sanyo Xstormy16a
The patch should be verified against them.