Преглед на файлове

+ dwarf for procedures and local symbols

git-svn-id: trunk@2360 -
florian преди 19 години
родител
ревизия
64acd83ab4
променени са 3 файла, в които са добавени 154 реда и са изтрити 118 реда
  1. 48 0
      compiler/aasmbase.pas
  2. 2 2
      compiler/aggas.pas
  3. 104 116
      compiler/dbgdwarf.pas

+ 48 - 0
compiler/aasmbase.pas

@@ -255,6 +255,9 @@ interface
          procedure UsedAsmSymbolListCheckUndefined;
        end;
 
+    function LengthUleb128(a: aword) : byte;
+    function LengthSleb128(a: aint) : byte;
+
     const
       { alt_jump,alt_addr,alt_data,alt_dbgline,alt_dbgfile }
       asmlabeltypeprefix : array[tasmlabeltype] of char = ('j','a','d','l','f','t','c');
@@ -274,6 +277,51 @@ implementation
       symbolsgrow = 100;
 
 
+    function LengthUleb128(a: aword) : byte;
+      var
+        b: byte;
+      begin
+        result:=0;
+        repeat
+          b := a and $7f;
+          a := a shr 7;
+          if (a <> 0) then
+            b := b or $80;
+          inc(result);
+          if a=0 then
+            break;
+        until false;
+      end;
+
+
+    function LengthSleb128(a: aint) : byte;
+      var
+        b, size: byte;
+        neg, more: boolean;
+      begin
+        more := true;
+        neg := a < 0;
+        size := sizeof(a)*8;
+        result:=0;
+        repeat
+          b := a and $7f;
+          a := a shr 7;
+          if (neg) then
+            a := a or -(1 shl (size - 7));
+          if (((a = 0) and
+               (a and $40 = 0)) or
+              ((a = -1) and
+               (a and $40 <> 0))) then
+            more := false
+          else
+            b := b or $80;
+          inc(result);
+          if not(more) then
+            break;
+        until false;
+      end;
+
+
 {*****************************************************************************
                                  TAsmSymbol
 *****************************************************************************}

+ 2 - 2
compiler/aggas.pas

