فهرست منبع

* Don't calculate data position of each object section. Instead, write out a copy of exesection's memory image, i.e. every objsection is placed at the same offset from its owning exesection both on disk and in memory. This approach is simpler and works regardless of alignment requirements, while existing one could work only if SectionDataAlign<=SectionMemAlign.
* Netware target may be broken by this change; at least it deserves a good cleanup because it contains a lot of code trying to solve similar task: to write exesections without alignment and deal with objsections that are nevertheless being aligned by TExeOutput.

git-svn-id: trunk@23291 -

sergei 12 سال پیش
والد
کامیت
d7c5daeccd
2فایلهای تغییر یافته به همراه21 افزوده شده و 33 حذف شده
  1. 8 19
      compiler/ogbase.pas
  2. 13 14
      compiler/ognlm.pas

+ 8 - 19
compiler/ogbase.pas

@@ -2114,9 +2114,6 @@ implementation
 
 
     procedure TExeOutput.DataPos_ExeSection(exesec:TExeSection);
-      var
-        i      : longint;
-        objsec : TObjSection;
       begin
         { don't write normal section if writing only debug info }
         if (ExeWriteMode=ewm_dbgonly) and
@@ -2127,20 +2124,7 @@ implementation
           begin
             CurrDataPos:=align_aword(CurrDataPos,DataAlign(exesec));
             exesec.DataPos:=CurrDataPos;
-          end;
-
-        { set position of object ObjSections }
-        for i:=0 to exesec.ObjSectionList.Count-1 do
-          begin
-            objsec:=TObjSection(exesec.ObjSectionList[i]);
-            if (oso_Data in objsec.SecOptions) then
-              begin
-                if not(oso_Data in exesec.SecOptions) then
-                  internalerror(200603043);
-                if not assigned(objsec.Data) then
-                  internalerror(200603044);
-                objsec.setDatapos(CurrDataPos);
-              end;
+            CurrDataPos:=CurrDataPos+exesec.Size;
           end;
       end;
 
@@ -3221,6 +3205,7 @@ implementation
         exesec : TExeSection;
         objsec : TObjSection;
         i,j    : longint;
+        dpos,pad: aword;
       begin
         for j:=0 to ExeSectionList.Count-1 do
           begin
@@ -3242,9 +3227,13 @@ implementation
                       begin
                         if not assigned(objsec.data) then
                           internalerror(200603042);
-                        FWriter.writezeros(objsec.dataalignbytes);
-                        if objsec.DataPos<>FWriter.Size then
+                        dpos:=objsec.MemPos-exesec.MemPos+exesec.DataPos;
+                        pad:=dpos-FWriter.Size;
+                        { objsection must be within SecAlign bytes from the previous one }
+                        if (dpos<FWriter.Size) or
+                          (pad>=max(objsec.SecAlign,1)) then
                           internalerror(200602251);
+                        FWriter.writeZeros(pad);
                         FWriter.writearray(objsec.data);
                       end;
                   end;

+ 13 - 14
compiler/ognlm.pas

@@ -524,6 +524,7 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
         objsec : TObjSection;
         i,j    : longint;
         b      : byte;
+        dpos,pad: aword;
       begin
 
         with texesection(p) do
@@ -535,17 +536,25 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
 
             if oso_data in secoptions then
               begin
+                if DataPos<FWriter.Size then
+                  InternalError(2012103001);
                 //if Align(FWriter.Size,SectionDataAlign)-FWriter.Size>0 then
                 //  writeln (name,' align ',Align(FWriter.Size,SectionDataAlign)-FWriter.Size,' SectionDataAlign:',SectionDataAlign);
-                FWriter.Writezeros(Align(FWriter.Size,SectionDataAlign)-FWriter.Size);
+                FWriter.Writezeros(DataPos-FWriter.Size);
                 for i:=0 to ObjSectionList.Count-1 do
                   begin
                     objsec:=TObjSection(ObjSectionList[i]);
                     if oso_data in objsec.secoptions then
                       begin
+                        { objsection must be within SecAlign bytes from the previous one }
+                        dpos:=objsec.MemPos-MemPos+DataPos;
+                        pad:=dpos-FWriter.Size;
+                        if (dpos<FWriter.Size) or
+                         (pad>=max(objsec.SecAlign,1)) then
+                          internalerror(200602251);
                         if assigned(exemap) then
                           if objsec.data.size > 0 then
-                            exemap.Add('  0x'+hexstr(objsec.DataPos,8)+': '+objsec.name);
+                            exemap.Add('  0x'+hexstr(dpos,8)+': '+objsec.name);
                         //writeln ('   ',objsec.name,'  size:',objsec.size,'  relocs:',objsec.ObjRelocations.count,'  DataPos:',objsec.DataPos,' MemPos:',objsec.MemPos);
                         {for j := 0 to objsec.ObjRelocations.count-1 do
                           begin
@@ -563,15 +572,10 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
                         if copy (objsec.Name,1,5) = '.text' then
                           begin        // write NOP's instead of zero's for .text, makes disassemble possible
                             b := $90;  // NOP
-                            if objsec.DataAlignBytes > 0 then
-                              for j := 1 to objsec.DataAlignBytes do
+                            for j := 1 to pad do
                                 FWriter.write(b,1);
                           end else
-                            FWriter.writezeros(objsec.dataalignbytes);
-                        //if objsec.dataalignbytes>0 then
-                        //  writeln ('  ',name,'  alignbytes: ',objsec.dataalignbytes);
-                        if objsec.DataPos<>FWriter.Size then
-                            internalerror(200602251);
+                            FWriter.writezeros(pad);
                         FWriter.writearray(objsec.data);
                       end else
                       begin
@@ -998,11 +1002,6 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
           for j:=0 to exesec.ObjSectionList.count-1 do
             begin
               objsec:=TObjSection(exesec.ObjSectionList[j]);
-              if j=0 then
-                begin
-                  exesec.DataPos:=objSec.DataPos;
-                  exesec.MemPos:=objSec.MemPos;
-                end;
               if (copy(objsec.name,1,5) <> '.text') and (copy(objsec.name,1,4) <> '.bss') and (copy(objsec.name,1,5) <> '.data') then
                   continue;
               for k:=0 to objsec.ObjRelocations.Count-1 do