mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 15:47:53 +02:00
* patch from Pavel with a new and much faster DLL Scanner for
automatic importing so $linklib works for DLLs. Thanks Pavel!
This commit is contained in:
parent
e49f13a393
commit
aab27143a3
@ -52,6 +52,14 @@ interface
|
||||
rr_asmolder,rr_crcchanged
|
||||
);
|
||||
|
||||
TExternalsItem=class(TLinkedListItem)
|
||||
public
|
||||
found : longbool;
|
||||
data : pstring;
|
||||
constructor Create(const s:string);
|
||||
Destructor Destroy;override;
|
||||
end;
|
||||
|
||||
tlinkcontaineritem=class(tlinkedlistitem)
|
||||
public
|
||||
data : pstring;
|
||||
@ -105,7 +113,7 @@ interface
|
||||
uses_imports : boolean; { Set if the module imports from DLL's.}
|
||||
imports : tlinkedlist;
|
||||
_exports : tlinkedlist;
|
||||
|
||||
externals : tlinkedlist; {Only for DLL scanners by using Unix-style $LINKLIB }
|
||||
resourcefiles : tstringlist;
|
||||
|
||||
linkunitofiles,
|
||||
@ -286,6 +294,25 @@ uses
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
TExternalsItem
|
||||
****************************************************************************}
|
||||
|
||||
constructor tExternalsItem.Create(const s:string);
|
||||
begin
|
||||
inherited Create;
|
||||
found:=false;
|
||||
data:=stringdup(s);
|
||||
end;
|
||||
|
||||
|
||||
destructor tExternalsItem.Destroy;
|
||||
begin
|
||||
stringdispose(data);
|
||||
inherited;
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
TMODULE
|
||||
****************************************************************************}
|
||||
@ -614,6 +641,8 @@ uses
|
||||
imports:=tlinkedlist.create;
|
||||
_exports.free;
|
||||
_exports:=tlinkedlist.create;
|
||||
externals.free;
|
||||
externals:=tlinkedlist.create;
|
||||
used_units.free;
|
||||
used_units:=TLinkedList.Create;
|
||||
{ all units that depend on this one must be recompiled ! }
|
||||
@ -745,6 +774,7 @@ uses
|
||||
uses_imports:=false;
|
||||
imports:=TLinkedList.Create;
|
||||
_exports:=TLinkedList.Create;
|
||||
externals:=TLinkedList.Create;
|
||||
{ search the PPU file if it is an unit }
|
||||
if is_unit then
|
||||
begin
|
||||
@ -776,6 +806,9 @@ uses
|
||||
if assigned(_exports) then
|
||||
_exports.free;
|
||||
_exports:=nil;
|
||||
if assigned(externals) then
|
||||
externals.free;
|
||||
externals:=nil;
|
||||
if assigned(scanner) then
|
||||
pscannerfile(scanner)^.invalid:=true;
|
||||
if assigned(sourcefiles) then
|
||||
@ -873,7 +906,11 @@ uses
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.7 2001-02-20 21:41:15 peter
|
||||
Revision 1.8 2001-03-06 18:28:02 peter
|
||||
* patch from Pavel with a new and much faster DLL Scanner for
|
||||
automatic importing so $linklib works for DLLs. Thanks Pavel!
|
||||
|
||||
Revision 1.7 2001/02/20 21:41:15 peter
|
||||
* new fixfilename, findfile for unix. Look first for lowercase, then
|
||||
NormalCase and last for UPPERCASE names.
|
||||
|
||||
|
@ -61,6 +61,19 @@ type
|
||||
procedure generatesmartlib;virtual;
|
||||
end;
|
||||
|
||||
TDLLScanner=class
|
||||
public
|
||||
f:file;
|
||||
impname:string;
|
||||
TheWord:array[0..1]of char;
|
||||
HeaderOffset:cardinal;
|
||||
loaded:integer;
|
||||
function isSuitableFileType(x:cardinal):longbool;virtual;abstract;
|
||||
function GetEdata(HeaderEntry:cardinal):longbool;virtual;abstract;
|
||||
function Scan(const binname:string):longbool;virtual;abstract;
|
||||
end;
|
||||
|
||||
|
||||
var
|
||||
importlib : timportlib;
|
||||
|
||||
@ -277,7 +290,11 @@ end;
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.10 2001-02-26 19:44:52 peter
|
||||
Revision 1.11 2001-03-06 18:28:02 peter
|
||||
* patch from Pavel with a new and much faster DLL Scanner for
|
||||
automatic importing so $linklib works for DLLs. Thanks Pavel!
|
||||
|
||||
Revision 1.10 2001/02/26 19:44:52 peter
|
||||
* merged generic m68k updates from fixes branch
|
||||
|
||||
Revision 1.9 2001/02/03 00:09:02 peter
|
||||
|
@ -1059,12 +1059,18 @@ begin
|
||||
consume(_NAME);
|
||||
import_name:=get_stringconst;
|
||||
aktprocsym^.definition^.setmangledname(import_name);
|
||||
if target_info.DllScanSupported then
|
||||
current_module.externals.insert(tExternalsItem.create(import_name));
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ external shouldn't override the cdecl/system name }
|
||||
if not (pocall_clearstack in aktprocsym^.definition^.proccalloptions) then
|
||||
aktprocsym^.definition^.setmangledname(aktprocsym^.realname);
|
||||
begin
|
||||
aktprocsym^.definition^.setmangledname(aktprocsym^.realname);
|
||||
if target_info.DllScanSupported then
|
||||
current_module.externals.insert(tExternalsItem.create(aktprocsym^.realname));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -1872,7 +1878,11 @@ end;
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.11 2001-01-08 21:40:26 peter
|
||||
Revision 1.12 2001-03-06 18:28:02 peter
|
||||
* patch from Pavel with a new and much faster DLL Scanner for
|
||||
automatic importing so $linklib works for DLLs. Thanks Pavel!
|
||||
|
||||
Revision 1.11 2001/01/08 21:40:26 peter
|
||||
* fixed crash with unsupported token overloading
|
||||
|
||||
Revision 1.10 2000/12/25 00:07:27 peter
|
||||
|
@ -402,6 +402,9 @@ implementation
|
||||
end;
|
||||
importlib.importvariable(aktvarsym^.mangledname,dll_name,C_name)
|
||||
end
|
||||
else
|
||||
if target_info.DllScanSupported then
|
||||
current_module.Externals.insert(tExternalsItem.create(aktvarsym^.mangledname));
|
||||
end;
|
||||
symdone:=true;
|
||||
end
|
||||
@ -538,7 +541,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.9 2001-02-20 21:42:54 peter
|
||||
Revision 1.10 2001-03-06 18:28:02 peter
|
||||
* patch from Pavel with a new and much faster DLL Scanner for
|
||||
automatic importing so $linklib works for DLLs. Thanks Pavel!
|
||||
|
||||
Revision 1.9 2001/02/20 21:42:54 peter
|
||||
* record and object declaration with same field as type fixed
|
||||
|
||||
Revision 1.7 2001/02/20 11:19:45 marco
|
||||
|
@ -54,6 +54,9 @@ implementation
|
||||
hcodegen,
|
||||
{$ifdef i386}
|
||||
cgai386,
|
||||
{$ifndef NOTARGETWIN32}
|
||||
t_win32,
|
||||
{$endif}
|
||||
{$endif i386}
|
||||
{$endif newcg}
|
||||
link,assemble,import,export,gendef,ppu,comprsrc,
|
||||
@ -64,7 +67,43 @@ implementation
|
||||
scanner,pbase,psystem,psub,parser;
|
||||
|
||||
procedure create_objectfile;
|
||||
var
|
||||
DLLScanner : TDLLScanner;
|
||||
s : string;
|
||||
begin
|
||||
{ try to create import entries from system dlls }
|
||||
if target_info.DllScanSupported and
|
||||
(not current_module.linkOtherSharedLibs.Empty) then
|
||||
begin
|
||||
{ Init DLLScanner }
|
||||
case target_info.target of
|
||||
{$ifdef i386}
|
||||
{$ifndef NOTARGETWIN32}
|
||||
target_i386_win32 :
|
||||
DLLScanner:=tDLLscannerWin32.create;
|
||||
{$endif}
|
||||
{$endif}
|
||||
else
|
||||
internalerror(769795413);
|
||||
end;
|
||||
{ Walk all shared libs }
|
||||
While not current_module.linkOtherSharedLibs.Empty do
|
||||
begin
|
||||
S:=current_module.linkOtherSharedLibs.Getusemask(link_allways);
|
||||
DLLScanner.scan(s)
|
||||
end;
|
||||
DLLscanner.Free;
|
||||
{ Recreate import section }
|
||||
if (target_info.target=target_i386_win32) then
|
||||
begin
|
||||
if assigned(importssection)then
|
||||
importssection.clear
|
||||
else
|
||||
importssection:=taasmoutput.Create;
|
||||
importlib.generatelib;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ create the .s file and assemble it }
|
||||
GenerateAsm(false);
|
||||
|
||||
@ -173,13 +212,9 @@ implementation
|
||||
Inc(Count);
|
||||
end;
|
||||
{ TableCount }
|
||||
{ doesn't work because of bug in the compiler !! (JM)
|
||||
With ResourceStringTables do}
|
||||
begin
|
||||
ResourceStringTables.insert(Tai_const.Create_32bit(count));
|
||||
ResourceStringTables.insert(Tai_symbol.Createdataname_global('FPC_RESOURCESTRINGTABLES',0));
|
||||
ResourceStringTables.concat(Tai_symbol_end.Createname('FPC_RESOURCESTRINGTABLES'));
|
||||
end;
|
||||
ResourceStringTables.insert(Tai_const.Create_32bit(count));
|
||||
ResourceStringTables.insert(Tai_symbol.Createdataname_global('FPC_RESOURCESTRINGTABLES',0));
|
||||
ResourceStringTables.concat(Tai_symbol_end.Createname('FPC_RESOURCESTRINGTABLES'));
|
||||
{ insert in data segment }
|
||||
if (cs_create_smart in aktmoduleswitches) then
|
||||
dataSegment.concat(Tai_cut.Create);
|
||||
@ -1627,7 +1662,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.23 2001-02-24 10:44:56 peter
|
||||
Revision 1.24 2001-03-06 18:28:02 peter
|
||||
* patch from Pavel with a new and much faster DLL Scanner for
|
||||
automatic importing so $linklib works for DLLs. Thanks Pavel!
|
||||
|
||||
Revision 1.23 2001/02/24 10:44:56 peter
|
||||
* generate .rst from ppufilename instead of modulename
|
||||
|
||||
Revision 1.22 2001/02/21 19:37:19 peter
|
||||
|
@ -214,6 +214,7 @@ interface
|
||||
heapsize,
|
||||
maxheapsize,
|
||||
stacksize : longint;
|
||||
DllScanSupported : boolean;
|
||||
end;
|
||||
|
||||
tasmmodeinfo=packed record
|
||||
@ -1080,7 +1081,8 @@ implementation
|
||||
res : res_none;
|
||||
heapsize : 2048*1024;
|
||||
maxheapsize : 32768*1024;
|
||||
stacksize : 16384
|
||||
stacksize : 16384;
|
||||
DllScanSupported:false
|
||||
),
|
||||
(
|
||||
target : target_i386_GO32V2;
|
||||
@ -1103,7 +1105,8 @@ implementation
|
||||
res : res_none;
|
||||
heapsize : 2048*1024;
|
||||
maxheapsize : 32768*1024;
|
||||
stacksize : 16384
|
||||
stacksize : 16384;
|
||||
DllScanSupported:false
|
||||
),
|
||||
(
|
||||
target : target_i386_LINUX;
|
||||
@ -1126,7 +1129,8 @@ implementation
|
||||
res : res_none;
|
||||
heapsize : 256*1024;
|
||||
maxheapsize : 32768*1024;
|
||||
stacksize : 8192
|
||||
stacksize : 8192;
|
||||
DllScanSupported:false
|
||||
),
|
||||
(
|
||||
target : target_i386_FreeBSD;
|
||||
@ -1149,7 +1153,8 @@ implementation
|
||||
res : res_none;
|
||||
heapsize : 256*1024;
|
||||
maxheapsize : 32768*1024;
|
||||
stacksize : 8192
|
||||
stacksize : 8192;
|
||||
DllScanSupported:false
|
||||
),
|
||||
(
|
||||
target : target_i386_OS2;
|
||||
@ -1172,7 +1177,8 @@ implementation
|
||||
res : res_i386_emx;
|
||||
heapsize : 256*1024;
|
||||
maxheapsize : 32768*1024;
|
||||
stacksize : 256*1024
|
||||
stacksize : 256*1024;
|
||||
DllScanSupported:true
|
||||
),
|
||||
(
|
||||
target : target_i386_WIN32;
|
||||
@ -1195,7 +1201,8 @@ implementation
|
||||
res : res_i386_windres;
|
||||
heapsize : 256*1024;
|
||||
maxheapsize : 32*1024*1024;
|
||||
stacksize : 32*1024*1024
|
||||
stacksize : 32*1024*1024;
|
||||
DllScanSupported:true
|
||||
),
|
||||
(
|
||||
target : target_i386_NETWARE;
|
||||
@ -1218,7 +1225,8 @@ implementation
|
||||
res : res_none;
|
||||
heapsize : 256*1024;
|
||||
maxheapsize : 32768*1024;
|
||||
stacksize : 8192
|
||||
stacksize : 8192;
|
||||
DllScanSupported:false
|
||||
),
|
||||
(
|
||||
target : target_i386_sunos;
|
||||
@ -1241,7 +1249,8 @@ implementation
|
||||
res : res_none;
|
||||
heapsize : 256*1024;
|
||||
maxheapsize : 32768*1024;
|
||||
stacksize : 8192
|
||||
stacksize : 8192;
|
||||
DllScanSupported:false
|
||||
)
|
||||
{$endif i386}
|
||||
{$ifdef m68k}
|
||||
@ -1266,7 +1275,8 @@ implementation
|
||||
res : res_none;
|
||||
heapsize : 128*1024;
|
||||
maxheapsize : 32768*1024;
|
||||
stacksize : 8192
|
||||
stacksize : 8192;
|
||||
DllScanSupported:false
|
||||
),
|
||||
(
|
||||
target : target_m68k_Atari;
|
||||
@ -1289,7 +1299,8 @@ implementation
|
||||
res : res_none;
|
||||
heapsize : 16*1024;
|
||||
maxheapsize : 32768*1024;
|
||||
stacksize : 8192
|
||||
stacksize : 8192;
|
||||
DllScanSupported:false
|
||||
),
|
||||
(
|
||||
target : target_m68k_Mac;
|
||||
@ -1312,7 +1323,8 @@ implementation
|
||||
res : res_none;
|
||||
heapsize : 128*1024;
|
||||
maxheapsize : 32768*1024;
|
||||
stacksize : 8192
|
||||
stacksize : 8192;
|
||||
DllScanSupported:false
|
||||
),
|
||||
(
|
||||
target : target_m68k_linux;
|
||||
@ -1335,7 +1347,8 @@ implementation
|
||||
res : res_none;
|
||||
heapsize : 128*1024;
|
||||
maxheapsize : 32768*1024;
|
||||
stacksize : 8192
|
||||
stacksize : 8192;
|
||||
DllScanSupported:false
|
||||
),
|
||||
(
|
||||
target : target_m68k_PalmOS;
|
||||
@ -1358,7 +1371,8 @@ implementation
|
||||
res : res_none;
|
||||
heapsize : 128*1024;
|
||||
maxheapsize : 32768*1024;
|
||||
stacksize : 8192
|
||||
stacksize : 8192;
|
||||
DllScanSupported:false
|
||||
)
|
||||
{$endif m68k}
|
||||
{$ifdef alpha}
|
||||
@ -1383,7 +1397,10 @@ implementation
|
||||
res : res_none;
|
||||
heapsize : 256*1024;
|
||||
maxheapsize : 32768*1024;
|
||||
stacksize : 8192
|
||||
{*** Changes made by Ozerski at 05.03.2001}
|
||||
stacksize : 8192;
|
||||
DllScanSupported:false
|
||||
{*** End changes}
|
||||
)
|
||||
{$endif}
|
||||
{$ifdef powerpc}
|
||||
@ -1408,7 +1425,8 @@ implementation
|
||||
res : res_none;
|
||||
heapsize : 256*1024;
|
||||
maxheapsize : 32768*1024;
|
||||
stacksize : 8192
|
||||
stacksize : 8192;
|
||||
DllScanSupported:false
|
||||
),
|
||||
(
|
||||
target : target_powerpc_MACOS;
|
||||
@ -1431,7 +1449,8 @@ implementation
|
||||
res : res_powerpc_mpw;
|
||||
heapsize : 256*1024;
|
||||
maxheapsize : 32768*1024;
|
||||
stacksize : 8192
|
||||
stacksize : 8192;
|
||||
DllScanSupported:false
|
||||
)
|
||||
{$endif}
|
||||
);
|
||||
@ -1763,7 +1782,11 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.14 2001-02-26 19:44:55 peter
|
||||
Revision 1.15 2001-03-06 18:28:02 peter
|
||||
* patch from Pavel with a new and much faster DLL Scanner for
|
||||
automatic importing so $linklib works for DLLs. Thanks Pavel!
|
||||
|
||||
Revision 1.14 2001/02/26 19:44:55 peter
|
||||
* merged generic m68k updates from fixes branch
|
||||
|
||||
Revision 1.13 2001/02/20 21:36:40 peter
|
||||
|
@ -63,6 +63,18 @@ interface
|
||||
function MakeSharedLibrary:boolean;override;
|
||||
end;
|
||||
|
||||
tDLLScannerWin32=class(tDLLScanner)
|
||||
private
|
||||
cstring : array[0..127]of char;
|
||||
function DOSstubOK(var x:cardinal):longbool;
|
||||
function FindDLL(const s:string;var founddll:string):boolean;
|
||||
function DllName(Const Name : string) : string;
|
||||
public
|
||||
function isSuitableFileType(x:cardinal):longbool;override;
|
||||
function GetEdata(HeaderEntry:cardinal):longbool;override;
|
||||
function Scan(const binname:string):longbool;override;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
@ -74,7 +86,7 @@ implementation
|
||||
{$endif Delphi}
|
||||
cutils,cclasses,
|
||||
aasm,fmodule,globtype,globals,systems,verbose,
|
||||
script,gendef,impdef,
|
||||
script,gendef,
|
||||
cpubase,cpuasm
|
||||
{$ifdef GDB}
|
||||
,gdb
|
||||
@ -92,34 +104,6 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function FindDLL(const s:string):string;
|
||||
var
|
||||
sysdir : string;
|
||||
FoundDll : string;
|
||||
Found : boolean;
|
||||
begin
|
||||
Found:=false;
|
||||
{ Look for DLL in:
|
||||
1. Current dir
|
||||
2. Library Path
|
||||
3. windir,windir/system,windir/system32 }
|
||||
Found:=FindFile(s,'.'+DirSep,founddll);
|
||||
if (not found) then
|
||||
Found:=includesearchpath.FindFile(s,founddll);
|
||||
if (not found) then
|
||||
begin
|
||||
sysdir:=FixPath(GetEnv('windir'),false);
|
||||
Found:=FindFile(s,sysdir+';'+sysdir+'system'+DirSep+';'+sysdir+'system32'+DirSep,founddll);
|
||||
end;
|
||||
if (not found) then
|
||||
begin
|
||||
message1(exec_w_libfile_not_found,s);
|
||||
FoundDll:=s;
|
||||
end;
|
||||
FindDll:=FoundDll;
|
||||
end;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
TIMPORTLIBWIN32
|
||||
*****************************************************************************}
|
||||
@ -737,64 +721,15 @@ end;
|
||||
|
||||
|
||||
Function TLinkerWin32.WriteResponseFile(isdll:boolean) : Boolean;
|
||||
|
||||
function do_makedef(const DllName,LibName:string):boolean;
|
||||
var
|
||||
CmdLine : string;
|
||||
begin
|
||||
if (not do_build) and
|
||||
FileExists(LibName) then
|
||||
begin
|
||||
if GetNamedFileTime(LibName)>GetNamedFileTime(DllName) then
|
||||
begin
|
||||
do_makedef:=true;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
asw_name:=FindUtil('asw');
|
||||
arw_name:=FindUtil('arw');
|
||||
if cs_link_extern in aktglobalswitches then
|
||||
begin
|
||||
CmdLine:='-l '+LibName+' -i '+DLLName;
|
||||
if asw_name<>'' then
|
||||
CmdLine:=CmdLine+' -a '+asw_name;
|
||||
if arw_name<>'' then
|
||||
CmdLine:=CmdLine+' -r '+arw_name;
|
||||
do_makedef:=DoExec(FindUtil('fpimpdef'),CmdLine,false,false);
|
||||
end
|
||||
else
|
||||
do_makedef:=makedef(DLLName,LIbName);
|
||||
end;
|
||||
|
||||
Var
|
||||
linkres : TLinkRes;
|
||||
i : longint;
|
||||
HPath : TStringListItem;
|
||||
s,s2 : string;
|
||||
found,
|
||||
linklibc : boolean;
|
||||
found:boolean;
|
||||
begin
|
||||
WriteResponseFile:=False;
|
||||
|
||||
{ Create static import libraries for DLL that are
|
||||
included using the $linklib directive }
|
||||
While not SharedLibFiles.Empty do
|
||||
begin
|
||||
s:=SharedLibFiles.GetFirst;
|
||||
s2:=AddExtension(s,target_os.sharedlibext);
|
||||
s:=target_os.libprefix+SplitName(s)+target_os.staticlibext;
|
||||
if Do_makedef(FindDLL(s2),s) then
|
||||
begin
|
||||
if s<>''then
|
||||
StaticLibFiles.insert(s);
|
||||
end
|
||||
else
|
||||
begin
|
||||
Message(exec_w_error_while_linking);
|
||||
aktglobalswitches:=aktglobalswitches+[cs_link_extern];
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Open link.res file }
|
||||
LinkRes.Init(outputexedir+Info.ResName);
|
||||
|
||||
@ -838,48 +773,6 @@ begin
|
||||
LinkRes.Add(')');
|
||||
end;
|
||||
|
||||
{ Write sharedlibraries like -l<lib>, also add the needed dynamic linker
|
||||
here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
|
||||
if not SharedLibFiles.Empty then
|
||||
begin
|
||||
linklibc:=false;
|
||||
LinkRes.Add('INPUT(');
|
||||
While not SharedLibFiles.Empty do
|
||||
begin
|
||||
S:=SharedLibFiles.GetFirst;
|
||||
if pos('.',s)=0 then
|
||||
{ we never directly link a DLL
|
||||
its allways through an import library PM }
|
||||
{ libraries created by C compilers have .a extensions }
|
||||
s2:=s+'.a'{ target_os.sharedlibext }
|
||||
else
|
||||
s2:=s;
|
||||
s2:=FindLibraryFile(s2,'',found);
|
||||
if found then
|
||||
begin
|
||||
LinkRes.Add(s2);
|
||||
continue;
|
||||
end;
|
||||
if pos(target_os.libprefix,s)=1 then
|
||||
s:=copy(s,length(target_os.libprefix)+1,255);
|
||||
if s<>'c' then
|
||||
begin
|
||||
i:=Pos(target_os.sharedlibext,S);
|
||||
if i>0 then
|
||||
Delete(S,i,255);
|
||||
LinkRes.Add('-l'+s);
|
||||
end
|
||||
else
|
||||
begin
|
||||
LinkRes.Add('-l'+s);
|
||||
linklibc:=true;
|
||||
end;
|
||||
end;
|
||||
{ be sure that libc is the last lib }
|
||||
if linklibc then
|
||||
LinkRes.Add('-lc');
|
||||
LinkRes.Add(')');
|
||||
end;
|
||||
{ Write and Close response }
|
||||
linkres.writetodisk;
|
||||
linkres.done;
|
||||
@ -1251,10 +1144,250 @@ begin
|
||||
postprocessexecutable:=true;
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
TDLLScannerWin32
|
||||
****************************************************************************}
|
||||
|
||||
function tDLLScannerWin32.DOSstubOK(var x:cardinal):longbool;
|
||||
begin
|
||||
blockread(f,TheWord,2,loaded);
|
||||
if loaded<>2 then
|
||||
DOSstubOK:=false
|
||||
else
|
||||
begin
|
||||
DOSstubOK:=TheWord='MZ';
|
||||
seek(f,$3C);
|
||||
blockread(f,x,4,loaded);
|
||||
if(loaded<>4)or(x>filesize(f))then
|
||||
DOSstubOK:=false;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDLLScannerWin32.FindDLL(const s:string;var founddll:string):boolean;
|
||||
var
|
||||
sysdir : string;
|
||||
Found : boolean;
|
||||
begin
|
||||
Found:=false;
|
||||
{ Look for DLL in:
|
||||
1. Current dir
|
||||
2. Library Path
|
||||
3. windir,windir/system,windir/system32 }
|
||||
Found:=FindFile(s,'.'+DirSep,founddll);
|
||||
if (not found) then
|
||||
Found:=librarysearchpath.FindFile(s,founddll);
|
||||
if (not found) then
|
||||
begin
|
||||
sysdir:=FixPath(GetEnv('windir'),false);
|
||||
Found:=FindFile(s,sysdir+';'+sysdir+'system'+DirSep+';'+sysdir+'system32'+DirSep,founddll);
|
||||
end;
|
||||
if (not found) then
|
||||
begin
|
||||
message1(exec_w_libfile_not_found,s);
|
||||
FoundDll:=s;
|
||||
end;
|
||||
FindDll:=Found;
|
||||
end;
|
||||
|
||||
|
||||
function tDLLScannerWin32.DllName(Const Name : string) : string;
|
||||
var n : string;
|
||||
begin
|
||||
n:=Upper(SplitExtension(Name));
|
||||
if (n='.DLL') or (n='.DRV') or (n='.EXE') then
|
||||
DllName:=Name
|
||||
else
|
||||
DllName:=Name+target_os.sharedlibext;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
function tDLLScannerWin32.isSuitableFileType(x:cardinal):longbool;
|
||||
begin
|
||||
seek(f,x);
|
||||
blockread(f,TheWord,2,loaded);
|
||||
isSuitableFileType:=(loaded=2)and(TheWord='PE');
|
||||
end;
|
||||
|
||||
|
||||
function tDLLScannerWin32.GetEdata(HeaderEntry:cardinal):longbool;
|
||||
type
|
||||
TObjInfo=packed record
|
||||
ObjName:array[0..7]of char;
|
||||
VirtSize,
|
||||
VirtAddr,
|
||||
RawSize,
|
||||
RawOffset,
|
||||
Reloc,
|
||||
LineNum:cardinal;
|
||||
RelCount,
|
||||
LineCount:word;
|
||||
flags:cardinal;
|
||||
end;
|
||||
var
|
||||
i:cardinal;
|
||||
ObjOfs:cardinal;
|
||||
Obj:TObjInfo;
|
||||
APE_obj,APE_Optsize:word;
|
||||
ExportRVA:cardinal;
|
||||
delta:cardinal;
|
||||
const
|
||||
IMAGE_SCN_CNT_CODE=$00000020;
|
||||
var
|
||||
_d:dirstr;
|
||||
_n:namestr;
|
||||
_e:extstr;
|
||||
function isUsedFunction(name:pchar):longbool;
|
||||
var
|
||||
hp:tExternalsItem;
|
||||
begin
|
||||
isUsedFunction:=false;
|
||||
hp:=tExternalsItem(current_module.Externals.first);
|
||||
while assigned(hp)do
|
||||
begin
|
||||
if(assigned(hp.data))and(not hp.found)then
|
||||
if hp.data^=StrPas(name)then
|
||||
begin
|
||||
isUsedFunction:=true;
|
||||
hp.found:=true;
|
||||
exit;
|
||||
end;
|
||||
hp:=tExternalsItem(hp.next);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Store(index:cardinal;name:pchar;isData:longbool);
|
||||
begin
|
||||
if not isUsedFunction(name)then
|
||||
exit;
|
||||
if not(current_module.uses_imports) then
|
||||
begin
|
||||
current_module.uses_imports:=true;
|
||||
importlib.preparelib(current_module.modulename^);
|
||||
end;
|
||||
if IsData then
|
||||
importlib.importvariable(name,_n,name)
|
||||
else
|
||||
importlib.importprocedure(name,_n,index,name);
|
||||
end;
|
||||
|
||||
procedure ProcessEdata;
|
||||
type
|
||||
a8=array[0..7]of char;
|
||||
function GetSectionName(rva:cardinal;var Flags:cardinal):a8;
|
||||
var
|
||||
i:cardinal;
|
||||
LocObjOfs:cardinal;
|
||||
LocObj:TObjInfo;
|
||||
begin
|
||||
GetSectionName:='';
|
||||
Flags:=0;
|
||||
LocObjOfs:=APE_OptSize+HeaderOffset+24;
|
||||
for i:=1 to APE_obj do
|
||||
begin
|
||||
seek(f,LocObjOfs);
|
||||
blockread(f,LocObj,sizeof(LocObj));
|
||||
if(rva>=LocObj.VirtAddr)and(rva<=LocObj.VirtAddr+LocObj.RawSize)then
|
||||
begin
|
||||
GetSectionName:=a8(LocObj.ObjName);
|
||||
Flags:=LocObj.flags;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
var
|
||||
j,Fl:cardinal;
|
||||
ulongval,procEntry:cardinal;
|
||||
Ordinal:word;
|
||||
isData:longbool;
|
||||
ExpDir:packed record
|
||||
flag,
|
||||
stamp:cardinal;
|
||||
Major,
|
||||
Minor:word;
|
||||
Name,
|
||||
Base,
|
||||
NumFuncs,
|
||||
NumNames,
|
||||
AddrFuncs,
|
||||
AddrNames,
|
||||
AddrOrds:cardinal;
|
||||
end;
|
||||
begin
|
||||
with Obj do
|
||||
begin
|
||||
seek(f,RawOffset+delta);
|
||||
blockread(f,ExpDir,sizeof(ExpDir));
|
||||
fsplit(impname,_d,_n,_e);
|
||||
for j:=0 to pred(ExpDir.NumNames)do
|
||||
begin
|
||||
seek(f,RawOffset-VirtAddr+ExpDir.AddrOrds+j*2);
|
||||
blockread(f,Ordinal,2);
|
||||
seek(f,RawOffset-VirtAddr+ExpDir.AddrFuncs+Ordinal*4);
|
||||
blockread(f,ProcEntry,4);
|
||||
seek(f,RawOffset-VirtAddr+ExpDir.AddrNames+j*4);
|
||||
blockread(f,ulongval,4);
|
||||
seek(f,RawOffset-VirtAddr+ulongval);
|
||||
blockread(f,cstring,sizeof(cstring));
|
||||
isData:=GetSectionName(procentry,Fl)='';
|
||||
if not isData then
|
||||
isData:=Fl and IMAGE_SCN_CNT_CODE<>IMAGE_SCN_CNT_CODE;
|
||||
Store(succ(Ordinal),cstring,isData);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
begin
|
||||
GetEdata:=false;
|
||||
seek(f,HeaderEntry+120);
|
||||
blockread(f,ExportRVA,4);
|
||||
seek(f,HeaderEntry+6);
|
||||
blockread(f,APE_Obj,2);
|
||||
seek(f,HeaderEntry+20);
|
||||
blockread(f,APE_OptSize,2);
|
||||
ObjOfs:=APE_OptSize+HeaderOffset+24;
|
||||
for i:=1 to APE_obj do
|
||||
begin
|
||||
seek(f,ObjOfs);
|
||||
blockread(f,Obj,sizeof(Obj));
|
||||
inc(ObjOfs,sizeof(Obj));
|
||||
with Obj do
|
||||
if(VirtAddr<=ExportRva)and(ExportRva<VirtAddr+VirtSize)then
|
||||
begin
|
||||
delta:=ExportRva-VirtAddr;
|
||||
ProcessEdata;
|
||||
GetEdata:=true;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function tDLLScannerWin32.scan(const binname:string):longbool;
|
||||
var
|
||||
OldFileMode:longint;
|
||||
begin
|
||||
if not FindDll(DLLName(binname),impname) then
|
||||
exit;
|
||||
assign(f,impname);
|
||||
OldFileMode:=filemode;
|
||||
filemode:=0;
|
||||
reset(f,1);
|
||||
filemode:=OldFileMode;
|
||||
if not DOSstubOK(HeaderOffset)then
|
||||
scan:=false
|
||||
else if not isSuitableFileType(HeaderOffset)then
|
||||
scan:=false
|
||||
else
|
||||
scan:=GetEdata(HeaderOffset);
|
||||
close(f);
|
||||
end;
|
||||
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.1 2001-02-26 19:43:11 peter
|
||||
Revision 1.2 2001-03-06 18:28:02 peter
|
||||
* patch from Pavel with a new and much faster DLL Scanner for
|
||||
automatic importing so $linklib works for DLLs. Thanks Pavel!
|
||||
|
||||
Revision 1.1 2001/02/26 19:43:11 peter
|
||||
* moved target units to subdir
|
||||
|
||||
Revision 1.10 2001/02/20 21:41:16 peter
|
||||
|
Loading…
Reference in New Issue
Block a user