浏览代码

* 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);
     procedure TExeOutput.DataPos_ExeSection(exesec:TExeSection);
-      var
-        i      : longint;
-        objsec : TObjSection;
       begin
       begin
         { don't write normal section if writing only debug info }
         { don't write normal section if writing only debug info }
         if (ExeWriteMode=ewm_dbgonly) and
         if (ExeWriteMode=ewm_dbgonly) and
@@ -2127,20 +2124,7 @@ implementation
           begin
           begin
             CurrDataPos:=align_aword(CurrDataPos,DataAlign(exesec));
             CurrDataPos:=align_aword(CurrDataPos,DataAlign(exesec));
             exesec.DataPos:=CurrDataPos;
             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;
       end;
       end;
 
 
@@ -3221,6 +3205,7 @@ implementation
         exesec : TExeSection;
         exesec : TExeSection;
         objsec : TObjSection;
         objsec : TObjSection;
         i,j    : longint;
         i,j    : longint;
+        dpos,pad: aword;
       begin
       begin
         for j:=0 to ExeSectionList.Count-1 do
         for j:=0 to ExeSectionList.Count-1 do
           begin
           begin
@@ -3242,9 +3227,13 @@ implementation
                       begin
                       begin
                         if not assigned(objsec.data) then
                         if not assigned(objsec.data) then
                           internalerror(200603042);
                           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);
                           internalerror(200602251);
+                        FWriter.writeZeros(pad);
                         FWriter.writearray(objsec.data);
                         FWriter.writearray(objsec.data);
                       end;
                       end;
                   end;
                   end;

+ 13 - 14
compiler/ognlm.pas

@@ -524,6 +524,7 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
         objsec : TObjSection;
         objsec : TObjSection;
         i,j    : longint;
         i,j    : longint;
         b      : byte;
         b      : byte;
+        dpos,pad: aword;
       begin
       begin
 
 
         with texesection(p) do
         with texesection(p) do
@@ -535,17 +536,25 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
 
 
             if oso_data in secoptions then
             if oso_data in secoptions then
               begin
               begin
+                if DataPos<FWriter.Size then
+                  InternalError(2012103001);
                 //if Align(FWriter.Size,SectionDataAlign)-FWriter.Size>0 then
                 //if Align(FWriter.Size,SectionDataAlign)-FWriter.Size>0 then
                 //  writeln (name,' align ',Align(FWriter.Size,SectionDataAlign)-FWriter.Size,' SectionDataAlign:',SectionDataAlign);
                 //  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
                 for i:=0 to ObjSectionList.Count-1 do
                   begin
                   begin
                     objsec:=TObjSection(ObjSectionList[i]);
                     objsec:=TObjSection(ObjSectionList[i]);
                     if oso_data in objsec.secoptions then
                     if oso_data in objsec.secoptions then
                       begin
                       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 assigned(exemap) then
                           if objsec.data.size > 0 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);
                         //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
                         {for j := 0 to objsec.ObjRelocations.count-1 do
                           begin
                           begin
@@ -563,15 +572,10 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
                         if copy (objsec.Name,1,5) = '.text' then
                         if copy (objsec.Name,1,5) = '.text' then
                           begin        // write NOP's instead of zero's for .text, makes disassemble possible
                           begin        // write NOP's instead of zero's for .text, makes disassemble possible
                             b := $90;  // NOP
                             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);
                                 FWriter.write(b,1);
                           end else
                           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);
                         FWriter.writearray(objsec.data);
                       end else
                       end else
                       begin
                       begin
@@ -998,11 +1002,6 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
           for j:=0 to exesec.ObjSectionList.count-1 do
           for j:=0 to exesec.ObjSectionList.count-1 do
             begin
             begin
               objsec:=TObjSection(exesec.ObjSectionList[j]);
               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
               if (copy(objsec.name,1,5) <> '.text') and (copy(objsec.name,1,4) <> '.bss') and (copy(objsec.name,1,5) <> '.data') then
                   continue;
                   continue;
               for k:=0 to objsec.ObjRelocations.Count-1 do
               for k:=0 to objsec.ObjRelocations.Count-1 do