Pārlūkot izejas kodu

+ Use DLL name in assembler labels used to import DLL functions/variables
in Windows, Emx and OS2 targets.
This fixes test failures: test/library/tlib1b.pp and lib2b.pp

link unit TLinker.AddImportSymbol: Added symmangledname parameter.
ogbase unit TImportSymbol.Create: Add AMangledName parameter.
fmodule unit TModule.AddExternalImport: Add symmangledname parameter.
fppu unit: Also put mangled name string for imported symbol.
ppu unit: Increase PPUVersion
utils/ppudump.pp: Adapt to PPU change above.
systems/T_OS units: Use ImportSymbol.MangledName property to create
import libraries or .idata sections.

git-svn-id: trunk@17804 -

pierre 14 gadi atpakaļ
vecāks
revīzija
239944f8d0

+ 25 - 6
compiler/fmodule.pas

@@ -199,7 +199,7 @@ interface
         function  resolve_unit(id:longint):tmodule;
         procedure allunitsused;
         procedure setmodulename(const s:string);
-        procedure AddExternalImport(const libname,symname:string;OrdNr: longint;isvar:boolean;ImportByOrdinalOnly:boolean);
+        procedure AddExternalImport(const libname,symname,symmangledname:string;OrdNr: longint;isvar:boolean;ImportByOrdinalOnly:boolean);
         property ImportLibraryList : TFPHashObjectList read FImportLibraryList;
       end;
 
@@ -955,21 +955,40 @@ implementation
       end;
 
 
-    procedure TModule.AddExternalImport(const libname,symname:string;OrdNr: longint;isvar:boolean;ImportByOrdinalOnly:boolean);
+    procedure TModule.AddExternalImport(const libname,symname,symmangledname:string;
+              OrdNr: longint;isvar:boolean;ImportByOrdinalOnly:boolean);
       var
-        ImportLibrary : TImportLibrary;
-        ImportSymbol  : TFPHashObject;
+        ImportLibrary,OtherIL : TImportLibrary;
+        ImportSymbol  : TImportSymbol;
+        i : longint;
       begin
         ImportLibrary:=TImportLibrary(ImportLibraryList.Find(libname));
         if not assigned(ImportLibrary) then
           ImportLibrary:=TImportLibrary.Create(ImportLibraryList,libname);
-        ImportSymbol:=TFPHashObject(ImportLibrary.ImportSymbolList.Find(symname));
+        ImportSymbol:=TImportSymbol(ImportLibrary.ImportSymbolList.Find(symname));
         if not assigned(ImportSymbol) then
           begin
+            { Check that the same name does not exist in another library }
+            { If it does and the same mangled name is used, issue a warning }
+            if ImportLibraryList.Count>1 then
+              for i:=0 To ImportLibraryList.Count-1 do
+                begin
+                  OtherIL:=TImportLibrary(ImportLibraryList.Items[i]);
+                  ImportSymbol:=TImportSymbol(OtherIL.ImportSymbolList.Find(symname));
+                  if assigned(ImportSymbol) then
+                    begin
+                      if ImportSymbol.MangledName=symmangledname then
+                        begin
+                          CGMessage3(sym_w_library_overload,symname,libname,OtherIL.Name);
+                          break;
+                        end;
+                    end;
+                end;
             if not ImportByOrdinalOnly then
               { negative ordinal number indicates import by name with ordinal number as hint }
               OrdNr:=-OrdNr;
-            ImportSymbol:=TImportSymbol.Create(ImportLibrary.ImportSymbolList,symname,OrdNr,isvar);
+            ImportSymbol:=TImportSymbol.Create(ImportLibrary.ImportSymbolList,
+              symname,symmangledname,OrdNr,isvar);
           end;
       end;
 

+ 5 - 1
compiler/fppu.pas

@@ -634,6 +634,7 @@ var
               begin
                 ImportSymbol:=TImportSymbol(ImportLibrary.ImportSymbolList[j]);
                 ppufile.putstring(ImportSymbol.Name);
