* redesigned linker object

+ library support for linux (only procedures can be exported)
This commit is contained in:
peter 1999-10-21 14:29:32 +00:00
parent 46b5193e9b
commit fefc839b29
18 changed files with 1980 additions and 1403 deletions

View File

@ -27,7 +27,7 @@ unit cgai386;
uses
cobjects,tree,
cpubase,cpuasm,
symconst,symtable,aasm,win_targ;
symconst,symtable,aasm;
{$define TESTGETTEMP to store const that
are written into temps for later release PM }
@ -150,6 +150,9 @@ procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
tgeni386,temp_gen,hcodegen,ppu
{$ifdef GDB}
,gdb
{$endif}
{$ifndef NOTARGETWIN32}
,t_win32
{$endif}
;
@ -2605,6 +2608,7 @@ procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
exprasmlist^.concat(new(paicpu,
op_const_reg(A_IMUL,S_L,
parraydef(pvarsym(p)^.definition)^.definition^.size,R_EDI)));
{$ifndef NOTARGETWIN32}
{ windows guards only a few pages for stack growing, }
{ so we have to access every page first }
if target_os.id=os_i386_win32 then
@ -2642,6 +2646,7 @@ procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
parraydef(pvarsym(p)^.definition)^.definition^.size,R_EDI)));
end
else
{$endif NOTARGETWIN32}
begin
exprasmlist^.concat(new(paicpu,
op_reg_reg(A_SUB,S_L,R_EDI,R_ESP)));
@ -3414,7 +3419,11 @@ procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
end.
{
$Log$
Revision 1.53 1999-10-13 22:09:29 pierre
Revision 1.54 1999-10-21 14:29:32 peter
* redesigned linker object
+ library support for linux (only procedures can be exported)
Revision 1.53 1999/10/13 22:09:29 pierre
* fix for uggly bug of Marco
Revision 1.52 1999/10/08 15:40:47 pierre

View File

@ -1,157 +0,0 @@
{
$Id$
Copyright (c) 1999 by Peter Vreman
This unit implements some support routines for the Dos targets
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit dos_targ;
interface
uses
link;
type
plinkergo32v2=^tlinkergo32v2;
tlinkergo32v2=object(tlinker)
procedure postprocessexecutable(const n : string);virtual;
end;
implementation
uses
strings,globtype,globals,cobjects,systems,verbose;
{****************************************************************************
Postprocess Executable
****************************************************************************}
procedure tlinkergo32v2.postprocessexecutable(const n : string);
begin
end;
{$ifdef dummy}
type
tcoffheader=packed record
mach : word;
nsects : word;
time : longint;
sympos : longint;
syms : longint;
opthdr : word;
flag : word;
end;
tcoffsechdr=packed record
name : array[0..7] of char;
vsize : longint;
rvaofs : longint;
datalen : longint;
datapos : longint;
relocpos : longint;
lineno1 : longint;
nrelocs : word;
lineno2 : word;
flags : longint;
end;
psecfill=^tsecfill;
tsecfill=record
fillpos,
fillsize : longint;
next : psecfill;
end;
var
f : file;
coffheader : tcoffheader;
firstsecpos,
maxfillsize,
l : longint;
coffsec : tcoffsechdr;
secroot,hsecroot : psecfill;
zerobuf : pointer;
begin
{ when -s is used quit, because there is no .exe }
if cs_link_extern in aktglobalswitches then
exit;
{ open file }
assign(f,n);
{$I-}
reset(f,1);
if ioresult<>0 then
Message1(execinfo_f_cant_open_executable,n);
{ read headers }
seek(f,2048);
blockread(f,coffheader,sizeof(tcoffheader));
{ read section info }
maxfillsize:=0;
firstsecpos:=0;
secroot:=nil;
for l:=1to coffheader.nSects do
begin
blockread(f,coffsec,sizeof(tcoffsechdr));
if coffsec.datapos>0 then
begin
if secroot=nil then
firstsecpos:=coffsec.datapos;
new(hsecroot);
hsecroot^.fillpos:=coffsec.datapos+coffsec.vsize;
hsecroot^.fillsize:=coffsec.datalen-coffsec.vsize;
hsecroot^.next:=secroot;
secroot:=hsecroot;
if secroot^.fillsize>maxfillsize then
maxfillsize:=secroot^.fillsize;
end;
end;
if firstsecpos>0 then
begin
l:=firstsecpos-filepos(f);
if l>maxfillsize then
maxfillsize:=l;
end
else
l:=0;
{ get zero buffer }
getmem(zerobuf,maxfillsize);
fillchar(zerobuf^,maxfillsize,0);
{ zero from sectioninfo until first section }
blockwrite(f,zerobuf^,l);
{ zero section alignments }
while assigned(secroot) do
begin
seek(f,secroot^.fillpos);
blockwrite(f,zerobuf^,secroot^.fillsize);
hsecroot:=secroot;
secroot:=secroot^.next;
dispose(hsecroot);
end;
freemem(zerobuf,maxfillsize);
close(f);
{$I+}
end;
{$endif}
end.
{
$Log$
Revision 1.1 1999-08-11 17:26:32 peter
* tlinker object is now inherited for win32 and dos
* postprocessexecutable is now a method of tlinker
}

View File

@ -1311,16 +1311,15 @@ exec_w_error_while_assembling=W_Error while assembling exitcode $1
exec_w_cant_call_assembler=W_Can't call the assembler, error $1 switching to external assembling
exec_i_assembling=I_Assembling $1
exec_i_assembling_smart=I_Assembling smartlink $1
exec_w_linker_not_found=W_Linker $1 not found, switching to external linking
exec_t_using_linker=T_Using linker: $1
exec_w_objfile_not_found=W_Object $1 not found, Linking may fail !
exec_w_libfile_not_found=W_Library $1 not found, Linking may fail !
exec_w_error_while_linking=W_Error while linking
exec_w_cant_call_linker=W_Can't call the linker, switching to external linking
exec_i_linking=I_Linking $1
exec_w_binder_not_found=W_binder not found, switching to external binding
exec_w_ar_not_found=W_ar not found, switching to external ar
exec_e_dll_not_supported=E_Dynamic Libraries not supported
exec_w_util_not_found=W_Util $1 not found, switching to external linking
exec_t_using_util=T_Using util $1
exec_e_exe_not_supported=E_Creation of Executables not supported
exec_e_dll_not_supported=E_Creation of Dynamic/Shared Libraries not supported
exec_i_closing_script=I_Closing script $1
exec_w_res_not_found=W_resource compiler not found, switching to external mode
exec_i_compilingresource=I_Compiling resource $1

View File

@ -39,6 +39,7 @@ type
index : longint;
name : pstring;
options : word;
is_var : boolean;
constructor init;
destructor done;virtual;
end;
@ -64,10 +65,34 @@ implementation
uses
systems,verbose,globals,files
{$ifdef i386}
,os2_targ
,win_targ
{$ifndef NOTARGETLINUX}
,t_linux
{$endif}
{$ifndef NOTARGETOS2}
,t_os2
{$endif}
{$ifndef NOTARGETWIN32}
,t_win32
{$endif}
{$ifndef NOTARGETGO32V2}
,t_go32v2
{$endif}
{$endif}
{$ifdef m68k}
{$ifndef NOTARGETLINUX}
,t_linux
{$endif}
{$endif}
{$ifdef powerpc}
{$ifndef NOTARGETLINUX}
,t_linux
{$endif}
{$endif}
{$ifdef alpha}
{$ifndef NOTARGETLINUX}
,t_linux
{$endif}
{$endif}
,lin_targ
;
{****************************************************************************
@ -81,6 +106,7 @@ begin
index:=-1;
name:=nil;
options:=0;
is_var:=false;
end;
@ -137,9 +163,8 @@ procedure InitExport;
begin
case target_info.target of
{$ifdef i386}
{ target_i386_Linux :
importlib:=new(pimportliblinux,Init);
}
target_i386_Linux :
exportlib:=new(pexportliblinux,Init);
target_i386_Win32 :
exportlib:=new(pexportlibwin32,Init);
{
@ -168,7 +193,11 @@ end;
end.
{
$Log$
Revision 1.6 1999-08-04 13:02:41 jonas
Revision 1.7 1999-10-21 14:29:34 peter
* redesigned linker object
+ library support for linux (only procedures can be exported)
Revision 1.6 1999/08/04 13:02:41 jonas
* all tokens now start with an underscore
* PowerPC compiles!!

View File

@ -235,13 +235,16 @@ unit globals;
Function ForceExtension(Const HStr,ext:String):String;
Function FixPath(s:string;allowdot:boolean):string;
function FixFileName(const s:string):string;
procedure SplitBinCmd(const s:string;var bstr,cstr:string);
procedure AddPathToList(var list:string;s:string;first:boolean);
function search(const f : string;path : string;var b : boolean) : string;
function getpathfromlist(var list:string):string;
function search(const f : string;path : string;var b : boolean) : string;
procedure SynchronizeFileTime(const fn1,fn2:string);
function FindExe(bin:string;var found:boolean):string;
Procedure Shell(const command:string);
procedure InitGlobals;
procedure DoneGlobals;
procedure InitGlobals;
procedure DoneGlobals;
procedure strdispose(var p : pchar);
@ -972,6 +975,24 @@ unit globals;
{$endif}
end;
procedure SplitBinCmd(const s:string;var bstr,cstr:string);
var
i : longint;
begin
i:=pos(' ',s);
if i>0 then
begin
bstr:=Copy(s,1,i-1);
cstr:=Copy(s,i+1,length(s)-i);
end
else
begin
bstr:='';
cstr:='';
end;
end;
procedure AddPathToList(var list:string;s:string;first:boolean);
var
@ -1039,6 +1060,26 @@ unit globals;
end;
function getpathfromlist(var list:string):string;
var
s : string;
i : longint;
begin
s:='';
while (list<>'') do
begin
i:=Pos(';',list);
If i=0 then
i:=255;
S:=Copy(list,1,i-1);
Delete (list,1,i);
if (S<>'') then
break;
end;
GetPathFromList:=s;
end;
function search(const f : string;path : string;var b : boolean) : string;
Var
singlepathstring : string;
@ -1158,6 +1199,22 @@ unit globals;
end;
Procedure Shell(const command:string);
{ This is already defined in the linux.ppu for linux, need for the *
expansion under linux }
{$ifdef linux}
begin
Linux.Shell(command);
end;
{$else}
var
comspec : string;
begin
comspec:=getenv('COMSPEC');
Exec(comspec,' /C '+command);
end;
{$endif}
{****************************************************************************
Init
****************************************************************************}
@ -1258,7 +1315,11 @@ begin
end.
{
$Log$
Revision 1.25 1999-09-10 18:48:02 florian
Revision 1.26 1999-10-21 14:29:34 peter
* redesigned linker object
+ library support for linux (only procedures can be exported)
Revision 1.25 1999/09/10 18:48:02 florian
* some bug fixes (e.g. must_be_valid and procinfo.funcret_is_valid)
* most things for stored properties fixed

View File

@ -67,10 +67,34 @@ implementation
uses
systems,verbose,globals
{$ifdef i386}
,os2_targ
,win_targ
{$ifndef NOTARGETLINUX}
,t_linux
{$endif}
{$ifndef NOTARGETOS2}
,t_os2
{$endif}
{$ifndef NOTARGETWIN32}
,t_win32
{$endif}
{$ifndef NOTARGETGO32V2}
,t_go32v2
{$endif}
{$endif}
{$ifdef m68k}
{$ifndef NOTARGETLINUX}
,t_linux
{$endif}
{$endif}
{$ifdef powerpc}
{$ifndef NOTARGETLINUX}
,t_linux
{$endif}
{$endif}
{$ifdef alpha}
{$ifndef NOTARGETLINUX}
,t_linux
{$endif}
{$endif}
,lin_targ
;
{****************************************************************************
@ -203,7 +227,11 @@ end;
end.
{
$Log$
Revision 1.12 1999-08-04 13:02:44 jonas
Revision 1.13 1999-10-21 14:29:34 peter
* redesigned linker object
+ library support for linux (only procedures can be exported)
Revision 1.12 1999/08/04 13:02:44 jonas
* all tokens now start with an underscore
* PowerPC compiles!!

View File

@ -1,106 +0,0 @@
{
$Id$
Copyright (c) 1998 by Florian Klaempfl
This unit implements some support routines for the linux target like
import/export handling
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit lin_targ;
interface
uses import;
type
pimportliblinux=^timportliblinux;
timportliblinux=object(timportlib)
procedure preparelib(const s:string);virtual;
procedure importprocedure(const func,module:string;index:longint;const name:string);virtual;
procedure importvariable(const varname,module:string;const name:string);virtual;
procedure generatelib;virtual;
end;
implementation
uses
verbose,strings,cobjects,systems,globtype,globals,
symconst,
files,aasm,symtable;
procedure timportliblinux.preparelib(const s : string);
begin
end;
procedure timportliblinux.importprocedure(const func,module : string;index : longint;const name : string);
begin
{ insert sharedlibrary }
current_module^.linkothersharedlibs.insert(SplitName(module),link_allways);
{ do nothing with the procedure, only set the mangledname }
if name<>'' then
aktprocsym^.definition^.setmangledname(name)
else
Message(parser_e_empty_import_name);
end;
procedure timportliblinux.importvariable(const varname,module:string;const name:string);
begin
{ insert sharedlibrary }
current_module^.linkothersharedlibs.insert(SplitName(module),link_allways);
{ reset the mangledname and turn off the dll_var option }
aktvarsym^.setmangledname(name);
{$ifdef INCLUDEOK}
exclude(aktvarsym^.varoptions,vo_is_dll_var);
{$else}
aktvarsym^.varoptions:=aktvarsym^.varoptions-[vo_is_dll_var];
{$endif}
end;
procedure timportliblinux.generatelib;
begin
end;
end.
{
$Log$
Revision 1.5 1999-08-03 22:02:54 peter
* moved bitmask constants to sets
* some other type/const renamings
Revision 1.4 1999/07/03 00:29:50 peter
* new link writing to the ppu, one .ppu is needed for all link types,
static (.o) is now always created also when smartlinking is used
Revision 1.3 1999/01/20 14:18:32 pierre
* bugs related to mangledname solved
- linux external without name
-external procs already used
(added count and is_used boolean fiels in tprocvar)
Revision 1.2 1998/11/28 16:20:51 peter
+ support for dll variables
Revision 1.1 1998/10/19 18:07:13 peter
+ external dll_name name func support for linux
}

View File

@ -33,17 +33,21 @@ Interface
uses cobjects,files;
Type
TLinkerInfo=record
ExeCmd,
DllCmd : array[1..3] of string[80];
ResName : string[12];
ExtraOptions : string;
DynamicLinker : string[80];
end;
PLinker=^TLinker;
TLinker = Object
Glibc2,
Glibc21,
LinkToC, { Should we link to the C libs? }
Strip : Boolean; { Strip symbols ? }
public
Info : TLinkerInfo;
ObjectFiles,
SharedLibFiles,
StaticLibFiles : TStringContainer;
LinkOptions : string; { Additional options to the linker }
DynamicLinker : String[80]; { What Dynamic linker ? }
LinkResName : String[32]; { Name of response file }
StaticLibFiles : TStringContainer;
{ Methods }
Constructor Init;
Destructor Done;
@ -53,15 +57,14 @@ Type
Procedure AddObject(const S : String);
Procedure AddStaticLibrary(const S : String);
Procedure AddSharedLibrary(S : String);
Function FindLinker:String; { Find linker, sets Name }
Function DoExec(const command,para:string;info,useshell:boolean):boolean;
Function WriteResponseFile:Boolean;
Function MakeExecutable:boolean;
Procedure MakeStaticLibrary(filescnt:longint);
Procedure MakeSharedLibrary;
procedure postprocessexecutable(const n : string);virtual;
Function FindUtil(const s:string):String;
Function DoExec(const command,para:string;showinfo,useshell:boolean):boolean;
{ Virtuals }
procedure SetDefaultInfo;virtual;
Function MakeExecutable:boolean;virtual;
Function MakeSharedLibrary:boolean;virtual;
Function MakeStaticLibrary(filescnt:longint):boolean;virtual;
end;
PLinker=^TLinker;
Var
Linker : PLinker;
@ -81,61 +84,61 @@ uses
globtype,systems,
script,globals,verbose,ppu
{$ifdef i386}
,win_targ
,dos_targ
{$ifndef NOTARGETLINUX}
,t_linux
{$endif}
{$ifndef NOTARGETOS2}
,t_os2
{$endif}
{$ifndef NOTARGETWIN32}
,t_win32
{$endif}
{$ifndef NOTARGETGO32V1}
,t_go32v1
{$endif}
{$ifndef NOTARGETGO32V2}
,t_go32v2
{$endif}
{$endif}
{$ifdef linux}
,linux
{$ifdef m68k}
{$ifndef NOTARGETLINUX}
,t_linux
{$endif}
{$endif}
{$ifdef powerpc}
{$ifndef NOTARGETLINUX}
,t_linux
{$endif}
{$endif}
{$ifdef alpha}
{$ifndef NOTARGETLINUX}
,t_linux
{$endif}
{$endif}
,gendef
;
{$ifndef linux}
Procedure Shell(const command:string);
{ This is already defined in the linux.ppu for linux, need for the *
expansion under linux }
var
comspec : string;
begin
comspec:=getenv('COMSPEC');
Exec(comspec,' /C '+command);
end;
{$endif}
{*****************************************************************************
TLINKER
*****************************************************************************}
Constructor TLinker.Init;
begin
ObjectFiles.Init_no_double;
{ libraries sometimes need to be loaded several times PM }
SharedLibFiles.Init{_no_double};
StaticLibFiles.Init{_no_double};
LinkToC:=(cs_link_toc in aktglobalswitches);
Strip:=(cs_link_strip in aktglobalswitches);
LinkOptions:=ParaLinkOptions;
DynamicLinker:=ParaDynamicLinker;
LinkResName:='link.res';
Glibc2:=false;
Glibc21:=false;
if target_info.target=target_i386_linux then
SharedLibFiles.Init_no_double;
StaticLibFiles.Init_no_double;
{ set generic defaults }
FillChar(Info,sizeof(Info),0);
Info.ResName:='link.res';
{ set the linker specific defaults }
SetDefaultInfo;
{ Allow Parameter overrides for linker info }
with Info do
begin
if DynamicLinker='' then
begin
{ first try glibc2 }
DynamicLinker:='/lib/ld-linux.so.2';
if FileExists(DynamicLinker) then
begin
Glibc2:=true;
{ also glibc 2.1 / 2.1.1 / 2.1.2 ? }
if FileExists('/lib/ld-2.1.so') or
FileExists('/lib/ld-2.1.1.so') or
FileExists('/lib/ld-2.1.2.so') then
Glibc21:=true;
end
else
DynamicLinker:='/lib/ld-linux.so.1';
end;
AddPathToList(LibrarySearchPath,'/lib;/usr/lib;/usr/X11R6/lib',true);
if ParaLinkOptions<>'' then
ExtraOptions:=ParaLinkOptions;
if ParaDynamicLinker<>'' then
DynamicLinker:=ParaDynamicLinker;
end;
end;
@ -148,6 +151,11 @@ begin
end;
Procedure TLinker.SetDefaultInfo;
begin
end;
procedure TLinker.AddModuleFiles(hp:pmodule);
var
mask : longint;
@ -229,28 +237,24 @@ begin
end;
var
LastLDBin : string;
Function TLinker.FindLinker:string;
Function TLinker.FindUtil(const s:string):string;
var
ldfound : boolean;
LastBin : string;
begin
if LastLDBin='' then
LastBin:='';
if utilsdirectory<>'' then
LastBin:=Search(s+source_os.exeext,utilsdirectory,ldfound)+s+source_os.exeext;
if LastBin='' then
LastBin:=FindExe(s,ldfound);
if (not ldfound) and not(cs_link_extern in aktglobalswitches) then
begin
if utilsdirectory<>'' then
LastLDBin:=Search(target_link.linkbin+source_os.exeext,utilsdirectory,ldfound)+
target_link.linkbin+source_os.exeext;
if LastLDBin='' then
LastLDBin:=FindExe(target_link.linkbin,ldfound);
if (not ldfound) and not(cs_link_extern in aktglobalswitches) then
begin
Message1(exec_w_linker_not_found,LastLDBin);
aktglobalswitches:=aktglobalswitches+[cs_link_extern];
end;
if ldfound then
Message1(exec_t_using_linker,LastLDBin);
Message1(exec_w_util_not_found,s);
aktglobalswitches:=aktglobalswitches+[cs_link_extern];
end;
FindLinker:=LastLDBin;
if ldfound then
Message1(exec_t_using_util,LastBin);
FindUtil:=LastBin;
end;
@ -349,7 +353,7 @@ begin
end;
Function TLinker.DoExec(const command,para:string;info,useshell:boolean):boolean;
Function TLinker.DoExec(const command,para:string;showinfo,useshell:boolean):boolean;
begin
DoExec:=true;
if not(cs_link_extern in aktglobalswitches) then
@ -381,7 +385,7 @@ begin
{ Update asmres when externmode is set }
if cs_link_extern in aktglobalswitches then
begin
if info then
if showinfo then
AsmRes.AddLinkCommand(Command,Para,current_module^.exefilename^)
else
AsmRes.AddLinkCommand(Command,Para,'');
@ -389,329 +393,43 @@ begin
end;
Function TLinker.WriteResponseFile : Boolean;
Var
LinkResponse : Text;
i : longint;
cprtobj,
gprtobj,
prtobj : string[80];
s,s2 : string;
found,linux_link_c,
linkdynamic,
linklibc : boolean;
procedure WriteRes(const s:string);
begin
if s<>'' then
WriteLn(Linkresponse,s);
end;
procedure WriteResFileName(const s:string);
begin
if s<>'' then
begin
if not(s[1] in ['a'..'z','A'..'Z','/','\','.']) then
Write(Linkresponse,'.',DirSep);
WriteLn(Linkresponse,s);
end;
end;
begin
WriteResponseFile:=False;
linux_link_c:=false;
{ set special options for some targets }
linkdynamic:=not(SharedLibFiles.empty);
linklibc:=SharedLibFiles.Find('c');
prtobj:='prt0';
cprtobj:='cprt0';
gprtobj:='gprt0';
if glibc21 then
begin
cprtobj:='cprt21';
gprtobj:='gprt21';
end;
case target_info.target of
target_m68k_Palmos,
target_i386_Win32 :
begin
if DLLsource then
prtobj:='wdllprt0'
else
prtobj:='wprt0';
end;
target_m68k_linux,
target_i386_linux :
begin
if cs_profile in aktmoduleswitches then
begin
prtobj:=gprtobj;
if not glibc2 then
AddSharedLibrary('gmon');
AddSharedLibrary('c');
linklibc:=true;
end
else
begin
if linklibc then
prtobj:=cprtobj;
end;
if linklibc then
linux_link_c:=true;
end;
end;
{ Fix command line options }
If (DynamicLinker<>'') and (not SharedLibFiles.Empty) then
LinkOptions:='-dynamic-linker='+DynamicLinker+' '+LinkOptions;
if Strip and not(cs_debuginfo in aktmoduleswitches) and
not (Target_Link.StripBind) then
LinkOptions:=LinkOptions+' '+target_link.stripopt;
{ Open linkresponse and write header }
assign(linkresponse,current_module^.outpath^+LinkResName);
{$I-}
rewrite(linkresponse);
{$I+}
if ioresult<>0 then
exit;
{ Write library searchpath }
if assigned(current_module^.locallibrarysearchpath) then
begin
S2:=current_module^.locallibrarysearchpath^;
Repeat
i:=Pos(';',S2);
If i=0 then
i:=255;
S:=Copy(S2,1,i-1);
If S<>'' then
WriteRes(target_link.libpathprefix+s+target_link.libpathsuffix);
Delete (S2,1,i);
until S2='';
end;
S2:=LibrarySearchPath;
Repeat
i:=Pos(';',S2);
If i=0 then
i:=255;
S:=Copy(S2,1,i-1);
If S<>'' then
WriteRes(target_link.libpathprefix+s+target_link.libpathsuffix);
Delete (S2,1,i);
until S2='';
WriteRes(target_link.inputstart);
{ add objectfiles, start with prt0 always }
if prtobj<>'' then
WriteResFileName(FindObjectFile(prtobj));
{ try to add crti and crtbegin, they are normally not required, but
adding can sometimes be usefull }
if linux_link_c then
begin
s:=search('crtbegin.o',librarysearchpath,found)+'crtbegin.o';
if found then
WriteResFileName(s);
s:=search('crti.o',librarysearchpath,found)+'crti.o';
if found then
WriteResFileName(s);
end;
while not ObjectFiles.Empty do
begin
s:=ObjectFiles.Get;
if s<>'' then
WriteResFileName(s);
end;
if linux_link_c then
begin
s:=search('crtend.o',librarysearchpath,found)+'crtend.o';
if found then
WriteResFileName(s);
s:=search('crtn.o',librarysearchpath,found)+'crtn.o';
if found then
WriteResFileName(s);
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) }
While not SharedLibFiles.Empty do
begin
S:=SharedLibFiles.Get;
if s<>'c' then
begin
i:=Pos(target_os.sharedlibext,S);
if i>0 then
Delete(S,i,255);
WriteRes(target_link.libprefix+s);
end
else
begin
{ Some times several references to libc are necessary !! PM }
WriteRes(target_link.libprefix+s);
linklibc:=true;
linkdynamic:=false; { C add's it automaticly }
end;
end;
{ be sure that libc is the last lib }
{ arghhhh this is wrong for DJGPP !!!
DJGPP need gcc after c lib (umod...) (PM) }
if linklibc then
WriteRes(target_link.libprefix+'c');
{ add libgcc after ! }
if linklibc and (target_info.target=target_i386_go32v2) then
WriteRes(target_link.libprefix+'gcc');
if linkdynamic and (DynamicLinker<>'') then
WriteResFileName(DynamicLinker);
WriteRes(target_link.inputend);
{ Write staticlibraries }
if not StaticLibFiles.Empty then
begin
WriteRes(target_link.GroupStart);
While not StaticLibFiles.Empty do
begin
S:=StaticLibFiles.Get;
WriteResFileName(s)
end;
WriteRes(target_link.GroupEnd);
end;
{ Close response }
close(linkresponse);
WriteResponseFile:=True;
end;
function TLinker.MakeExecutable:boolean;
var
bindbin : string[80];
bindfound : boolean;
s : string;
success : boolean;
ii : longint;
begin
{ can be changed after InitLinker
for DLLs due to relocation problems PM }
Strip:=(cs_link_strip in aktglobalswitches);
{$ifdef linux}
if LinkToC then
begin
AddObject('/usr/lib/crt0.o');
AddObject('lprt');
AddStaticLibrary('libc.a');
AddStaticLibrary('libgcc.a');
end;
{$endif Linux}
{ Write used files and libraries }
WriteResponseFile;
{ Call linker }
if not(cs_link_extern in aktglobalswitches) then
Message1(exec_i_linking,current_module^.exefilename^);
s:=target_link.linkcmd;
if DLLsource then
Replace(s,'$EXE',current_module^.sharedlibfilename^)
else
Replace(s,'$EXE',current_module^.exefilename^);
Replace(s,'$OPT',LinkOptions);
Replace(s,'$RES',current_module^.outpath^+LinkResName);
success:=DoExec(FindLinker,s,true,false);
{Bind}
if (target_link.bindbin[1]<>'') and
((target_info.target<>target_i386_win32) or
(RelocSection and not Deffile.empty)) then
for ii:=1 to target_link.binders do
begin
s:=target_link.bindcmd[ii];
Replace(s,'$OPT',LinkOptions);
Replace(s,'$RES',current_module^.outpath^+LinkResName);
if DLLsource then
Replace(s,'$EXE',current_module^.sharedlibfilename^)
else
Replace(s,'$EXE',current_module^.exefilename^);
{Size of the heap when an EMX program runs in OS/2.}
Replace(s,'$HEAPMB',tostr((maxheapsize+1048575) shr 20));
{Size of the stack when an EMX program runs in OS/2.}
Replace(s,'$STACKKB',tostr((stacksize+1023) shr 10));
{When an EMX program runs in DOS, the heap and stack share the
same memory pool. The heap grows upwards, the stack grows downwards.}
Replace(s,'$DOSHEAPKB',tostr((stacksize+maxheapsize+1023) shr 10));
if Strip and Target_Link.StripBind then
Replace (S, '$STRIP', Target_Link.StripOpt)
else
Replace (S, '$STRIP', '');
{This is a hack. But I don't think other platforms have a presenation
manager, so it should work. (DM)}
if usewindowapi then
replace (s, '$PM',' -p')
else
replace (s, '$PM','');
if utilsdirectory<>'' then
begin
bindbin:=Search(target_link.bindbin[ii]+source_os.exeext,
utilsdirectory,bindfound)+target_link.bindbin[ii]+source_os.exeext;
end
else
bindbin:=FindExe(target_link.bindbin[ii],bindfound);
if (not bindfound) and not (cs_link_extern in aktglobalswitches) then
begin
Message1(exec_w_binder_not_found,bindbin);
aktglobalswitches:=aktglobalswitches+[cs_link_extern];
end;
DoExec(bindbin,s,false,false);
end;
{ Post processor executable }
if success and
not(cs_link_extern in aktglobalswitches) then
begin
if DLLsource then
postprocessexecutable(current_module^.sharedlibfilename^)
else
postprocessexecutable(current_module^.exefilename^);
end;
{Remove ReponseFile}
if (success) and not(cs_link_extern in aktglobalswitches) then
RemoveFile(current_module^.outpath^+LinkResName);
MakeExecutable:=success; { otherwise a recursive call to link method }
MakeExecutable:=false;
Message(exec_e_exe_not_supported);
end;
Procedure TLinker.MakeStaticLibrary(filescnt:longint);
Function TLinker.MakeSharedLibrary:boolean;
begin
MakeSharedLibrary:=false;
Message(exec_e_dll_not_supported);
end;
Function TLinker.MakeStaticLibrary(filescnt:longint):boolean;
{
FilesCnt holds the amount of .o files created, if filescnt=0 then
no smartlinking is used
}
var
smartpath,
s,
arbin : string;
arfound : boolean;
cmdstr,
binstr : string;
success : boolean;
cnt : longint;
begin
MakeStaticLibrary:=false;
smartpath:=current_module^.path^+FixPath(FixFileName(current_module^.modulename^)+target_info.smartext,false);
{ find ar binary }
if utilsdirectory<>'' then
begin
arbin:=Search(target_ar.arbin+source_os.exeext,
utilsdirectory,arfound)+target_ar.arbin+source_os.exeext;
end
else
arbin:=FindExe(target_ar.arbin,arfound);
if (not arfound) and not(cs_link_extern in aktglobalswitches) then
begin
Message(exec_w_ar_not_found);
aktglobalswitches:=aktglobalswitches+[cs_link_extern];
end;
s:=target_ar.arcmd;
Replace(s,'$LIB',current_module^.staticlibfilename^);
SplitBinCmd(target_ar.arcmd,binstr,cmdstr);
Replace(cmdstr,'$LIB',current_module^.staticlibfilename^);
if filescnt=0 then
Replace(s,'$FILES',current_module^.objfilename^)
Replace(cmdstr,'$FILES',current_module^.objfilename^)
else
Replace(s,'$FILES',FixFileName(smartpath+current_module^.asmprefix^+'*'+target_info.objext));
DoExec(arbin,s,false,true);
Replace(cmdstr,'$FILES',FixFileName(smartpath+current_module^.asmprefix^+'*'+target_info.objext));
success:=DoExec(FindUtil(binstr),cmdstr,false,true);
{ Clean up }
if not(cs_asm_leave in aktglobalswitches) then
if not(cs_link_extern in aktglobalswitches) then
@ -736,45 +454,56 @@ begin
AsmRes.Add('rmdir '+smartpath);
end;
end;
MakeStaticLibrary:=success;
end;
Procedure TLinker.MakeSharedLibrary;
var
s : string;
begin
s:=' -shared -o $LIB $FILES';
Replace(s,'$LIB',current_module^.sharedlibfilename^);
Replace(s,'$FILES',current_module^.objfilename^);
if DoExec(FindLinker,s,false,false) then
RemoveFile(current_module^.objfilename^);
end;
procedure tlinker.postprocessexecutable(const n:string);
begin
end;
{*****************************************************************************
Init/Done
*****************************************************************************}
procedure InitLinker;
begin
case target_info.target of
{$ifdef i386}
{$ifndef NOTARGETLINUX}
target_i386_linux :
linker:=new(plinkerlinux,Init);
{$endif}
{$ifndef NOTARGETWIN32}
target_i386_Win32 :
linker:=new(plinkerwin32,Init);
{$endif}
{$ifndef NOTARGETGO32V1}
target_i386_Go32v1 :
linker:=new(plinkergo32v1,Init);
{$endif}
{$ifndef NOTARGETGO32V2}
target_i386_Go32v2 :
linker:=new(plinkergo32v2,Init);
{$endif}
{$endif i386}
{$ifdef m68k}
{$ifndef NOTARGETPALMOS}
target_m68k_palmos:
linker:=new(plinker,Init);
{$endif}
{$ifndef NOTARGETLINUX}
target_m68k_linux :
linker:=new(plinkerlinux,Init);
{$endif}
{$endif m68k}
{$ifdef alpha}
target_alpha_linux:
linker:=new(plinker,Init);
{$ifndef NOTARGETLINUX}
target_alpha_linux :
linker:=new(plinkerlinux,Init);
{$endif}
{$endif alpha}
{$ifdef powerpc}
target_powerpc_linux:
linker:=new(plinker,Init);
{$ifndef NOTARGETLINUX}
target_powerpc_linux :
linker:=new(plinkerlinux,Init);
{$endif}
{$endif powerpc}
else
linker:=new(plinker,Init);
@ -792,8 +521,9 @@ end;
end.
{
$Log$
Revision 1.73 1999-10-08 15:38:42 pierre
* library list keeps doubles
Revision 1.74 1999-10-21 14:29:34 peter
* redesigned linker object
+ library support for linux (only procedures can be exported)
Revision 1.72 1999/09/16 23:05:52 florian
* m68k compiler is again compilable (only gas writer, no assembler reader)

View File

@ -413,15 +413,14 @@ type tmsgconst=(
exec_w_cant_call_assembler,
exec_i_assembling,
exec_i_assembling_smart,
exec_w_linker_not_found,
exec_t_using_linker,
exec_w_objfile_not_found,
exec_w_libfile_not_found,
exec_w_error_while_linking,
exec_w_cant_call_linker,
exec_i_linking,
exec_w_binder_not_found,
exec_w_ar_not_found,
exec_w_util_not_found,
exec_t_using_util,
exec_e_exe_not_supported,
exec_e_dll_not_supported,
exec_i_closing_script,
exec_w_res_not_found,

View File

@ -1,7 +1,7 @@
{$ifdef Delphi}
const msgtxt : array[0..000103] of string[240]=(
const msgtxt : array[0..000102] of string[240]=(
{$else Delphi}
const msgtxt : array[0..000103,1..240] of char=(
const msgtxt : array[0..000102,1..240] of char=(
{$endif Delphi}
'T_Compiler: $1'#000+
'D_Compiler OS: $1'#000+
@ -436,135 +436,134 @@ const msgtxt : array[0..000103,1..240] of char=(
'ing'#000+
'I_Assembling $1'#000+
'I_Assembling smartlink $1'#000+
'W_Linker $1 not found, sw','itching to external linking'#000+
'T_Using linker: $1'#000+
'W_Object $1 not found, Linking may fail !'#000+
'W_Object $1 not found, Li','nking may fail !'#000+
'W_Library $1 not found, Linking may fail !'#000+
'W_Error while linking'#000+
'W_Can'#039't call the linker, switching to external linking'#000+
'I_Linking $1'#000+
'W_binder not found',', switching to external binding'#000+
'W_ar not found, switching to external ar'#000+
'E_Dynamic Libraries not supported'#000+
'W_$1 not found: $2, switching to external linking'#000+
'T_Using $1: $2'#000+
'E_Creation of Executables',' not supported'#000+
'E_Creation of Dynamic/Shared Libraries not supported'#000+
'I_Closing script $1'#000+
'W_resource compiler not found, switching to external mode'#000+
'I_Compiling resource $1'#000+
'F_Can'#039't post process executable',' $1'#000+
'F_Can'#039't post process executable $1'#000+
'F_Can'#039't open executable $1'#000+
'X_Size of Code: $1 bytes'#000+
'X_Size o','f Code: $1 bytes'#000+
'X_Size of initialized data: $1 bytes'#000+
'X_Size of uninitialized data: $1 bytes'#000+
'X_Stack space reserved: $1 bytes'#000+
'X_Stack space commited: $1 bytes'#000+
'T_Unitsearch: $1'#000+
'T_PPU Loading $1'#000+
'U_PPU Na','me: $1'#000+
'U_PPU Name: $1'#000+
'U_PPU Flags: $1'#000+
'U_PPU Crc: $1'#000+
'U_PPU Time: $1'#000+
'U_','PPU Time: $1'#000+
'U_PPU File too short'#000+
'U_PPU Invalid Header (no PPU at the begin)'#000+
'U_PPU Invalid Version $1'#000+
'U_PPU is compiled for an other processor'#000+
'U_PPU is compiled for an other target'#000+
'U_PPU Source: $1'#000+
'U_W','riting $1'#000+
'U_Writing $1'#000+
'F_Can'#039't Write PPU-File'#000+
'F_reading PPU-File'#000+
'F_read','ing PPU-File'#000+
'F_unexpected end of PPU-File'#000+
'F_Invalid PPU-File entry: $1'#000+
'F_PPU Dbx count problem'#000+
'E_Illegal unit name: $1'#000+
'F_Too much units'#000+
'F_Circular unit reference between $1 and $2'#000+
'F_Can'#039't compile unit ','$1, no sources available'#000+
'F_Can'#039't find unit $1'#000+
'F_Can'#039't compile unit $1, no sources available'#000+
'F_Can'#039't find u','nit $1'#000+
'W_Unit $1 was not found but $2 exists'#000+
'F_Unit $1 searched but $2 found'#000+
'W_Compiling the system unit requires the -Us switch'#000+
'F_There were $1 errors compiling module, stopping'#000+
'U_Load from $1 ($2) un','it $3'#000+
'U_Recompiling $1, checksum changed for $2'#000+
'U_Load from $1 ($2) unit $3'#000+
'U_Recompiling $1, checksum change','d for $2'#000+
'U_Recompiling $1, source found only'#000+
'U_Recompiling unit, static lib is older than ppufile'#000+
'U_Recompiling unit, shared lib is older than ppufile'#000+
'U_Recompiling unit, obj and asm are older than ppu','file'#000+
'U_Recompiling unit, obj is older than asm'#000+
'U_Recompiling unit, obj and asm are older than ppufile'#000+
'U_Recompiling unit, obj is older t','han asm'#000+
'U_Parsing interface of $1'#000+
'U_Parsing implementation of $1'#000+
'U_Second load for unit $1'#000+
'U_PPU Check file $1 time $2'#000+
'$1 [options] <inputfile> [options]'#000+
'W_Only one source file supported'#000+
'W_DEF file can',' be created only for OS/2'#000+
'E_nested response files are not supported'#000+
'W_DEF file can be created only for OS/2'#000+
'E_nested resp','onse files are not supported'#000+
'F_No source file name in command line'#000+
'E_Illegal parameter: $1'#000+
'H_-? writes help pages'#000+
'F_Too many config files nested'#000+
'F_Unable to open file $1'#000+
'N_Reading further options from ','$1'#000+
'N_Reading further options from $1'#000+
'W_Target is already set to: $1'#000+
'W_Shared libs not supported on DOS platform, reverting to static'#000+
'W_Sha','red libs not supported on DOS platform, reverting to static'#000+
'F_too many IF(N)DEFs'#000+
'F_too many ENDIFs'#000+
'F_open conditional at the end of the file'#000+
'W_Debug information generation is not supported by this exec','utable'#000+
'W_Debug information generation is not supported by this executable'#000+
'H_Try recompiling with -dGDB'#000+
'E_You are using the obsolete switch $1'#000+
'E_Y','ou are using the obsolete switch $1'#000+
'E_You are using the obsolete switch $1, please use $2'#000+
'N_Switching assembler to default source writing assembler'#000+
'Free Pascal Compiler version $FPCVER [$FPCDATE] for $','FPCTARGET'#000+
'Copyright (c) 1993-1999 by Florian Klaempfl'#000+
'Free Pascal Compiler version $FPCVER [$FPCDATE] for $FPCTARGET'#000+
'Copyright (c) 1993-1999 by Fl','orian Klaempfl'#000+
'Free Pascal Compiler version $FPCVER'#000+
#000+
'Compiler Date : $FPCDATE'#000+
'Compiler Target: $FPCTARGET'#000+
#000+
'This program comes under the GNU General Public Licence'#000+
'For more information read COPYING.FPC',#000+
'For more information read COPYING.FPC'#000+
#000+
'Report bugs,suggestions etc to:'#000+
' fpc-devel@vekoll.saturnus.vein.hu'#000+
' ',' fpc-devel@vekoll.saturnus.vein.hu'#000+
'**0*_put + after a boolean switch option to enable it, - to disable it'+
#000+
'**1a_the compiler doesn'#039't delete the generated assembler file'#000+
'**2al_list sourcecode ','lines in assembler file'#000+
'**2ar_list register allocation/release info in assembler file'#000+
'**2al_list sourcecode lines in assembler file'#000+
'**2ar_list regi','ster allocation/release info in assembler file'#000+
'**2at_list temp allocation/release info in assembler file'#000+
'**1b_generate browser info'#000+
'**2bl_generate local symbol info'#000+
'**1B_build all modules'#000+
'**1C<x>_code ','generation options:'#000+
'3*2CD_create dynamic library'#000+
'**1C<x>_code generation options:'#000+
'3*2CD_create dynami','c library'#000+
'**2Ch<n>_<n> bytes heap (between 1023 and 67107840)'#000+
'**2Ci_IO-checking'#000+
'**2Cn_omit linking stage'#000+
'**2Co_check overflow of integer operations'#000+
'**2Cr_range checking'#000+
'**2Cs<n>_set stack size to <n>'#000+
'*','*2Ct_stack checking'#000+
'**2CD_create also dynamic library (* doesn'#039't work yet *)'#000+
'**2Ct_stack checking'#000+
'**2CD_create also d','ynamic library (* doesn'#039't work yet *)'#000+
'**2CX_create also smartlinked library'#000+
'**1d<x>_defines the symbol <x>'#000+
'*O1D_generate a DEF file'#000+
'*O2Dd<x>_set description to <x>'#000+
'*O2Dw_PM application'#000+
'**1e<x>_set path',' to executable'#000+
'**1e<x>_set path to executable'#000+
'**1E_same as -Cn'#000+
'**1F<x>_set file names and paths:'#000+
'**1F<x>','_set file names and paths:'#000+
'**2FD<x>_sets the directory where to search for compiler utilities'#000+
'**2Fe<x>_redirect error output to <x>'#000+
'**2FE<x>_set exe/unit output path to <x>'#000+
'**2Fi<x>_adds <x> to include',' path'#000+
'**2Fl<x>_adds <x> to library path'#000+
'**2Fi<x>_adds <x> to include path'#000+
'**2Fl<x>_adds <x> to library path',#000+
'*L2FL<x>_uses <x> as dynamic linker'#000+
'**2Fo<x>_adds <x> to object path'#000+
'**2Fr<x>_load error message file <x>'#000+
'**2Fu<x>_adds <x> to unit path'#000+
'**2FU<x>_set unit output path to <x>, overrides -FE'#000+
'*g1g<x>_gen','erate debugger information:'#000+
'*g2gg_use gsym'#000+
'*g1g<x>_generate debugger information:'#000+
'*g2gg_use g','sym'#000+
'*g2gd_use dbx'#000+
'*g2gh_use heap trace unit'#000+
'*g2gc_generate checks for pointers'#000+
@ -572,97 +571,98 @@ const msgtxt : array[0..000103,1..240] of char=(
'**2iD_return compiler date'#000+
'**2iV_return compiler version'#000+
'**2iSO_return compiler OS'#000+
'**2iSP_return compiler',' processor'#000+
'**2iSP_return compiler processor'#000+
'**2iTO_return target OS'#000+
'**2iTP_return target processor'#000+
'**2i','TP_return target processor'#000+
'**1I<x>_adds <x> to include path'#000+
'**1k<x>_Pass <x> to the linker'#000+
'**1l_write logo'#000+
'**1n_don'#039't read the default config file'#000+
'**1o<x>_change the name of the executable produced to ','<x>'#000+
'**1pg_generate profile code for gprof (defines FPC_PROFILE)'#000+
'**1o<x>_change the name of the executable produced to <x>'#000+
'**1pg_generate profile code for gpr','of (defines FPC_PROFILE)'#000+
'*L1P_use pipes instead of creating temporary assembler files'#000+
'**1S<x>_syntax options:'#000+
'**2S2_switch some Delphi 2 extensions on'#000+
'**2Sc_supports operators like C (*=,+=,/= and -=)'#000,
'**2Sc_supports operators like C (*=,+=,/= and -=)'#000+
'**2Sd_tries to be Delphi compatible'#000+
'**2Se<x>_compiler stops after the <x> errors (default is 1)'#000+
'**2','Se<x>_compiler stops after the <x> errors (default is 1)'#000+
'**2Sg_allow LABEL and GOTO'#000+
'**2Sh_Use ansistrings'#000+
'**2Si_support C++ styled INLINE'#000+
'**2Sm_support macros like C (global)'#000+
'**2So_tries to be TP/BP 7.','0 compatible'#000+
'**2Sp_tries to be gpc compatible'#000+
'**2So_tries to be TP/BP 7.0 compatible'#000+
'**2Sp_tries to be gpc comp','atible'#000+
'**2Ss_constructor name must be init (destructor must be done)'#000+
'**2St_allow static keyword in objects'#000+
'**1s_don'#039't call assembler and linker (only with -a)'#000+
'**1u<x>_undefines the symbol <x>'#000+
'**1U_unit',' options:'#000+
'**2Un_don'#039't check the unit name'#000+
'**1U_unit options:'#000+
'**2Un_don'#039't check the unit na','me'#000+
'**2Us_compile a system unit'#000+
'**1v<x>_Be verbose. <x> is a combination of the following letters:'#000+
'**2*_e : Show errors (default) d : Show debug info'#000+
'**2*_w : Show warnings u : Show ','unit info'#000+
'**2*_n : Show notes t : Show tried/used files'#000+
'**2*_w : Show warnings u : Show unit info'#000+
'**2*_n : Show notes ',' t : Show tried/used files'#000+
'**2*_h : Show hints m : Show defined macros'#000+
'**2*_i : Show general info p : Show compiled procedures'#000+
'**2*_l : Show linenumbers c :',' Show conditionals'#000+
'**2*_a : Show everything 0 : Show nothing (except errors)'#000+
'**2*_l : Show linenumbers c : Show conditionals'#000+
'**2*_a : Show everyt','hing 0 : Show nothing (except errors'+
')'#000+
'**2*_b : Show all procedure r : Rhide/GCC compatibility mode'#000+
'**2*_ declarations if an error x : Executable info (Win32 only)'#000+
'**2*_ oc','curs'#000+
'**2*_ occurs'#000+
'**1X_executable options:'#000+
'*L2Xc_link with the c library'#000+
'*L2Xc_lin','k with the c library'#000+
'**2Xs_strip all symbols from executable'#000+
'**2XD_try to link dynamic (defines FPC_LINK_DYNAMIC)'#000+
'**2XS_try to link static (default) (defines FPC_LINK_STATIC)'#000+
'**2XX_try to link',' smart (defines FPC_LINK_SMART)'#000+
'**2XX_try to link smart (defines FPC_LINK_SMA','RT)'#000+
'**0*_Processor specific options:'#000+
'3*1A<x>_output format:'#000+
'3*2Aas_assemble using GNU AS'#000+
'3*2Aasaout_assemble using GNU AS for aout (Go32v1)'#000+
'3*2Anasmcoff_coff (Go32v2) file using Nasm'#000+
'3*2Anasmelf_elf32 ','(Linux) file using Nasm'#000+
'3*2Anasmobj_obj file using Nasm'#000+
'3*2Anasmelf_elf32 (Linux) file using Nasm'#000+
'3*2Anasmobj_obj',' file using Nasm'#000+
'3*2Amasm_obj file using Masm (Microsoft)'#000+
'3*2Atasm_obj file using Tasm (Borland)'#000+
'3*2Acoff_coff (Go32v2) using internal writer'#000+
'3*2Apecoff_pecoff (Win32) using internal writer'#000+
'3*1R<x>_ass','embler reading style:'#000+
'3*2Ratt_read AT&T style assembler'#000+
'3*1R<x>_assembler reading style:'#000+
'3*2Ratt_read AT&T',' style assembler'#000+
'3*2Rintel_read Intel style assembler'#000+
'3*2Rdirect_copy assembler text directly to assembler file'#000+
'3*1O<x>_optimizations:'#000+
'3*2Og_generate smaller code'#000+
'3*2OG_generate faster code (default)'#000+
'3','*2Or_keep certain variables in registers (still BUGGY!!!)'#000+
'3*2Or_keep certain variables in register','s (still BUGGY!!!)'#000+
'3*2Ou_enable uncertain optimizations (see docs)'#000+
'3*2O1_level 1 optimizations (quick optimizations)'#000+
'3*2O2_level 2 optimizations (-O1 + slower optimizations)'#000+
'3*2O3_level 3 optimizations',' (same as -O2u)'#000+
'3*2Op<x>_target processor:'#000+
'3*2O3_level 3 optimizations (same as -O2u)'#000+
'3*2Op<x>_target process','or:'#000+
'3*3Op1_set target processor to 386/486'#000+
'3*3Op2_set target processor to Pentium/PentiumMMX (tm)'#000+
'3*3Op3_set target processor to PPro/PII/c6x86/K6 (tm)'#000+
'3*1T<x>_Target operating system:'#000+
'3*2TGO32V1_versi','on 1 of DJ Delorie DOS extender'#000+
'3*2TGO32V2_version 2 of DJ Delorie DOS extender'#000+
'3*2TGO32V1_version 1 of DJ Delorie DOS extender'#000+
'3*2TGO3','2V2_version 2 of DJ Delorie DOS extender'#000+
'3*2TLINUX_Linux'#000+
'3*2TOS2_OS/2 2.x'#000+
'3*2TWin32_Windows 32 Bit'#000+
'6*1A<x>_output format'#000+
'6*2Aas_Unix o-file using GNU AS'#000+
'6*2Agas_GNU Motorola assembler'#000+
'6*2Amit_MIT Synta','x (old GAS)'#000+
'6*2Amot_Standard Motorola assembler'#000+
'6*2Amit_MIT Syntax (old GAS)'#000+
'6*2Amot_Standard Motorola a','ssembler'#000+
'6*1O_optimizations:'#000+
'6*2Oa_turn on the optimizer'#000+
'6*2Og_generate smaller code'#000+
'6*2OG_generate faster code (default)'#000+
'6*2Ox_optimize maximum (still BUGGY!!!)'#000+
'6*2O2_set target processor to a MC68020','+'#000+
'6*2O2_set target processor to a MC68020+'#000+
'6*1R<x>_assembler reading style:'#000+
'6*2RMOT_read motorola style assembler'#000+
'6*2R','MOT_read motorola style assembler'#000+
'6*1T<x>_Target operating system:'#000+
'6*2TAMIGA_Commodore Amiga'#000+
'6*2TATARI_Atari ST/STe/TT'#000+
@ -670,5 +670,5 @@ const msgtxt : array[0..000103,1..240] of char=(
'6*2TLINUX_Linux-68k'#000+
'**1*_'#000+
'**1?_shows this help'#000+
'**1h_shows',' this help without waiting'#000
'**1h_shows this help without waiting'#000
);

View File

@ -274,33 +274,6 @@ unit pmodules;
datasegment^.concat(new(pai_symbol,initname_global('__stklen',4)));
datasegment^.concat(new(pai_const,init_32bit(stacksize)));
end;
target_i386_WIN32 :
begin
target_link.bindcmd[1]:=target_link.bindcmd[1]+' -d '+deffile.fname;
if DLLsource then
begin
target_link.binders:=2;
target_link.linkcmd:='--dll '+target_link.linkcmd;
target_link.bindcmd[2]:='--dll '+target_link.bindcmd[2];
if RelocSection then
begin
target_link.linkcmd:=target_link.linkcmd+' --base-file base.$$$';
target_link.bindcmd[1]:=target_link.bindcmd[1]+' --base-file base.$$$';
end;
if assigned(DLLImageBase) then
begin
target_link.linkcmd:=target_link.linkcmd+' --image-base=0x'+DLLImageBase^;
target_link.bindcmd[2]:=target_link.bindcmd[2]+' --image-base=0x'+DLLImageBase^;
end;
end;
if apptype=at_gui then
begin
target_link.linkcmd:='--subsystem windows '+target_link.linkcmd;
target_link.bindcmd[2]:='--subsystem windows '+target_link.bindcmd[2];
end;
if (cs_link_strip in aktglobalswitches) then
target_link.bindcmd[2]:='-s '+target_link.bindcmd[2];
end;
{$endif i386}
{$ifdef m68k}
target_m68k_Atari :
@ -1453,14 +1426,23 @@ unit pmodules;
deffile.writefile;
{ finally we can create a executable }
if (not current_module^.is_unit) then
Linker^.MakeExecutable;
begin
if DLLSource then
Linker^.MakeSharedLibrary
else
Linker^.MakeExecutable;
end;
end;
end;
end.
{
$Log$
Revision 1.159 1999-10-12 21:20:45 florian
Revision 1.160 1999-10-21 14:29:37 peter
* redesigned linker object
+ library support for linux (only procedures can be exported)
Revision 1.159 1999/10/12 21:20:45 florian
* new codegenerator compiles again
Revision 1.158 1999/10/03 19:44:42 peter

View File

@ -31,7 +31,9 @@ type
TScript=object
fn : string[80];
data : TStringQueue;
executable : boolean;
constructor Init(const s:string);
constructor InitExec(const s:string);
destructor Done;
procedure AddStart(const s:string);
procedure Add(const s:string);
@ -39,18 +41,24 @@ type
procedure WriteToDisk;virtual;
end;
PAsmScript = ^TAsmScript;
TAsmScript = Object (TScript)
Constructor Init (Const ScriptName : String);
Procedure AddAsmCommand (Const Command, Options,FileName : String);
Procedure AddLinkCommand (Const Command, Options, FileName : String);
Procedure AddDeleteCommand (Const FileName : String);
Procedure WriteToDisk;virtual;
end;
PAsmScript = ^TAsmScript;
end;
PLinkRes = ^TLinkRes;
TLinkRes = Object (TScript)
procedure Add(const s:string);
procedure AddFileName(const s:string);
end;
{ Asm response file }
var
AsmRes : TAsmScript;
LinkRes : TLinkRes;
implementation
@ -67,8 +75,17 @@ uses
****************************************************************************}
constructor TScript.Init(const s:string);
begin
fn:=FixFileName(s);
executable:=false;
data.Init;
end;
constructor TScript.InitExec(const s:string);
begin
fn:=FixFileName(s)+source_os.scriptext;
executable:=true;
data.Init;
end;
@ -107,7 +124,8 @@ begin
Writeln(t,data.Get);
Close(t);
{$ifdef linux}
ChMod(fn,493);
if executable then
ChMod(fn,493);
{$endif}
end;
@ -118,7 +136,7 @@ end;
Constructor TAsmScript.Init (Const ScriptName : String);
begin
Inherited Init(ScriptName);
Inherited InitExec(ScriptName);
end;
@ -188,14 +206,39 @@ Begin
Add('echo An error occured while linking %THEFILE%');
Add(':end');
{$endif}
TScript.WriteToDisk;
inherited WriteToDisk;
end;
{****************************************************************************
Link Response
****************************************************************************}
procedure TLinkRes.Add(const s:string);
begin
if s<>'' then
inherited Add(s);
end;
procedure TLinkRes.AddFileName(const s:string);
begin
if s<>'' then
begin
if not(s[1] in ['a'..'z','A'..'Z','/','\','.']) then
inherited Add('.'+DirSep+s)
else
inherited Add(s);
end;
end;
end.
{
$Log$
Revision 1.2 1998-05-04 17:54:29 peter
Revision 1.3 1999-10-21 14:29:37 peter
* redesigned linker object
+ library support for linux (only procedures can be exported)
Revision 1.2 1998/05/04 17:54:29 peter
+ smartlinking works (only case jumptable left todo)
* redesign of systems.pas to support assemblers and linkers
+ Unitname is now also in the PPU-file, increased version to 14

View File

@ -96,20 +96,6 @@ unit systems;
as_i386_dbg,as_i386_coff,as_i386_pecoff
];
type
tlink = (link_none
,link_i386_ld,link_i386_ldgo32v1,
link_i386_ldgo32v2,link_i386_ldw,
link_i386_ldos2
,link_m68k_ld,link_alpha_ld,link_powerpc_ld
);
const
{$ifdef i386} i386linkcnt=5; {$else} i386linkcnt=0; {$endif}
{$ifdef m68k} m68klinkcnt=1; {$else} m68klinkcnt=0; {$endif}
{$ifdef alpha} alphalinkcnt=1; {$else} alphalinkcnt=0; {$endif}
{$ifdef powerpc} powerpclinkcnt=1; {$else} powerpclinkcnt=0; {$endif}
linkcnt=i386linkcnt+m68klinkcnt+alphalinkcnt+powerpclinkcnt+1;
type
tar = (ar_none
,ar_i386_ar,ar_i386_arw
@ -149,9 +135,9 @@ unit systems;
type
tosinfo = packed record
id : tos;
name : string[30];
shortname : string[8];
id : tos;
name : string[30];
shortname : string[8];
sharedlibext : string[10];
staticlibext,
sourceext,
@ -171,7 +157,7 @@ unit systems;
end;
tasminfo = packed record
id : tasm;
id : tasm;
idtxt : string[8];
asmbin : string[8];
asmcmd : string[50];
@ -183,24 +169,6 @@ unit systems;
secnames : array[tsection] of string[20];
end;
tlinkinfo = packed record
id : tlink;
linkbin : string[8];
linkcmd : string[127];
binders : word;
bindbin : array[1..2]of string[8];
bindcmd : array[1..2]of string[127];
stripopt : string[2];
stripbind : boolean; { Strip symbols in binder? }
libpathprefix : string[13];
libpathsuffix : string[2];
groupstart : string[8];
groupend : string[2];
inputstart : string[8];
inputend : string[2];
libprefix : string[2];
end;
tarinfo = packed record
id : tar;
arbin : string[8];
@ -229,7 +197,6 @@ unit systems;
resobjext,
exeext : string[4];
os : tos;
link : tlink;
assem : tasm;
assemsrc : tasm; { default source writing assembler }
ar : tar;
@ -249,7 +216,6 @@ unit systems;
target_info : ttargetinfo;
target_os : tosinfo;
target_asm : tasminfo;
target_link : tlinkinfo;
target_ar : tarinfo;
target_res : tresinfo;
target_path : string[12]; { for rtl/<X>/,fcl/<X>/, etc. }
@ -257,7 +223,6 @@ unit systems;
function set_target_os(t:tos):boolean;
function set_target_asm(t:tasm):boolean;
function set_target_link(t:tlink):boolean;
function set_target_ar(t:tar):boolean;
function set_target_res(t:tres):boolean;
function set_target_info(t:ttarget):boolean;
@ -828,162 +793,6 @@ implementation
);
{****************************************************************************
Linker Info
****************************************************************************}
link_infos : array[1..linkcnt] of tlinkinfo = (
(
id : link_none
)
{$ifdef i386}
,(
id : link_i386_ld;
linkbin : 'ld';
linkcmd : '$OPT -o $EXE $RES';
binders : 0;
bindbin : ('','');
bindcmd : ('','');
stripopt : '-s';
stripbind : false;
libpathprefix : 'SEARCH_DIR(';
libpathsuffix : ')';
groupstart : 'GROUP(';
groupend : ')';
inputstart : 'INPUT(';
inputend : ')';
libprefix : '-l'
)
,(
id : link_i386_ldgo32v1;
linkbin : 'ld';
linkcmd : '-oformat coff-go32 $OPT -o $EXE @$RES';
binders : 1;
bindbin : ('aout2exe','');
bindcmd : ('$EXE','');
stripopt : '-s';
stripbind : false;
libpathprefix : '-L';
libpathsuffix : '';
groupstart : '-(';
groupend : '-)';
inputstart : '';
inputend : '';
libprefix : '-l'
)
,(
id : link_i386_ldgo32v2;
linkbin : 'ld';
linkcmd : '-oformat coff-go32-exe $OPT -o $EXE @$RES';
binders:0;
bindbin : ('','');
bindcmd : ('','');
stripopt : '-s';
stripbind : false;
libpathprefix : '-L';
libpathsuffix : '';
groupstart : '-(';
groupend : '-)';
inputstart : '';
inputend : '';
libprefix : '-l'
)
,(
id : link_i386_ldw;
linkbin : 'ldw';
linkcmd : '$OPT -o $EXE $RES';
binders : 0;
bindbin : ('dlltool','ldw');
bindcmd : ('--as asw.exe --dllname $EXE --output-exp exp.$$$',
'$OPT -o $EXE $RES exp.$$$');
stripopt : '-s';
stripbind : false;
libpathprefix : 'SEARCH_DIR(';
libpathsuffix : ')';
groupstart : 'GROUP(';
groupend : ')';
inputstart : 'INPUT(';
inputend : ')';
libprefix : '-l'
)
,(
id : link_i386_ldos2;
linkbin : 'ld'; { Os/2 }
linkcmd : '-o $EXE @$RES';
binders : 1;
bindbin : ('emxbind','');
bindcmd : ('-b $STRIP$PM -k$STACKKB -h$HEAPMB -o $EXE.exe $EXE -aim -s$DOSHEAPKB',
'');
stripopt : '-s';
stripbind : true;
libpathprefix : '-L';
libpathsuffix : '';
groupstart : ''; {Linker is too primitive...}
groupend : '';
inputstart : '';
inputend : '';
libprefix : '-l'
)
{$endif i386}
{$ifdef m68k}
,(
id : link_m68k_ld;
linkbin : 'ld';
linkcmd : '$OPT -o $EXE $RES';
binders:0;
bindbin : ('','');
bindcmd : ('','');
stripopt : '-s';
stripbind : false;
libpathprefix : 'SEARCH_DIR(';
libpathsuffix : ')';
groupstart : 'GROUP(';
groupend : ')';
inputstart : 'INPUT(';
inputend : ')';
libprefix : '-l'
)
{$endif m68k}
{$ifdef alpha}
,(
id : link_alpha_ld;
linkbin : 'ld';
linkcmd : '$OPT -o $EXE $RES';
binders : 0;
bindbin : ('','');
bindcmd : ('','');
stripopt : '-s';
stripbind : false;
libpathprefix : 'SEARCH_DIR(';
libpathsuffix : ')';
groupstart : 'GROUP(';
groupend : ')';
inputstart : 'INPUT(';
inputend : ')';
libprefix : '-l'
)
{$endif}
{$ifdef powerpc}
,(
id : link_powerpc_ld;
linkbin : 'ld';
linkcmd : '$OPT -o $EXE $RES';
binders : 0;
bindbin : ('','');
bindcmd : ('','');
stripopt : '-s';
stripbind : false;
libpathprefix : 'SEARCH_DIR(';
libpathsuffix : ')';
groupstart : 'GROUP(';
groupend : ')';
inputstart : 'INPUT(';
inputend : ')';
libprefix : '-l'
)
{$endif}
);
{****************************************************************************
Ar Info
****************************************************************************}
@ -1071,7 +880,6 @@ implementation
resobjext : '.o1r';
exeext : ''; { The linker produces a.out }
os : os_i386_GO32V1;
link : link_i386_ldgo32v1;
assem : as_i386_as;
assemsrc : as_i386_as;
ar : ar_i386_ar;
@ -1096,7 +904,6 @@ implementation
resobjext : '.or';
exeext : '.exe';
os : os_i386_GO32V2;
link : link_i386_ldgo32v2;
assem : as_i386_coff;
assemsrc : as_i386_as;
ar : ar_i386_ar;
@ -1121,7 +928,6 @@ implementation
resobjext : '.or';
exeext : '';
os : os_i386_Linux;
link : link_i386_ld;
assem : as_i386_as;
assemsrc : as_i386_as;
ar : ar_i386_ar;
@ -1146,7 +952,6 @@ implementation
resobjext : '.oor';
exeext : ''; { The linker produces a.out }
os : os_i386_OS2;
link : link_i386_ldos2;
assem : as_i386_as_aout;
assemsrc : as_i386_as_aout;
ar : ar_i386_ar;
@ -1171,7 +976,6 @@ implementation
resobjext : '.owr';
exeext : '.exe';
os : os_i386_Win32;
link : link_i386_ldw;
assem : as_i386_pecoff;
assemsrc : as_i386_asw;
ar : ar_i386_arw;
@ -1198,7 +1002,6 @@ implementation
resobjext : '.or';
exeext : '';
os : os_m68k_Amiga;
link : link_m68k_ld;
assem : as_m68k_as;
assemsrc : as_m68k_as;
ar : ar_m68k_ar;
@ -1223,7 +1026,6 @@ implementation
resobjext : '.or';
exeext : '.ttp';
os : os_m68k_Atari;
link : link_m68k_ld;
assem : as_m68k_as;
assemsrc : as_m68k_as;
ar : ar_m68k_ar;
@ -1248,7 +1050,6 @@ implementation
resobjext : '.or';
exeext : '';
os : os_m68k_Mac;
link : link_m68k_ld;
assem : as_m68k_mpw;
assemsrc : as_m68k_mpw;
ar : ar_m68k_ar;
@ -1273,7 +1074,6 @@ implementation
resobjext : '.or';
exeext : '';
os : os_m68k_Linux;
link : link_m68k_ld;
assem : as_m68k_as;
assemsrc : as_m68k_as;
ar : ar_m68k_ar;
@ -1298,7 +1098,6 @@ implementation
resobjext : '.or';
exeext : '';
os : os_m68k_PalmOS;
link : link_m68k_ld;
assem : as_m68k_as;
assemsrc : as_m68k_as;
ar : ar_m68k_ar;
@ -1325,7 +1124,6 @@ implementation
resobjext : '.or';
exeext : '';
os : os_alpha_Linux;
link : link_alpha_ld;
assem : as_alpha_as;
assemsrc : as_alpha_as;
ar : ar_alpha_ar;
@ -1352,7 +1150,6 @@ implementation
resobjext : '.or';
exeext : '';
os : os_powerpc_Linux;
link : link_powerpc_ld;
assem : as_powerpc_as;
assemsrc : as_powerpc_as;
ar : ar_powerpc_ar;
@ -1482,21 +1279,6 @@ begin
end;
function set_target_link(t:tlink):boolean;
var
i : longint;
begin
set_target_link:=false;
for i:=1 to linkcnt do
if link_infos[i].id=t then
begin
target_link:=link_infos[i];
set_target_link:=true;
exit;
end;
end;
function set_target_ar(t:tar):boolean;
var
i : longint;
@ -1538,7 +1320,6 @@ begin
target_info:=target_infos[i];
set_target_os(target_info.os);
set_target_asm(target_info.assem);
set_target_link(target_info.link);
set_target_ar(target_info.ar);
set_target_res(target_info.res);
target_path:=lower(target_info.short_name);
@ -1734,7 +1515,11 @@ begin
end.
{
$Log$
Revision 1.94 1999-09-15 22:09:27 florian
Revision 1.95 1999-10-21 14:29:37 peter
* redesigned linker object
+ library support for linux (only procedures can be exported)
Revision 1.94 1999/09/15 22:09:27 florian
+ rtti is now automatically generated for published classes, i.e.
they are handled like an implicit property

194
compiler/t_go32v1.pas Normal file
View File

@ -0,0 +1,194 @@
{
$Id$
Copyright (c) 1999 by Peter Vreman
This unit implements support import,export,link routines
for the (i386) go32v1 target
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit t_go32v1;
interface
uses
link;
type
plinkergo32v1=^tlinkergo32v1;
tlinkergo32v1=object(tlinker)
private
Function WriteResponseFile(isdll:boolean) : Boolean;
public
constructor Init;
procedure SetDefaultInfo;virtual;
function MakeExecutable:boolean;virtual;
end;
implementation
uses
globtype,globals,cobjects,systems,verbose,script,files;
{****************************************************************************
TLinkergo32v1
****************************************************************************}
Constructor TLinkergo32v1.Init;
begin
Inherited Init;
{ allow duplicated libs (PM) }
SharedLibFiles.doubles:=true;
StaticLibFiles.doubles:=true;
end;
procedure TLinkergo32v1.SetDefaultInfo;
begin
with Info do
begin
ExeCmd[1]:='ld -oformat coff-go32 $OPT $STRIP -o $EXE @$RES';
ExeCmd[2]:='aout2exe $EXE';
end;
end;
Function TLinkergo32v1.WriteResponseFile(isdll:boolean) : Boolean;
Var
linkres : TLinkRes;
i : longint;
s,s2 : string;
linklibc : boolean;
begin
WriteResponseFile:=False;
{ Open link.res file }
LinkRes.Init(Info.ResName);
{ Write path to search libraries }
if assigned(current_module^.locallibrarysearchpath) then
begin
S:=current_module^.locallibrarysearchpath^;
while s<>'' do
begin
s2:=GetPathFromList(s);
LinkRes.Add('-L'+s2);
end;
end;
S:=LibrarySearchPath;
while s<>'' do
begin
s2:=GetPathFromList(s);
LinkRes.Add('-L'+s2);
end;
{ add objectfiles, start with prt0 always }
LinkRes.AddFileName(FindObjectFile('prt0'));
while not ObjectFiles.Empty do
begin
s:=ObjectFiles.Get;
if s<>'' then
LinkRes.AddFileName(s);
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) }
While not SharedLibFiles.Empty do
begin
S:=SharedLibFiles.Get;
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&libgcc is the last lib }
if linklibc then
begin
LinkRes.Add('-lc');
LinkRes.Add('-lgcc');
end;
{ Write staticlibraries }
if not StaticLibFiles.Empty then
begin
LinkRes.Add('-(');
While not StaticLibFiles.Empty do
begin
S:=StaticLibFiles.Get;
LinkRes.AddFileName(s)
end;
LinkRes.Add('-)');
end;
{ Write and Close response }
linkres.writetodisk;
linkres.done;
WriteResponseFile:=True;
end;
function TLinkergo32v1.MakeExecutable:boolean;
var
binstr,
cmdstr : string;
success : boolean;
StripStr : string[40];
begin
if not(cs_link_extern in aktglobalswitches) then
Message1(exec_i_linking,current_module^.exefilename^);
{ Create some replacements }
StripStr:='';
if (cs_link_strip in aktglobalswitches) then
StripStr:='-s';
{ Write used files and libraries }
WriteResponseFile(false);
{ Call linker }
SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
Replace(cmdstr,'$EXE',current_module^.exefilename^);
Replace(cmdstr,'$OPT',Info.ExtraOptions);
Replace(cmdstr,'$RES',current_module^.outpath^+Info.ResName);
Replace(cmdstr,'$STRIP',StripStr);
success:=DoExec(FindUtil(BinStr),cmdstr,true,false);
{ Remove ReponseFile }
if (success) and not(cs_link_extern in aktglobalswitches) then
RemoveFile(current_module^.outpath^+Info.ResName);
MakeExecutable:=success; { otherwise a recursive call to link method }
end;
end.
{
$Log$
Revision 1.1 1999-10-21 14:29:38 peter
* redesigned linker object
+ library support for linux (only procedures can be exported)
}

296
compiler/t_go32v2.pas Normal file
View File

@ -0,0 +1,296 @@
{
$Id$
Copyright (c) 1999 by Peter Vreman
This unit implements support import,export,link routines
for the (i386) Go32v2 target
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit t_go32v2;
interface
uses
link;
type
plinkergo32v2=^tlinkergo32v2;
tlinkergo32v2=object(tlinker)
private
Function WriteResponseFile(isdll:boolean) : Boolean;
public
constructor Init;
procedure SetDefaultInfo;virtual;
function MakeExecutable:boolean;virtual;
end;
implementation
uses
strings,globtype,globals,cobjects,systems,verbose,script,files;
{****************************************************************************
TLinkerGo32v2
****************************************************************************}
Constructor TLinkerGo32v2.Init;
begin
Inherited Init;
{ allow duplicated libs (PM) }
SharedLibFiles.doubles:=true;
StaticLibFiles.doubles:=true;
end;
procedure TLinkerGo32v2.SetDefaultInfo;
begin
with Info do
begin
ExeCmd[1]:='ld -oformat coff-go32-exe $OPT $STRIP -o $EXE @$RES';
end;
end;
Function TLinkerGo32v2.WriteResponseFile(isdll:boolean) : Boolean;
Var
linkres : TLinkRes;
i : longint;
s,s2 : string;
linklibc : boolean;
begin
WriteResponseFile:=False;
{ Open link.res file }
LinkRes.Init(Info.ResName);
{ Write path to search libraries }
if assigned(current_module^.locallibrarysearchpath) then
begin
S:=current_module^.locallibrarysearchpath^;
while s<>'' do
begin
s2:=GetPathFromList(s);
LinkRes.Add('-L'+s2);
end;
end;
S:=LibrarySearchPath;
while s<>'' do
begin
s2:=GetPathFromList(s);
LinkRes.Add('-L'+s2);
end;
{ add objectfiles, start with prt0 always }
LinkRes.AddFileName(FindObjectFile('prt0'));
while not ObjectFiles.Empty do
begin
s:=ObjectFiles.Get;
if s<>'' then
LinkRes.AddFileName(s);
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) }
While not SharedLibFiles.Empty do
begin
S:=SharedLibFiles.Get;
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&libgcc is the last lib }
if linklibc then
begin
LinkRes.Add('-lc');
LinkRes.Add('-lgcc');
end;
{ Write staticlibraries }
if not StaticLibFiles.Empty then
begin
LinkRes.Add('-(');
While not StaticLibFiles.Empty do
begin
S:=StaticLibFiles.Get;
LinkRes.AddFileName(s)
end;
LinkRes.Add('-)');
end;
{ Write and Close response }
linkres.writetodisk;
linkres.done;
WriteResponseFile:=True;
end;
function TLinkerGo32v2.MakeExecutable:boolean;
var
binstr,
cmdstr : string;
success : boolean;
StripStr : string[40];
begin
if not(cs_link_extern in aktglobalswitches) then
Message1(exec_i_linking,current_module^.exefilename^);
{ Create some replacements }
StripStr:='';
if (cs_link_strip in aktglobalswitches) then
StripStr:='-s';
{ Write used files and libraries }
WriteResponseFile(false);
{ Call linker }
SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
Replace(cmdstr,'$EXE',current_module^.exefilename^);
Replace(cmdstr,'$OPT',Info.ExtraOptions);
Replace(cmdstr,'$RES',current_module^.outpath^+Info.ResName);
Replace(cmdstr,'$STRIP',StripStr);
success:=DoExec(FindUtil(BinStr),cmdstr,true,false);
{ Remove ReponseFile }
if (success) and not(cs_link_extern in aktglobalswitches) then
RemoveFile(current_module^.outpath^+Info.ResName);
MakeExecutable:=success; { otherwise a recursive call to link method }
end;
{$ifdef notnecessary}
procedure tlinkergo32v2.postprocessexecutable(const n : string);
type
tcoffheader=packed record
mach : word;
nsects : word;
time : longint;
sympos : longint;
syms : longint;
opthdr : word;
flag : word;
end;
tcoffsechdr=packed record
name : array[0..7] of char;
vsize : longint;
rvaofs : longint;
datalen : longint;
datapos : longint;
relocpos : longint;
lineno1 : longint;
nrelocs : word;
lineno2 : word;
flags : longint;
end;
psecfill=^tsecfill;
tsecfill=record
fillpos,
fillsize : longint;
next : psecfill;
end;
var
f : file;
coffheader : tcoffheader;
firstsecpos,
maxfillsize,
l : longint;
coffsec : tcoffsechdr;
secroot,hsecroot : psecfill;
zerobuf : pointer;
begin
{ when -s is used quit, because there is no .exe }
if cs_link_extern in aktglobalswitches then
exit;
{ open file }
assign(f,n);
{$I-}
reset(f,1);
if ioresult<>0 then
Message1(execinfo_f_cant_open_executable,n);
{ read headers }
seek(f,2048);
blockread(f,coffheader,sizeof(tcoffheader));
{ read section info }
maxfillsize:=0;
firstsecpos:=0;
secroot:=nil;
for l:=1to coffheader.nSects do
begin
blockread(f,coffsec,sizeof(tcoffsechdr));
if coffsec.datapos>0 then
begin
if secroot=nil then
firstsecpos:=coffsec.datapos;
new(hsecroot);
hsecroot^.fillpos:=coffsec.datapos+coffsec.vsize;
hsecroot^.fillsize:=coffsec.datalen-coffsec.vsize;
hsecroot^.next:=secroot;
secroot:=hsecroot;
if secroot^.fillsize>maxfillsize then
maxfillsize:=secroot^.fillsize;
end;
end;
if firstsecpos>0 then
begin
l:=firstsecpos-filepos(f);
if l>maxfillsize then
maxfillsize:=l;
end
else
l:=0;
{ get zero buffer }
getmem(zerobuf,maxfillsize);
fillchar(zerobuf^,maxfillsize,0);
{ zero from sectioninfo until first section }
blockwrite(f,zerobuf^,l);
{ zero section alignments }
while assigned(secroot) do
begin
seek(f,secroot^.fillpos);
blockwrite(f,zerobuf^,secroot^.fillsize);
hsecroot:=secroot;
secroot:=secroot^.next;
dispose(hsecroot);
end;
freemem(zerobuf,maxfillsize);
close(f);
{$I+}
i:=ioresult;
postprocessexecutable:=true;
end;
{$endif}
end.
{
$Log$
Revision 1.1 1999-10-21 14:29:38 peter
* redesigned linker object
+ library support for linux (only procedures can be exported)
}

441
compiler/t_linux.pas Normal file
View File

@ -0,0 +1,441 @@
{
$Id$
Copyright (c) 1999 by Peter Vreman
This unit implements support import,export,link routines
for the (i386) Linux target
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit t_linux;
interface
uses
import,export,link;
type
pimportliblinux=^timportliblinux;
timportliblinux=object(timportlib)
procedure preparelib(const s:string);virtual;
procedure importprocedure(const func,module:string;index:longint;const name:string);virtual;
procedure importvariable(const varname,module:string;const name:string);virtual;
procedure generatelib;virtual;
end;
pexportliblinux=^texportliblinux;
texportliblinux=object(texportlib)
procedure preparelib(const s : string);virtual;
procedure exportprocedure(hp : pexported_item);virtual;
procedure exportvar(hp : pexported_item);virtual;
procedure generatelib;virtual;
end;
plinkerlinux=^tlinkerlinux;
tlinkerlinux=object(tlinker)
private
Glibc2,
Glibc21 : boolean;
Function WriteResponseFile(isdll:boolean) : Boolean;
public
constructor Init;
procedure SetDefaultInfo;virtual;
function MakeExecutable:boolean;virtual;
function MakeSharedLibrary:boolean;virtual;
end;
implementation
uses
verbose,strings,cobjects,systems,globtype,globals,
symconst,script,
files,aasm,cpuasm,cpubase,symtable;
{*****************************************************************************
TIMPORTLIBLINUX
*****************************************************************************}
procedure timportliblinux.preparelib(const s : string);
begin
end;
procedure timportliblinux.importprocedure(const func,module : string;index : longint;const name : string);
begin
{ insert sharedlibrary }
current_module^.linkothersharedlibs.insert(SplitName(module),link_allways);
{ do nothing with the procedure, only set the mangledname }
if name<>'' then
aktprocsym^.definition^.setmangledname(name)
else
Message(parser_e_empty_import_name);
end;
procedure timportliblinux.importvariable(const varname,module:string;const name:string);
begin
{ insert sharedlibrary }
current_module^.linkothersharedlibs.insert(SplitName(module),link_allways);
{ reset the mangledname and turn off the dll_var option }
aktvarsym^.setmangledname(name);
{$ifdef INCLUDEOK}
exclude(aktvarsym^.varoptions,vo_is_dll_var);
{$else}
aktvarsym^.varoptions:=aktvarsym^.varoptions-[vo_is_dll_var];
{$endif}
end;
procedure timportliblinux.generatelib;
begin
end;
{*****************************************************************************
TEXPORTLIBLINUX
*****************************************************************************}
procedure texportliblinux.preparelib(const s:string);
begin
end;
procedure texportliblinux.exportprocedure(hp : pexported_item);
var
hp2 : pexported_item;
begin
{ first test the index value }
if (hp^.options and eo_index)<>0 then
begin
Comment(V_Error,'can''t export with index under linux');
exit;
end;
{ use pascal name is none specified }
if (hp^.options and eo_name)=0 then
begin
hp^.name:=stringdup(hp^.sym^.name);
hp^.options:=hp^.options or eo_name;
end;
{ now place in correct order }
hp2:=pexported_item(current_module^._exports^.first);
while assigned(hp2) and
(hp^.name^>hp2^.name^) do
hp2:=pexported_item(hp2^.next);
{ insert hp there !! }
if assigned(hp2) and (hp2^.name^=hp^.name^) then
begin
{ this is not allowed !! }
Message1(parser_e_export_name_double,hp^.name^);
exit;
end;
if hp2=pexported_item(current_module^._exports^.first) then
current_module^._exports^.insert(hp)
else if assigned(hp2) then
begin
hp^.next:=hp2;
hp^.previous:=hp2^.previous;
if assigned(hp2^.previous) then
hp2^.previous^.next:=hp;
hp2^.previous:=hp;
end
else
current_module^._exports^.concat(hp);
end;
procedure texportliblinux.exportvar(hp : pexported_item);
begin
hp^.is_var:=true;
exportprocedure(hp);
end;
procedure texportliblinux.generatelib;
var
hp2 : pexported_item;
begin
hp2:=pexported_item(current_module^._exports^.first);
while assigned(hp2) do
begin
if not hp2^.is_var then
begin
{ place jump in codesegment }
codesegment^.concat(new(pai_align,init_op(4,$90)));
codesegment^.concat(new(pai_symbol,initname_global(hp2^.name^,0)));
codesegment^.concat(new(paicpu,op_sym(A_JMP,S_NO,newasmsymbol(hp2^.sym^.mangledname))));
codesegment^.concat(new(pai_symbol_end,initname(hp2^.name^)));
end
else
Comment(V_Error,'Exporting of variables is not supported under linux');
hp2:=pexported_item(hp2^.next);
end;
end;
{*****************************************************************************
TLINKERLINUX
*****************************************************************************}
Constructor TLinkerLinux.Init;
begin
Inherited Init;
AddPathToList(LibrarySearchPath,'/lib;/usr/lib;/usr/X11R6/lib',true);
end;
procedure TLinkerLinux.SetDefaultInfo;
{
This will also detect which libc version will be used
}
begin
Glibc2:=false;
Glibc21:=false;
with Info do
begin
ExeCmd[1]:='ld $OPT $DYNLINK $STRIP -L. -o $EXE $RES';
DllCmd[1]:='ld $OPT -shared -L. -o $EXE $RES';
DllCmd[2]:='strip --strip-unneeded $EXE';
{ first try glibc2 }
DynamicLinker:='/lib/ld-linux.so.2';
if FileExists(DynamicLinker) then
begin
Glibc2:=true;
{ also glibc 2.1 / 2.1.1 / 2.1.2 ? }
if FileExists('/lib/ld-2.1.so') or
FileExists('/lib/ld-2.1.1.so') or
FileExists('/lib/ld-2.1.2.so') then
Glibc21:=true;
end
else
DynamicLinker:='/lib/ld-linux.so.1';
end;
end;
Function TLinkerLinux.WriteResponseFile(isdll:boolean) : Boolean;
Var
linkres : TLinkRes;
i : longint;
cprtobj,
gprtobj,
prtobj : string[80];
s,s2 : string;
found,
linkdynamic,
linklibc : boolean;
begin
WriteResponseFile:=False;
{ set special options for some targets }
linkdynamic:=not(SharedLibFiles.empty);
linklibc:=SharedLibFiles.Find('c');
prtobj:='prt0';
cprtobj:='cprt0';
gprtobj:='gprt0';
if glibc21 then
begin
cprtobj:='cprt21';
gprtobj:='gprt21';
end;
if cs_profile in aktmoduleswitches then
begin
prtobj:=gprtobj;
if not glibc2 then
AddSharedLibrary('gmon');
AddSharedLibrary('c');
linklibc:=true;
end
else
begin
if linklibc then
prtobj:=cprtobj;
end;
{ Open link.res file }
LinkRes.Init(Info.ResName);
{ Write path to search libraries }
if assigned(current_module^.locallibrarysearchpath) then
begin
S:=current_module^.locallibrarysearchpath^;
while s<>'' do
begin
s2:=GetPathFromList(s);
LinkRes.Add('SEARCH_DIR('+s2+')');
end;
end;
S:=LibrarySearchPath;
while s<>'' do
begin
s2:=GetPathFromList(s);
LinkRes.Add('SEARCH_DIR('+s2+')');
end;
LinkRes.Add('INPUT(');
{ add objectfiles, start with prt0 always }
if prtobj<>'' then
LinkRes.AddFileName(FindObjectFile(prtobj));
{ try to add crti and crtbegin, they are normally not required, but
adding can sometimes be usefull }
s:=search('crtbegin.o',librarysearchpath,found)+'crtbegin.o';
if found then
LinkRes.AddFileName(s);
s:=search('crti.o',librarysearchpath,found)+'crti.o';
if found then
LinkRes.AddFileName(s);
{ main objectfiles }
while not ObjectFiles.Empty do
begin
s:=ObjectFiles.Get;
if s<>'' then
LinkRes.AddFileName(s);
end;
{ objects which must be at the end }
s:=search('crtend.o',librarysearchpath,found)+'crtend.o';
if found then
LinkRes.AddFileName(s);
s:=search('crtn.o',librarysearchpath,found)+'crtn.o';
if found then
LinkRes.AddFileName(s);
{ 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) }
While not SharedLibFiles.Empty do
begin
S:=SharedLibFiles.Get;
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
linklibc:=true;
linkdynamic:=false; { libc will include the ld-linux for us }
end;
end;
{ be sure that libc is the last lib }
if linklibc then
LinkRes.Add('-lc');
if linkdynamic and (Info.DynamicLinker<>'') then
LinkRes.AddFileName(Info.DynamicLinker);
LinkRes.Add(')');
{ Write staticlibraries }
if not StaticLibFiles.Empty then
begin
LinkRes.Add('GROUP(');
While not StaticLibFiles.Empty do
begin
S:=StaticLibFiles.Get;
LinkRes.AddFileName(s)
end;
LinkRes.Add(')');
end;
{ Write and Close response }
linkres.writetodisk;
linkres.done;
WriteResponseFile:=True;
end;
function TLinkerLinux.MakeExecutable:boolean;
var
binstr,
cmdstr : string;
success : boolean;
DynLinkStr : string[60];
StripStr : string[40];
begin
if not(cs_link_extern in aktglobalswitches) then
Message1(exec_i_linking,current_module^.exefilename^);
{ Create some replacements }
StripStr:='';
DynLinkStr:='';
if (cs_link_strip in aktglobalswitches) then
StripStr:='-s';
If (Info.DynamicLinker<>'') and (not SharedLibFiles.Empty) then
DynLinkStr:='-dynamic-linker='+Info.DynamicLinker;
{ Write used files and libraries }
WriteResponseFile(false);
{ Call linker }
SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
Replace(cmdstr,'$EXE',current_module^.exefilename^);
Replace(cmdstr,'$OPT',Info.ExtraOptions);
Replace(cmdstr,'$RES',current_module^.outpath^+Info.ResName);
Replace(cmdstr,'$STRIP',StripStr);
Replace(cmdstr,'$DYNLINK',DynLinkStr);
success:=DoExec(FindUtil(BinStr),CmdStr,true,false);
{ Remove ReponseFile }
if (success) and not(cs_link_extern in aktglobalswitches) then
RemoveFile(current_module^.outpath^+Info.ResName);
MakeExecutable:=success; { otherwise a recursive call to link method }
end;
Function TLinkerLinux.MakeSharedLibrary:boolean;
var
binstr,
cmdstr : string;
success : boolean;
begin
MakeSharedLibrary:=false;
if not(cs_link_extern in aktglobalswitches) then
Message1(exec_i_linking,current_module^.sharedlibfilename^);
{ Write used files and libraries }
WriteResponseFile(true);
{ Call linker }
SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
Replace(cmdstr,'$EXE',current_module^.sharedlibfilename^);
Replace(cmdstr,'$OPT',Info.ExtraOptions);
Replace(cmdstr,'$RES',current_module^.outpath^+Info.ResName);
success:=DoExec(FindUtil(binstr),cmdstr,true,false);
{ Strip the library ? }
if success and (cs_link_strip in aktglobalswitches) then
begin
SplitBinCmd(Info.DllCmd[2],binstr,cmdstr);
Replace(cmdstr,'$EXE',current_module^.sharedlibfilename^);
success:=DoExec(FindUtil(binstr),cmdstr,true,false);
end;
{ Remove ReponseFile }
if (success) and not(cs_link_extern in aktglobalswitches) then
RemoveFile(current_module^.outpath^+Info.ResName);
MakeSharedLibrary:=success; { otherwise a recursive call to link method }
end;
end.
{
$Log$
Revision 1.1 1999-10-21 14:29:38 peter
* redesigned linker object
+ library support for linux (only procedures can be exported)
}

View File

@ -28,10 +28,11 @@
port, please send questions to Daniel Mantione
<d.s.p.mantione@twi.tudelft.nl>.
}
unit os2_targ;
unit t_os2;
interface
uses import;
uses
import,link;
type
pimportlibos2=^timportlibos2;
@ -41,6 +42,17 @@ type
procedure generatelib;virtual;
end;
plinkeros2=^tlinkeros2;
tlinkeros2=object(tlinker)
private
Function WriteResponseFile(isdll:boolean) : Boolean;
public
constructor Init;
procedure SetDefaultInfo;virtual;
function MakeExecutable:boolean;virtual;
end;
{***************************************************************************}
{***************************************************************************}
@ -53,8 +65,8 @@ implementation
{$else Delphi}
dos,
{$endif Delphi}
globtype,strings,comphook,
globals,link,files;
globtype,strings,comphook,systems,
globals,verbose,files,script;
const profile_flag:boolean=false;
@ -331,49 +343,155 @@ begin
end;
{****************************************************************************
TLinkeros2
****************************************************************************}
Constructor TLinkeros2.Init;
begin
Inherited Init;
{ allow duplicated libs (PM) }
SharedLibFiles.doubles:=true;
StaticLibFiles.doubles:=true;
end;
procedure TLinkeros2.SetDefaultInfo;
begin
with Info do
begin
ExeCmd[1]:='ld -o $EXE @$RES';
ExeCmd[2]:='emxbind -b $STRIP$PM -k$STACKKB -h$HEAPMB -o $EXE.exe $EXE -aim -s$DOSHEAPKB';
end;
end;
Function TLinkeros2.WriteResponseFile(isdll:boolean) : Boolean;
Var
linkres : TLinkRes;
i : longint;
s,s2 : string;
begin
WriteResponseFile:=False;
{ Open link.res file }
LinkRes.Init(Info.ResName);
{ Write path to search libraries }
if assigned(current_module^.locallibrarysearchpath) then
begin
S:=current_module^.locallibrarysearchpath^;
while s<>'' do
begin
s2:=GetPathFromList(s);
LinkRes.Add('-L'+s2);
end;
end;
S:=LibrarySearchPath;
while s<>'' do
begin
s2:=GetPathFromList(s);
LinkRes.Add('-L'+s2);
end;
{ add objectfiles, start with prt0 always }
LinkRes.AddFileName(FindObjectFile('prt0'));
while not ObjectFiles.Empty do
begin
s:=ObjectFiles.Get;
if s<>'' then
LinkRes.AddFileName(s);
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) }
While not SharedLibFiles.Empty do
begin
S:=SharedLibFiles.Get;
i:=Pos(target_os.sharedlibext,S);
if i>0 then
Delete(S,i,255);
LinkRes.Add('-l'+s);
end;
{ Write staticlibraries }
if not StaticLibFiles.Empty then
begin
While not StaticLibFiles.Empty do
begin
S:=StaticLibFiles.Get;
LinkRes.AddFileName(s)
end;
end;
{ Write and Close response }
linkres.writetodisk;
linkres.done;
WriteResponseFile:=True;
end;
function TLinkeros2.MakeExecutable:boolean;
var
binstr,
cmdstr : string;
success : boolean;
i : longint;
PMStr,
StripStr : string[40];
begin
if not(cs_link_extern in aktglobalswitches) then
Message1(exec_i_linking,current_module^.exefilename^);
{ Create some replacements }
StripStr:='';
PMStr:='';
if (cs_link_strip in aktglobalswitches) then
StripStr:='-s';
if usewindowapi then
PMStr:='-p';
{ Write used files and libraries }
WriteResponseFile(false);
{ Call linker }
success:=false;
for i:=1to 2 do
begin
SplitBinCmd(Info.ExeCmd[i],binstr,cmdstr);
if binstr<>'' then
begin
Replace(cmdstr,'$EXE',current_module^.exefilename^);
Replace(cmdstr,'$OPT',Info.ExtraOptions);
Replace(cmdstr,'$RES',current_module^.outpath^+Info.ResName);
Replace(cmdstr,'$STRIP',StripStr);
Replace(cmdstr,'$HEAPMB',tostr((maxheapsize+1048575) shr 20));
{Size of the stack when an EMX program runs in OS/2.}
Replace(cmdstr,'$STACKKB',tostr((stacksize+1023) shr 10));
{When an EMX program runs in DOS, the heap and stack share the
same memory pool. The heap grows upwards, the stack grows downwards.}
Replace(cmdstr,'$DOSHEAPKB',tostr((stacksize+maxheapsize+1023) shr 10));
Replace(cmdstr,'$PM',PMStr);
success:=DoExec(FindUtil(binstr),cmdstr,(i=1),false);
if not success then
break;
end;
end;
{ Remove ReponseFile }
if (success) and not(cs_link_extern in aktglobalswitches) then
RemoveFile(current_module^.outpath^+Info.ResName);
MakeExecutable:=success; { otherwise a recursive call to link method }
end;
end.
{
$Log$
Revision 1.11 1999-09-20 16:38:59 peter
* cs_create_smart instead of cs_smartlink
* -CX is create smartlink
* -CD is create dynamic, but does nothing atm.
Revision 1.10 1999/09/07 15:05:19 pierre
* use do_halt instead of runerror
Revision 1.9 1999/07/18 10:19:58 florian
* made it compilable with Dlephi 4 again
+ fixed problem with large stack allocations on win32
Revision 1.8 1999/07/03 00:29:55 peter
* new link writing to the ppu, one .ppu is needed for all link types,
static (.o) is now always created also when smartlinking is used
Revision 1.7 1999/05/04 21:44:52 florian
* changes to compile it with Delphi 4.0
Revision 1.6 1998/12/11 00:03:25 peter
+ globtype,tokens,version unit splitted from globals
Revision 1.5 1998/10/16 14:20:53 daniel
* Faster keyword scanning.
* Import library and smartlink library in one file.
Revision 1.4 1998/06/17 14:10:14 peter
* small os2 fixes
* fixed interdependent units with newppu (remake3 under linux works now)
Revision 1.3 1998/06/04 23:51:48 peter
* m68k compiles
+ .def file creation moved to gendef.pas so it could also be used
for win32
Revision 1.2 1998/05/04 17:54:27 peter
+ smartlinking works (only case jumptable left todo)
* redesign of systems.pas to support assemblers and linkers
+ Unitname is now also in the PPU-file, increased version to 14
Revision 1.1 1999-10-21 14:29:38 peter
* redesigned linker object
+ library support for linux (only procedures can be exported)
}

View File

@ -1,9 +1,9 @@
{
$Id$
Copyright (c) 1998 by Florian Klaempfl
Copyright (c) 1999 by Peter Vreman
This unit implements some support routines for the win32 target like
import/export handling
This unit implements support import,export,link routines
for the (i386) Win32 target
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -21,7 +21,7 @@
****************************************************************************
}
unit win_targ;
unit t_win32;
interface
@ -52,14 +52,21 @@ unit win_targ;
plinkerwin32=^tlinkerwin32;
tlinkerwin32=object(tlinker)
procedure postprocessexecutable(const n : string);virtual;
private
Function WriteResponseFile(isdll:boolean) : Boolean;
Function PostProcessExecutable(const fn:string;isdll:boolean) : Boolean;
public
Procedure SetDefaultInfo;virtual;
function MakeExecutable:boolean;virtual;
function MakeSharedLibrary:boolean;virtual;
end;
implementation
uses
aasm,files,strings,globtype,globals,cobjects,systems,verbose,
aasm,files,globtype,globals,cobjects,systems,verbose,
script,gendef,
cpubase,cpuasm
{$ifdef GDB}
,gdb
@ -75,21 +82,25 @@ unit win_targ;
else
DllName:=Name+target_os.sharedlibext;
end;
procedure timportlibwin32.preparelib(const s : string);
{*****************************************************************************
TIMPORTLIBWIN32
*****************************************************************************}
procedure timportlibwin32.preparelib(const s : string);
begin
if not(assigned(importssection)) then
importssection:=new(paasmoutput,init);
end;
procedure timportlibwin32.importprocedure(const func,module : string;index : longint;const name : string);
var
hp1 : pimportlist;
hp2 : pimported_item;
hs : string;
begin
{ that IS wrong for DRV files
hs:=SplitName(module); }
hs:=DllName(module);
{ search for the module }
hp1:=pimportlist(current_module^.imports^.first);
@ -366,8 +377,12 @@ unit win_targ;
end;
end;
procedure texportlibwin32.preparelib(const s:string);
{*****************************************************************************
TEXPORTLIBWIN32
*****************************************************************************}
procedure texportlibwin32.preparelib(const s:string);
begin
if not(assigned(exportssection)) then
exportssection:=new(paasmoutput,init);
@ -384,22 +399,27 @@ unit win_targ;
procedure texportlibwin32.exportprocedure(hp : pexported_item);
{ must be ordered at least for win32 !! }
var hp2 : pexported_item;
begin
hp2:=pexported_item(current_module^._exports^.first);
var
hp2 : pexported_item;
begin
{ first test the index value }
if (hp^.options and eo_index)<>0 then
begin
if (hp^.index<=0) or (hp^.index>$ffff) then
message1(parser_e_export_invalid_index,tostr(hp^.index))
else while assigned(hp2) do
begin
message1(parser_e_export_invalid_index,tostr(hp^.index));
exit;
end;
hp2:=pexported_item(current_module^._exports^.first);
while assigned(hp2) do
begin
if (hp^.index=hp2^.index) then
if ((hp2^.options and eo_index)<>0) then
message1(parser_e_export_ordinal_double,tostr(hp^.index))
begin
message1(parser_e_export_ordinal_double,tostr(hp^.index));
exit;
end
else
begin
inc(last_index);
@ -421,7 +441,6 @@ unit win_targ;
hp^.name:=stringdup(hp^.sym^.name);
hp^.options:=hp^.options or eo_name;
end;
{ now place in correct order }
hp2:=pexported_item(current_module^._exports^.first);
while assigned(hp2) and
@ -432,6 +451,7 @@ unit win_targ;
begin
{ this is not allowed !! }
message1(parser_e_export_name_double,hp^.name^);
exit;
end;
if hp2=pexported_item(current_module^._exports^.first) then
current_module^._exports^.insert(hp)
@ -445,11 +465,10 @@ unit win_targ;
end
else
current_module^._exports^.concat(hp);
end;
end;
procedure texportlibwin32.generatelib;
var
ordinal_base,ordinal_max,ordinal_min : longint;
current_index : longint;
@ -460,7 +479,6 @@ unit win_targ;
tempexport : plinkedlist;
address_table,name_table_pointers,
name_table,ordinal_table : paasmoutput;
begin
ordinal_max:=0;
ordinal_min:=$7FFFFFFF;
@ -579,8 +597,6 @@ unit win_targ;
hp:=pexported_item(current_module^._exports^.first);;
end;
{ write the export adress table }
current_index:=ordinal_base;
hp:=pexported_item(tempexport^.first);
@ -610,320 +626,430 @@ unit win_targ;
{****************************************************************************
Postprocess Executable
TLINKERWIN32
****************************************************************************}
procedure tlinkerwin32.postprocessexecutable(const n : string);
type
tdosheader = packed record
e_magic : word;
e_cblp : word;
e_cp : word;
e_crlc : word;
e_cparhdr : word;
e_minalloc : word;
e_maxalloc : word;
e_ss : word;
e_sp : word;
e_csum : word;
e_ip : word;
e_cs : word;
e_lfarlc : word;
e_ovno : word;
e_res : array[0..3] of word;
e_oemid : word;
e_oeminfo : word;
e_res2 : array[0..9] of word;
e_lfanew : longint;
end;
Procedure TLinkerWin32.SetDefaultInfo;
begin
with Info do
begin
ExeCmd[1]:='ldw $OPT $STRIP $APPTYPE $IMAGEBASE $RELOC -o $EXE $RES';
DllCmd[1]:='ldw $OPT --dll $APPTYPE $IMAGEBASE $RELOC -o $EXE $RES';
DllCmd[2]:='dlltool --as asw.exe --dllname $EXE --output-exp exp.$$$ $RELOC -d $DEF';
DllCmd[3]:='ldw $OPT $STRIP --dll $APPTYPE $IMAGEBASE -o $EXE $RES exp.$$$';
end;
end;
tpeheader = packed record
PEMagic : array[0..3] of char;
Machine : word;
NumberOfSections : word;
TimeDateStamp : longint;
PointerToSymbolTable : longint;
NumberOfSymbols : longint;
SizeOfOptionalHeader : word;
Characteristics : word;
Magic : word;
MajorLinkerVersion : byte;
MinorLinkerVersion : byte;
SizeOfCode : longint;
SizeOfInitializedData : longint;
SizeOfUninitializedData : longint;
AddressOfEntryPoint : longint;
BaseOfCode : longint;
BaseOfData : longint;
ImageBase : longint;
SectionAlignment : longint;
FileAlignment : longint;
MajorOperatingSystemVersion : word;
MinorOperatingSystemVersion : word;
MajorImageVersion : word;
MinorImageVersion : word;
MajorSubsystemVersion : word;
MinorSubsystemVersion : word;
Reserved1 : longint;
SizeOfImage : longint;
SizeOfHeaders : longint;
CheckSum : longint;
Subsystem : word;
DllCharacteristics : word;
SizeOfStackReserve : longint;
SizeOfStackCommit : longint;
SizeOfHeapReserve : longint;
SizeOfHeapCommit : longint;
LoaderFlags : longint;
NumberOfRvaAndSizes : longint;
DataDirectory : array[1..$80] of byte;
end;
tcoffsechdr=packed record
name : array[0..7] of char;
vsize : longint;
rvaofs : longint;
datalen : longint;
datapos : longint;
relocpos : longint;
lineno1 : longint;
nrelocs : word;
lineno2 : word;
flags : longint;
end;
psecfill=^tsecfill;
tsecfill=record
fillpos,
fillsize : longint;
next : psecfill;
end;
var
f : file;
dosheader : tdosheader;
peheader : tpeheader;
firstsecpos,
maxfillsize,
l,peheaderpos : longint;
coffsec : tcoffsechdr;
secroot,hsecroot : psecfill;
zerobuf : pointer;
Function TLinkerWin32.WriteResponseFile(isdll:boolean) : Boolean;
Var
linkres : TLinkRes;
i : longint;
s,s2 : string;
linklibc : boolean;
begin
WriteResponseFile:=False;
{ Open link.res file }
LinkRes.Init(Info.ResName);
{ Write path to search libraries }
if assigned(current_module^.locallibrarysearchpath) then
begin
S:=current_module^.locallibrarysearchpath^;
while s<>'' do
begin
{ when -s is used quit, because there is no .exe }
if cs_link_extern in aktglobalswitches then
exit;
{ open file }
assign(f,n);
{$I-}
reset(f,1);
if ioresult<>0 then
Message1(execinfo_f_cant_open_executable,n);
{ read headers }
blockread(f,dosheader,sizeof(tdosheader));
peheaderpos:=dosheader.e_lfanew;
seek(f,peheaderpos);
blockread(f,peheader,sizeof(tpeheader));
{ write info }
Message1(execinfo_x_codesize,tostr(peheader.SizeOfCode));
Message1(execinfo_x_initdatasize,tostr(peheader.SizeOfInitializedData));
Message1(execinfo_x_uninitdatasize,tostr(peheader.SizeOfUninitializedData));
{ change stack size (PM) }
{ I am not sure that the default value is adequate !! }
peheader.SizeOfStackReserve:=stacksize;
{ change the header }
{ sub system }
{ gui=2 }
{ cui=3 }
if apptype=at_gui then
peheader.Subsystem:=2
else if apptype=at_cui then
peheader.Subsystem:=3;
seek(f,peheaderpos);
blockwrite(f,peheader,sizeof(tpeheader));
if ioresult<>0 then
Message1(execinfo_f_cant_process_executable,n);
seek(f,peheaderpos);
blockread(f,peheader,sizeof(tpeheader));
{ write the value after the change }
Message1(execinfo_x_stackreserve,tostr(peheader.SizeOfStackReserve));
Message1(execinfo_x_stackcommit,tostr(peheader.SizeOfStackCommit));
{ read section info }
maxfillsize:=0;
firstsecpos:=0;
secroot:=nil;
for l:=1to peheader.NumberOfSections do
begin
blockread(f,coffsec,sizeof(tcoffsechdr));
if coffsec.datapos>0 then
begin
if secroot=nil then
firstsecpos:=coffsec.datapos;
new(hsecroot);
hsecroot^.fillpos:=coffsec.datapos+coffsec.vsize;
hsecroot^.fillsize:=coffsec.datalen-coffsec.vsize;
hsecroot^.next:=secroot;
secroot:=hsecroot;
if secroot^.fillsize>maxfillsize then
maxfillsize:=secroot^.fillsize;
end;
end;
if firstsecpos>0 then
begin
l:=firstsecpos-filepos(f);
if l>maxfillsize then
maxfillsize:=l;
end
else
l:=0;
{ get zero buffer }
getmem(zerobuf,maxfillsize);
fillchar(zerobuf^,maxfillsize,0);
{ zero from sectioninfo until first section }
blockwrite(f,zerobuf^,l);
{ zero section alignments }
while assigned(secroot) do
begin
seek(f,secroot^.fillpos);
blockwrite(f,zerobuf^,secroot^.fillsize);
hsecroot:=secroot;
secroot:=secroot^.next;
dispose(hsecroot);
end;
freemem(zerobuf,maxfillsize);
close(f);
{$I+}
s2:=GetPathFromList(s);
LinkRes.Add('SEARCH_DIR('+s2+')');
end;
end;
S:=LibrarySearchPath;
while s<>'' do
begin
s2:=GetPathFromList(s);
LinkRes.Add('SEARCH_DIR('+s2+')');
end;
{ add objectfiles, start with prt0 always }
LinkRes.Add('INPUT(');
if isdll then
LinkRes.AddFileName(FindObjectFile('wdllprt0'))
else
LinkRes.AddFileName(FindObjectFile('wprt0'));
while not ObjectFiles.Empty do
begin
s:=ObjectFiles.Get;
if s<>'' then
LinkRes.AddFileName(s);
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) }
While not SharedLibFiles.Empty do
begin
S:=SharedLibFiles.Get;
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(')');
{ Write staticlibraries }
if not StaticLibFiles.Empty then
begin
LinkRes.Add('GROUP(');
While not StaticLibFiles.Empty do
begin
S:=StaticLibFiles.Get;
LinkRes.AddFileName(s)
end;
LinkRes.Add(')');
end;
{ Write and Close response }
linkres.writetodisk;
linkres.done;
WriteResponseFile:=True;
end;
function TLinkerWin32.MakeExecutable:boolean;
var
binstr,
cmdstr : string;
success : boolean;
i : longint;
StripStr,
RelocStr,
AppTypeStr,
ImageBaseStr : string[40];
begin
if not(cs_link_extern in aktglobalswitches) then
Message1(exec_i_linking,current_module^.exefilename^);
{ Create some replacements }
RelocStr:='';
AppTypeStr:='';
ImageBaseStr:='';
StripStr:='';
if RelocSection then
RelocStr:='--base-file base.$$$';
if apptype=at_gui then
AppTypeStr:='--subsystem windows';
if assigned(DLLImageBase) then
ImageBaseStr:='--image-base=0x'+DLLImageBase^;
if (cs_link_strip in aktglobalswitches) then
StripStr:='-s';
{ Write used files and libraries }
WriteResponseFile(false);
{ Call linker }
success:=false;
for i:=1to 1 do
begin
SplitBinCmd(Info.ExeCmd[i],binstr,cmdstr);
if binstr<>'' then
begin
Replace(cmdstr,'$EXE',current_module^.exefilename^);
Replace(cmdstr,'$OPT',Info.ExtraOptions);
Replace(cmdstr,'$RES',current_module^.outpath^+Info.ResName);
Replace(cmdstr,'$APPTYPE',AppTypeStr);
Replace(cmdstr,'$RELOC',RelocStr);
Replace(cmdstr,'$IMAGEBASE',ImageBaseStr);
Replace(cmdstr,'$STRIP',StripStr);
success:=DoExec(FindUtil(binstr),cmdstr,(i=1),false);
if not success then
break;
end;
end;
{ Post process }
if success then
success:=PostProcessExecutable(current_module^.exefilename^,false);
{ Remove ReponseFile }
if (success) and not(cs_link_extern in aktglobalswitches) then
begin
RemoveFile(current_module^.outpath^+Info.ResName);
RemoveFile('base.$$$');
RemoveFile('exp.$$$');
end;
MakeExecutable:=success; { otherwise a recursive call to link method }
end;
Function TLinkerWin32.MakeSharedLibrary:boolean;
var
binstr,
cmdstr : string;
success : boolean;
i : longint;
StripStr,
RelocStr,
AppTypeStr,
ImageBaseStr : string[40];
begin
MakeSharedLibrary:=false;
if not(cs_link_extern in aktglobalswitches) then
Message1(exec_i_linking,current_module^.sharedlibfilename^);
{ Create some replacements }
RelocStr:='';
AppTypeStr:='';
ImageBaseStr:='';
StripStr:='';
if RelocSection then
RelocStr:='--base-file base.$$$';
if apptype=at_gui then
AppTypeStr:='--subsystem windows';
if assigned(DLLImageBase) then
ImageBaseStr:='--image-base=0x'+DLLImageBase^;
if (cs_link_strip in aktglobalswitches) then
StripStr:='-s';
{ Write used files and libraries }
WriteResponseFile(true);
{ Call linker }
success:=false;
for i:=1to 3 do
begin
SplitBinCmd(Info.DllCmd[i],binstr,cmdstr);
if binstr<>'' then
begin
Replace(cmdstr,'$EXE',current_module^.sharedlibfilename^);
Replace(cmdstr,'$OPT',Info.ExtraOptions);
Replace(cmdstr,'$RES',current_module^.outpath^+Info.ResName);
Replace(cmdstr,'$APPTYPE',AppTypeStr);
Replace(cmdstr,'$RELOC',RelocStr);
Replace(cmdstr,'$IMAGEBASE',ImageBaseStr);
Replace(cmdstr,'$STRIP',StripStr);
Replace(cmdstr,'$DEF',deffile.fname);
success:=DoExec(FindUtil(binstr),cmdstr,(i=1),false);
if not success then
break;
end;
end;
{ Post process }
if success then
success:=PostProcessExecutable(current_module^.sharedlibfilename^,true);
{ Remove ReponseFile }
if (success) and not(cs_link_extern in aktglobalswitches) then
begin
RemoveFile(current_module^.outpath^+Info.ResName);
RemoveFile('base.$$$');
RemoveFile('exp.$$$');
end;
MakeSharedLibrary:=success; { otherwise a recursive call to link method }
end;
function tlinkerwin32.postprocessexecutable(const fn : string;isdll:boolean):boolean;
type
tdosheader = packed record
e_magic : word;
e_cblp : word;
e_cp : word;
e_crlc : word;
e_cparhdr : word;
e_minalloc : word;
e_maxalloc : word;
e_ss : word;
e_sp : word;
e_csum : word;
e_ip : word;
e_cs : word;
e_lfarlc : word;
e_ovno : word;
e_res : array[0..3] of word;
e_oemid : word;
e_oeminfo : word;
e_res2 : array[0..9] of word;
e_lfanew : longint;
end;
tpeheader = packed record
PEMagic : array[0..3] of char;
Machine : word;
NumberOfSections : word;
TimeDateStamp : longint;
PointerToSymbolTable : longint;
NumberOfSymbols : longint;
SizeOfOptionalHeader : word;
Characteristics : word;
Magic : word;
MajorLinkerVersion : byte;
MinorLinkerVersion : byte;
SizeOfCode : longint;
SizeOfInitializedData : longint;
SizeOfUninitializedData : longint;
AddressOfEntryPoint : longint;
BaseOfCode : longint;
BaseOfData : longint;
ImageBase : longint;
SectionAlignment : longint;
FileAlignment : longint;
MajorOperatingSystemVersion : word;
MinorOperatingSystemVersion : word;
MajorImageVersion : word;
MinorImageVersion : word;
MajorSubsystemVersion : word;
MinorSubsystemVersion : word;
Reserved1 : longint;
SizeOfImage : longint;
SizeOfHeaders : longint;
CheckSum : longint;
Subsystem : word;
DllCharacteristics : word;
SizeOfStackReserve : longint;
SizeOfStackCommit : longint;
SizeOfHeapReserve : longint;
SizeOfHeapCommit : longint;
LoaderFlags : longint;
NumberOfRvaAndSizes : longint;
DataDirectory : array[1..$80] of byte;
end;
tcoffsechdr=packed record
name : array[0..7] of char;
vsize : longint;
rvaofs : longint;
datalen : longint;
datapos : longint;
relocpos : longint;
lineno1 : longint;
nrelocs : word;
lineno2 : word;
flags : longint;
end;
psecfill=^tsecfill;
tsecfill=record
fillpos,
fillsize : longint;
next : psecfill;
end;
var
f : file;
dosheader : tdosheader;
peheader : tpeheader;
firstsecpos,
maxfillsize,
i,l,peheaderpos : longint;
coffsec : tcoffsechdr;
secroot,hsecroot : psecfill;
zerobuf : pointer;
begin
postprocessexecutable:=false;
{ when -s is used or it's a dll then quit }
if (cs_link_extern in aktglobalswitches) then
begin
postprocessexecutable:=true;
exit;
end;
{ open file }
assign(f,fn);
{$I-}
reset(f,1);
if ioresult<>0 then
Message1(execinfo_f_cant_open_executable,fn);
{ read headers }
blockread(f,dosheader,sizeof(tdosheader));
peheaderpos:=dosheader.e_lfanew;
seek(f,peheaderpos);
blockread(f,peheader,sizeof(tpeheader));
{ write info }
Message1(execinfo_x_codesize,tostr(peheader.SizeOfCode));
Message1(execinfo_x_initdatasize,tostr(peheader.SizeOfInitializedData));
Message1(execinfo_x_uninitdatasize,tostr(peheader.SizeOfUninitializedData));
{ change stack size (PM) }
{ I am not sure that the default value is adequate !! }
peheader.SizeOfStackReserve:=stacksize;
{ change the header }
{ sub system }
{ gui=2 }
{ cui=3 }
if apptype=at_gui then
peheader.Subsystem:=2
else if apptype=at_cui then
peheader.Subsystem:=3;
seek(f,peheaderpos);
blockwrite(f,peheader,sizeof(tpeheader));
if ioresult<>0 then
Message1(execinfo_f_cant_process_executable,fn);
seek(f,peheaderpos);
blockread(f,peheader,sizeof(tpeheader));
{ write the value after the change }
Message1(execinfo_x_stackreserve,tostr(peheader.SizeOfStackReserve));
Message1(execinfo_x_stackcommit,tostr(peheader.SizeOfStackCommit));
{ read section info }
maxfillsize:=0;
firstsecpos:=0;
secroot:=nil;
for l:=1to peheader.NumberOfSections do
begin
blockread(f,coffsec,sizeof(tcoffsechdr));
if coffsec.datapos>0 then
begin
if secroot=nil then
firstsecpos:=coffsec.datapos;
new(hsecroot);
hsecroot^.fillpos:=coffsec.datapos+coffsec.vsize;
hsecroot^.fillsize:=coffsec.datalen-coffsec.vsize;
hsecroot^.next:=secroot;
secroot:=hsecroot;
if secroot^.fillsize>maxfillsize then
maxfillsize:=secroot^.fillsize;
end;
end;
if firstsecpos>0 then
begin
l:=firstsecpos-filepos(f);
if l>maxfillsize then
maxfillsize:=l;
end
else
l:=0;
{ get zero buffer }
getmem(zerobuf,maxfillsize);
fillchar(zerobuf^,maxfillsize,0);
{ zero from sectioninfo until first section }
blockwrite(f,zerobuf^,l);
{ zero section alignments }
while assigned(secroot) do
begin
seek(f,secroot^.fillpos);
blockwrite(f,zerobuf^,secroot^.fillsize);
hsecroot:=secroot;
secroot:=secroot^.next;
dispose(hsecroot);
end;
freemem(zerobuf,maxfillsize);
close(f);
{$I+}
i:=ioresult;
postprocessexecutable:=true;
end;
end.
{
$Log$
Revision 1.34 1999-09-20 16:39:04 peter
* cs_create_smart instead of cs_smartlink
* -CX is create smartlink
* -CD is create dynamic, but does nothing atm.
Revision 1.33 1999/08/25 12:00:07 jonas
* changed pai386, paippc and paiapha (same for tai*) to paicpu (taicpu)
Revision 1.32 1999/08/11 17:26:38 peter
* tlinker object is now inherited for win32 and dos
* postprocessexecutable is now a method of tlinker
Revision 1.31 1999/08/04 00:23:50 florian
* renamed i386asm and i386base to cpuasm and cpubase
Revision 1.30 1999/07/29 20:54:11 peter
* write .size also
Revision 1.29 1999/07/22 16:12:28 peter
* merged
Revision 1.28 1999/07/18 10:20:03 florian
* made it compilable with Dlephi 4 again
+ fixed problem with large stack allocations on win32
Revision 1.27.2.1 1999/07/22 16:09:30 peter
* reuse old import entries
Revision 1.27 1999/05/27 19:45:30 peter
* removed oldasm
* plabel -> pasmlabel
* -a switches to source writing automaticly
* assembler readers OOPed
* asmsymbol automaticly external
* jumptables and other label fixes for asm readers
Revision 1.26 1999/05/21 13:55:24 peter
* NEWLAB for label as symbol
Revision 1.25 1999/05/17 13:02:13 pierre
* -Csmmm works for win32 but default is set to 32Mb
Revision 1.24 1999/05/01 13:25:04 peter
* merged nasm compiler
* old asm moved to oldasm/
Revision 1.23 1999/04/07 14:18:32 pierre
* typo correction
Revision 1.22 1999/04/07 14:04:40 pierre
* adds .dll as library suffix only if
the name does not end with .dll .drv or .exe !
Revision 1.21 1999/02/25 21:02:59 peter
* ag386bin updates
+ coff writer
Revision 1.20 1999/02/22 02:44:14 peter
* ag386bin doesn't use i386.pas anymore
Revision 1.19 1998/12/11 00:04:06 peter
+ globtype,tokens,version unit splitted from globals
Revision 1.18 1998/12/02 10:26:13 pierre
* writing of .edata was wrong for indexes above number of exported items
* importing by index only did not work !
Revision 1.17 1998/12/01 23:35:43 pierre
* alignment fixes
Revision 1.16 1998/11/30 13:26:26 pierre
* the code for ordering the exported procs/vars was buggy
+ added -WB to force binding (Ozerski way of creating DLL)
this is off by default as direct writing of .edata section seems
OK
Revision 1.15 1998/11/30 09:43:25 pierre
* some range check bugs fixed (still not working !)
+ added DLL writing support for win32 (also accepts variables)
+ TempAnsi for code that could be used for Temporary ansi strings
handling
Revision 1.14 1998/11/28 16:21:00 peter
+ support for dll variables
Revision 1.13 1998/10/29 11:35:54 florian
* some dll support for win32
* fixed assembler writing for PalmOS
Revision 1.12 1998/10/27 10:22:35 florian
+ First things for win32 export sections
Revision 1.11 1998/10/22 17:54:09 florian
+ switch $APPTYPE for win32 added
Revision 1.10 1998/10/22 15:18:51 florian
+ switch -vx for win32 added
Revision 1.9 1998/10/19 15:41:03 peter
* better splitname to support glib-1.1.dll alike names
Revision 1.8 1998/09/07 18:33:35 peter
+ smartlinking for win95 imports
Revision 1.7 1998/09/03 17:39:06 florian
+ better code for type conversation longint/dword to real type
Revision 1.6 1998/08/10 14:50:38 peter
+ localswitches, moduleswitches, globalswitches splitting
Revision 1.5 1998/06/10 10:43:18 peter
* write also the .dll extension (needed for NT)
Revision 1.4 1998/06/08 22:59:56 peter
* smartlinking works for win32
* some defines to exclude some compiler parts
Revision 1.3 1998/06/04 23:52:06 peter
* m68k compiles
+ .def file creation moved to gendef.pas so it could also be used
for win32
Revision 1.2 1998/05/06 18:36:55 peter
* tai_section extended with code,data,bss sections and enumerated type
* ident 'compiled by FPC' moved to pmodules
* small fix for smartlink
Revision 1.1 1999-10-21 14:29:38 peter
* redesigned linker object
+ library support for linux (only procedures can be exported)
}