From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jim Blandy To: Andrew Cagney Cc: gdb-patches@sources.redhat.com Subject: Re: RFA: addresses and pointers may be different sizes while printing Date: Thu, 05 Jul 2001 10:13:00 -0000 Message-id: References: <20010628223546.BDE7F5E9CB@zwingli.cygnus.com> <3B43F682.1040502@cygnus.com> X-SW-Source: 2001-07/msg00102.html Andrew Cagney writes: > Would you have an example illustrating the actual affect of this change? Sure. First, read the section ``Pointers Are Not Always Addresses'' in doc/gdbint.texinfo. It actually uses the D10V as its running example. This patch only affects architectures where code addresses and pointers are different sizes, like the D10V. Without my larger D10V patch ("RFA: Remove D10V-specific code from arch-independent modules"), GDB represents all code pointers as 32 bit values, so this patch has no effect there, either. However, the fact that GDB believes pointers are 32 bits long, while the target believes they are 16 bits long, is exactly the source of all the GDB_TARGET_IS_D10V stuff and D10V-specific macros. The whole idea is to get rid of them. So, assume that we've first applied my patch referenced above. Now sizeof (void (*)()) == 2, as it should. When we print the address of a function, we have some troubles: $ cat hello.c #include main () { printf ("Hello, world!\n"); } $ $CMitsuB/d10v-elf-gcc -g hello.c -o hello $ $DD10v/gdb/gdb hello GNU gdb 2001-07-02-cvs (MI_OUT) Copyright 2001 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "--host=i686-pc-linux-gnu --target=d10v-elf"... (gdb) print main $1 = {int ()} 0x101405c
(gdb) print/x &main $2 = 0x405c (gdb) Notice that print/x yields only the bottom 16 bits of the address of main. Some further explanation is in order here: on the D10V, our toolchain treats the data and code address spaces (64k and 256k in size) as subregions of a single, larger 32-bit address code space. Code space starts at 0x01000000. So main is 0x1405c bytes from the base of code space. So when we're printing out that code address, not only are we stripping off the top 0x01 byte, but we're also stripping off the second-to-top byte (also 0x01), which carries vital information. 0x0100405c is a completely distinct, perfectly valid code address. Those bits are tossed by the following code in print_scalar_formatted: /* If we are printing it as unsigned, truncate it in case it is actually a negative signed value (e.g. "print/u (short)-1" should print 65535 (if shorts are 16 bits) instead of 4294967295). */ if (format != 'd') { if (len < sizeof (LONGEST)) val_long &= ((LONGEST) 1 << HOST_CHAR_BIT * len) - 1; } At this point, `len' is correctly set to the size of the type in bits: 16. However, since we've already converted the 16-bit code pointer into a 32-bit code address (which is what the user wants to see), this code masks off bits which actually matter. My change adds code which says, in effect, "If we are printing an address, use a `len' of TARGET_ADDR_BIT, not TARGET_PTR_BIT." I'm assuming that TARGET_ADDR_BIT should be 32 for an architecture like the D10V. With my patch, GDB behaves like this: $ $DD10v/gdb/gdb hello GNU gdb 2001-07-02-cvs (MI_OUT) Copyright 2001 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "--host=i686-pc-linux-gnu --target=d10v-elf"... (gdb) print main $1 = {int ()} 0x101405c
(gdb) print/x &main $2 = 0x101405c (gdb) Note that the upper sixteen bits of $2 haven't been masked off: the address prints correctly with and without the /x format.