mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 23:29:13 +02:00
* use the extern and public assembler symbol lists stored in the units to resolve those symbols to a used package that don't have a corresponding Pascal symbol
git-svn-id: trunk@34179 -
This commit is contained in:
parent
6cc7539208
commit
022df814c2
@ -45,8 +45,10 @@ implementation
|
|||||||
globtype,systems,
|
globtype,systems,
|
||||||
cutils,
|
cutils,
|
||||||
globals,verbose,
|
globals,verbose,
|
||||||
|
aasmbase,aasmdata,
|
||||||
symtype,symconst,symsym,symdef,symbase,symtable,
|
symtype,symconst,symsym,symdef,symbase,symtable,
|
||||||
psub,
|
psub,pdecsub,
|
||||||
|
ncgutil,
|
||||||
ppu,entfile,fpcp,
|
ppu,entfile,fpcp,
|
||||||
export;
|
export;
|
||||||
|
|
||||||
@ -540,10 +542,149 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
procedure createimportlibfromexternals;
|
procedure createimportlibfromexternals;
|
||||||
|
type
|
||||||
|
tcacheentry=record
|
||||||
|
pkg:tpackage;
|
||||||
|
sym:tasmsymbol;
|
||||||
|
end;
|
||||||
|
pcacheentry=^tcacheentry;
|
||||||
var
|
var
|
||||||
|
cache : tfphashlist;
|
||||||
alreadyloaded : tfpobjectlist;
|
alreadyloaded : tfpobjectlist;
|
||||||
|
|
||||||
|
|
||||||
|
function findpackagewithsym(symname:tsymstr):tcacheentry;
|
||||||
|
var
|
||||||
|
i,j : longint;
|
||||||
|
pkgentry : ppackageentry;
|
||||||
|
unitentry : pcontainedunit;
|
||||||
|
begin
|
||||||
|
for i:=0 to packagelist.count-1 do
|
||||||
|
begin
|
||||||
|
pkgentry:=ppackageentry(packagelist[i]);
|
||||||
|
for j:=0 to pkgentry^.package.containedmodules.count-1 do
|
||||||
|
begin
|
||||||
|
unitentry:=pcontainedunit(pkgentry^.package.containedmodules[j]);
|
||||||
|
if not assigned(unitentry^.module) then
|
||||||
|
{ the unit is not loaded }
|
||||||
|
continue;
|
||||||
|
result.sym:=tasmsymbol(tmodule(unitentry^.module).publicasmsyms.find(symname));
|
||||||
|
if assigned(result.sym) then
|
||||||
|
begin
|
||||||
|
{ completely ignore other external symbols }
|
||||||
|
if result.sym.bind in [ab_external,ab_weak_external] then
|
||||||
|
begin
|
||||||
|
result.sym:=nil;
|
||||||
|
continue;
|
||||||
|
end;
|
||||||
|
{ only accept global symbols of the used unit }
|
||||||
|
if result.sym.bind<>ab_global then
|
||||||
|
begin
|
||||||
|
result.sym:=nil;
|
||||||
|
result.pkg:=nil;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
result.pkg:=pkgentry^.package;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
result.sym:=nil;
|
||||||
|
result.pkg:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure processasmsyms(symlist:tfphashobjectlist);
|
||||||
|
var
|
||||||
|
i,j,k : longint;
|
||||||
|
sym : tasmsymbol;
|
||||||
|
cacheentry : pcacheentry;
|
||||||
|
list : TAsmList;
|
||||||
|
labind : tasmsymbol;
|
||||||
|
psym : tsymentry;
|
||||||
|
pd : tprocdef;
|
||||||
|
found : boolean;
|
||||||
|
impname,symname : TSymStr;
|
||||||
|
suffixidx : longint;
|
||||||
|
begin
|
||||||
|
for i:=0 to symlist.count-1 do
|
||||||
|
begin
|
||||||
|
sym:=tasmsymbol(symlist[i]);
|
||||||
|
if not (sym.bind in [ab_external,ab_external_indirect]) then
|
||||||
|
continue;
|
||||||
|
|
||||||
|
{ remove the indirect suffix }
|
||||||
|
symname:=sym.name;
|
||||||
|
if sym.bind=ab_external_indirect then
|
||||||
|
begin
|
||||||
|
suffixidx:=pos(suffix_indirect,symname);
|
||||||
|
if suffixidx=length(symname)-length(suffix_indirect)+1 then
|
||||||
|
symname:=copy(symname,1,suffixidx-1)
|
||||||
|
else
|
||||||
|
internalerror(2016062401);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ did we already import the symbol? }
|
||||||
|
cacheentry:=pcacheentry(cache.find(symname));
|
||||||
|
if assigned(cacheentry) then
|
||||||
|
continue;
|
||||||
|
|
||||||
|
{ was the symbol already imported in the previous pass? }
|
||||||
|
found:=false;
|
||||||
|
for j:=0 to alreadyloaded.count-1 do
|
||||||
|
begin
|
||||||
|
psym:=tsymentry(alreadyloaded[j]);
|
||||||
|
case psym.typ of
|
||||||
|
procsym:
|
||||||
|
for k:=0 to tprocsym(psym).procdeflist.count-1 do
|
||||||
|
begin
|
||||||
|
pd:=tprocdef(tprocsym(psym).procdeflist[k]);
|
||||||
|
if has_alias_name(pd,symname) or
|
||||||
|
(
|
||||||
|
([po_external,po_has_importdll]*pd.procoptions=[po_external,po_has_importdll]) and
|
||||||
|
(symname=proc_get_importname(pd))
|
||||||
|
) then
|
||||||
|
begin
|
||||||
|
found:=true;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
staticvarsym:
|
||||||
|
if tstaticvarsym(psym).mangledname=symname then
|
||||||
|
found:=true;
|
||||||
|
else
|
||||||
|
internalerror(2014101005);
|
||||||
|
end;
|
||||||
|
if found then
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
if found then begin
|
||||||
|
{ add a dummy entry }
|
||||||
|
new(cacheentry);
|
||||||
|
cacheentry^.pkg:=nil;
|
||||||
|
cacheentry^.sym:=sym;
|
||||||
|
cache.add(symname,cacheentry);
|
||||||
|
continue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
new(cacheentry);
|
||||||
|
cacheentry^:=findpackagewithsym(symname);
|
||||||
|
cache.add(symname,cacheentry);
|
||||||
|
|
||||||
|
{ use cacheentry^.sym instead of sym, because for the later typ
|
||||||
|
is always at_none in case of an external symbol }
|
||||||
|
if assigned(cacheentry^.pkg) then
|
||||||
|
begin
|
||||||
|
impname:=symname;
|
||||||
|
if cacheentry^.sym.typ=AT_DATA then
|
||||||
|
{ import as the $indirect symbol if it as a variable }
|
||||||
|
impname:=symname+suffix_indirect;
|
||||||
|
current_module.addexternalimport(cacheentry^.pkg.pplfilename,symname,impname,0,cacheentry^.sym.typ=at_data,false);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure import_proc_symbol(pd:tprocdef;pkg:tpackage);
|
procedure import_proc_symbol(pd:tprocdef;pkg:tpackage);
|
||||||
var
|
var
|
||||||
item : TCmdStrListItem;
|
item : TCmdStrListItem;
|
||||||
@ -636,7 +777,9 @@ implementation
|
|||||||
var
|
var
|
||||||
unitentry : pcontainedunit;
|
unitentry : pcontainedunit;
|
||||||
module : tmodule;
|
module : tmodule;
|
||||||
|
i : longint;
|
||||||
begin
|
begin
|
||||||
|
cache:=tfphashlist.create;
|
||||||
{ check each external asm symbol of each unit of the package whether it is
|
{ check each external asm symbol of each unit of the package whether it is
|
||||||
contained in the unit of a loaded package (and thus an import entry
|
contained in the unit of a loaded package (and thus an import entry
|
||||||
is needed) }
|
is needed) }
|
||||||
@ -651,7 +794,19 @@ implementation
|
|||||||
module:=tmodule(module.next);
|
module:=tmodule(module.next);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ second pass to find all symbols that were loaded by asm name }
|
||||||
|
module:=tmodule(loaded_units.first);
|
||||||
|
while assigned(module) do
|
||||||
|
begin
|
||||||
|
if not assigned(module.package) then
|
||||||
|
processasmsyms(module.externasmsyms);
|
||||||
|
module:=tmodule(module.next);
|
||||||
|
end;
|
||||||
|
|
||||||
alreadyloaded.free;
|
alreadyloaded.free;
|
||||||
|
for i:=0 to cache.count-1 do
|
||||||
|
dispose(pcacheentry(cache[i]));
|
||||||
|
cache.free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user