Browse Source

+ Property TObjSymbol.ObjData, allows to access owning TObjData for external/common symbols, i.e. ones with ObjSection=nil.
* For common symbols, report objdata of the original ObjSymbol, not of the resolving one, so the map file shows where it comes from.
+ TElfExeOutput.OrderOrphanSections method, handles object sections not mentioned in script similar to ld.
- t_linux.pas: removed sections that are not part of ld scripts, they are now handled by OrderOrphanSections.

git-svn-id: trunk@25184 -

sergei 12 years ago
parent
commit
1f8a67f552
5 changed files with 122 additions and 26 deletions
  1. 1 0
      compiler/cclasses.pas
  2. 34 4
      compiler/ogbase.pas
  3. 86 0
      compiler/ogelf.pas
  4. 1 1
      compiler/ogmap.pas
  5. 0 21
      compiler/systems/t_linux.pas

+ 1 - 0
compiler/cclasses.pas

@@ -273,6 +273,7 @@ type
     procedure Rename(const ANewName:TSymStr);
     property Name:TSymStr read GetName;
     property Hash:Longword read GetHash;
+    property OwnerList: TFPHashObjectList read FOwner;
   end;
 
   TFPHashObjectList = class(TObject)

+ 34 - 4
compiler/ogbase.pas

@@ -169,6 +169,7 @@ interface
        constructor create(AList:TFPHashObjectList;const AName:string);
        function  address:aword;
        procedure SetAddress(apass:byte;aobjsec:TObjSection;abind:TAsmsymbind;atyp:Tasmsymtype);
+       function  ObjData: TObjData;
      end;
 
      { Stabs is common for all targets }
@@ -256,13 +257,18 @@ interface
 
      TString80 = string[80];
 
+     TObjSymbolList = class(TFPHashObjectList)
+     public
+       Owner: TObjData;
+     end;
+
      TObjData = class(TLinkedListItem)
      private
        FCurrObjSec : TObjSection;
        FObjSectionList  : TFPHashObjectList;
        FCObjSection     : TObjSectionClass;
        { Symbols that will be defined in this object file }
-       FObjSymbolList    : TFPHashObjectList;
+       FObjSymbolList    : TObjSymbolList;
        FCachedAsmSymbolList : TFPObjectList;
        { Special info sections that are written to during object generation }
        FStabsObjSec,
@@ -309,7 +315,7 @@ interface
        procedure layoutsections(var datapos:aword);
        property Name:TString80 read FName;
        property CurrObjSec:TObjSection read FCurrObjSec;
-       property ObjSymbolList:TFPHashObjectList read FObjSymbolList;
+       property ObjSymbolList:TObjSymbolList read FObjSymbolList;
        property ObjSectionList:TFPHashObjectList read FObjSectionList;
        property GroupsList:TFPHashObjectList read FGroupsList;
        property StabsSec:TObjSection read FStabsObjSec write FStabsObjSec;
@@ -522,6 +528,7 @@ interface
         procedure DoRelocationFixup(objsec:TObjSection);virtual;abstract;
         function MemAlign(exesec: TExeSection): longword;
         function DataAlign(exesec: TExeSection): longword;
+        procedure ReplaceExeSectionList(newlist: TFPList);
       public
         CurrDataPos  : aword;
         MaxMemPos    : qword;
@@ -707,6 +714,12 @@ implementation
         offset:=aobjsec.size;
       end;
 
+
+    function TObjSymbol.ObjData: TObjData;
+      begin
+        result:=(OwnerList as TObjSymbolList).Owner;
+      end;
+
 {****************************************************************************
                               TObjRelocation
 ****************************************************************************}
@@ -960,7 +973,8 @@ implementation
         FStabsObjSec:=nil;
         FStabStrObjSec:=nil;
         { symbols }
-        FObjSymbolList:=TFPHashObjectList.Create(true);
+        FObjSymbolList:=TObjSymbolList.Create(true);
+        FObjSymbolList.Owner:=Self;
         FCachedAsmSymbolList:=TFPObjectList.Create(false);
         { section class type for creating of new sections }
         FCObjSection:=TObjSection;
