Browse Source

* Internal linker: fixed alignment routines. Neither of existing ones is suitable for 64-bit targets: cutils.align() is 32-bit only and moreover signed, system.align() crashes on zero alignment values and handles only pointer size of source platform.
Therefore, added dedicated routines align_aword and align_qword that handle target platform size and 64-bit unsigned, respectively.
+ Also added TExeOutput.FixedSectionAlign boolean that, when set to False, ignores SectionDataAlign and SectionMemAlign and aligns every exe section to its own SecAlign value. This kind of alignment is used on ELF targets.

git-svn-id: trunk@22858 -

sergei 12 years ago
parent
commit
499162ca50
1 changed files with 53 additions and 8 deletions
  1. 53 8
      compiler/ogbase.pas

+ 53 - 8
compiler/ogbase.pas

@@ -483,12 +483,15 @@ interface
         EntrySym  : TObjSymbol;
         EntrySym  : TObjSymbol;
         SectionDataAlign,
         SectionDataAlign,
         SectionMemAlign : aword;
         SectionMemAlign : aword;
+        FixedSectionAlign : boolean;
         function  writeData:boolean;virtual;abstract;
         function  writeData:boolean;virtual;abstract;
         property CExeSection:TExeSectionClass read FCExeSection write FCExeSection;
         property CExeSection:TExeSectionClass read FCExeSection write FCExeSection;
         property CObjData:TObjDataClass read FCObjData write FCObjData;
         property CObjData:TObjDataClass read FCObjData write FCObjData;
         procedure Order_ObjSectionList(ObjSectionList : TFPObjectList; const aPattern:string);virtual;
         procedure Order_ObjSectionList(ObjSectionList : TFPObjectList; const aPattern:string);virtual;
         procedure WriteExeSectionContent;
         procedure WriteExeSectionContent;
         procedure DoRelocationFixup(objsec:TObjSection);virtual;abstract;
         procedure DoRelocationFixup(objsec:TObjSection);virtual;abstract;
+        function MemAlign(exesec: TExeSection): longword;
+        function DataAlign(exesec: TExeSection): longword;
       public
       public
         CurrDataPos  : aword;
         CurrDataPos  : aword;
         MaxMemPos    : qword;
         MaxMemPos    : qword;
@@ -563,6 +566,8 @@ interface
     var
     var
       exeoutput : TExeOutput;
       exeoutput : TExeOutput;
 
 
+    function align_aword(v:aword;a:longword):aword;
+    function align_qword(v:qword;a:longword):qword;
 
 
 implementation
 implementation
 
 
@@ -579,6 +584,27 @@ implementation
       memobjsections : TMemDebug;
       memobjsections : TMemDebug;
 {$endif MEMDEBUG}
 {$endif MEMDEBUG}
 
 
+{*****************************************************************************
+                                 Helpers
+*****************************************************************************}
+
+    function align_aword(v:aword;a:longword):aword;
+      begin
+        if a<=1 then
+          result:=v
+        else
+          result:=((v+a-1) div a) * a;
+      end;
+
+
+    function align_qword(v:qword;a:longword):qword;
+      begin
+        if a<=1 then
+          result:=v
+        else
+          result:=((v+a-1) div a) * a;
+      end;
+
 {*****************************************************************************
 {*****************************************************************************
                                  TObjSymbol
                                  TObjSymbol
 *****************************************************************************}
 *****************************************************************************}
@@ -809,7 +835,7 @@ implementation
         if oso_Data in secoptions then
         if oso_Data in secoptions then
           begin
           begin
             { get aligned Datapos }
             { get aligned Datapos }
-            Datapos:=align(dpos,secalign);
+            Datapos:=align_aword(dpos,secalign);
             Dataalignbytes:=Datapos-dpos;
             Dataalignbytes:=Datapos-dpos;
             { return updated Datapos }
             { return updated Datapos }
             dpos:=Datapos+size;
             dpos:=Datapos+size;
@@ -821,7 +847,7 @@ implementation
 
 
     function TObjSection.setmempos(mpos:qword):qword;
     function TObjSection.setmempos(mpos:qword):qword;
       begin
       begin
-        mempos:=align(mpos,secalign);
+        mempos:=align_qword(mpos,secalign);
         { return updated mempos }
         { return updated mempos }
         result:=mempos+size;
         result:=mempos+size;
       end;
       end;