+                ppufile.putstring(ImportSymbol.MangledName);
                 ppufile.putlongint(ImportSymbol.OrdNr);
                 ppufile.putbyte(byte(ImportSymbol.IsVar));
               end;
@@ -894,6 +895,7 @@ var
         extsymcnt   : longint;
         ImportLibrary  : TImportLibrary;
         extsymname  : string;
+        extsymmangledname : string;
         extsymordnr : longint;
         extsymisvar : boolean;
       begin
@@ -904,9 +906,11 @@ var
             for j:=0 to extsymcnt-1 do
               begin
                 extsymname:=ppufile.getstring;
+                extsymmangledname:=ppufile.getstring;
                 extsymordnr:=ppufile.getlongint;
                 extsymisvar:=(ppufile.getbyte<>0);
-                TImportSymbol.Create(ImportLibrary.ImportSymbolList,extsymname,extsymordnr,extsymisvar);
+                TImportSymbol.Create(ImportLibrary.ImportSymbolList,extsymname,
+                  extsymmangledname,extsymordnr,extsymisvar);
               end;
           end;
       end;

+ 8 - 7
compiler/link.pas

@@ -63,7 +63,7 @@ interface
          Procedure AddStaticCLibrary(const S : TCmdStr);
          Procedure AddSharedCLibrary(S : TCmdStr);
          Procedure AddFramework(S : TCmdStr);
-         procedure AddImportSymbol(const libname,symname:TCmdStr;OrdNr: longint;isvar:boolean);virtual;
+         procedure AddImportSymbol(const libname,symname,symmangledname:TCmdStr;OrdNr: longint;isvar:boolean);virtual;
          Procedure InitSysInitUnitName;virtual;
          Function  MakeExecutable:boolean;virtual;
          Function  MakeSharedLibrary:boolean;virtual;
@@ -113,7 +113,7 @@ interface
          Destructor Destroy;override;
          Function  MakeExecutable:boolean;override;
          Function  MakeSharedLibrary:boolean;override;
-         procedure AddImportSymbol(const libname,symname:TCmdStr;OrdNr: longint;isvar:boolean);override;
+         procedure AddImportSymbol(const libname,symname,symmangledname:TCmdStr;OrdNr: longint;isvar:boolean);override;
        end;
 
     var
@@ -435,14 +435,15 @@ Implementation
                for j:=0 to ImportLibrary.ImportSymbolList.Count-1 do
                  begin
                    ImportSymbol:=TImportSymbol(ImportLibrary.ImportSymbolList[j]);
-                   AddImportSymbol(ImportLibrary.Name,ImportSymbol.Name,ImportSymbol.OrdNr,ImportSymbol.IsVar);
+                   AddImportSymbol(ImportLibrary.Name,ImportSymbol.Name,
+                     ImportSymbol.MangledName,ImportSymbol.OrdNr,ImportSymbol.IsVar);
                  end;
              end;
          end;
       end;
 
 
-    procedure TLinker.AddImportSymbol(const libname,symname:TCmdStr;OrdNr: longint;isvar:boolean);
+    procedure TLinker.AddImportSymbol(const libname,symname,symmangledname:TCmdStr;OrdNr: longint;isvar:boolean);
       begin
       end;
 
@@ -520,7 +521,7 @@ Implementation
       end;
 
 
-    procedure AddImportSymbol(const libname,symname:TCmdStr;OrdNr: longint;isvar:boolean);
+    procedure AddImportSymbol(const libname,symname,symmangledname:TCmdStr;OrdNr: longint;isvar:boolean);
       begin
       end;
 
@@ -833,7 +834,7 @@ Implementation
       end;
 
 
-    procedure TInternalLinker.AddImportSymbol(const libname,symname:TCmdStr;OrdNr: longint;isvar:boolean);
+    procedure TInternalLinker.AddImportSymbol(const libname,symname,symmangledname:TCmdStr;OrdNr: longint;isvar:boolean);
       var
         ImportLibrary : TImportLibrary;
         ImportSymbol  : TFPHashObject;
