Explorar o código

* -Xg generates a separate file with the debug info sections

git-svn-id: trunk@6628 -
peter %!s(int64=18) %!d(string=hai) anos
pai
achega
9f3de7e809
Modificáronse 5 ficheiros con 191 adicións e 68 borrados
  1. 1 1
      compiler/globtype.pas
  2. 2 0
      compiler/link.pas
  3. 157 32
      compiler/ogbase.pas
  4. 22 33
      compiler/ogcoff.pas
  5. 9 2
      compiler/options.pas

+ 1 - 1
compiler/globtype.pas

@@ -132,7 +132,7 @@ interface
          { linking }
          cs_link_nolink,cs_link_static,cs_link_smart,cs_link_shared,cs_link_deffile,
          cs_link_strip,cs_link_staticflag,cs_link_on_target,cs_link_extern,cs_link_opt_vtable,
-         cs_link_opt_used_sections,
+         cs_link_opt_used_sections,cs_link_separate_dbg_file,
          cs_link_map,cs_link_pthread,cs_link_no_default_lib_order
        );
        tglobalswitches = set of tglobalswitch;

+ 2 - 0
compiler/link.pas

@@ -990,6 +990,8 @@ Implementation
           goto myexit;
 
         exeoutput.WriteExeFile(outputname);
+        if cs_link_separate_dbg_file in current_settings.globalswitches then
+          exeoutput.WriteDbgFile(ChangeFileExt(outputname,'.dbg'));
 
 {$warning TODO fixed section names}
         status.codesize:=exeoutput.findexesection('.text').size;

+ 157 - 32
compiler/ogbase.pas

@@ -389,6 +389,7 @@ interface
         FCExeSection      : TExeSectionClass;
         FCurrExeSec       : TExeSection;
         FExeSectionList   : TFPHashObjectList;
+        FDebugSectionList : TFPHashObjectList;
         Fzeronr           : longint;
         { Symbols }
         FExeSymbolList    : TFPHashObjectList;
@@ -428,8 +429,8 @@ interface
         procedure Order_Start;virtual;
         procedure Order_End;virtual;
         procedure Order_ExeSection(const aname:string);virtual;
-        procedure Order_Align(const aname:string);virtual;
-        procedure Order_Zeros(const aname:string);virtual;
+        procedure Order_Align(const avalue:string);virtual;
+        procedure Order_Zeros(const avalue:string);virtual;
         procedure Order_Symbol(const aname:string);virtual;
         procedure Order_EndExeSection;virtual;
         procedure Order_ObjSection(const aname:string);virtual;
@@ -448,9 +449,11 @@ interface
         procedure RemoveUnreferencedSections;
         procedure RemoveEmptySections;
         procedure GenerateLibraryImports(ImportLibraryList:TFPHashObjectList);virtual;
+        function  writedbgfile(const fn:string):boolean;
         function  writeexefile(const fn:string):boolean;
         property Writer:TObjectWriter read FWriter;
         property ExeSectionList:TFPHashObjectList read FExeSectionList;
+        property DebugSectionList:TFPHashObjectList read FDebugSectionList;
         property ObjDataList:TFPObjectList read FObjDataList;
         property ExeSymbolList:TFPHashObjectList read FExeSymbolList;
         property UnresolvedExeSymbols:TFPObjectList read FUnresolvedExeSymbols;
@@ -1372,6 +1375,7 @@ implementation
         FEntryName:='start';
         { sections }
         FExeSectionList:=TFPHashObjectList.Create(true);
+        FDebugSectionList:=TFPHashObjectList.Create(true);
         FImageBase:=0;
         SectionMemAlign:=$1000;
         SectionDataAlign:=$200;
@@ -1388,15 +1392,97 @@ implementation
         CommonObjSymbols.free;
         ExeVTableList.free;
         FExeSectionList.free;
+        FDebugSectionList.free;
         ObjDatalist.free;
         FWriter.free;
         inherited destroy;
       end;
 
 
