+ 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 -
This commit is contained in:
pierre 2011-06-23 11:38:57 +00:00
parent f220513821
commit 239944f8d0
15 changed files with 111 additions and 46 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

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

View File

@ -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 }

View File

@ -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 }

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;