mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-03 02:50:42 +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
|
rr_asmolder,rr_crcchanged
|
||||||
);
|
);
|
||||||
|
|
||||||
|
TExternalsItem=class(TLinkedListItem)
|
||||||
|
public
|
||||||
|
found : longbool;
|
||||||
|
data : pstring;
|
||||||
|
constructor Create(const s:string);
|
||||||
|
Destructor Destroy;override;
|
||||||
|
end;
|
||||||
|
|
||||||
tlinkcontaineritem=class(tlinkedlistitem)
|
tlinkcontaineritem=class(tlinkedlistitem)
|
||||||
public
|
public
|
||||||
data : pstring;
|
data : pstring;
|
||||||
@ -105,7 +113,7 @@ interface
|
|||||||
uses_imports : boolean; { Set if the module imports from DLL's.}
|
uses_imports : boolean; { Set if the module imports from DLL's.}
|
||||||
imports : tlinkedlist;
|
imports : tlinkedlist;
|
||||||
_exports : tlinkedlist;
|
_exports : tlinkedlist;
|
||||||
|
externals : tlinkedlist; {Only for DLL scanners by using Unix-style $LINKLIB }
|
||||||
resourcefiles : tstringlist;
|
resourcefiles : tstringlist;
|
||||||
|
|
||||||
linkunitofiles,
|
linkunitofiles,
|
||||||
@ -286,6 +294,25 @@ uses
|
|||||||
end;
|
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
|
TMODULE
|
||||||
****************************************************************************}
|
****************************************************************************}
|
||||||
@ -614,6 +641,8 @@ uses
|
|||||||
imports:=tlinkedlist.create;
|
imports:=tlinkedlist.create;
|
||||||
_exports.free;
|
_exports.free;
|
||||||
_exports:=tlinkedlist.create;
|
_exports:=tlinkedlist.create;
|
||||||
|
externals.free;
|
||||||
|
externals:=tlinkedlist.create;
|
||||||
used_units.free;
|
used_units.free;
|
||||||
used_units:=TLinkedList.Create;
|
used_units:=TLinkedList.Create;
|
||||||
{ all units that depend on this one must be recompiled ! }
|
{ all units that depend on this one must be recompiled ! }
|
||||||
@ -745,6 +774,7 @@ uses
|
|||||||
uses_imports:=false;
|
uses_imports:=false;
|
||||||
imports:=TLinkedList.Create;
|
imports:=TLinkedList.Create;
|
||||||
_exports:=TLinkedList.Create;
|
_exports:=TLinkedList.Create;
|
||||||
|
externals:=TLinkedList.Create;
|
||||||
{ search the PPU file if it is an unit }
|
{ search the PPU file if it is an unit }
|
||||||
if is_unit then
|
if is_unit then
|
||||||
begin
|
begin
|
||||||
@ -776,6 +806,9 @@ uses
|
|||||||
if assigned(_exports) then
|
if assigned(_exports) then
|
||||||
_exports.free;
|
_exports.free;
|
||||||
_exports:=nil;
|
_exports:=nil;
|
||||||
|
if assigned(externals) then
|
||||||
|
externals.free;
|
||||||
|
externals:=nil;
|
||||||
if assigned(scanner) then
|
if assigned(scanner) then
|
||||||
pscannerfile(scanner)^.invalid:=true;
|
pscannerfile(scanner)^.invalid:=true;
|
||||||
if assigned(sourcefiles) then
|
if assigned(sourcefiles) then
|
||||||
@ -873,7 +906,11 @@ uses
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$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
|
* new fixfilename, findfile for unix. Look first for lowercase, then
|
||||||
NormalCase and last for UPPERCASE names.
|
NormalCase and last for UPPERCASE names.
|
||||||
|
|
||||||
|
@ -61,6 +61,19 @@ type
|
|||||||
procedure generatesmartlib;virtual;
|
procedure generatesmartlib;virtual;
|
||||||
end;
|
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
|
var
|
||||||
importlib : timportlib;
|
importlib : timportlib;
|
||||||
|
|
||||||
@ -277,7 +290,11 @@ end;
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$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
|
* merged generic m68k updates from fixes branch
|
||||||
|
|
||||||
Revision 1.9 2001/02/03 00:09:02 peter
|
Revision 1.9 2001/02/03 00:09:02 peter
|
||||||
|
@ -1059,12 +1059,18 @@ begin
|
|||||||
consume(_NAME);
|
consume(_NAME);
|
||||||
import_name:=get_stringconst;
|
import_name:=get_stringconst;
|
||||||
aktprocsym^.definition^.setmangledname(import_name);
|
aktprocsym^.definition^.setmangledname(import_name);
|
||||||
|
if target_info.DllScanSupported then
|
||||||
|
current_module.externals.insert(tExternalsItem.create(import_name));
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
{ external shouldn't override the cdecl/system name }
|
{ external shouldn't override the cdecl/system name }
|
||||||
if not (pocall_clearstack in aktprocsym^.definition^.proccalloptions) then
|
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;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1872,7 +1878,11 @@ end;
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$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
|
* fixed crash with unsupported token overloading
|
||||||
|
|
||||||
Revision 1.10 2000/12/25 00:07:27 peter
|
Revision 1.10 2000/12/25 00:07:27 peter
|
||||||
|
@ -402,6 +402,9 @@ implementation
|
|||||||
end;
|
end;
|
||||||
importlib.importvariable(aktvarsym^.mangledname,dll_name,C_name)
|
importlib.importvariable(aktvarsym^.mangledname,dll_name,C_name)
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
if target_info.DllScanSupported then
|
||||||
|
current_module.Externals.insert(tExternalsItem.create(aktvarsym^.mangledname));
|
||||||
end;
|
end;
|
||||||
symdone:=true;
|
symdone:=true;
|
||||||
end
|
end
|
||||||
@ -538,7 +541,11 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$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
|
* record and object declaration with same field as type fixed
|
||||||
|
|
||||||
Revision 1.7 2001/02/20 11:19:45 marco
|
Revision 1.7 2001/02/20 11:19:45 marco
|
||||||
|
@ -54,6 +54,9 @@ implementation
|
|||||||
hcodegen,
|
hcodegen,
|
||||||
{$ifdef i386}
|
{$ifdef i386}
|
||||||
cgai386,
|
cgai386,
|
||||||
|
{$ifndef NOTARGETWIN32}
|
||||||
|
t_win32,
|
||||||
|
{$endif}
|
||||||
{$endif i386}
|
{$endif i386}
|
||||||
{$endif newcg}
|
{$endif newcg}
|
||||||
link,assemble,import,export,gendef,ppu,comprsrc,
|
link,assemble,import,export,gendef,ppu,comprsrc,
|
||||||
@ -64,7 +67,43 @@ implementation
|
|||||||
scanner,pbase,psystem,psub,parser;
|
scanner,pbase,psystem,psub,parser;
|
||||||
|
|
||||||
procedure create_objectfile;
|
procedure create_objectfile;
|
||||||
|
var
|
||||||
|
DLLScanner : TDLLScanner;
|
||||||
|
s : string;
|
||||||
begin
|
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 }
|
{ create the .s file and assemble it }
|
||||||
GenerateAsm(false);
|
GenerateAsm(false);
|
||||||
|
|
||||||
@ -173,13 +212,9 @@ implementation
|
|||||||
Inc(Count);
|
Inc(Count);
|
||||||
end;
|
end;
|
||||||
{ TableCount }
|
{ TableCount }
|
||||||
{ doesn't work because of bug in the compiler !! (JM)
|
ResourceStringTables.insert(Tai_const.Create_32bit(count));
|
||||||
With ResourceStringTables do}
|
ResourceStringTables.insert(Tai_symbol.Createdataname_global('FPC_RESOURCESTRINGTABLES',0));
|
||||||
begin
|
ResourceStringTables.concat(Tai_symbol_end.Createname('FPC_RESOURCESTRINGTABLES'));
|
||||||
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;
|
|
||||||
{ insert in data segment }
|
{ insert in data segment }
|
||||||
if (cs_create_smart in aktmoduleswitches) then
|
if (cs_create_smart in aktmoduleswitches) then
|
||||||
dataSegment.concat(Tai_cut.Create);
|
dataSegment.concat(Tai_cut.Create);
|
||||||
@ -1627,7 +1662,11 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$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
|
* generate .rst from ppufilename instead of modulename
|
||||||
|
|
||||||
Revision 1.22 2001/02/21 19:37:19 peter
|
Revision 1.22 2001/02/21 19:37:19 peter
|
||||||
|
@ -214,6 +214,7 @@ interface
|
|||||||
heapsize,
|
heapsize,
|
||||||
maxheapsize,
|
maxheapsize,
|
||||||
stacksize : longint;
|
stacksize : longint;
|
||||||
|
DllScanSupported : boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
tasmmodeinfo=packed record
|
tasmmodeinfo=packed record
|
||||||
@ -1080,7 +1081,8 @@ implementation
|
|||||||
res : res_none;
|
res : res_none;
|
||||||
heapsize : 2048*1024;
|
heapsize : 2048*1024;
|
||||||
maxheapsize : 32768*1024;
|
maxheapsize : 32768*1024;
|
||||||
stacksize : 16384
|
stacksize : 16384;
|
||||||
|
DllScanSupported:false
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
target : target_i386_GO32V2;
|
target : target_i386_GO32V2;
|
||||||
@ -1103,7 +1105,8 @@ implementation
|
|||||||
res : res_none;
|
res : res_none;
|
||||||
heapsize : 2048*1024;
|
heapsize : 2048*1024;
|
||||||
maxheapsize : 32768*1024;
|
maxheapsize : 32768*1024;
|
||||||
stacksize : 16384
|
stacksize : 16384;
|
||||||
|
DllScanSupported:false
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
target : target_i386_LINUX;
|
target : target_i386_LINUX;
|
||||||
@ -1126,7 +1129,8 @@ implementation
|
|||||||
res : res_none;
|
res : res_none;
|
||||||
heapsize : 256*1024;
|
heapsize : 256*1024;
|
||||||
maxheapsize : 32768*1024;
|
maxheapsize : 32768*1024;
|
||||||
stacksize : 8192
|
stacksize : 8192;
|
||||||
|
DllScanSupported:false
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
target : target_i386_FreeBSD;
|
target : target_i386_FreeBSD;
|
||||||
@ -1149,7 +1153,8 @@ implementation
|
|||||||
res : res_none;
|
res : res_none;
|
||||||
heapsize : 256*1024;
|
heapsize : 256*1024;
|
||||||
maxheapsize : 32768*1024;
|
maxheapsize : 32768*1024;
|
||||||
stacksize : 8192
|
stacksize : 8192;
|
||||||
|
DllScanSupported:false
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
target : target_i386_OS2;
|
target : target_i386_OS2;
|
||||||
@ -1172,7 +1177,8 @@ implementation
|
|||||||
res : res_i386_emx;
|
res : res_i386_emx;
|
||||||
heapsize : 256*1024;
|
heapsize : 256*1024;
|
||||||
maxheapsize : 32768*1024;
|
maxheapsize : 32768*1024;
|
||||||
stacksize : 256*1024
|
stacksize : 256*1024;
|
||||||
|
DllScanSupported:true
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
target : target_i386_WIN32;
|
target : target_i386_WIN32;
|
||||||
@ -1195,7 +1201,8 @@ implementation
|
|||||||
res : res_i386_windres;
|
res : res_i386_windres;
|
||||||
heapsize : 256*1024;
|
heapsize : 256*1024;
|
||||||
maxheapsize : 32*1024*1024;
|
maxheapsize : 32*1024*1024;
|
||||||
stacksize : 32*1024*1024
|
stacksize : 32*1024*1024;
|
||||||
|
DllScanSupported:true
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
target : target_i386_NETWARE;
|
target : target_i386_NETWARE;
|
||||||
@ -1218,7 +1225,8 @@ implementation
|
|||||||
res : res_none;
|
res : res_none;
|
||||||
heapsize : 256*1024;
|
heapsize : 256*1024;
|
||||||
maxheapsize : 32768*1024;
|
maxheapsize : 32768*1024;
|
||||||
stacksize : 8192
|
stacksize : 8192;
|
||||||
|
DllScanSupported:false
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
target : target_i386_sunos;
|
target : target_i386_sunos;
|
||||||
@ -1241,7 +1249,8 @@ implementation
|
|||||||
res : res_none;
|
res : res_none;
|
||||||
heapsize : 256*1024;
|
heapsize : 256*1024;
|
||||||
maxheapsize : 32768*1024;
|
maxheapsize : 32768*1024;
|
||||||
stacksize : 8192
|
stacksize : 8192;
|
||||||
|
DllScanSupported:false
|
||||||
)
|
)
|
||||||
{$endif i386}
|
{$endif i386}
|
||||||
{$ifdef m68k}
|
{$ifdef m68k}
|
||||||
@ -1266,7 +1275,8 @@ implementation
|
|||||||
res : res_none;
|
res : res_none;
|
||||||
heapsize : 128*1024;
|
heapsize : 128*1024;
|
||||||
maxheapsize : 32768*1024;
|
maxheapsize : 32768*1024;
|
||||||
stacksize : 8192
|
stacksize : 8192;
|
||||||
|
DllScanSupported:false
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
target : target_m68k_Atari;
|
target : target_m68k_Atari;
|
||||||
@ -1289,7 +1299,8 @@ implementation
|
|||||||
res : res_none;
|
res : res_none;
|
||||||
heapsize : 16*1024;
|
heapsize : 16*1024;
|
||||||
maxheapsize : 32768*1024;
|
maxheapsize : 32768*1024;
|
||||||
stacksize : 8192
|
stacksize : 8192;
|
||||||
|
DllScanSupported:false
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
target : target_m68k_Mac;
|
target : target_m68k_Mac;
|
||||||
@ -1312,7 +1323,8 @@ implementation
|
|||||||
res : res_none;
|
res : res_none;
|
||||||
heapsize : 128*1024;
|
heapsize : 128*1024;
|
||||||
maxheapsize : 32768*1024;
|
maxheapsize : 32768*1024;
|
||||||
stacksize : 8192
|
stacksize : 8192;
|
||||||
|
DllScanSupported:false
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
target : target_m68k_linux;
|
target : target_m68k_linux;
|
||||||
@ -1335,7 +1347,8 @@ implementation
|
|||||||
res : res_none;
|
res : res_none;
|
||||||
heapsize : 128*1024;
|
heapsize : 128*1024;
|
||||||
maxheapsize : 32768*1024;
|
maxheapsize : 32768*1024;
|
||||||
stacksize : 8192
|
stacksize : 8192;
|
||||||
|
DllScanSupported:false
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
target : target_m68k_PalmOS;
|
target : target_m68k_PalmOS;
|
||||||
@ -1358,7 +1371,8 @@ implementation
|
|||||||
res : res_none;
|
res : res_none;
|
||||||
heapsize : 128*1024;
|
heapsize : 128*1024;
|
||||||
maxheapsize : 32768*1024;
|
maxheapsize : 32768*1024;
|
||||||
stacksize : 8192
|
stacksize : 8192;
|
||||||
|
DllScanSupported:false
|
||||||
)
|
)
|
||||||
{$endif m68k}
|
{$endif m68k}
|
||||||
{$ifdef alpha}
|
{$ifdef alpha}
|
||||||
@ -1383,7 +1397,10 @@ implementation
|
|||||||
res : res_none;
|
res : res_none;
|
||||||
heapsize : 256*1024;
|
heapsize : 256*1024;
|
||||||
maxheapsize : 32768*1024;
|
maxheapsize : 32768*1024;
|
||||||
stacksize : 8192
|
{*** Changes made by Ozerski at 05.03.2001}
|
||||||
|
stacksize : 8192;
|
||||||
|
DllScanSupported:false
|
||||||
|
{*** End changes}
|
||||||
)
|
)
|
||||||
{$endif}
|
{$endif}
|
||||||
{$ifdef powerpc}
|
{$ifdef powerpc}
|
||||||
@ -1408,7 +1425,8 @@ implementation
|
|||||||
res : res_none;
|
res : res_none;
|
||||||
heapsize : 256*1024;
|
heapsize : 256*1024;
|
||||||
maxheapsize : 32768*1024;
|
maxheapsize : 32768*1024;
|
||||||
stacksize : 8192
|
stacksize : 8192;
|
||||||
|
DllScanSupported:false
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
target : target_powerpc_MACOS;
|
target : target_powerpc_MACOS;
|
||||||
@ -1431,7 +1449,8 @@ implementation
|
|||||||
res : res_powerpc_mpw;
|
res : res_powerpc_mpw;
|
||||||
heapsize : 256*1024;
|
heapsize : 256*1024;
|
||||||
maxheapsize : 32768*1024;
|
maxheapsize : 32768*1024;
|
||||||
stacksize : 8192
|
stacksize : 8192;
|
||||||
|
DllScanSupported:false
|
||||||
)
|
)
|
||||||
{$endif}
|
{$endif}
|
||||||
);
|
);
|
||||||
@ -1763,7 +1782,11 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$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
|
* merged generic m68k updates from fixes branch
|
||||||
|
|
||||||
Revision 1.13 2001/02/20 21:36:40 peter
|
Revision 1.13 2001/02/20 21:36:40 peter
|
||||||
|
@ -63,6 +63,18 @@ interface
|
|||||||
function MakeSharedLibrary:boolean;override;
|
function MakeSharedLibrary:boolean;override;
|
||||||
end;
|
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
|
implementation
|
||||||
|
|
||||||
@ -74,7 +86,7 @@ implementation
|
|||||||
{$endif Delphi}
|
{$endif Delphi}
|
||||||
cutils,cclasses,
|
cutils,cclasses,
|
||||||
aasm,fmodule,globtype,globals,systems,verbose,
|
aasm,fmodule,globtype,globals,systems,verbose,
|
||||||
script,gendef,impdef,
|
script,gendef,
|
||||||
cpubase,cpuasm
|
cpubase,cpuasm
|
||||||
{$ifdef GDB}
|
{$ifdef GDB}
|
||||||
,gdb
|
,gdb
|
||||||
@ -92,34 +104,6 @@ implementation
|
|||||||
end;
|
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
|
TIMPORTLIBWIN32
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
@ -737,64 +721,15 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
Function TLinkerWin32.WriteResponseFile(isdll:boolean) : Boolean;
|
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
|
Var
|
||||||
linkres : TLinkRes;
|
linkres : TLinkRes;
|
||||||
i : longint;
|
i : longint;
|
||||||
HPath : TStringListItem;
|
HPath : TStringListItem;
|
||||||
s,s2 : string;
|
s,s2 : string;
|
||||||
found,
|
found:boolean;
|
||||||
linklibc : boolean;
|
|
||||||
begin
|
begin
|
||||||
WriteResponseFile:=False;
|
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 }
|
{ Open link.res file }
|
||||||
LinkRes.Init(outputexedir+Info.ResName);
|
LinkRes.Init(outputexedir+Info.ResName);
|
||||||
|
|
||||||
@ -838,48 +773,6 @@ begin
|
|||||||
LinkRes.Add(')');
|
LinkRes.Add(')');
|
||||||
end;
|
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 }
|
{ Write and Close response }
|
||||||
linkres.writetodisk;
|
linkres.writetodisk;
|
||||||
linkres.done;
|
linkres.done;
|
||||||
@ -1251,10 +1144,250 @@ begin
|
|||||||
postprocessexecutable:=true;
|
postprocessexecutable:=true;
|
||||||
end;
|
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.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$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
|
* moved target units to subdir
|
||||||
|
|
||||||
Revision 1.10 2001/02/20 21:41:16 peter
|
Revision 1.10 2001/02/20 21:41:16 peter
|
||||||
|
Loading…
Reference in New Issue
Block a user