Przeglądaj źródła

To correctly generate the import library for a package we need to resolve the dangling external symbols of all units. For this each unit now stores which symbols it exported from another unit and it also stores all global and external assembler symbols it has (maybe this can be streamlined later on, but for now this works).

entfile.pas:
  + new entry for the imported unit symbols; for the global assembler symbols a deprecated entry is revived
fmodule.pas, tmodule:
  + new field globalasmsyms which holds all global/external assembler symbols of a unit
  + new field unitimportsyms which holds all symbols imported by a unit from another unit
  + new method to extract all global/external assembler symbols of a unit
  * create, destroy & reset: correctly instantiate/free the two new lists
fppu.pas, tppumodule:
  + new field unitimportsymsderefs to hold the derefs during loading from/storing to PPU
  + new method buildderefunitimportsyms to generate the derefs for each imported symbol
  + new method derefunitimportsyms to resolve each imported symbol deref
  + new method readunitimportsyms to read the imported symbols from the PPU
  + new method writeunitimportsyms to write all imported symbols to the PPU
  + new method writeasmsymbols to write all global/external assembler symbols to the PPU
  + new method readasmsymbols to read all global/external assembler symbols from the PPU
  * load_implementation: read the assembler symbols and the imported symbols if their respective entry is encountered
  * writeppu: generate the derefs and write them and the assembler symbols to PPU
  * load_usedunits: resolve the imported symbols once all derefs are known
pmoudles.pas:
  * finish_unit: extract all global/external assembler symbols before writing the PPU
symtable.pas:
  * addsymref: if the symbol is not from the current unit than mark it as imported
ppu.pas:
  * increase PPU version

git-svn-id: branches/svenbarth/packages@28846 -
svenbarth 10 lat temu
rodzic
commit
6f15aef215
6 zmienionych plików z 163 dodań i 11 usunięć
  1. 1 0
      compiler/entfile.pas
  2. 27 0
      compiler/fmodule.pas
  3. 114 2
      compiler/fppu.pas
  4. 6 1
      compiler/pmodules.pas
  5. 1 1
      compiler/ppu.pas
  6. 14 7
      compiler/symtable.pas

+ 1 - 0
compiler/entfile.pas

@@ -113,6 +113,7 @@ interface
     ibcreatedobjtypes = 83;
     ibwpofile         = 84;
     ibmoduleoptions   = 85;
+    ibunitimportsyms  = 86;
 
     ibmainname            = 90;
     ibsymtableoptions     = 91;

+ 27 - 0
compiler/fmodule.pas

@@ -153,6 +153,9 @@ interface
         scanner       : TObject;  { scanner object used }
         procinfo      : TObject;  { current procedure being compiled }
         asmdata       : TObject;  { Assembler data }
+        globalasmsyms : TFPHashObjectList; { contains the assembler symbols which can potentially be exported for e.g. packages;
+                                             it's filled either by loading from a ppu or after parsing the unit has finished }
+        unitimportsyms: tfpobjectlist;
         asmprefix     : pshortstring;  { prefix for the smartlink asmfiles }
         debuginfo     : TObject;
         loaded_from   : tmodule;
@@ -225,6 +228,7 @@ interface
         function  resolve_unit(id:longint):tmodule;
         procedure allunitsused;
         procedure end_of_parsing;virtual;
+        procedure extractexportasmsyms;
         procedure setmodulename(const s:string);
         procedure AddExternalImport(const libname,symname,symmangledname:string;OrdNr: longint;isvar:boolean;ImportByOrdinalOnly:boolean);
         property ImportLibraryList : TFPHashObjectList read FImportLibraryList;
@@ -510,6 +514,21 @@ implementation
                                   TMODULE
  ****************************************************************************}
 
+    procedure tmodule.extractexportasmsyms;
+      var
+        symold,symnew : tasmsymbol;
+        i : longint;
+        n : string;
+      begin
+        for i:=0 to tasmdata(asmdata).AsmSymbolDict.Count-1 do
+          begin
+            symold:=tasmsymbol(tasmdata(asmdata).asmsymboldict[i]);
+            n:=symold.name;
+            if (symold.classtype=tasmsymbol) and (symold.bind in [AB_GLOBAL,AB_EXTERNAL,AB_WEAK_EXTERNAL]) then
+              symnew:=tasmsymbol.create(globalasmsyms,symold.name,symold.bind,symold.typ);
+          end;
+      end;
+
     constructor tmodule.create(LoadedFrom:TModule;const amodulename: string; const afilename:TPathStr;_is_unit:boolean);
       var
         n:string;
@@ -602,6 +621,8 @@ implementation
         _exports:=TLinkedList.Create;
         dllscannerinputlist:=TFPHashList.Create;
         asmdata:=casmdata.create(modulename);