@@ -843,7 +844,7 @@ Implementation
           ImportLibrary:=TImportLibrary.Create(ImportLibraryList,libname);
         ImportSymbol:=TFPHashObject(ImportLibrary.ImportSymbolList.Find(symname));
         if not assigned(ImportSymbol) then
-          ImportSymbol:=TImportSymbol.Create(ImportLibrary.ImportSymbolList,symname,OrdNr,isvar);
+          ImportSymbol:=TImportSymbol.Create(ImportLibrary.ImportSymbolList,symname,symmangledname,OrdNr,isvar);
       end;
 
 

+ 4 - 3
compiler/ogbase.pas

@@ -397,7 +397,7 @@ interface
         FIsVar  : boolean;
         FMangledName : string;
       public
-        constructor create(AList:TFPHashObjectList;const AName:string;AOrdNr:longint;AIsVar:boolean);
+        constructor create(AList:TFPHashObjectList;const AName,AMangledName:string;AOrdNr:longint;AIsVar:boolean);
         property OrdNr: longint read FOrdNr;
         property MangledName: string read FMangledName;
         property IsVar: boolean read FIsVar;
@@ -1477,12 +1477,13 @@ implementation
                                 TImportSymbol
 ****************************************************************************}
 
-    constructor TImportSymbol.create(AList:TFPHashObjectList;const AName:string;AOrdNr:longint;AIsVar:boolean);
+    constructor TImportSymbol.create(AList:TFPHashObjectList;
+            const AName,AMangledName:string;AOrdNr:longint;AIsVar:boolean);
       begin
         inherited Create(AList, AName);
         FOrdNr:=AOrdNr;
         FIsVar:=AIsVar;
-        FMangledName:=AName;
+        FMangledName:=AMangledName;
         { Replace ? and @ in import name, since GNU AS does not allow these characters in symbol names. }
         { This allows to import VC++ mangled names from DLLs. }
         if target_info.system in systems_all_windows then

+ 1 - 1
compiler/pdecsub.pas

@@ -2756,7 +2756,7 @@ const
                     if target_info.system in (systems_all_windows + systems_nativent +
                                        [system_i386_emx, system_i386_os2]) then
                    { cprefix is not used in DLL imports under Windows or OS/2 }
-                      result:=pd.import_name^
+                      result:='_$dll$'+ExtractFileName(pd.import_dll^)+'$'+pd.import_name^
                     else
                       result:=maybe_cprefix(pd.import_name^);
                   end

+ 10 - 3
compiler/pdecvar.pas

@@ -926,7 +926,7 @@ implementation
       is_weak_external,
       is_public_var  : boolean;
       dll_name,
-      C_name      : string;
+      C_name,mangledname      : string;
     begin
       { only allowed for one var }
       { only allow external and public on global symbols }
@@ -1016,6 +1016,7 @@ implementation
           inc(vs.refs);
         end;
 
+      mangledname:=C_name;
       { now we can insert it in the import lib if its a dll, or
         add it to the externals }
       if is_external_var then
@@ -1031,14 +1032,20 @@ implementation
             end;
           vs.varregable := vr_none;
           if is_dll then
-            current_module.AddExternalImport(dll_name,C_Name,0,true,false)
+            begin
+              if target_info.system in (systems_all_windows + systems_nativent +
+                                       [system_i386_emx, system_i386_os2]) then
+                mangledname:='_$dll$'+ExtractFileName(dll_name)+'$'+C_name;
+
+              current_module.AddExternalImport(dll_name,C_Name,mangledname,0,true,false);
+            end
           else
             if tf_has_dllscanner in target_info.flags then
               current_module.dllscannerinputlist.Add(vs.mangledname,vs);
         end;
 
       { Set the assembler name }