@@ -1,7 +1,8 @@
 {
     Copyright (c) 1998-2006 by the Free Pascal team
 
-    This unit implements generic GNU assembler (v2.8 or later)
+    This unit implements the generic part of the GNU assembler
+    (v2.8 or later) writer
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -63,7 +64,6 @@ interface
         function NextSetLabel: string;
       end;
 
-
 implementation
 
     uses

+ 104 - 116
compiler/dbgdwarf.pas

@@ -221,8 +221,10 @@ implementation
       verbose,
       systems,
       cpubase,
+      cgbase,
       finput,
       fmodule,
+      defutil,
       symconst,symsym
       ;
 
@@ -438,7 +440,7 @@ implementation
         i : longint;
       begin
         inc(currabbrevnumber);
-        
+
         asmlist[al_dwarf_abbrev].concat(tai_comment.Create(strpnew('Abbrev '+tostr(currabbrevnumber))));
 
         { abbrev number }
@@ -508,7 +510,7 @@ implementation
                   else
                     internalerror(200601285);
                 end;
-                
+
               DW_FORM_udata:
                 case data[i].VType of
                   vtInteger:
@@ -520,7 +522,7 @@ implementation
                   else
                     internalerror(200601284);
                 end;
-                
+
               { block gets only the size, the rest is appended manually by the caller }
               DW_FORM_block1:
                 asmlist[al_dwarf_info].concat(tai_const.create_8bit(data[i].VInteger));
@@ -573,7 +575,7 @@ implementation
 
     procedure TDebugInfoDwarf.finish_children;
       begin
-        asmlist[al_dwarf_abbrev].concat(tai_const.create_8bit(0));
+        asmlist[al_dwarf_info].concat(tai_const.create_8bit(0));
       end;
 
 
@@ -587,7 +589,7 @@ implementation
             s32bit :
               begin
                 { we should generate a subrange type here }
-                if assigned(def.typesym) then                
+                if assigned(def.typesym) then
                   append_entry(DW_TAG_base_type,false,[
                     DW_AT_name,DW_FORM_string,def.typesym.name+#0,
                     DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
@@ -889,38 +891,41 @@ implementation
 
 
     procedure TDebugInfoDwarf.append_procdef(list:taasmoutput;pd:tprocdef);
-    {
       var
-        templist : taasmoutput;
-        stabsendlabel : tasmlabel;
+        procendlabel : tasmlabel;
         mangled_length : longint;
         p : pchar;
         hs : string;
-    }
       begin
-        {
         if assigned(pd.procstarttai) then
           begin
-            templist:=taasmoutput.create;
-            { para types }
-            write_def_stabstr(templist,pd);
-            if assigned(pd.parast) then
-              write_symtable_syms(templist,pd.parast);
-            { local type defs and vars should not be written
-              inside the main proc stab }
-            if assigned(pd.localst) and
-               (pd.localst.symtabletype=localsymtable) then
-              write_symtable_syms(templist,pd.localst);
-            asmlist[al_procedures].insertlistbefore(pd.procstarttai,templist);
-            { end of procedure }
-            objectlibrary.getlabel(stabsendlabel,alt_dbgtype);
-            templist.concat(tai_label.create(stabsendlabel));
+            append_entry(DW_TAG_subprogram,true,
+              [DW_AT_name,DW_FORM_string,pd.procsym.name+#0
+              { data continues below }
+              { problem: base reg isn't known here
+                DW_AT_frame_base,DW_FORM_block1,1
+              }
+              ]);
+            { append block data }
+            { asmlist[al_dwarf_info].concat(tai_const.create_8bit(dwarf_reg(pd.))); }
+
+            if not(is_void(tprocdef(pd).rettype.def)) then
+              append_labelentry_ref(DW_AT_type,def_dwarf_lab(tprocdef(pd).rettype.def));
+
+            { mark end of procedure }
+            objectlibrary.getlabel(procendlabel,alt_dbgtype);
+            asmlist[al_procedures].insertbefore(tai_label.create(procendlabel),pd.procendtai);
+
+            append_labelentry(DW_AT_low_pc,objectlibrary.newasmsymbol(pd.mangledname,AB_LOCAL,AT_DATA));
+            append_labelentry(DW_AT_high_pc,procendlabel);
+
+            {
             if assigned(pd.funcretsym) and
                (tabstractnormalvarsym(pd.funcretsym).refs>0) then
               begin
                 if tabstractnormalvarsym(pd.funcretsym).localloc.loc=LOC_REFERENCE then
                   begin
-    {$warning Need to add gdb support for ret in param register calling}
+{$warning Need to add gdb support for ret in param register calling}
                     if paramanager.ret_in_param(pd.rettype.def,pd.proccalloption) then
                       hs:='X*'
                     else
@@ -934,31 +939,25 @@ implementation
                          tostr(N_tsym)+',0,0,'+tostr(tabstractnormalvarsym(pd.funcretsym).localloc.reference.offset))));
                   end;
               end;
-            mangled_length:=length(pd.mangledname);
-            getmem(p,2*mangled_length+50);
-            strpcopy(p,'192,0,0,');
-            {$IFDEF POWERPC64}strpcopy(strend(p), '.');{$ENDIF POWERPC64}
-            strpcopy(strend(p),pd.mangledname);
-            if (tf_use_function_relative_addresses in target_info.flags) then
-              begin
-                strpcopy(strend(p),'-');
-                {$IFDEF POWERPC64}strpcopy(strend(p), '.');{$ENDIF POWERPC64}
-                strpcopy(strend(p),pd.mangledname);
-              end;
-            templist.concat(Tai_stab.Create(stab_stabn,strnew(p)));
-            strpcopy(p,'224,0,0,'+stabsendlabel.name);
-            if (tf_use_function_relative_addresses in target_info.flags) then
-              begin
-                strpcopy(strend(p),'-');
-                {$IFDEF POWERPC64}strpcopy(strend(p), '.');{$ENDIF POWERPC64}
-                strpcopy(strend(p),pd.mangledname);
-              end;
-            templist.concat(Tai_stab.Create(stab_stabn,strnew(p)));
-            freemem(p,2*mangled_length+50);
-            asmlist[al_procedures].insertlistbefore(pd.procendtai,templist);
-            templist.free;
+            }
+
+            finish_entry;
+{
+            { para types }
+            write_def_stabstr(templist,pd);
+}
+
+            if assigned(pd.parast) then
+              write_symtable_syms(list,pd.parast);
+            { local type defs and vars should not be written
+              inside the main proc stab }
+            if assigned(pd.localst) and
+               (pd.localst.symtabletype=localsymtable) then
+              write_symtable_syms(list,pd.localst);
+
+            finish_children;
           end;
-      }
+
       end;
 
 