@@ -2524,7 +2538,7 @@ implementation
                 commonsym.size:=objsym.size;
                 internalObjData.alloc(objsym.size);
                 if assigned(exemap) then
-                  exemap.AddCommonSymbol(commonsym);
+                  exemap.AddCommonSymbol(objsym);
                 { Assign to the exesymbol }
                 objsym.exesymbol.objsymbol:=commonsym;
                 objsym.exesymbol.state:=symstate_defined;
@@ -3290,6 +3304,22 @@ implementation
       end;
 
 
+    procedure TExeOutput.ReplaceExeSectionList(newlist: TFPList);
+      var
+        tmp: TFPHashObjectList;
+        i: longint;
+      begin
+        tmp:=TFPHashObjectList.Create(true);
+        for i:=0 to newlist.count-1 do
+          TFPHashObject(newlist[i]).ChangeOwner(tmp);
+        { prevent destruction of existing sections }
+        for i:=0 to ExeSectionList.count-1 do
+          ExeSectionList.List[i]:=nil;
+        FExeSectionList.Free;
+        FExeSectionList:=tmp;
+      end;
+
+
 {****************************************************************************
                                 TObjInput
 ****************************************************************************}

+ 86 - 0
compiler/ogelf.pas

@@ -271,6 +271,7 @@ interface
          procedure WriteShstrtab;
          procedure FixupSectionLinks;
          procedure InitDynlink;
+         procedure OrderOrphanSections;
        protected
          dynamiclink: boolean;
          hastextrelocs: boolean;
@@ -2348,6 +2349,7 @@ implementation
         end;
 
       begin
+        OrderOrphanSections;
         inherited Order_end;
         set_oso_keep('.init');
         set_oso_keep('.fini');
@@ -2366,6 +2368,90 @@ implementation
       end;
 
 
+    procedure TElfExeOutput.OrderOrphanSections;
+      var
+        i,j:longint;
+        objdata:TObjData;
+        objsec:TObjSection;
+        exesec:TExeSection;
+        opts:TObjSectionOptions;
+        s:string;
+        newsections,tmp:TFPHashObjectList;
+        allsections:TFPList;
+        inserts:array[0..6] of TExeSection;
+        idx,inspos:longint;
+      begin
+        newsections:=TFPHashObjectList.Create(false);
+        allsections:=TFPList.Create;
+        { copy existing sections }
+        for i:=0 to ExeSectionList.Count-1 do
+          allsections.add(ExeSectionList[i]);
+        inserts[0]:=FindExeSection('.comment');
+        inserts[1]:=nil;
+        inserts[2]:=FindExeSection('.interp');
+        inserts[3]:=FindExeSection('.bss');
+        inserts[4]:=FindExeSection('.data');
+        inserts[5]:=FindExeSection('.rodata');
+        inserts[6]:=FindExeSection('.text');
+
+        for i:=0 to ObjDataList.Count-1 do
+          begin
+            ObjData:=TObjData(ObjDataList[i]);
+            for j:=0 to ObjData.ObjSectionList.Count-1 do
+              begin
+                objsec:=TObjSection(ObjData.ObjSectionList[j]);
+                if objsec.Used then
+                  continue;
+                s:=objsec.name;
+                exesec:=TExeSection(newsections.Find(s));
+                if assigned(exesec) then
+                  begin
+                    exesec.AddObjSection(objsec);
+                    continue;
+                  end;
+                opts:=objsec.SecOptions*[oso_data,oso_load,oso_write,oso_executable];
+                if (objsec.SecOptions*[oso_load,oso_debug]=[]) then
+                  { non-alloc, after .comment
+                    GNU ld places .comment between stabs and dwarf debug info }
+                  inspos:=0
+                else if not (oso_load in objsec.SecOptions) then
+                  inspos:=1   { debugging, skip }
+                else if (oso_load in objsec.SecOptions) and
+                  (TElfObjSection(objsec).shtype=SHT_NOTE) then
+                  inspos:=2   { after .interp }
+                else if (opts=[oso_load,oso_write]) then
+                  inspos:=3   { after .bss }
+                else if (opts=[oso_data,oso_load,oso_write]) then
+                  inspos:=4   { after .data }
+                else if (opts=[oso_data,oso_load]) then
+                  inspos:=5   { rodata, relocs=??? }
+                else if (opts=[oso_data,oso_load,oso_executable]) then
+                  inspos:=6   { text }
+                else
+                  begin
+                    Comment(v_debug,'Orphan section '+objsec.fullname+' has attributes that are not handled!');
+                    continue;
+                  end;
+                if (inserts[inspos]=nil) then
+                  begin
+                    Comment(v_debug,'Orphan section '+objsec.fullname+': nowhere to insert, ignored');
+                    continue;
+                  end;
+                idx:=allsections.IndexOf(inserts[inspos]);
+                exesec:=CExeSection.Create(newsections,s);
+                allsections.Insert(idx+1,exesec);
+                inserts[inspos]:=exesec;
+                exesec.AddObjSection(objsec);
+              end;
+          end;
+        { Now replace the ExeSectionList with content of allsections }
+        if (newsections.count<>0) then
+          ReplaceExeSectionList(allsections);
+        newsections.Free;
+        allsections.Free;
+      end;
+
+
     procedure TElfExeOutput.AfterUnusedSectionRemoval;
       var
         i:longint;

