浏览代码

+ append_block1() to add extra block DW_FORM_block1 attributes to
a dwarf entry
- (dwarf3) removed stride size from dynamic array entries because
it's not required there (the stride always equals the element size)
+ (dwarf3) added "allocated" attribute for dynamic arrays
+ (dwarf3) added generic implementation of string support for dwarf3,
which no longer depends on the hacked fake record type in gdb's
Pascal support. Includes support for all string types, except for
winlike widestrings (because I don't know how to extract the
length from them)

git-svn-id: trunk@12444 -

Jonas Maebe 16 年之前
父节点
当前提交
03a7d089b9
共有 1 个文件被更改,包括 139 次插入6 次删除
  1. 139 6
      compiler/dbgdwarf.pas

+ 139 - 6
compiler/dbgdwarf.pas

@@ -243,6 +243,7 @@ interface
         procedure set_def_dwarf_labs(def:tdef);
         procedure set_def_dwarf_labs(def:tdef);
 
 
         procedure append_entry(tag : tdwarf_tag;has_children : boolean;data : array of const);
         procedure append_entry(tag : tdwarf_tag;has_children : boolean;data : array of const);
+        procedure append_block1(attr: tdwarf_attribute; size: aint);
         procedure append_labelentry(attr : tdwarf_attribute;sym : tasmsymbol);
         procedure append_labelentry(attr : tdwarf_attribute;sym : tasmsymbol);
         procedure append_labelentry_ref(attr : tdwarf_attribute;sym : tasmsymbol);
         procedure append_labelentry_ref(attr : tdwarf_attribute;sym : tasmsymbol);
         procedure append_labelentry_dataptr_abs(attr : tdwarf_attribute;sym : tasmsymbol);
         procedure append_labelentry_dataptr_abs(attr : tdwarf_attribute;sym : tasmsymbol);
@@ -311,6 +312,7 @@ interface
       private
       private
       protected
       protected
         procedure appenddef_array(list:TAsmList;def:tarraydef); override;
         procedure appenddef_array(list:TAsmList;def:tarraydef); override;
+        procedure appenddef_string(list:TAsmList;def:tstringdef);override;
         procedure appenddef_file(list:TAsmList;def:tfiledef); override;
         procedure appenddef_file(list:TAsmList;def:tfiledef); override;
         procedure appenddef_formal(list:TAsmList;def:tformaldef); override;
         procedure appenddef_formal(list:TAsmList;def:tformaldef); override;
         procedure appenddef_object(list:TAsmList;def:tobjectdef); override;
         procedure appenddef_object(list:TAsmList;def:tobjectdef); override;
@@ -954,6 +956,14 @@ implementation
       end;
       end;
 
 
 
 
+    procedure TDebugInfoDwarf.append_block1(attr: tdwarf_attribute; size: aint);
+      begin
+        current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(attr)));
+        current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_block1)));
+        current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(size));
+      end;
+
+
     procedure TDebugInfoDwarf.append_labelentry(attr : tdwarf_attribute;sym : tasmsymbol);
     procedure TDebugInfoDwarf.append_labelentry(attr : tdwarf_attribute;sym : tasmsymbol);
       begin
       begin
         current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(attr)));
         current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(attr)));
@@ -2842,8 +2852,6 @@ implementation
 ****************************************************************************}
 ****************************************************************************}
 
 
     procedure tdebuginfodwarf3.appenddef_array(list: tasmlist; def: tarraydef);
     procedure tdebuginfodwarf3.appenddef_array(list: tasmlist; def: tarraydef);
-      var
-        elesize : aint;
       begin
       begin
         if not is_dynamic_array(def) then
         if not is_dynamic_array(def) then
           begin
           begin
@@ -2851,21 +2859,21 @@ implementation
             exit;
             exit;
           end;
           end;
 
 