+    function TExeOutput.writedbgfile(const fn:string):boolean;
+      var
+        ObjWriter : TObjectwriter;
+        exesec    : TExeSection;
+        objsec    : TObjSection;
+        header    : string[6];
+        s         : string;
+        i,j,
+        seccnt,
+        secstart  : longint;
+      begin
+        result:=false;
+        {
+          File layout:
+            <header>           6 bytes
+            <section count>    4 bytes
+            (
+              <section offset> 4 bytes
+              <section name>   asciiz
+              ...
+            )
+            (
+              <section data>
+              ...
+            )
+        }
+        header:='FPCDBG';
+        { Calculate file offsets }
+        secstart:=length(header)+sizeof(seccnt);
+        for i:=0 to DebugSectionList.Count-1 do
+          begin
+            exesec:=TExeSection(DebugSectionList[i]);
+            inc(secstart,sizeof(secstart)+length(exesec.Name)+1);
+          end;
+        for i:=0 to DebugSectionList.Count-1 do
+          begin
+            exesec:=TExeSection(DebugSectionList[i]);
+            exesec.DataPos:=secstart;
+            for j:=0 to exesec.ObjSectionList.Count-1 do
+              begin
+                objsec:=TObjSection(exesec.ObjSectionList[j]);
+                inc(secstart,objsec.size);
+              end;
+          end;
+        { Create file }
+        ObjWriter:=TObjectwriter.Create;
+        if not ObjWriter.createfile(fn) then
+          begin
+            ObjWriter.Free;
+            exit;
+          end;
+        { Header }
+        ObjWriter.Write(header[1], Length(header));
+        seccnt:=DebugSectionList.Count;
+        ObjWriter.Write(seccnt,sizeof(seccnt));
+        for i:=0 to DebugSectionList.Count-1 do
+          begin
+            exesec:=TExeSection(DebugSectionList[i]);
+            ObjWriter.Write(exesec.DataPos,sizeof(secstart));
+            s:=exesec.Name;
+            ObjWriter.Write(s[1],length(s));
+            ObjWriter.writezeros(1);
+          end;
+        { Write section data }
+        for i:=0 to DebugSectionList.Count-1 do
+          begin
+            exesec:=TExeSection(DebugSectionList[i]);
+            if exesec.DataPos<>ObjWriter.ObjSize then
+              internalerror(200702241);
+            for j:=0 to exesec.ObjSectionList.Count-1 do
+              begin
+                objsec:=TObjSection(exesec.ObjSectionList[j]);
+                ObjWriter.writearray(objsec.data);
+              end;
+          end;
+        ObjWriter.Free;
+        result:=true;
+      end;
+
+
     function TExeOutput.writeexefile(const fn:string):boolean;
       begin
         result:=false;
+
         if FWriter.createfile(fn) then
          begin
            { Only write the .o if there are no errors }
@@ -1458,6 +1544,8 @@ implementation
         exesym : TExeSymbol;
       begin
         val(avalue,ImageBase,code);
+        if code<>0 then
+          Comment(V_Error,'Invalid number '+avalue);
         { Create __image_base__ symbol, create the symbol
           in a section with adress 0 and at offset 0 }
         objsec:=internalObjData.createsection('*__image_base__',0,[]);
@@ -1560,13 +1648,15 @@ implementation
       end;
 
 
-    procedure TExeOutput.Order_Align(const aname:string);
+    procedure TExeOutput.Order_Align(const avalue:string);
       var
         code     : integer;
         alignval : shortint;
         objsec   : TObjSection;
       begin
-        val(aname,alignval,code);
+        val(avalue,alignval,code);
+        if code<>0 then
+          Comment(V_Error,'Invalid number '+avalue);
         if alignval<=0 then
           exit;
         { Create an empty section with the required aligning }
@@ -1576,14 +1666,16 @@ implementation
       end;
 
 
-    procedure TExeOutput.Order_Zeros(const aname:string);
+    procedure TExeOutput.Order_Zeros(const avalue:string);
       var
         zeros : array[0..1023] of byte;
         code  : integer;
         len   : longint;
         objsec : TObjSection;
       begin
-        val(aname,len,code);
+        val(avalue,len,code);
+        if code<>0 then
+          Comment(V_Error,'Invalid number '+avalue);
         if len<=0 then
           exit;
         if len>sizeof(zeros) then
@@ -1609,6 +1701,7 @@ implementation
         { Alignment of ExeSection }
         CurrMemPos:=align(CurrMemPos,SectionMemAlign);
         CurrExeSec.MemPos:=CurrMemPos;