+        globalasmsyms:=tfphashobjectlist.create(true);
+        unitimportsyms:=tfpobjectlist.create(false);
         InitDebugInfo(self,false);
       end;
 
@@ -661,6 +682,8 @@ implementation
         linkothersharedlibs.Free;
         linkotherframeworks.Free;
         stringdispose(mainname);
+        globalasmsyms.free;
+        unitimportsyms.free;
         FImportLibraryList.Free;
         extendeddefs.Free;
         genericdummysyms.free;
@@ -751,6 +774,10 @@ implementation
         wpoinfo:=nil;
         checkforwarddefs.free;
         checkforwarddefs:=TFPObjectList.Create(false);
+        globalasmsyms.free;
+        globalasmsyms:=tfphashobjectlist.create(true);
+        unitimportsyms.free;
+        unitimportsyms:=tfpobjectlist.create(false);
         derefdata.free;
         derefdata:=TDynamicArray.Create(1024);
         if assigned(unitmap) then

+ 114 - 2
compiler/fppu.pas

@@ -66,6 +66,7 @@ interface
           procedure reload_flagged_units;
           procedure end_of_parsing;override;
        private
+          unitimportsymsderefs : tfplist;
          { Each time a unit's defs are (re)created, its defsgeneration is
            set to the value of a global counter, and the global counter is
            increased. We only reresolve its dependent units' defs in case
@@ -80,12 +81,17 @@ interface
           procedure load_usedunits;
           procedure printcomments;
           procedure queuecomment(const s:TMsgStr;v,w:longint);
+          procedure buildderefunitimportsyms;
+          procedure derefunitimportsyms;
+          procedure readunitimportsyms;
+          procedure writeunitimportsyms;
           procedure writesourcefiles;
           procedure writeusedunit(intf:boolean);
           procedure writelinkcontainer(var p:tlinkcontainer;id:byte;strippath:boolean);
           procedure writederefmap;
           procedure writederefdata;
           procedure writeImportSymbols;
+          procedure writeasmsymbols;
           procedure writeResources;
           procedure readsourcefiles;
           procedure readloadunit;
@@ -94,6 +100,7 @@ interface
           procedure readderefdata;
           procedure readImportSymbols;
           procedure readResources;
+          procedure readasmsymbols;
           procedure readwpofile;
 {$IFDEF MACRO_DIFF_HINT}
           procedure writeusedmacro(p:TNamedIndexItem;arg:pointer);
@@ -132,6 +139,7 @@ var
         inherited create(LoadedFrom,amodulename,afilename,_is_unit);
         ppufile:=nil;
         sourcefn:=afilename;
+        unitimportsymsderefs:=tfplist.create;
       end;
 
 
@@ -142,6 +150,8 @@ var
         ppufile:=nil;
         comments.free;
         comments:=nil;
+        unitimportsymsderefs.free;
+        unitimportsymsderefs:=nil;
         inherited Destroy;
       end;
 
@@ -677,6 +687,22 @@ var
         ppufile.writeentry(ibImportSymbols);
       end;
 
+    procedure tppumodule.writeasmsymbols;
+      var
+        sym : tasmsymbol;
+        i : longint;
+      begin
+        ppufile.putlongint(globalasmsyms.count);
+        for i:=0 to globalasmsyms.count-1 do
+          begin
+            sym:=tasmsymbol(globalasmsyms[i]);
+            ppufile.putstring(sym.name);
+            ppufile.putbyte(ord(sym.bind));
+            ppufile.putbyte(ord(sym.typ));
+          end;
+        ppufile.writeentry(ibasmsymbols);
+      end;
+
 
     procedure tppumodule.writeResources;
       var
@@ -692,6 +718,63 @@ var
       end;
 
 
+    procedure tppumodule.buildderefunitimportsyms;
+      var
+        deref : pderef;
+        i : longint;
+      begin
+        for i:=0 to unitimportsyms.count-1 do
+          begin
+            new(deref);
+            deref^.build(unitimportsyms[i]);
+            unitimportsymsderefs.add(deref);
+          end;
+      end;
+
+
+    procedure tppumodule.derefunitimportsyms;
+      var
+        i : longint;
+        sym : tsym;
+      begin
+        { since this list can get quite large we clear it immediately after we derefd it }
+        for i:=0 to unitimportsymsderefs.count-1 do
+          begin
+            sym:=tsym(pderef(unitimportsymsderefs[i])^.resolve);
+            unitimportsyms.add(sym);
+            dispose(pderef(unitimportsymsderefs[i]));
+          end;
+        unitimportsymsderefs.clear;
+      end;
+
+
+    procedure tppumodule.readunitimportsyms;
+      var
+        c,i : longint;
+        deref : pderef;
+      begin
+        c:=ppufile.getlongint;
+        writeln('loading: unit ', modulename^, ' has ', c, ' imported symbols');
+        for i:=0 to c-1 do
+          begin
+            new(deref);
+            ppufile.getderef(deref^);
+            unitimportsymsderefs.add(deref);
+          end;
+      end;
+
+
+    procedure tppumodule.writeunitimportsyms;
+      var
+        i : longint;
+      begin
+        writeln('writing: unit ', modulename^, ' has ', unitimportsymsderefs.Count, ' imported symbols');
+        ppufile.putlongint(unitimportsymsderefs.count);
+        for i:=0 to unitimportsymsderefs.count-1 do
+          ppufile.putderef(pderef(unitimportsymsderefs[i])^);
+        ppufile.writeentry(ibunitimportsyms);
+      end;
+
 {$IFDEF MACRO_DIFF_HINT}
 
 {
@@ -963,6 +1046,25 @@ var
       end;
 
 
+    procedure tppumodule.readasmsymbols;
+      var
+        cnt : longint;
+        s : string;
+        bind : tasmsymbind;
+        typ : tasmsymtype;
+      begin
+        cnt:=ppufile.getlongint;
+        writeln('loading: unit ', modulename^, ' has ', cnt, ' imported asm symbols');
+        while not ppufile.endofentry and not ppufile.error do
+          begin
+            s:=ppufile.getstring;
+            bind:=tasmsymbind(ppufile.getbyte);
+            typ:=tasmsymtype(ppufile.getbyte);
+            tasmsymbol.create(globalasmsyms,s,bind,typ);
+          end;
+      end;
+
+
     procedure tppumodule.readwpofile;
       var
         orgwpofilename: string;
@@ -1077,8 +1179,9 @@ var
              ibloadunit :
                readloadunit;
              ibasmsymbols :
-{ TODO: Remove ibasmsymbols}
-               ;
+               readasmsymbols;
+             ibunitimportsyms :
+               readunitimportsyms;
              ibendimplementation :
                break;
            else
@@ -1197,6 +1300,7 @@ var
            end;
          tunitwpoinfo(wpoinfo).buildderef;
          tunitwpoinfo(wpoinfo).buildderefimpl;
+         buildderefunitimportsyms;
          writederefmap;
          writederefdata;
 
@@ -1223,6 +1327,12 @@ var
          { write implementation uses }
          writeusedunit(false);
 
+         { write global assembler symbols }
+         writeasmsymbols;
+
+         { write all symbols imported from another unit }
+         writeunitimportsyms;
+
          { end of implementation }
          ppufile.writeentry(ibendimplementation);
 
@@ -1474,6 +1584,8 @@ var
         if assigned(localsymtable) then
           tstoredsymtable(localsymtable).derefimpl;
 
+        derefunitimportsyms;
+
          { read whole program optimisation-related information }
          wpoinfo:=tunitwpoinfo.ppuload(ppufile);
          tunitwpoinfo(wpoinfo).deref;

+ 6 - 1
compiler/pmodules.pas

@@ -1216,7 +1216,12 @@ type
          store_crc:=current_module.crc;
 {$endif EXTDEBUG}
          if (Errorcount=0) then
-           tppumodule(current_module).writeppu;
+           begin
+             { ensure that all asm symbols that can potentially be exported are
+               available in the ppu }
+             current_module.extractexportasmsyms;
+             tppumodule(current_module).writeppu;
+           end;
 
          if not(cs_compilesystem in current_settings.moduleswitches) then
            begin

+ 1 - 1
compiler/ppu.pas

@@ -43,7 +43,7 @@ type
 {$endif Test_Double_checksum}
 
 const
-  CurrentPPUVersion = 170;
+  CurrentPPUVersion = 172;
 
   ppubufsize   = 16384;
 

+ 14 - 7
compiler/symtable.pas

@@ -2116,13 +2116,20 @@ implementation
          owner:=sym.owner;
          while owner.symtabletype in [objectsymtable,recordsymtable,enumsymtable] do
            owner:=tdef(owner.defowner).owner;
-         if assigned(current_module) and
-            (owner.symtabletype=globalsymtable) then
-             begin
-               if tglobalsymtable(owner).moduleid>=current_module.unitmapsize then
-                 internalerror(200501152);
-               inc(current_module.unitmap[tglobalsymtable(owner).moduleid].refs);
-             end;
+         if assigned(current_module) then
+           begin
+             if (owner.symtabletype=globalsymtable) then
+               begin
+                 if tglobalsymtable(owner).moduleid>=current_module.unitmapsize then
+                   internalerror(200501152);
+                 inc(current_module.unitmap[tglobalsymtable(owner).moduleid].refs);
+               end;
+             if (owner.symtabletype=globalsymtable) and (current_module.globalsymtable<>owner) then
+               begin
+                 if current_module.unitimportsyms.indexof(sym)<0 then
+                   current_module.unitimportsyms.add(sym);
+               end;
+           end;
        end;