Browse Source

+ support for bitpacked records in dwarf debug info

git-svn-id: trunk@7935 -
Jonas Maebe 18 years ago
parent
commit
695d7c4d6d
1 changed files with 64 additions and 24 deletions
  1. 64 24
      compiler/dbgdwarf.pas

+ 64 - 24
compiler/dbgdwarf.pas

@@ -29,6 +29,9 @@
   The easiest way to debug dwarf debug info generation is the usage of
   readelf --debug-dump <executable>
   This works only with elf targets though.
+  
+  There is a similar utility called dwarfdump which is not elf-specific and
+  which has been ported to most systems.
 }
 unit dbgdwarf;
 
@@ -331,7 +334,7 @@ interface
 implementation
 
     uses
-      cutils,cfileutl,
+      cutils,cfileutl,constexp,
       version,globtype,globals,verbose,systems,
       cpubase,cgbase,paramgr,
       fmodule,
@@ -1011,40 +1014,35 @@ implementation
       end;
 
     procedure TDebugInfoDwarf.appenddef_ord(def:torddef);
+      var
+        sign: tdwarf_type;
       begin
         case def.ordtype of
           s8bit,
           s16bit,
-          s32bit :
-            begin
-              { we should generate a subrange type here }
-              if assigned(def.typesym) then
-                append_entry(DW_TAG_base_type,false,[
-                  DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
-                  DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
-                  DW_AT_byte_size,DW_FORM_data1,def.size
-                  ])
-              else
-                append_entry(DW_TAG_base_type,false,[
-                  DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
-                  DW_AT_byte_size,DW_FORM_data1,def.size
-                  ]);
-              finish_entry;
-            end;
+          s32bit,
           u8bit,
           u16bit,
           u32bit :
             begin
+              { generate proper signed/unsigned info for types like 0..3 }
+              { these are s8bit, but should be identified as unsigned    }
+              { because otherwise they are interpreted wrongly when used }
+              { in a bitpacked record                                    }
+              if (def.low<0) then
+                sign:=DW_ATE_signed
+              else
+                sign:=DW_ATE_unsigned;
               { we should generate a subrange type here }
               if assigned(def.typesym) then
                 append_entry(DW_TAG_base_type,false,[
                   DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
-                  DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned,
+                  DW_AT_encoding,DW_FORM_data1,sign,
                   DW_AT_byte_size,DW_FORM_data1,def.size
                   ])
               else
                 append_entry(DW_TAG_base_type,false,[
-                  DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned,
+                  DW_AT_encoding,DW_FORM_data1,sign,
                   DW_AT_byte_size,DW_FORM_data1,def.size
                   ]);
               finish_entry;
@@ -1842,15 +1840,57 @@ implementation
 
 
       procedure TDebugInfoDwarf.appendsym_fieldvar(sym: tfieldvarsym);
+        var
+          bitoffset,
+          fieldoffset,
+          fieldnatsize: aint;
         begin
           if sp_static in sym.symoptions then Exit;
 
-          append_entry(DW_TAG_member,false,[
-            DW_AT_name,DW_FORM_string,symname(sym)+#0,
-            DW_AT_data_member_location,DW_FORM_block1,1+lengthuleb128(sym.fieldoffset)
-            ]);
+          if (tabstractrecordsymtable(sym.owner).usefieldalignment<>bit_alignment) or
+             { only ordinals are bitpacked }
+             not is_ordinal(sym.vardef) then
+            begin
+              { other kinds of fields can however also appear in a bitpacked   }
+              { record, and then their offset is also specified in bits rather }
+              { than in bytes                                                  }
+              if (tabstractrecordsymtable(sym.owner).usefieldalignment<>bit_alignment) then
+                fieldoffset:=sym.fieldoffset
+              else
+                fieldoffset:=sym.fieldoffset div 8;
+              append_entry(DW_TAG_member,false,[
+                DW_AT_name,DW_FORM_string,symname(sym)+#0,
+                DW_AT_data_member_location,DW_FORM_block1,1+lengthuleb128(fieldoffset)
+                ]);
+            end
+          else
+            begin
+              if (sym.vardef.packedbitsize > 255) then
+                internalerror(2007061201);
+
+              { we don't bitpack according to the ABI, but as close as }
+              { possible, i.e., equivalent to gcc's                    }
+              { __attribute__((__packed__)), which is also what gpc    }
+              { does.                                                  }
+              fieldnatsize:=max(sizeof(aint),sym.vardef.size);
+              fieldoffset:=(sym.fieldoffset div (fieldnatsize*8)) * fieldnatsize;
+              bitoffset:=sym.fieldoffset mod (fieldnatsize*8);
+              if (target_info.endian=endian_little) then
+                bitoffset:=(fieldnatsize*8)-bitoffset-sym.vardef.packedbitsize;
+              append_entry(DW_TAG_member,false,[
+                DW_AT_name,DW_FORM_string,symname(sym)+#0,
+                { gcc also generates both a bit and byte size attribute }
+                { we don't support ordinals >= 256 bits }
+                DW_AT_byte_size,DW_FORM_data1,fieldnatsize,
+                { nor >= 256 bits (not yet, anyway, see IE above) }
+                DW_AT_bit_size,DW_FORM_data1,sym.vardef.packedbitsize,
+                { data1 and data2 are unsigned, bitoffset can also be negative }
+                DW_AT_bit_offset,DW_FORM_data4,bitoffset,
+                DW_AT_data_member_location,DW_FORM_block1,1+lengthuleb128(fieldoffset)
+                ]);
+            end;
           current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_plus_uconst)));
-          current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(sym.fieldoffset));
+          current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(fieldoffset));
 
           append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.vardef));
           finish_entry;