+
         if (oso_Data in currexesec.SecOptions) then
           begin
             CurrDataPos:=align(CurrDataPos,SectionDataAlign);
@@ -1619,6 +1712,7 @@ implementation
         for i:=0 to CurrExeSec.ObjSectionList.Count-1 do
           begin
             objsec:=TObjSection(CurrExeSec.ObjSectionList[i]);
+
             { Position in memory }
             objsec.setmempos(CurrMemPos);
             { Position in File }
@@ -1658,7 +1752,18 @@ implementation
 
 
     procedure TExeOutput.CalcPos_Symbols;
+      var
+        i : longint;
+        sym : TExeSymbol;
       begin
+        { Removing unused symbols }
+        for i:=0 to ExeSymbolList.Count-1 do
+          begin
+            sym:=TExeSymbol(ExeSymbolList[i]);
+            if not sym.ObjSymbol.objsection.Used then
+              ExeSymbolList[i]:=nil;
+          end;
+        ExeSymbolList.Pack;
       end;
 
 
@@ -2214,17 +2319,30 @@ implementation
         for i:=0 to ExeSectionList.Count-1 do
           begin
             exesec:=TExeSection(ExeSectionList[i]);
-            if not(oso_keep in exesec.SecOptions) and
-                (
-                 (exesec.ObjSectionlist.count=0) or
-                 (
-                  (cs_link_strip in current_settings.globalswitches) and
-                  (oso_debug in exesec.SecOptions)
-                 )
-               ) then
+
+            if (cs_link_separate_dbg_file in current_settings.globalswitches) and
+               (oso_debug in exesec.SecOptions) then
               begin
-                Comment(V_Debug,'Deleting empty section '+exesec.name);
+                Comment(V_Debug,'Adding debug section '+exesec.name+' to debugfile');
+                ExeSectionList.OwnsObjects:=false;
                 ExeSectionList[i]:=nil;
+                ExeSectionList.OwnsObjects:=true;
+                DebugSectionList.Add(exesec.Name,exesec);
+              end
+            else
+              begin
+                if not(oso_keep in exesec.SecOptions) and
+                    (
+                     (exesec.ObjSectionlist.count=0) or
+                     (
+                      (cs_link_strip in current_settings.globalswitches) and
+                      (oso_debug in exesec.SecOptions)
+                     )
+                   ) then
+                  begin
+                    Comment(V_Debug,'Deleting empty section '+exesec.name);
+                    ExeSectionList[i]:=nil;
+                  end;
               end;
           end;
         ExeSectionList.Pack;
@@ -2396,24 +2514,31 @@ implementation
 
 
     procedure TExeOutput.FixupRelocations;
-      var
-        i,j     : longint;
-        exesec  : TExeSection;
-        objsec  : TObjSection;
+
+        procedure FixupSectionList(List:TFPHashObjectList);
+        var
+          i,j     : longint;
+          exesec  : TExeSection;
+          objsec  : TObjSection;
+        begin
+          for i:=0 to List.Count-1 do
+            begin
+              exesec:=TExeSection(List[i]);
+              if not assigned(exesec) then
+                continue;
+              for j:=0 to exesec.ObjSectionlist.count-1 do
+                begin
+                  objsec:=TObjSection(exesec.ObjSectionlist[j]);
+                  if not objsec.Used then
+                    internalerror(200603301);
+                  objsec.FixupRelocs;
+                end;
+            end;
+        end;
+
       begin
-        for i:=0 to ExeSectionList.Count-1 do
-          begin
-            exesec:=TExeSection(ExeSectionList[i]);
-            if not assigned(exesec) then
-              continue;
-            for j:=0 to exesec.ObjSectionlist.count-1 do
-              begin
-                objsec:=TObjSection(exesec.ObjSectionlist[j]);
-                if not objsec.Used then
-                  internalerror(200603301);
-                objsec.FixupRelocs;
-              end;
-          end;
+        FixupSectionList(ExeSectionList);
+        FixupSectionList(DebugSectionList);
       end;
 
 

+ 22 - 33
compiler/ogcoff.pas

