Bug 40659 - A simple struct member offset doesn't need a full dwarf location expression
Summary: A simple struct member offset doesn't need a full dwarf location expression
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-07-06 14:58 UTC by Mark Wielaard
Modified: 2009-07-08 18:21 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Wielaard 2009-07-06 14:58:01 UTC
dwarf2out.c (add_data_member_location_attribute) always generates a full dwarf location expression even for simple struct member offsets. This results in debug_info for structs that looks like this:

 <1><77>: Abbrev Number: 7 (DW_TAG_structure_type)
    <78>   DW_AT_name        : (indirect string, offset: 0x64): mystruct        
    <7c>   DW_AT_byte_size   : 40       
    <7d>   DW_AT_decl_file   : 1        
    <7e>   DW_AT_decl_line   : 5        
    <7f>   DW_AT_sibling     : <0xc0>   
 <2><83>: Abbrev Number: 8 (DW_TAG_member)
    <84>   DW_AT_name        : n        
    <86>   DW_AT_decl_file   : 1        
    <87>   DW_AT_decl_line   : 6        
    <88>   DW_AT_type        : <0xc0>   
    <8c>   DW_AT_data_member_location: 2 byte block: 23 0       (DW_OP_plus_uconst: 0)
 <2><8f>: Abbrev Number: 8 (DW_TAG_member)
    <90>   DW_AT_name        : c        
    <92>   DW_AT_decl_file   : 1        
    <93>   DW_AT_decl_line   : 7        
    <94>   DW_AT_type        : <0x6a>   
    <98>   DW_AT_data_member_location: 2 byte block: 23 8       (DW_OP_plus_uconst: 8)
 <2><9b>: Abbrev Number: 8 (DW_TAG_member)
    <9c>   DW_AT_name        : i        
    <9e>   DW_AT_decl_file   : 1        
    <9f>   DW_AT_decl_line   : 8        
    <a0>   DW_AT_type        : <0x57>   
    <a4>   DW_AT_data_member_location: 2 byte block: 23 10      (DW_OP_plus_uconst: 16)


The dwarf spec says:

"If a data member is defined in a structure, union or class, the corresponding member entry has a DW_AT_data_member_location attribute whose value describes the location of that member relative to the base address of the structure, union, or class that most closely encloses the member declaration. If that value is a constant, it is the offset in bytes from the beginning of the innermost enclosing structure, union or class to the beginning of the data member. Otherwise, the value must be a location description."

So if we only have a simple constant offset it seems more space efficient to output the offset as a constant instead of a location expression using DW_OP_plus_uconst.

A suggested patch might be the following (still building/testing against gdb and stap - gdb should work, systemtap will need some adjusting):

Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	(revision 149279)
+++ gcc/dwarf2out.c	(working copy)
@@ -11475,8 +11475,6 @@
 
   if (! loc_descr)
     {
-      enum dwarf_location_atom op;
-
       /* The DWARF2 standard says that we should assume that the structure
 	 address is already on the stack, so we can specify a structure field
 	 address by using DW_OP_plus_uconst.  */
@@ -11485,12 +11483,16 @@
       /* ??? The SGI dwarf reader does not handle the DW_OP_plus_uconst
 	 operator correctly.  It works only if we leave the offset on the
 	 stack.  */
+      enum dwarf_location_atom op;
+
       op = DW_OP_constu;
+      loc_descr = new_loc_descr (op, offset, 0);
 #else
-      op = DW_OP_plus_uconst;
+      /* Don't need an whole location expression, just a constant offset. */
+      add_AT_int (die, DW_AT_data_member_location, offset);
+      return;
 #endif
 
-      loc_descr = new_loc_descr (op, offset, 0);
     }
 
   add_AT_loc (die, DW_AT_data_member_location, loc_descr);


That will simplify the debug_info for structs so it reads:

 <1><77>: Abbrev Number: 7 (DW_TAG_structure_type)
    <78>   DW_AT_name        : (indirect string, offset: 0x3d): mystruct        
    <7c>   DW_AT_byte_size   : 40       
    <7d>   DW_AT_decl_file   : 1        
    <7e>   DW_AT_decl_line   : 4        
    <7f>   DW_AT_sibling     : <0xb6>   
 <2><83>: Abbrev Number: 8 (DW_TAG_member)
    <84>   DW_AT_name        : n        
    <86>   DW_AT_decl_file   : 1        
    <87>   DW_AT_decl_line   : 6        
    <88>   DW_AT_type        : <0xb6>   
    <8c>   DW_AT_data_member_location: 0        
 <2><8d>: Abbrev Number: 8 (DW_TAG_member)
    <8e>   DW_AT_name        : c        
    <90>   DW_AT_decl_file   : 1        
    <91>   DW_AT_decl_line   : 7        
    <92>   DW_AT_type        : <0x6a>   
    <96>   DW_AT_data_member_location: 8        
 <2><97>: Abbrev Number: 8 (DW_TAG_member)
    <98>   DW_AT_name        : i        
    <9a>   DW_AT_decl_file   : 1        
    <9b>   DW_AT_decl_line   : 8        
    <9c>   DW_AT_type        : <0x57>   
    <a0>   DW_AT_data_member_location: 16
Comment 1 Mark Wielaard 2009-07-08 18:08:02 UTC
Subject: Bug 40659

Author: mark
Date: Wed Jul  8 18:07:47 2009
New Revision: 149377

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=149377
Log:
2009-07-08  Mark Wielaard  <mjw@redhat.com>

	PR debug/40659
	* dwarf2out.c (add_data_member_location_attribute): When we have
	only a constant offset don't emit a new location description using
	DW_OP_plus_uconst, but just add the constant with add_AT_int, when
	dwarf_version > 2.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/dwarf2out.c

Comment 2 Mark Wielaard 2009-07-08 18:21:24 UTC
Patch pushed.