Description of problem: For an inlined parameter value with a link-time constant value, we are getting a DW_AT_const_value whose value is encoded with DW_FORM_data* instead of DW_FORM_addr. This confuses the consumer that needs to distinguish addresses from miscellaneous integers. cf http://sources.redhat.com/bugzilla/show_bug.cgi?id=11074 bug breaking systemtap $foo resolution Version-Release number of selected component (if applicable): gcc-4.4.2-7.fc12 How reproducible: 100% Steps to Reproduce: 1. full command line below, i386 target 2. examine DWARF data for inlined build_zonelists_node formal_parameter pgdat 3. profit Actual results: .uleb128 0x58 # (DIE (0x15984) DW_TAG_formal_parameter) .long 0xf2e4 # DW_AT_abstract_origin .long contig_page_data # DW_AT_const_value ... .uleb128 0x58 # (abbrev code) .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) .byte 0x0 # DW_children_no .uleb128 0x31 # (DW_AT_abstract_origin) .uleb128 0x13 # (DW_FORM_ref4) .uleb128 0x1c # (DW_AT_const_value) .uleb128 0x6 # (DW_FORM_data4) .byte 0x0 .byte 0x0 Expected results: s/DW_FORM_data4/DW_FORM_addr/ Additional info: % gcc -Wp,-MD,mm/.page_alloc.o.d -nostdinc -isystem /usr/lib/gcc/i68 -I/notnfs/linux-2.6/arch/x86/include -include include/linux/autoconf.h -D__KERs -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declte-null-pointer-checks -Os -m32 -msoft-float -mregparm=3 -freg-struct-return -mp-mtune=generic -Wa,-mtune=generic32 -ffreestanding -fstack-protector -DCONFIG_AS-pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-s4 -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -pg -Wdeclaration-afterct-overflow -fno-dwarf2-cfi-asm -fconserve-stack -D"KBUILD_STR(s)=#s" -D"KBUIL"KBUILD_MODNAME=KBUILD_STR(page_alloc)" -D"DEBUG_HASH=38" -D"DEBUG_HASH2=48" -c erbose-asm -save-temps -dA -v gcc: warning: -pipe ignored because -save-temps specified Using built-in specs. Target: i686-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i686 --build=i686-redhat-linux Thread model: posix gcc version 4.4.2 20091027 (Red Hat 4.4.2-7) (GCC) COLLECT_GCC_OPTIONS='-nostdinc' '-isystem' '/usr/lib/gcc/i686-redhat-linux/4.4.2/include' '-Iinclude' '-I/notnfs/linux-2.6/arch/x86/include' '-include' 'include/linux/autoconf.h' '-D__KERNEL__' '-Wall' '-Wundef' '-Wstrict-prototypes' '-Wno-trigraphs' '-fno-strict-aliasing' '-fno-common' '-Werror-implicit-function-declaration' '-Wno-format-security' '-fno-delete-null-pointer-checks' '-Os' '-m32' '-msoft-float' '-mregparm=3' '-freg-struct-return' '-mpreferred-stack-boundary=2' '-march=i686' '-mtune=generic' '-ffreestanding' '-fstack-protector' '-DCONFIG_AS_CFI=1' '-DCONFIG_AS_CFI_SIGNAL_FRAME=1' '-pipe' '-Wno-sign-compare' '-fno-asynchronous-unwind-tables' '-mno-sse' '-mno-mmx' '-mno-sse2' '-mno-3dnow' '-Wframe-larger-than=1024' '-fno-omit-frame-pointer' '-fno-optimize-sibling-calls' '-g' '-pg' '-Wdeclaration-after-statement' '-Wno-pointer-sign' '-fno-strict-overflow' '-fno-dwarf2-cfi-asm' '-fconserve-stack' '-DKBUILD_STR(s)=#s' '-DKBUILD_BASENAME=KBUILD_STR(page_alloc)' '-DKBUILD_MODNAME=KBUILD_STR(page_alloc)' '-DDEBUG_HASH=38' '-DDEBUG_HASH2=48' '-c' '-fverbose-asm' '-save-temps' '-dA' '-v' '-E' /usr/libexec/gcc/i686-redhat-linux/4.4.2/cc1 -E -quiet -nostdinc -v -Iinclude -I/notnfs/linux-2.6/arch/x86/include -D__KERNEL__ -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DKBUILD_STR(s)=#s -DKBUILD_BASENAME=KBUILD_STR(page_alloc) -DKBUILD_MODNAME=KBUILD_STR(page_alloc) -DDEBUG_HASH=38 -DDEBUG_HASH2=48 -isystem /usr/lib/gcc/i686-redhat-linux/4.4.2/include -include include/linux/autoconf.h -MD mm/.page_alloc.o.d mm/page_alloc.c -m32 -msoft-float -mregparm=3 -mpreferred-stack-boundary=2 -march=i686 -mtune=generic -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -Werror-implicit-function-declaration -Wno-format-security -Wno-sign-compare -Wframe-larger-than=1024 -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-aliasing -fno-common -fno-delete-null-pointer-checks -freg-struct-return -ffreestanding -fstack-protector -fno-asynchronous-unwind-tables -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-strict-overflow -fno-dwarf2-cfi-asm -fconserve-stack -fverbose-asm -g -fworking-directory -Os -fpch-preprocess -dA #include "..." search starts here: #include <...> search starts here: include /notnfs/linux-2.6/arch/x86/include /usr/lib/gcc/i686-redhat-linux/4.4.2/include End of search list. COMPILER_PATH=/usr/libexec/gcc/i686-redhat-linux/4.4.2/:/usr/libexec/gcc/i686-redhat-linux/4.4.2/:/usr/libexec/gcc/i686-redhat-linux/:/usr/lib/gcc/i686-redhat-linux/4.4.2/:/usr/lib/gcc/i686-redhat-linux/:/usr/libexec/gcc/i686-redhat-linux/4.4.2/:/usr/libexec/gcc/i686-redhat-linux/:/usr/lib/gcc/i686-redhat-linux/4.4.2/:/usr/lib/gcc/i686-redhat-linux/ LIBRARY_PATH=/usr/lib/gcc/i686-redhat-linux/4.4.2/:/usr/lib/gcc/i686-redhat-linux/4.4.2/:/usr/lib/gcc/i686-redhat-linux/4.4.2/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-nostdinc' '-isystem' '/usr/lib/gcc/i686-redhat-linux/4.4.2/include' '-Iinclude' '-I/notnfs/linux-2.6/arch/x86/include' '-include' 'include/linux/autoconf.h' '-D__KERNEL__' '-Wall' '-Wundef' '-Wstrict-prototypes' '-Wno-trigraphs' '-fno-strict-aliasing' '-fno-common' '-Werror-implicit-function-declaration' '-Wno-format-security' '-fno-delete-null-pointer-checks' '-Os' '-m32' '-msoft-float' '-mregparm=3' '-freg-struct-return' '-mpreferred-stack-boundary=2' '-march=i686' '-mtune=generic' '-ffreestanding' '-fstack-protector' '-DCONFIG_AS_CFI=1' '-DCONFIG_AS_CFI_SIGNAL_FRAME=1' '-pipe' '-Wno-sign-compare' '-fno-asynchronous-unwind-tables' '-mno-sse' '-mno-mmx' '-mno-sse2' '-mno-3dnow' '-Wframe-larger-than=1024' '-fno-omit-frame-pointer' '-fno-optimize-sibling-calls' '-g' '-pg' '-Wdeclaration-after-statement' '-Wno-pointer-sign' '-fno-strict-overflow' '-fno-dwarf2-cfi-asm' '-fconserve-stack' '-DKBUILD_STR(s)=#s' '-DKBUILD_BASENAME=KBUILD_STR(page_alloc)' '-DKBUILD_MODNAME=KBUILD_STR(page_alloc)' '-DDEBUG_HASH=38' '-DDEBUG_HASH2=48' '-c' '-fverbose-asm' '-save-temps' '-dA' '-v' '-E' gcc: warning: -pipe ignored because -save-temps specified Using built-in specs. Target: i686-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i686 --build=i686-redhat-linux Thread model: posix gcc version 4.4.2 20091027 (Red Hat 4.4.2-7) (GCC) COLLECT_GCC_OPTIONS='-nostdinc' '-isystem' '/usr/lib/gcc/i686-redhat-linux/4.4.2/include' '-Iinclude' '-I/notnfs/linux-2.6/arch/x86/include' '-include' 'include/linux/autoconf.h' '-D__KERNEL__' '-Wall' '-Wundef' '-Wstrict-prototypes' '-Wno-trigraphs' '-fno-strict-aliasing' '-fno-common' '-Werror-implicit-function-declaration' '-Wno-format-security' '-fno-delete-null-pointer-checks' '-Os' '-m32' '-msoft-float' '-mregparm=3' '-freg-struct-return' '-mpreferred-stack-boundary=2' '-march=i686' '-mtune=generic' '-ffreestanding' '-fstack-protector' '-DCONFIG_AS_CFI=1' '-DCONFIG_AS_CFI_SIGNAL_FRAME=1' '-pipe' '-Wno-sign-compare' '-fno-asynchronous-unwind-tables' '-mno-sse' '-mno-mmx' '-mno-sse2' '-mno-3dnow' '-Wframe-larger-than=1024' '-fno-omit-frame-pointer' '-fno-optimize-sibling-calls' '-g' '-pg' '-Wdeclaration-after-statement' '-Wno-pointer-sign' '-fno-strict-overflow' '-fno-dwarf2-cfi-asm' '-fconserve-stack' '-DKBUILD_STR(s)=#s' '-DKBUILD_BASENAME=KBUILD_STR(page_alloc)' '-DKBUILD_MODNAME=KBUILD_STR(page_alloc)' '-DDEBUG_HASH=38' '-DDEBUG_HASH2=48' '-c' '-fverbose-asm' '-save-temps' '-dA' '-v' '-o' '/var/tmp/fche/ccache/tmp.hash.vm-rawhide-32.2765.o' /usr/libexec/gcc/i686-redhat-linux/4.4.2/cc1 -fpreprocessed /var/tmp/fche/ccache/page_alloc.tmp.vm-rawhide-32.2765.i -quiet -dumpbase page_alloc.tmp.vm-rawhide-32.2765.i -dA -m32 -msoft-float -mregparm=3 -mpreferred-stack-boundary=2 -march=i686 -mtune=generic -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -auxbase-strip /var/tmp/fche/ccache/tmp.hash.vm-rawhide-32.2765.o -g -Os -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -Werror-implicit-function-declaration -Wno-format-security -Wno-sign-compare -Wframe-larger-than=1024 -Wdeclaration-after-statement -Wno-pointer-sign -version -p -fno-strict-aliasing -fno-common -fno-delete-null-pointer-checks -freg-struct-return -ffreestanding -fstack-protector -fno-asynchronous-unwind-tables -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-strict-overflow -fno-dwarf2-cfi-asm -fconserve-stack -fverbose-asm -o page_alloc.tmp.vm-rawhide-32.2765.s GNU C (GCC) version 4.4.2 20091027 (Red Hat 4.4.2-7) (i686-redhat-linux) compiled by GNU C version 4.4.2 20091027 (Red Hat 4.4.2-7), GMP version 4.3.1, MPFR version 2.4.1. GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: bba6b4235667b4e22536a25004e123c4 COLLECT_GCC_OPTIONS='-nostdinc' '-isystem' '/usr/lib/gcc/i686-redhat-linux/4.4.2/include' '-Iinclude' '-I/notnfs/linux-2.6/arch/x86/include' '-include' 'include/linux/autoconf.h' '-D__KERNEL__' '-Wall' '-Wundef' '-Wstrict-prototypes' '-Wno-trigraphs' '-fno-strict-aliasing' '-fno-common' '-Werror-implicit-function-declaration' '-Wno-format-security' '-fno-delete-null-pointer-checks' '-Os' '-m32' '-msoft-float' '-mregparm=3' '-freg-struct-return' '-mpreferred-stack-boundary=2' '-march=i686' '-mtune=generic' '-ffreestanding' '-fstack-protector' '-DCONFIG_AS_CFI=1' '-DCONFIG_AS_CFI_SIGNAL_FRAME=1' '-pipe' '-Wno-sign-compare' '-fno-asynchronous-unwind-tables' '-mno-sse' '-mno-mmx' '-mno-sse2' '-mno-3dnow' '-Wframe-larger-than=1024' '-fno-omit-frame-pointer' '-fno-optimize-sibling-calls' '-g' '-pg' '-Wdeclaration-after-statement' '-Wno-pointer-sign' '-fno-strict-overflow' '-fno-dwarf2-cfi-asm' '-fconserve-stack' '-DKBUILD_STR(s)=#s' '-DKBUILD_BASENAME=KBUILD_STR(page_alloc)' '-DKBUILD_MODNAME=KBUILD_STR(page_alloc)' '-DDEBUG_HASH=38' '-DDEBUG_HASH2=48' '-c' '-fverbose-asm' '-save-temps' '-dA' '-v' '-o' '/var/tmp/fche/ccache/tmp.hash.vm-rawhide-32.2765.o'
I believe DW_FORM_addr is invalid for DW_AT_const_value, see http://gcc.gnu.org/ml/gcc-patches/2009-09/msg02275.html The standard lists block, constant, string classes for DW_AT_const_value, but not address. And I had to change it also because gdb couldn't handle. If you get the standard changed to allow this and get gdb fixed first, I guess that part of the change could be reverted.
Reading the dwarf4 dwarf spec does indeed suggest DW_FORM_addr isn't allowed for DW_AT_const_value. But in that case can DW_AT_const_value even be used for (constant) addresses? "An entry describing a variable or formal parameter whose value is constant and not represented by an object in the address space of the program, or an entry describing a named constant, does not have a location attribute." So, does "not represented by an object in the address space" mean that it cannot be an address itself? "Such entries have a DW_AT_const_value attribute, whose value may be a string or any of the constant data or data block forms, asappropriate for the representation of the variable’s value." The problem is that "as appropriate for the representation of the variable's value" doesn't make sense for addresses, if you may not use DW_FORM_addr. So it seems we really should ask the dwarf committee to allow this.
GDB cannot relocate such debug info addresses. But GDB can easily fix it by checking if its DW_AT_type is a pointer. Not sure what is right now. echo -e 'static int i;static int *const ip = &i;void g (void *a, void *b) {} void f (void) { g (&i, ip); }'|gcc -O2 -o a.so -shared -fPIC -Wall -g -x c -;echo -e 'extern void f (void); int main () { f(); return 0; }'|gcc -o a ./a.so -Wall -g -x c -;gdb -nx -ex start -ex 'adv g' -ex 'p &i' -ex 'p ip' ./a g (a=0x7ffff7ffc848, b=0x7ffff7ffc848) at <stdin>:1 $1 = (int *) 0x7ffff7ffc848 $2 = (int * const) 0x200848 $2 (`ip') is errorneously not relocated. It is correct with -O0: g (a=0x7ffff7ffc890, b=0x7ffff7ffc890) at <stdin>:1 $1 = (int *) 0x7ffff7ffc890 $2 = (int * const) 0x7ffff7ffc890 <1><92>: Abbrev Number: 8 (DW_TAG_variable) <93> DW_AT_name : ip ... <9c> DW_AT_const_value : 0x200848 0x0 8 DW_TAG_variable [no children] DW_AT_name DW_FORM_string ... DW_AT_const_value DW_FORM_data8
I posted to dwarf-discuss at some length about the broad subject we've hit. Regardless of possible spec changes coming about from that, there is something gcc can do today. When emitting v4 format, always emit DW_AT_location using DW_OP_addr DW_OP_stack_value for any case that uses symbols rather than pure integer literals in the emitted assembly. When not emitting v4 format, omit DW_AT_const_value/DW_AT_location entirely when it would need to be a symbolic address literal.
Fixed in gcc-4.4.2-20.fc{12,13}.
Making gdb support DW_FORM_addr for DW_AT_const_value does not seem very hard. While looking at this I found that we are also not relocating DW_OP_addr. Then, while looking at that, I found that GCC emits: DW_OP_addr: 4; DW_OP_GNU_push_tls_address ... to implement TLS. IIUC, though, the value here is really just a constant. So, using DW_OP_addr seems incorrect. If we need to support the full generality of DW_OP_GNU_push_tls_address anywhere in an expression, then the fix is going to be quite ugly. OTOH, if the short form above is all that is generated, there is already a special hack in gdb for it.