@@ -976,7 +975,11 @@ implementation
           end;
 
 
-        procedure append_globalvarsym(sym:tglobalvarsym);
+        procedure append_varsym(sym:tabstractnormalvarsym);
+          var
+            templist : taasmoutput;
+            blocksize : longint;
+            regidx : longint;
           begin
             { external symbols can't be resolved at link time, so we
               can't generate stabs for them
@@ -986,24 +989,12 @@ implementation
             if vo_is_external in sym.varoptions then
               exit;
 
-            append_entry(DW_TAG_variable,false,[
-              DW_AT_name,DW_FORM_string,sym.name+#0,
-              {
-              DW_AT_decl_file,DW_FORM_data1,0,
-              DW_AT_decl_line,DW_FORM_data1,
-              }
-              DW_AT_external,DW_FORM_flag,true,
-              { data continues below }
-              DW_AT_location,DW_FORM_block1,1+sizeof(aword)
-              ]);
-            { append block data }
-            asmlist[al_dwarf_info].concat(tai_const.create_8bit(3));
-            asmlist[al_dwarf_info].concat(tai_const.createname(sym.mangledname,AT_DATA,0));
+            { There is no space allocated for not referenced locals }
+            if (sym.owner.symtabletype=localsymtable) and (sym.refs=0) then
+              exit;
 
-            append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.vartype.def));
+            templist:=taasmoutput.create;
 
-            // ,,
-            {
             case sym.localloc.loc of
               LOC_REGISTER,
               LOC_CREGISTER,
@@ -1012,67 +1003,62 @@ implementation
               LOC_FPUREGISTER,
               LOC_CFPUREGISTER :
                 begin
+                {
                   regidx:=findreg_by_number(sym.localloc.register);
                   { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
                   { this is the register order for GDB}
                   if regidx<>0 then
                     result:=sym_stabstr_evaluate(sym,'"${name}:r$1",${N_RSYM},0,${line},$2',[st,tostr(regstabs_table[regidx])]);
+                }
                 end;
               else
                 begin
-                  if (vo_is_thread_var in sym.varoptions) then
-                    threadvaroffset:='+'+tostr(sizeof(aint))
-                  else
-                    threadvaroffset:='';
-                  { Here we used S instead of
-                    because with G GDB doesn't look at the address field
-                    but searches the same name or with a leading underscore
-                    but these names don't exist in pascal !}
-                  st:='S'+st;
-                  result:=sym_stabstr_evaluate(sym,'"${name}:$1",${N_LCSYM},0,${line},${mangledname}$2',[st,threadvaroffset]);
+                  case sym.typ of
+                    globalvarsym:
+                      begin
+                        if (vo_is_thread_var in sym.varoptions) then
+                          begin
+{$warning !!! FIXME: dwarf for thread vars !!!}
+                          end
+                        else
+                          begin
+                            templist.concat(tai_const.create_8bit(3));
+                            templist.concat(tai_const.createname(sym.mangledname,AT_DATA,0));
+                            blocksize:=1+sizeof(aword);
+                          end;
+                      end;
+                    localvarsym:
+                      begin
+                        regidx:=findreg_by_number(sym.localloc.reference.base);
+                        templist.concat(tai_const.create_8bit(ord(DW_OP_breg0)+regdwarf_table[regidx]));
+                        templist.concat(tai_const.create_sleb128bit(sym.localloc.reference.offset));
+                        blocksize:=Lengthsleb128(sym.localloc.reference.offset)+1;
+                      end
+                    else
+                      internalerror(200601288);
+                  end;
                 end;
             end;
-            }
-            finish_entry;
-          end;
-
+            append_entry(DW_TAG_variable,false,[
+              DW_AT_name,DW_FORM_string,sym.name+#0,
+              {
+              DW_AT_decl_file,DW_FORM_data1,0,
+              DW_AT_decl_line,DW_FORM_data1,
+              }
+              DW_AT_external,DW_FORM_flag,true,
+              { data continues below }
+              DW_AT_location,DW_FORM_block1,blocksize
+              ]);
+            { append block data }
+            asmlist[al_dwarf_info].concatlist(templist);
+            append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.vartype.def));
 