@@ -1674,8 +1674,9 @@ const pemagic : array[0..3] of byte = (
         with TCoffObjSection(p) do
           begin
             { Skip debug sections }
-            if (cs_link_strip in current_settings.globalswitches) and
-               (oso_debug in secoptions) then
+            if (oso_debug in secoptions)  and
+               (cs_link_strip in current_settings.globalswitches) and
+               not(cs_link_separate_dbg_file in current_settings.globalswitches) then
               exit;
 
             if assigned(data) then
@@ -1696,8 +1697,9 @@ const pemagic : array[0..3] of byte = (
         with TCoffObjSection(p) do
           begin
             { Skip debug sections }
-            if (cs_link_strip in current_settings.globalswitches) and
-               (oso_debug in secoptions) then
+            if (oso_debug in secoptions)  and
+               (cs_link_strip in current_settings.globalswitches) and
+               not(cs_link_separate_dbg_file in current_settings.globalswitches) then
               exit;
 
             if coffrelocs>0 then
@@ -2033,27 +2035,14 @@ const pemagic : array[0..3] of byte = (
 
 
     procedure tcoffexeoutput.CalcPos_Symbols;
-      var
-        i : longint;
-        sym : TExeSymbol;
       begin
+        inherited CalcPos_Symbols;
         nsyms:=0;
         sympos:=0;
-        if not(cs_link_strip in current_settings.globalswitches) then
-         begin
-           { Removing unused symbols }
-           for i:=0 to ExeSymbolList.Count-1 do
-             begin
-               sym:=TExeSymbol(ExeSymbolList[i]);
-               if not sym.ObjSymbol.objsection.Used then
-                 ExeSymbolList[i]:=nil;
-             end;
-           ExeSymbolList.Pack;
-           { Calculating symbols position and size }
-           nsyms:=ExeSymbolList.Count;
-           sympos:=CurrDataPos;
-           inc(CurrDataPos,sizeof(coffsymbol)*nsyms);
-         end;
+        { Calculating symbols position and size }
+        nsyms:=ExeSymbolList.Count;
+        sympos:=CurrDataPos;
+        inc(CurrDataPos,sizeof(coffsymbol)*nsyms);
       end;
 
 
@@ -2195,18 +2184,18 @@ const pemagic : array[0..3] of byte = (
         ExeSectionList.ForEachCall(@ExeSectionList_write_header,nil);
         { Section data }
         ExeSectionList.ForEachCall(@ExeSectionList_write_data,nil);
-        { Optional ObjSymbols }
+        { Optional Symbols }
         if not(cs_link_strip in current_settings.globalswitches) then
-         begin
-           if SymPos<>FWriter.Size then
-             internalerror(200602252);
-           { ObjSymbols }
-           ExeSymbolList.ForEachCall(@globalsyms_write_symbol,nil);
-           { Strings }
-           i:=FCoffStrs.size+4;
-           FWriter.write(i,4);
-           FWriter.writearray(FCoffStrs);
-         end;
+          begin
+            if SymPos<>FWriter.Size then
+              internalerror(200602252);
+            { ObjSymbols }
+            ExeSymbolList.ForEachCall(@globalsyms_write_symbol,nil);
+            { Strings }
+            i:=FCoffStrs.size+4;
+            FWriter.write(i,4);
+            FWriter.writearray(FCoffStrs);
+          end;
         { Release }
         FCoffStrs.Free;
         FCoffSyms.Free;

+ 9 - 2
compiler/options.pas

@@ -791,13 +791,13 @@ begin
                          else
                            include(init_settings.globalswitches,cs_use_lineinfo);
                        end;
-                     'p' : 
+                     'p' :
                        begin
                          if UnsetBool(More, j) then
                            exclude(init_settings.globalswitches,cs_stabs_preservecase)
                          else
                            include(init_settings.globalswitches,cs_stabs_preservecase);
-                       end;  
+                       end;
                      's' :
                        begin
                          paratargetdbg:=dbg_stabs;
@@ -1276,6 +1276,13 @@ begin
                       end;
                     'f' :
                       include(init_settings.globalswitches,cs_link_pthread);
+                    'g' :
+                      begin
+                        If UnsetBool(More, j) then
+                          exclude(init_settings.globalswitches,cs_link_separate_dbg_file)
+                        else
+                          include(init_settings.globalswitches,cs_link_separate_dbg_file);
+                      end;
                     'i' :
                       begin
                         If UnsetBool(More, j) then