mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 23:28:13 +02:00
Merge branch 'mfr-dwarf-tag-string' into 'main'
Draft: Introduce DW_TAG_string_type for dwarf-4 See merge request freepascal.org/fpc/source!683
This commit is contained in:
commit
451a647b6b
@ -259,9 +259,12 @@ interface
|
||||
end;
|
||||
|
||||
|
||||
{ TDebugInfoDwarf4 }
|
||||
|
||||
TDebugInfoDwarf4 = class(TDebugInfoDwarf3)
|
||||
public
|
||||
function dwarf_version: Word; override;
|
||||
procedure appenddef_string(list:TAsmList;def:tstringdef);override;
|
||||
end;
|
||||
|
||||
|
||||
@ -4486,6 +4489,145 @@ implementation
|
||||
Result:=4;
|
||||
end;
|
||||
|
||||
procedure TDebugInfoDwarf4.appenddef_string(list: TAsmList; def: tstringdef);
|
||||
|
||||
procedure addstringdef(const name: shortstring; chardef: tdef; deref: boolean; lensize: aint);
|
||||
var
|
||||
upperopcodes: longint;
|
||||
begin
|
||||
{ deref=true -> ansi/unicde/widestring; deref = false -> short/longstring }
|
||||
if assigned(def.typesym) then
|
||||
append_entry(DW_TAG_string_type,false,[
|
||||
DW_AT_name,DW_FORM_string,name+#0,
|
||||
DW_AT_data_location,DW_FORM_block1,2+ord(not(deref))
|
||||
])
|
||||
else
|
||||
append_entry(DW_TAG_string_type,false,[
|
||||
DW_AT_data_location,DW_FORM_block1,2+ord(not(deref))
|
||||
]);
|
||||
|
||||
{ in all cases we start with the address of the string }
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_push_object_address)));
|
||||
if deref then
|
||||
begin
|
||||
{ ansi/unicode/widestring -> dereference the address of the string, and then
|
||||
we point to address of the string
|
||||
}
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_deref)));
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ shortstring characters begin at string[1], so add one to the string's address }
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_lit0)+lensize));
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_plus)))
|
||||
end;
|
||||
|
||||
{ reference to the element type of the string }
|
||||
append_labelentry_ref(DW_AT_type,def_dwarf_lab(chardef));
|
||||
|
||||
if deref then
|
||||
begin
|
||||
if not (is_widestring(def) and (tf_winlikewidestring in target_info.flags)) then
|
||||
upperopcodes:=14
|
||||
else
|
||||
upperopcodes:=17;
|
||||
|
||||
// DWARF-4: DW_AT_byte_size
|
||||
// DWARF-5: DW_AT_string_length_byte_size
|
||||
append_attribute(DW_AT_byte_size, DW_FORM_data1, [4]); // size of the length field
|
||||
append_block1(DW_AT_string_length, upperopcodes);
|
||||
|
||||
{ high(string) is stored sizeof(sizeint) bytes before the string data }
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_push_object_address)));
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_deref)));
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_dup)));
|
||||
{ pointer = nil? }
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_bra)));
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_16bit_unaligned(4));
|
||||
{ yes -> length = 0 }
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_lit0)));
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_skip)));
|
||||
if upperopcodes=17 then
|
||||
{ skip the extra deref_size argument and the division by two of the length }
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_16bit_unaligned(6))
|
||||
else
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_16bit_unaligned(3));
|
||||
{ no -> load length }
|
||||
if upperopcodes=17 then
|
||||
{ for Windows WideString the size is always a DWORD }
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_lit4)))
|
||||
else
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_lit0)+sizesinttype.size));
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_minus)));
|
||||
if upperopcodes=17 then
|
||||
begin
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_deref_size)));
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(4));
|
||||
end
|
||||
else
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_deref)));
|
||||
|
||||
{ for widestrings, the length is specified in bytes, so divide by two }
|
||||
if (upperopcodes=17) then
|
||||
begin
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_lit1)));
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_shr)));
|
||||
end;
|
||||
{ skip to past end is not allowed, thus use a nop here }
|
||||
{ Replace NOP by DW_OP_stack_value / only needed if done OP_shr, but ok in other cases}
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_stack_value)));
|
||||
end
|
||||
else
|
||||
begin
|
||||
// DWARF-4: DW_AT_byte_size
|
||||
// DWARF-5: DW_AT_string_length_byte_size
|
||||
append_attribute(DW_AT_byte_size, DW_FORM_data1, [lensize]); // size of the length field
|
||||
|
||||
append_block1(DW_AT_string_length, 1);
|
||||
{ for shortstrings, the length is the first byte of the string }
|
||||
current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_push_object_address)));
|
||||
end;
|
||||
|
||||
finish_entry;
|
||||
end;
|
||||
|
||||
begin
|
||||
if (ds_dwarf_cpp in current_settings.debugswitches) then
|
||||
begin
|
||||
// At least LLDB 6.0.0 does not like this implementation of string types.
|
||||
// Call the inherited DWARF 2 implementation, which works fine.
|
||||
inherited;
|
||||
exit;
|
||||
end;
|
||||
|
||||
case def.stringtype of
|
||||
st_shortstring:
|
||||
begin
|
||||
addstringdef('ShortString',cansichartype,false,1);
|
||||
end;
|
||||
st_longstring:
|
||||
begin
|
||||
{$ifdef cpu64bitaddr}
|
||||
addstringdef('LongString',cansichartype,false,8);
|
||||
{$else cpu64bitaddr}
|
||||
addstringdef('LongString',cansichartype,false,4);
|
||||
{$endif cpu64bitaddr}
|
||||
end;
|
||||
st_ansistring:
|
||||
begin
|
||||
addstringdef('AnsiString',cansichartype,true,-1);
|
||||
end;
|
||||
st_unicodestring:
|
||||
begin
|
||||
addstringdef('UnicodeString',cwidechartype,true,-1);
|
||||
end;
|
||||
st_widestring:
|
||||
begin
|
||||
addstringdef('WideString',cwidechartype,true,-1)
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
****************************************************************************}
|
||||
|
Loading…
Reference in New Issue
Block a user