@@ -1250,14 +1276,14 @@ implementation
       begin
       begin
         if not assigned(CurrObjSec) then
         if not assigned(CurrObjSec) then
           internalerror(200402253);
           internalerror(200402253);
-        CurrObjSec.alloc(align(CurrObjSec.size,len)-CurrObjSec.size);
+        CurrObjSec.alloc(align_aword(CurrObjSec.size,len)-CurrObjSec.size);
       end;
       end;
 
 
 
 
     procedure TObjData.section_afteralloc(p:TObject;arg:pointer);
     procedure TObjData.section_afteralloc(p:TObject;arg:pointer);
       begin
       begin
         with TObjSection(p) do
         with TObjSection(p) do
-          alloc(align(size,secalign)-size);
+          alloc(align_aword(size,secalign)-size);
       end;
       end;
 
 
 
 
@@ -1266,7 +1292,7 @@ implementation
         with TObjSection(p) do
         with TObjSection(p) do
           begin
           begin
             if assigned(Data) then
             if assigned(Data) then
-              writezeros(align(size,secalign)-size);
+              writezeros(align_aword(size,secalign)-size);
           end;
           end;
       end;
       end;
 
 
@@ -1700,6 +1726,7 @@ implementation
         SectionMemAlign:=$1000;
         SectionMemAlign:=$1000;
         SectionDataAlign:=$200;
         SectionDataAlign:=$200;
 {$endif cpu16bitaddr}
 {$endif cpu16bitaddr}
+        FixedSectionAlign:=True;
         FCExeSection:=TExeSection;
         FCExeSection:=TExeSection;
         FCObjData:=TObjData;
         FCObjData:=TObjData;
       end;
       end;
@@ -1721,6 +1748,24 @@ implementation
       end;
       end;
 
 
 
 
+    function TExeOutput.MemAlign(exesec:TExeSection):longword;
+      begin
+        if FixedSectionAlign then
+          result:=SectionMemAlign
+        else
+          result:=exesec.SecAlign;
+      end;
+
+
+    function TExeOutput.DataAlign(exesec:TExeSection):longword;
+      begin
+        if FixedSectionAlign then
+          result:=SectionDataAlign
+        else
+          result:=exesec.SecAlign;
+      end;
+
+
     function TExeOutput.WriteExeFile(const fn:string):boolean;
     function TExeOutput.WriteExeFile(const fn:string):boolean;
       begin
       begin
         result:=false;
         result:=false;
@@ -2066,7 +2111,7 @@ implementation
         objsec : TObjSection;
         objsec : TObjSection;
       begin
       begin
         { Alignment of ExeSection }
         { Alignment of ExeSection }
-        CurrMemPos:=align(CurrMemPos,SectionMemAlign);
+        CurrMemPos:=align_qword(CurrMemPos,MemAlign(exesec));
         exesec.MemPos:=CurrMemPos;
         exesec.MemPos:=CurrMemPos;
 
 
         { set position of object ObjSections }
         { set position of object ObjSections }
@@ -2122,7 +2167,7 @@ implementation
 
 
         if (oso_Data in exesec.SecOptions) then
         if (oso_Data in exesec.SecOptions) then
           begin
           begin
-            CurrDataPos:=align(CurrDataPos,SectionDataAlign);
+            CurrDataPos:=align_aword(CurrDataPos,DataAlign(exesec));
             exesec.DataPos:=CurrDataPos;
             exesec.DataPos:=CurrDataPos;
           end;
           end;
 
 
@@ -3199,7 +3244,7 @@ implementation
 
 
             if oso_data in exesec.SecOptions then
             if oso_data in exesec.SecOptions then
               begin
               begin
-                FWriter.Writezeros(Align(FWriter.Size,SectionDataAlign)-FWriter.Size);
+                FWriter.Writezeros(Align(FWriter.Size,DataAlign(exesec))-FWriter.Size);
                 for i:=0 to exesec.ObjSectionList.Count-1 do
                 for i:=0 to exesec.ObjSectionList.Count-1 do
                   begin
                   begin
                     objsec:=TObjSection(exesec.ObjSectionList[i]);
                     objsec:=TObjSection(exesec.ObjSectionList[i]);