From 239944f8d01c2e1d5e0a7e29e2bd6387c8291ae7 Mon Sep 17 00:00:00 2001 From: pierre Date: Thu, 23 Jun 2011 11:38:57 +0000 Subject: [PATCH] + 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 - --- compiler/fmodule.pas | 31 ++++++++++++++++++++++++------ compiler/fppu.pas | 6 +++++- compiler/link.pas | 15 ++++++++------- compiler/ogbase.pas | 7 ++++--- compiler/pdecsub.pas | 2 +- compiler/pdecvar.pas | 13 ++++++++++--- compiler/pmodules.pas | 2 +- compiler/ppu.pas | 2 +- compiler/psub.pas | 11 ++++++++++- compiler/symdef.pas | 2 +- compiler/systems/t_emx.pas | 7 ++++--- compiler/systems/t_nwm.pas | 2 +- compiler/systems/t_os2.pas | 16 +++++++++------- compiler/systems/t_win.pas | 2 +- compiler/utils/ppudump.pp | 39 +++++++++++++++++++++++++++++--------- 15 files changed, 111 insertions(+), 46 deletions(-) diff --git a/compiler/fmodule.pas b/compiler/fmodule.pas index 0feddcb42e..1892ea42e6 100644 --- a/compiler/fmodule.pas +++ b/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; diff --git a/compiler/fppu.pas b/compiler/fppu.pas index 3602070b6b..3c951bba34 100644 --- a/compiler/fppu.pas +++ b/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; diff --git a/compiler/link.pas b/compiler/link.pas index 3757033bb1..7d8bd70af3 100644 --- a/compiler/link.pas +++ b/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; diff --git a/compiler/ogbase.pas b/compiler/ogbase.pas index 3d71355ebd..08e6df2fec 100644 --- a/compiler/ogbase.pas +++ b/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 diff --git a/compiler/pdecsub.pas b/compiler/pdecsub.pas index 50276eed79..d16034740d 100644 --- a/compiler/pdecsub.pas +++ b/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 diff --git a/compiler/pdecvar.pas b/compiler/pdecvar.pas index 38e01b0585..8de78aade4 100644 --- a/compiler/pdecvar.pas +++ b/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; diff --git a/compiler/pmodules.pas b/compiler/pmodules.pas index 9de7959431..74ce36aa67 100644 --- a/compiler/pmodules.pas +++ b/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; diff --git a/compiler/ppu.pas b/compiler/ppu.pas index 7fafe04dcd..905ca8931d 100644 --- a/compiler/ppu.pas +++ b/compiler/ppu.pas @@ -43,7 +43,7 @@ type {$endif Test_Double_checksum} const - CurrentPPUVersion = 130; + CurrentPPUVersion = 131; { buffer sizes } maxentrysize = 1024; diff --git a/compiler/psub.pas b/compiler/psub.pas index b3e27e172a..165b427337 100644 --- a/compiler/psub.pas +++ b/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 } diff --git a/compiler/symdef.pas b/compiler/symdef.pas index cc1c051d56..07bfae013c 100644 --- a/compiler/symdef.pas +++ b/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 } diff --git a/compiler/systems/t_emx.pas b/compiler/systems/t_emx.pas index d5fcdbccb4..3ea0c134b9 100644 --- a/compiler/systems/t_emx.pas +++ b/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; diff --git a/compiler/systems/t_nwm.pas b/compiler/systems/t_nwm.pas index 8bdaf39aae..e8fdbf62bc 100644 --- a/compiler/systems/t_nwm.pas +++ b/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; diff --git a/compiler/systems/t_os2.pas b/compiler/systems/t_os2.pas index e4d8915f3a..ff0ca20106 100644 --- a/compiler/systems/t_os2.pas +++ b/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); diff --git a/compiler/systems/t_win.pas b/compiler/systems/t_win.pas index 5d590657de..b766f4ab6d 100644 --- a/compiler/systems/t_win.pas +++ b/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; diff --git a/compiler/utils/ppudump.pp b/compiler/utils/ppudump.pp index de1cc60626..ab29f7aada 100644 --- a/compiler/utils/ppudump.pp +++ b/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:=''; + 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:=''; + Target2Str:=Unknown('target',w); end; @@ -190,7 +196,7 @@ begin if w<=ord(high(tsystemcpu)) then Cpu2Str:=CpuTxt[tsystemcpu(w)] else - Cpu2Str:=''; + Cpu2Str:=Unknown('cpu',w); end; @@ -203,7 +209,7 @@ begin if w<=ord(high(varspezstr)) then Varspez2Str:=varspezstr[tvarspez(w)] else - Varspez2Str:=''; + 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:=''; + Varregable2Str:=Unknown('regable',w); end; @@ -230,7 +236,7 @@ begin if w<=ord(high(visibilityName)) then result:=visibilityName[tvisibility(w)] else - result:=''; + 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 (