-      tstaticvarsym(vs).set_mangledname(C_Name);
+      tstaticvarsym(vs).set_mangledname(mangledname);
     end;
 
 

+ 1 - 1
compiler/pmodules.pas

@@ -1749,7 +1749,7 @@ implementation
         hp:=texported_item(current_module._exports.first);
         while assigned(hp) do
           begin
-            current_module.AddExternalImport(current_module.realmodulename^,hp.name^,hp.index,hp.is_var,false);
+            current_module.AddExternalImport(current_module.realmodulename^,hp.name^,hp.name^,hp.index,hp.is_var,false);
             hp:=texported_item(hp.next);
           end;
       end;

+ 1 - 1
compiler/ppu.pas

@@ -43,7 +43,7 @@ type
 {$endif Test_Double_checksum}
 
 const
-  CurrentPPUVersion = 130;
+  CurrentPPUVersion = 131;
 
 { buffer sizes }
   maxentrysize = 1024;

+ 10 - 1
compiler/psub.pas

@@ -1777,7 +1777,16 @@ implementation
 
                  { Import DLL specified? }
                  if assigned(pd.import_dll) then
-                   current_module.AddExternalImport(pd.import_dll^,proc_get_importname(pd),pd.import_nr,false,pd.import_name=nil)
+                   begin
+                     if assigned (pd.import_name) then
+                       current_module.AddExternalImport(pd.import_dll^,
+                         pd.import_name^,proc_get_importname(pd),
+                         pd.import_nr,false,false)
+                     else
+                       current_module.AddExternalImport(pd.import_dll^,
+                         proc_get_importname(pd),proc_get_importname(pd),
+                         pd.import_nr,false,true);
+                   end
                  else
                    begin
                      { add import name to external list for DLL scanning }

+ 1 - 1
compiler/symdef.pas

@@ -5275,7 +5275,7 @@ implementation
               begin
                 { copied from psub.read_proc }
                 if assigned(tobjectdef(pd.struct).import_lib) then
-                   current_module.AddExternalImport(tobjectdef(pd.struct).import_lib^,pd.mangledname,0,false,false)
+                   current_module.AddExternalImport(tobjectdef(pd.struct).import_lib^,pd.mangledname,pd.mangledname,0,false,false)
                  else
                    begin
                      { add import name to external list for DLL scanning }

+ 4 - 3
compiler/systems/t_emx.pas

@@ -279,7 +279,7 @@ begin
 end;
 
 