-        elesize := def.elesize*8;
-
         if assigned(def.typesym) then
         if assigned(def.typesym) then
           append_entry(DW_TAG_array_type,true,[
           append_entry(DW_TAG_array_type,true,[
             DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
             DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
-            DW_AT_stride_size,DW_FORM_udata,elesize,
             DW_AT_data_location,DW_FORM_block1,2
             DW_AT_data_location,DW_FORM_block1,2
             ])
             ])
         else
         else
           append_entry(DW_TAG_array_type,true,[
           append_entry(DW_TAG_array_type,true,[
-            DW_AT_stride_size,DW_FORM_udata,elesize,
             DW_AT_data_location,DW_FORM_block1,2
             DW_AT_data_location,DW_FORM_block1,2
             ]);
             ]);
         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_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_deref)));
+        append_block1(DW_AT_allocated,2);
+        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)));
+
         append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.elementdef));
         append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.elementdef));
         finish_entry;
         finish_entry;
         { to simplify things, we don't write a multidimensional array here }
         { to simplify things, we don't write a multidimensional array here }
@@ -2884,6 +2892,131 @@ implementation
         finish_children;
         finish_children;
       end;
       end;
 
 
+
+    procedure tdebuginfodwarf3.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_array_type,true,[
+              DW_AT_name,DW_FORM_string,name+#0,
+              DW_AT_data_location,DW_FORM_block1,2+ord(not(deref))
+              ])
+          else
+            append_entry(DW_TAG_array_type,true,[
+              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)));
+
+              { also add how to detect whether or not the string is allocated: if the pointer is 0
+                then it isn't, otherwise it is
+              }
+              append_block1(DW_AT_allocated,2);
+              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)));
+            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));
+          finish_entry;
+
+          { now the information about the length of the string }
+          if deref then
+            begin
+              if (chardef.size=1) then
+                upperopcodes:=5
+              else
+                upperopcodes:=7;
+              { lower bound is always 1, upper bound (length) needs to be calculated }
+              append_entry(DW_TAG_subrange_type,false,[
+                DW_AT_lower_bound,DW_FORM_udata,1,
+                DW_AT_upper_bound,DW_FORM_block1,upperopcodes
+                ]);
+
+              { high(string) is stored sizeof(ptrint) 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_lit0)+sizeof(ptrint)));
+              current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_minus)));
+              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=7) 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_shra)));
+                end;
+            end
+          else
+            begin
+              append_entry(DW_TAG_subrange_type,false,[
+                DW_AT_lower_bound,DW_FORM_udata,1,
+                DW_AT_upper_bound,DW_FORM_block1,3
+                ]);
+              { 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)));
+              { load 1 byte }
+              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(lensize));
+            end;
+          finish_entry;
+
+          finish_children;
+        end;
+
+      begin
+        case def.stringtype of
+          st_shortstring:
+            begin
+              addstringdef('ShortString',cchartype,false,1);
+            end;
+          st_longstring:
+            begin
+{$ifdef cpu64bitaddr}
+              addstringdef('LongString',cchartype,false,8);
+{$else cpu64bitaddr}
+              addstringdef('LongString',cchartype,false,4);
+{$endif cpu64bitaddr}
+           end;
+         st_ansistring:
+           begin
+             addstringdef('AnsiString',u8inttype,true,-1);
+           end;
+         st_unicodestring:
+           begin
+             addstringdef('UnicodeString',cwidechartype,true,-1);
+           end;
+         st_widestring:
+           begin
+             if not(tf_winlikewidestring in target_info.flags) then
+               addstringdef('WideString',cwidechartype,true,-1)
+             else
+               begin
+                 { looks like a pwidechar (no idea about length location) }
+                 append_entry(DW_TAG_pointer_type,false,[]);
+                 append_labelentry_ref(DW_AT_type,def_dwarf_lab(cwidechartype));
+                 finish_entry;
+              end;
+           end;
+        end;
+      end;
+
     procedure TDebugInfoDwarf3.appenddef_file(list:TAsmList;def: tfiledef);
     procedure TDebugInfoDwarf3.appenddef_file(list:TAsmList;def: tfiledef);
       begin
       begin
         if assigned(def.typesym) then
         if assigned(def.typesym) then