mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-13 13:49:17 +02:00
+ support for bitpacked records in dwarf debug info
git-svn-id: trunk@7935 -
This commit is contained in:
parent
ac778e906d
commit
695d7c4d6d
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user