-procedure AddImport(const module:string;index:longint;const name:string);
+procedure AddImport(const module:string;index:longint;const name,mangledname:string);
 {func       = Name of function to import.
  module     = Name of DLL to import from.
  index      = Index of function in DLL. Use 0 to import by name.
@@ -290,7 +290,7 @@ var tmp1,tmp2,tmp3:string;
     func : string;
 begin
     aout_init;
-    func:='';
+    func:=mangledname;
     tmp2:=func;
     if profile_flag and not (copy(func,1,4)='_16_') then
         begin
@@ -353,7 +353,8 @@ end;
             for j:=0 to ImportLibrary.ImportSymbolList.Count-1 do
               begin
                 ImportSymbol:=TImportSymbol(ImportLibrary.ImportSymbolList[j]);
-                AddImport(ImportLibrary.Name,ImportSymbol.OrdNr,ImportSymbol.Name);
+                AddImport(ImportLibrary.Name,ImportSymbol.OrdNr,
+                  ImportSymbol.Name,ImportSymbol.MangledName);
               end;
             close(out_file);
          end;

+ 1 - 1
compiler/systems/t_nwm.pas

@@ -939,7 +939,7 @@ end;
             s := trimspace(s);
             if (length(s) > 0) then
               if copy(s,1,1) <> '#' then
-                AddImportSymbol('!clib',s,0,false);
+                AddImportSymbol('!clib',s,s,0,false);
           end;
         close(t);
       end;

+ 9 - 7
compiler/systems/t_os2.pas

@@ -279,24 +279,25 @@ begin
 end;
 
 
-procedure AddImport(const module:string;index:longint;const name:string);
-{func       = Name of function to import.
+procedure AddImport(const module:string;index:longint;const name,mangledname:string);
+{mangledname= Assembler label of the function to import.
  module     = Name of DLL to import from.
  index      = Index of function in DLL. Use 0 to import by name.
  name       = Name of function in DLL. Ignored when index=0;}
 (*
 var tmp1,tmp2,tmp3:string;
 *)
-var tmp1,tmp3:string;
+var tmp1,tmp2,tmp3:string;
     sym_mcount,sym_import:longint;
     fixup_mcount,fixup_import:longint;
 begin
     aout_init;
+    tmp2:=mangledname;
 (*
     tmp2:=func;
     if profile_flag and not (copy(func,1,4)='_16_') then
 *)
-    if profile_flag and not (copy(Name,1,4)='_16_') then
+    if profile_flag and not (copy(tmp2,1,4)='_16_') then
         begin
             {sym_entry:=aout_sym(func,n_text+n_ext,0,0,aout_text_size);}
             sym_mcount:=aout_sym('__mcount',n_ext,0,0,0);
@@ -306,7 +307,7 @@ begin
             tmp2:='__$U_'+func;
             sym_import:=aout_sym(tmp2,n_ext,0,0,0);
 *)
-            sym_import:=aout_sym(name,n_ext,0,0,0);
+            sym_import:=aout_sym(tmp2,n_ext,0,0,0);
             aout_text_byte($55);    {push ebp}
             aout_text_byte($89);    {mov ebp, esp}
             aout_text_byte($e5);
@@ -340,7 +341,7 @@ begin
         tmp3:=func+'='+module+'.'+name;
     aout_sym(tmp2,n_imp1+n_ext,0,0,0);
 *)
-    aout_sym(Name,n_imp1+n_ext,0,0,0);
+    aout_sym(tmp2,n_imp1+n_ext,0,0,0);
     aout_sym(tmp3,n_imp2+n_ext,0,0,0);
     aout_finish;
     write_ar(tmp1,aout_size);
@@ -369,7 +370,8 @@ end;
             for j:=0 to ImportLibrary.ImportSymbolList.Count-1 do
               begin
                 ImportSymbol:=TImportSymbol(ImportLibrary.ImportSymbolList[j]);
-                AddImport(ChangeFileExt(ExtractFileName(ImportLibrary.Name),''),ImportSymbol.OrdNr,ImportSymbol.Name);
+                AddImport(ChangeFileExt(ExtractFileName(ImportLibrary.Name),''),
+                  ImportSymbol.OrdNr,ImportSymbol.Name,ImportSymbol.MangledName);
               end;
          end;
          close(out_file);

+ 1 - 1
compiler/systems/t_win.pas

@@ -1764,7 +1764,7 @@ implementation
             ExtName:=current_module.dllscannerinputlist.NameOfIndex(i);
             if (ExtName=funcname) then
               begin
-                current_module.AddExternalImport(dllname,funcname,0,false,false);
+                current_module.AddExternalImport(dllname,funcname,funcname,0,false,false);
                 importfound:=true;
                 current_module.dllscannerinputlist.Delete(i);
                 exit;

+ 30 - 9
compiler/utils/ppudump.pp

@@ -154,6 +154,7 @@ type
 
 var
   ppufile     : tppufile;
+  ppuversion  : dword;
   space       : string;
   verbose     : longint;
   derefdata   : pbyte;
@@ -170,6 +171,11 @@ Begin
    has_errors:=true;
 End;
 
+function Unknown(const st : string; val :longint) : string;
+Begin
+  Unknown:='<!! Unknown'+st+' value '+tostr(val)+'>';
+  has_errors:=true;
+end;
 
 function ToStr(w:longint):String;
 begin