-        function localvarsym_stabstr(sym:tlocalvarsym):Pchar;
-          var
-            st : string;
-            regidx : Tregisterindex;
-          begin
-            {
-            result:=nil;
-            { There is no space allocated for not referenced locals }
-            if (sym.owner.symtabletype=localsymtable) and (sym.refs=0) then
-              exit;
+            templist.free;
 
-            st:=def_stab_number(sym.vartype.def);
-            case sym.localloc.loc of
-              LOC_REGISTER,
-              LOC_CREGISTER,
-              LOC_MMREGISTER,
-              LOC_CMMREGISTER,
-              LOC_FPUREGISTER,
-              LOC_CFPUREGISTER :
-                begin
-                  regidx:=findreg_by_number(sym.localloc.register);
-                  { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
-                  { this is the register order for GDB}
-                  if regidx<>0 then
-                    result:=sym_stabstr_evaluate(sym,'"${name}:r$1",${N_RSYM},0,${line},$2',[st,tostr(regstabs_table[regidx])]);
-                end;
-              LOC_REFERENCE :
-                { offset to ebp => will not work if the framepointer is esp
-                  so some optimizing will make things harder to debug }
-                result:=sym_stabstr_evaluate(sym,'"${name}:$1",${N_TSYM},0,${line},$2',[st,tostr(sym.localloc.reference.offset)])
-              else
-                internalerror(2003091814);
-            end;
-            }
+            finish_entry;
           end;
 
+
         function paravarsym_stabstr(sym:tparavarsym):Pchar;
           var
             st : string;
@@ -1216,7 +1202,7 @@ implementation
       begin
         case sym.typ of
           globalvarsym :
-            append_globalvarsym(tglobalvarsym(sym));
+            append_varsym(tglobalvarsym(sym));
           unitsym:
             { for now, we ignore unit symbols }
             ;
@@ -1227,8 +1213,10 @@ implementation
             stabstr:=sym_stabstr_evaluate(sym,'"${name}",${N_LSYM},0,${line},0',[]);
           fieldvarsym :
             stabstr:=fieldvarsym_stabstr(tfieldvarsym(sym));
+          }
           localvarsym :
-            stabstr:=localvarsym_stabstr(tlocalvarsym(sym));
+            append_varsym(tlocalvarsym(sym));
+          {
           paravarsym :
             stabstr:=paravarsym_stabstr(tparavarsym(sym));
           typedconstsym :
@@ -1303,7 +1291,7 @@ implementation
         templist.concat(tai_symbol.createname('.Ldebug_abbrev0',AT_DATA,0));
         asmlist[al_start].insertlist(templist);
         templist.free;
-        
+
         { insert .Ldebug_line0 label }
         templist:=taasmoutput.create;
         new_section(templist,sec_debug_line,'',0);