Browse Source

+ fill and write the NewExe imported name table

git-svn-id: trunk@42611 -
nickysn 6 years ago
parent
commit
d5a18f03a8
1 changed files with 93 additions and 0 deletions
  1. 93 0
      compiler/ogomf.pas

+ 93 - 0
compiler/ogomf.pas

@@ -507,6 +507,22 @@ interface
         property Size: QWord read GetSize;
         property Size: QWord read GetSize;
       end;
       end;
 
 
+      { TNewExeImportedNameTableEntry }
+
+      TNewExeImportedNameTableEntry = class(TFPHashObject)
+      end;
+
+      { TNewExeImportedNameTable }
+
+      TNewExeImportedNameTable = class(TFPHashObjectList)
+      private
+        function GetSize: QWord;
+      public
+        procedure AddImportedName(const name:TSymStr);
+        procedure WriteTo(aWriter: TObjectWriter);
+        property Size: QWord read GetSize;
+      end;
+
       { These are fake "meta sections" used by the linker script. The actual
       { These are fake "meta sections" used by the linker script. The actual
         NewExe sections are segments, limited to 64kb, which means there can be
         NewExe sections are segments, limited to 64kb, which means there can be
         multiple code segments, etc. These are created manually as object
         multiple code segments, etc. These are created manually as object
@@ -563,14 +579,17 @@ interface
         FCurrExeMetaSec: TNewExeMetaSection;
         FCurrExeMetaSec: TNewExeMetaSection;
         FResourceTable: TNewExeResourceTable;
         FResourceTable: TNewExeResourceTable;
         FResidentNameTable: TNewExeResidentNameTable;
         FResidentNameTable: TNewExeResidentNameTable;
+        FImportedNameTable: TNewExeImportedNameTable;
         procedure AddImportSymbol(const libname,symname,symmangledname:TCmdStr;OrdNr: longint;isvar:boolean);
         procedure AddImportSymbol(const libname,symname,symmangledname:TCmdStr;OrdNr: longint;isvar:boolean);
         procedure AddImportLibrariesExtractedFromObjectModules;
         procedure AddImportLibrariesExtractedFromObjectModules;
         procedure AddNewExeSection;
         procedure AddNewExeSection;
         function WriteNewExe:boolean;
         function WriteNewExe:boolean;
+        procedure FillImportedNameTable;
         property Header: TNewExeHeader read FHeader;
         property Header: TNewExeHeader read FHeader;
         property CurrExeMetaSec: TNewExeMetaSection read FCurrExeMetaSec write FCurrExeMetaSec;
         property CurrExeMetaSec: TNewExeMetaSection read FCurrExeMetaSec write FCurrExeMetaSec;
         property ResourceTable: TNewExeResourceTable read FResourceTable;
         property ResourceTable: TNewExeResourceTable read FResourceTable;
         property ResidentNameTable: TNewExeResidentNameTable read FResidentNameTable;
         property ResidentNameTable: TNewExeResidentNameTable read FResidentNameTable;
+        property ImportedNameTable: TNewExeImportedNameTable read FImportedNameTable;
       protected
       protected
         procedure DoRelocationFixup(objsec:TObjSection);override;
         procedure DoRelocationFixup(objsec:TObjSection);override;
         procedure Order_ObjSectionList(ObjSectionList : TFPObjectList;const aPattern:string);override;
         procedure Order_ObjSectionList(ObjSectionList : TFPObjectList;const aPattern:string);override;
@@ -3737,6 +3756,48 @@ cleanup:
         aWriter.write(slen,1);
         aWriter.write(slen,1);
       end;
       end;
 
 
+{****************************************************************************
+                          TNewExeImportedNameTable
+****************************************************************************}
+
+    function TNewExeImportedNameTable.GetSize: QWord;
+      var
+        i: Integer;
+      begin
+        { the table starts with an empty entry, which takes 1 byte }
+        Result:=1;
+        { each entry is 1 byte, plus the length of the name }
+        for i:=0 to Count-1 do
+          Inc(Result,1+Length(TNewExeResidentNameTableEntry(Items[i]).Name));
+      end;
+
+    procedure TNewExeImportedNameTable.AddImportedName(const name: TSymStr);
+      begin
+        if not Assigned(Find(name)) then
+          TNewExeImportedNameTableEntry.Create(Self,name);
+      end;
+
+    procedure TNewExeImportedNameTable.WriteTo(aWriter: TObjectWriter);
+      var
+        i: Integer;
+        entry: TNewExeImportedNameTableEntry;
+        slen: Byte;
+      begin
+        { the table starts with an empty entry }
+        slen:=0;
+        aWriter.write(slen,1);
+
+        for i:=0 to Count-1 do
+          begin
+            entry:=TNewExeImportedNameTableEntry(Items[i]);
+            slen:=Length(entry.Name);
+            if slen=0 then
+              internalerror(2019080901);
+            aWriter.write(slen,1);
+            aWriter.write(entry.Name[1],slen);
+          end;
+      end;
+
 {****************************************************************************
 {****************************************************************************
                               TNewExeSection
                               TNewExeSection
 ****************************************************************************}
 ****************************************************************************}
@@ -3886,6 +3947,8 @@ cleanup:
         { the first entry in the resident-name table is the module name }
         { the first entry in the resident-name table is the module name }
         TNewExeResidentNameTableEntry.Create(ResidentNameTable,ExtractModuleName(current_module.exefilename),0);
         TNewExeResidentNameTableEntry.Create(ResidentNameTable,ExtractModuleName(current_module.exefilename),0);
 
 
+        FillImportedNameTable;
+
         Header.InitialIP:=EntrySym.address;
         Header.InitialIP:=EntrySym.address;
         Header.InitialCS:=TNewExeSection(EntrySym.objsection.ExeSection).MemBasePos;
         Header.InitialCS:=TNewExeSection(EntrySym.objsection.ExeSection).MemBasePos;
         Header.InitialSP:=0;
         Header.InitialSP:=0;
@@ -3899,6 +3962,7 @@ cleanup:
         Header.ResourceTableStart:=Header.SegmentTableStart+NewExeSegmentHeaderSize*Header.SegmentTableEntriesCount;
         Header.ResourceTableStart:=Header.SegmentTableStart+NewExeSegmentHeaderSize*Header.SegmentTableEntriesCount;
         Header.ResidentNameTableStart:=Header.ResourceTableStart+ResourceTable.Size;
         Header.ResidentNameTableStart:=Header.ResourceTableStart+ResourceTable.Size;
         Header.ModuleReferenceTableStart:=Header.ResidentNameTableStart+ResidentNameTable.Size;
         Header.ModuleReferenceTableStart:=Header.ResidentNameTableStart+ResidentNameTable.Size;
+        Header.ImportedNameTableStart:=Header.ModuleReferenceTableStart+2*Header.ModuleReferenceTableEntriesCount;
 
 
         Header.WriteTo(FWriter);
         Header.WriteTo(FWriter);
 
 
@@ -3907,12 +3971,39 @@ cleanup:
 
 
         ResourceTable.WriteTo(FWriter);
         ResourceTable.WriteTo(FWriter);
         ResidentNameTable.WriteTo(FWriter);
         ResidentNameTable.WriteTo(FWriter);
+        { todo: write the module reference table here }
+        ImportedNameTable.WriteTo(FWriter);
 
 
         { todo: write the rest of the file as well }
         { todo: write the rest of the file as well }
 
 
         Result:=True;
         Result:=True;
       end;
       end;
 
 
+    procedure TNewExeOutput.FillImportedNameTable;
+      var
+        i, j: Integer;
+        ImportLibrary: TImportLibrary;
+        ImportSymbol: TImportSymbol;
+        exesym: TExeSymbol;
+      begin
+        for i:=0 to FImports.Count-1 do
+          begin
+            ImportLibrary:=TImportLibrary(FImports[i]);
+
+            for j:=0 to ImportLibrary.ImportSymbolList.Count-1 do
+              begin
+                ImportSymbol:=TImportSymbol(ImportLibrary.ImportSymbolList[j]);
+                exesym:=TExeSymbol(ExeSymbolList.Find(ImportSymbol.MangledName));
+                if assigned(exesym) then
+                  begin
+                    ImportedNameTable.AddImportedName(ImportLibrary.Name);
+                    if (ImportSymbol.OrdNr=0) and (ImportSymbol.Name<>'') then
+                      ImportedNameTable.AddImportedName(ImportSymbol.Name);
+                  end;
+              end;
+          end;
+      end;
+
     procedure TNewExeOutput.DoRelocationFixup(objsec: TObjSection);
     procedure TNewExeOutput.DoRelocationFixup(objsec: TObjSection);
       begin
       begin
         {todo}
         {todo}
@@ -3950,10 +4041,12 @@ cleanup:
         CurrExeMetaSec:=nemsNone;
         CurrExeMetaSec:=nemsNone;
         FResourceTable:=TNewExeResourceTable.Create;
         FResourceTable:=TNewExeResourceTable.Create;
         FResidentNameTable:=TNewExeResidentNameTable.Create;
         FResidentNameTable:=TNewExeResidentNameTable.Create;
+        FImportedNameTable:=TNewExeImportedNameTable.Create;
       end;
       end;
 
 
     destructor TNewExeOutput.destroy;
     destructor TNewExeOutput.destroy;
       begin
       begin
+        FImportedNameTable.Free;
         FResidentNameTable.Free;
         FResidentNameTable.Free;
         FResourceTable.Free;
         FResourceTable.Free;
         FHeader.Free;
         FHeader.Free;