@@ -181,7 +187,7 @@ begin
   if w<=ord(high(tsystem)) then
     Target2Str:=Targets[tsystem(w)]
   else
-    Target2Str:='<!! Unknown target value '+tostr(w)+'>';
+    Target2Str:=Unknown('target',w);
 end;
 
 
@@ -190,7 +196,7 @@ begin
   if w<=ord(high(tsystemcpu)) then
     Cpu2Str:=CpuTxt[tsystemcpu(w)]
   else
-    Cpu2Str:='<!! Unknown cpu value '+tostr(w)+'>';
+    Cpu2Str:=Unknown('cpu',w);
 end;
 
 
@@ -203,7 +209,7 @@ begin
   if w<=ord(high(varspezstr)) then
     Varspez2Str:=varspezstr[tvarspez(w)]
   else
-    Varspez2Str:='<!! Unknown varspez value '+tostr(w)+'>';
+    Varspez2Str:=Unknown('varspez',w);
 end;
 
 Function VarRegable2Str(w:longint):string;
@@ -214,7 +220,7 @@ begin
   if w<=ord(high(varregablestr)) then
     Varregable2Str:=varregablestr[tvarregable(w)]
   else
-    Varregable2Str:='<!! Unknown regable value '+tostr(w)+'>';
+    Varregable2Str:=Unknown('regable',w);
 end;
 
 
@@ -230,7 +236,7 @@ begin
   if w<=ord(high(visibilityName)) then
     result:=visibilityName[tvisibility(w)]
   else
-    result:='<!! Unknown visibility value '+tostr(w)+'>';
+    result:=Unknown('visibility',w);
 end;
 
 
@@ -270,13 +276,14 @@ const
     (mask: $800000  ;str:'has_classinits')
   );
 var
-  i : longint;
+  i,ntflags : longint;
   first  : boolean;
   s : string;
 begin
   s:='';
   if flags<>0 then
    begin
+     ntflags:=flags;
      first:=true;
      for i:=1to flagopts do
       if (flags and flagopt[i].mask)<>0 then
@@ -286,10 +293,16 @@ begin
          else
            s:=s+', ';
          s:=s+flagopt[i].str;
+         ntflags:=ntflags and (not flagopt[i].mask);
        end;
    end
   else
    s:='none';
+  if ntflags<>0 then
+    begin
+      s:=s+' unknown '+hexstr(ntflags,8);
+      has_errors:=true;
+    end;
   PPUFlags2Str:=s;
 end;
 
@@ -459,6 +472,7 @@ var
   j,
   extsymcnt   : longint;
   extsymname  : string;
+  extsymmangledname  : string;
   extsymordnr : longint;
   extsymisvar : boolean;
 begin
@@ -470,9 +484,14 @@ begin
       for j:=0 to extsymcnt-1 do
         begin
           extsymname:=ppufile.getstring;
+          if ppuversion>130 then
+            extsymmangledname:=ppufile.getstring
+          else
+            extsymmangledname:=extsymname;
           extsymordnr:=ppufile.getlongint;
           extsymisvar:=ppufile.getbyte<>0;
-          writeln(' ',extsymname,' (OrdNr: ',extsymordnr,' IsVar: ',extsymisvar,')');
+          writeln(' ',extsymname,' as ',extsymmangledname,
+            '(OrdNr: ',extsymordnr,' IsVar: ',extsymisvar,')');
         end;
     end;
 end;
@@ -2261,8 +2280,10 @@ begin
      exit;
    end;
 { Check PPU Version }
-  Writeln('Analyzing ',filename,' (v',ppufile.GetPPUVersion,')');
-  if ppufile.GetPPUVersion<16 then
+  ppuversion:=ppufile.GetPPUVersion;
+
+  Writeln('Analyzing ',filename,' (v',PPUVersion,')');
+  if PPUVersion<16 then
    begin
      writeln(Filename,' : Old PPU Formats (<v16) are not supported, Skipping');
      exit;