+ 1 - 1
compiler/ogmap.pas

@@ -145,7 +145,7 @@ implementation
             writeln(t,p.name);
             s:='';
           end;
-         Add(PadSpace(s,20)+'0x'+PadSpace(sizestr(p.size),16)+p.objsection.objdata.name);
+         Add(PadSpace(s,20)+PadSpace(sizestr(p.size),16)+p.objdata.name);
        end;
 
 

+ 0 - 21
compiler/systems/t_linux.pas

@@ -1380,20 +1380,6 @@ begin
       Concat('EXESECTION .text');
       Concat('  OBJSECTION .text*');
       Concat('ENDEXESECTION');
-
-      { This is not in standard ld scripts, it is handled by 'orphan section' functionality }
-      Concat('EXESECTION __libc_thread_freeres_fn');
-      Concat('  PROVIDE __start__libc_thread_freeres_fn');
-      Concat('  OBJSECTION __libc_thread_freeres_fn');
-      Concat('  PROVIDE __stop__libc_thread_freeres_fn');
-      Concat('ENDEXESECTION');
-
-      Concat('EXESECTION __libc_freeres_fn');
-      Concat('  PROVIDE __start__libc_freeres_fn');
-      Concat('  OBJSECTION __libc_freeres_fn');
-      Concat('  PROVIDE __stop__libc_freeres_fn');
-      Concat('ENDEXESECTION');
-
       Concat('EXESECTION .fini');
       Concat('  OBJSECTION .fini');
       Concat('  PROVIDE __etext');
@@ -1494,13 +1480,6 @@ begin
       Concat('  SYMBOL _end');
       Concat('ENDEXESECTION');
 
-      { This is not in standard ld scripts, it is handled by 'orphan section' functionality }
-      Concat('EXESECTION __libc_freeres_ptrs');
-      Concat('  PROVIDE __start__libc_freeres_ptrs');
-      Concat('  OBJSECTION __libc_freeres_ptrs');
-      Concat('  PROVIDE __stop__libc_freeres_ptrs');
-      Concat('ENDEXESECTION');
-
       ScriptAddGenericSections('.debug_aranges,.debug_pubnames,.debug_info,'+
          '.debug_abbrev,.debug_line,.debug_frame,.debug_str,.debug_loc,'+
          '.debug_macinfo,.debug_weaknames,.debug_funcnames,.debug_typenames,.debug_varnames,.debug_ranges');