Bug 546017
| Summary: | DW_AT_const_value not using DW_FORM_addr for address constant | ||
|---|---|---|---|
| Product: | [Fedora] Fedora | Reporter: | Roland McGrath <roland> |
| Component: | gcc | Assignee: | Jakub Jelinek <jakub> |
| Status: | CLOSED RAWHIDE | QA Contact: | Fedora Extras Quality Assurance <extras-qa> |
| Severity: | medium | Docs Contact: | |
| Priority: | low | ||
| Version: | 12 | CC: | aoliva, fche, jakub, jan.kratochvil, mjw, tromey |
| Target Milestone: | --- | ||
| Target Release: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | Bug Fix | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2009-12-22 21:04:08 UTC | Type: | --- |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
|
Description
Roland McGrath
2009-12-09 20:00:00 UTC
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. |