summaryrefslogtreecommitdiff
path: root/compiler/systems
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/systems')
-rw-r--r--compiler/systems/i_amiga.pas169
-rw-r--r--compiler/systems/i_atari.pas83
-rw-r--r--compiler/systems/i_beos.pas100
-rw-r--r--compiler/systems/i_bsd.pas572
-rw-r--r--compiler/systems/i_emx.pas114
-rw-r--r--compiler/systems/i_gba.pas101
-rw-r--r--compiler/systems/i_go32v2.pas100
-rw-r--r--compiler/systems/i_linux.pas658
-rw-r--r--compiler/systems/i_macos.pas100
-rw-r--r--compiler/systems/i_morph.pas101
-rw-r--r--compiler/systems/i_nwl.pas100
-rw-r--r--compiler/systems/i_nwm.pas100
-rw-r--r--compiler/systems/i_os2.pas114
-rw-r--r--compiler/systems/i_palmos.pas90
-rw-r--r--compiler/systems/i_sunos.pas168
-rw-r--r--compiler/systems/i_watcom.pas102
-rw-r--r--compiler/systems/i_wdosx.pas102
-rw-r--r--compiler/systems/i_win.pas306
-rw-r--r--compiler/systems/mac_crea.txt71
-rw-r--r--compiler/systems/t_amiga.pas43
-rw-r--r--compiler/systems/t_atari.pas43
-rw-r--r--compiler/systems/t_beos.pas495
-rw-r--r--compiler/systems/t_bsd.pas655
-rw-r--r--compiler/systems/t_emx.pas516
-rw-r--r--compiler/systems/t_gba.pas300
-rw-r--r--compiler/systems/t_go32v2.pas364
-rw-r--r--compiler/systems/t_linux.pas755
-rw-r--r--compiler/systems/t_macos.pas273
-rw-r--r--compiler/systems/t_morph.pas269
-rw-r--r--compiler/systems/t_nwl.pas645
-rw-r--r--compiler/systems/t_nwm.pas576
-rw-r--r--compiler/systems/t_os2.pas516
-rw-r--r--compiler/systems/t_palmos.pas212
-rw-r--r--compiler/systems/t_sunos.pas490
-rw-r--r--compiler/systems/t_watcom.pas178
-rw-r--r--compiler/systems/t_wdosx.pas84
-rw-r--r--compiler/systems/t_win.pas1673
37 files changed, 11338 insertions, 0 deletions
diff --git a/compiler/systems/i_amiga.pas b/compiler/systems/i_amiga.pas
new file mode 100644
index 0000000000..139eff7cfd
--- /dev/null
+++ b/compiler/systems/i_amiga.pas
@@ -0,0 +1,169 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ This unit implements support information structures for AmigaOS
+
+ 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.
+ ****************************************************************************
+}
+{ This unit implements support information structures for the AmigaOS. }
+unit i_amiga;
+
+ interface
+
+ uses
+ systems;
+
+ const
+ system_m68k_amiga_info : tsysteminfo =
+ (
+ system : system_m68k_Amiga;
+ name : 'Commodore Amiga';
+ shortname : 'amiga';
+ flags : [];
+ cpu : cpu_m68k;
+ unit_env : '';
+ extradefines : '';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.library';
+ staticlibext : '.a';
+ staticlibprefix : 'lib';
+ sharedlibprefix : '';
+ sharedClibext : '.library';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : '';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_amiga;
+ endian : endian_big;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 0;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 2;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 262144;
+ DllScanSupported:false;
+ use_function_relative_addresses : true;
+ abi : abi_default;
+ );
+
+ system_powerpc_amiga_info : tsysteminfo =
+ (
+ system : system_powerpc_Amiga;
+ name : 'AmigaOS for PowerPC';
+ shortname : 'amigappc';
+ flags : [];
+ cpu : cpu_powerpc;
+ unit_env : '';
+ extradefines : '';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.library';
+ staticlibext : '.a';
+ staticlibprefix : 'lib';
+ sharedlibprefix : '';
+ sharedClibext : '.library';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : '';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_amiga;
+ endian : endian_big;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 0;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 4;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 262144;
+ DllScanSupported:false;
+ use_function_relative_addresses : true;
+ abi : abi_powerpc_sysv;
+ );
+
+ implementation
+
+initialization
+{$ifdef CPU68}
+ {$ifdef AMIGA}
+ set_source_info(system_m68k_Amiga_info);
+ {$endif AMIGA}
+{$endif CPU68}
+{$ifdef CPUPOWERPC}
+ {$ifdef AMIGA}
+// set_source_info(system_powerpc_Amiga_info);
+ {$endif AMIGA}
+{$endif CPUPOWERPC}
+end.
diff --git a/compiler/systems/i_atari.pas b/compiler/systems/i_atari.pas
new file mode 100644
index 0000000000..9ecbcab126
--- /dev/null
+++ b/compiler/systems/i_atari.pas
@@ -0,0 +1,83 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ This unit implements support information structures for atari
+
+ 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.
+ ****************************************************************************
+}
+{ This unit implements support information structures for atari. }
+unit i_atari;
+
+ interface
+
+ uses
+ systems;
+
+ const
+ system_m68k_atari_info : tsysteminfo =
+ (
+ system : target_m68k_Atari;
+ name : 'Atari ST/STE';
+ shortname : 'atari';
+ flags : [tf_use_8_3];
+ cpu : cpu_m68k;
+ short_name : 'ATARI';
+ unit_env : '';
+ extradefines : '';
+ sharedlibext : '.dll';
+ staticlibext : '.a';
+ exeext : '.tpp';
+ defext : '';
+ scriptext : '';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ staticlibprefix : '';
+ sharedlibprefix : '';
+ p_ext_support : false;
+ Cprefix : '_';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : ld_m68k_atari;
+ linkextern : ld_m68k_atari;
+ ar : ar_m68k_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_big;
+ stackalignment : 2;
+ maxCrecordalignment : 4;
+ stacksize : 8192;
+ DllScanSupported:false;
+ use_function_relative_addresses : false
+ );
+
+ implementation
+
+initialization
+{$ifdef cpu68}
+ {$ifdef atari}
+ set_source_info(system_m68k_atari_info);
+ {$endif atari}
+{$endif cpu68}
+end.
diff --git a/compiler/systems/i_beos.pas b/compiler/systems/i_beos.pas
new file mode 100644
index 0000000000..b10777a401
--- /dev/null
+++ b/compiler/systems/i_beos.pas
@@ -0,0 +1,100 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ This unit implements support information structures for BeOS
+
+ 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.
+ ****************************************************************************
+}
+{ This unit implements support information structures for BeOS. }
+unit i_beos;
+
+ interface
+
+ uses
+ systems;
+
+ const
+ system_i386_beos_info : tsysteminfo =
+ (
+ system : system_i386_BeOS;
+ name : 'Beos for i386';
+ shortname : 'Beos';
+ flags : [tf_under_development,tf_needs_symbol_size];
+ cpu : cpu_i386;
+ unit_env : 'BEOSUNITS';
+ extradefines : 'UNIX;HASUNIX';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 0;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 2;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 8192;
+ DllScanSupported:false;
+ use_function_relative_addresses : true
+ );
+
+ implementation
+
+initialization
+{$ifdef cpu86}
+ {$ifdef beos}
+ set_source_info(system_i386_beos_info);
+ {$endif beos}
+{$endif cpu86}
+end.
diff --git a/compiler/systems/i_bsd.pas b/compiler/systems/i_bsd.pas
new file mode 100644
index 0000000000..4ed3c183df
--- /dev/null
+++ b/compiler/systems/i_bsd.pas
@@ -0,0 +1,572 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ This unit implements support information structures for FreeBSD/NetBSD
+
+ 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.
+ ****************************************************************************
+}
+{ This unit implements support information structures for FreeBSD/NetBSD.
+ OpenBSD is only added for i386 for now, though it exists for most
+ other common CPU's too}
+
+unit i_bsd;
+
+ interface
+
+ uses
+ systems;
+
+ const
+ system_i386_freebsd_info : tsysteminfo =
+ (
+ system : system_i386_FreeBSD;
+ name : 'FreeBSD/ELF for i386';
+ shortname : 'FreeBSD';
+ flags : [tf_pic_uses_got];
+ cpu : cpu_i386;
+ unit_env : 'BSDUNITS';
+ extradefines : 'UNIX;BSD;HASUNIX';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_i386_elf32;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 0;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 2;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 262144;
+ DllScanSupported:false;
+ use_function_relative_addresses : true
+ );
+
+
+ system_x86_64_freebsd_info : tsysteminfo =
+ (
+ system : system_x86_64_freebsd;
+ name : 'FreeBSD for x86-64';
+ shortname : 'FreeBSD';
+ flags : [tf_needs_symbol_size,tf_pic_uses_got{,tf_smartlink_sections}];
+ cpu : cpu_x86_64;
+ unit_env : 'BSDUNITS';
+ extradefines : 'UNIX;HASUNIX';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 8;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 8;
+ varalignmin : 0;
+ varalignmax : 8;
+ localalignmin : 4;
+ localalignmax : 8;
+ recordalignmin : 0;
+ recordalignmax : 8;
+ maxCrecordalign : 8
+ );
+ first_parm_offset : 16;
+ stacksize : 256*1024;
+ DllScanSupported:false;
+ use_function_relative_addresses : true
+ );
+
+
+ system_i386_netbsd_info : tsysteminfo =
+ (
+ system : system_i386_NetBSD;
+ name : 'NetBSD for i386';
+ shortname : 'NetBSD';
+ flags : [tf_under_development];
+ cpu : cpu_i386;
+ unit_env : 'BSDUNITS';
+ extradefines : 'UNIX;BSD;HASUNIX';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '_';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 1;
+ varalignmin : 0;
+ varalignmax : 1;
+ localalignmin : 0;
+ localalignmax : 1;
+ recordalignmin : 0;
+ recordalignmax : 2;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 262144;
+ DllScanSupported:false;
+ use_function_relative_addresses : true
+ );
+
+ system_i386_openbsd_info : tsysteminfo =
+ (
+ system : system_i386_OpenBSD;
+ name : 'OpenBSD for i386';
+ shortname : 'OpenBSD';
+ flags : [tf_under_development];
+ cpu : cpu_i386;
+ unit_env : 'BSDUNITS';
+ extradefines : 'UNIX;BSD;HASUNIX';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '_';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 1;
+ varalignmin : 0;
+ varalignmax : 1;
+ localalignmin : 0;
+ localalignmax : 1;
+ recordalignmin : 0;
+ recordalignmax : 2;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 262144;
+ DllScanSupported:false;
+ use_function_relative_addresses : true
+ );
+
+ system_m68k_netbsd_info : tsysteminfo =
+ (
+ system : system_m68k_NetBSD;
+ name : 'NetBSD for m68k';
+ shortname : 'NetBSD';
+ flags : [tf_under_development];
+ cpu : cpu_m68k;
+ unit_env : 'BSDUNITS';
+ extradefines : 'UNIX;BSD;HASUNIX';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_big;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 1;
+ varalignmin : 0;
+ varalignmax : 1;
+ localalignmin : 0;
+ localalignmax : 1;
+ recordalignmin : 0;
+ recordalignmax : 2;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 262144;
+ DllScanSupported:false;
+ use_function_relative_addresses : true
+ );
+
+ system_powerpc_netbsd_info : tsysteminfo =
+ (
+ system : system_powerpc_netbsd;
+ name : 'NetBSD for PowerPC';
+ shortname : 'NetBSD';
+ flags : [tf_under_development];
+ cpu : cpu_powerpc;
+ unit_env : '';
+ extradefines : 'UNIX;BSD;HASUNIX';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.s';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_big;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 0;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 2;
+ maxCrecordalign : 4 // should be 8 probably
+ );
+ first_parm_offset : 8;
+ stacksize : 32*1024*1024;
+ DllScanSupported:false;
+ use_function_relative_addresses : true;
+ { abi_powerpc_sysv doesn't work yet }
+ abi : abi_powerpc_aix;
+ );
+
+
+ system_powerpc_darwin_info : tsysteminfo =
+ (
+ system : system_powerpc_darwin;
+ name : 'Darwin for PowerPC';
+ shortname : 'Darwin';
+ flags : [];
+ cpu : cpu_powerpc;
+ unit_env : 'BSDUNITS';
+ extradefines : 'UNIX;BSD;HASUNIX';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.dylib';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.dylib';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : true;
+ Cprefix : '_';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_darwin;
+ assemextern : as_darwin;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_big;
+ alignment :
+ (
+ procalign : 16;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 0;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 2;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 24;
+ stacksize : 262144;
+ DllScanSupported:false;
+ use_function_relative_addresses : false;
+ abi : abi_powerpc_aix;
+ );
+
+
+
+ system_i386_darwin_info : tsysteminfo =
+ (
+ system : system_i386_darwin;
+ name : 'Darwin for i386';
+ shortname : 'Darwin';
+ flags : [];
+ cpu : cpu_i386;
+ unit_env : 'BSDUNITS';
+ extradefines : 'UNIX;BSD;HASUNIX';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.dylib';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.dylib';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : true;
+ Cprefix : '_';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_darwin;
+ assemextern : as_darwin;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_big;
+ alignment :
+ (
+ procalign : 16;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 0;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 16;
+ maxCrecordalign : 16
+ );
+ first_parm_offset : 8;
+ stacksize : 262144;
+ DllScanSupported:false;
+ use_function_relative_addresses : true;
+ );
+
+ implementation
+
+initialization
+{$ifdef cpu86}
+ {$ifdef FreeBSD}
+ set_source_info(system_i386_FreeBSD_info);
+ {$endif}
+ {$ifdef NetBSD}
+ set_source_info(system_i386_NetBSD_info);
+ {$endif}
+ {$ifdef OpenBSD}
+ set_source_info(system_i386_NetBSD_info);
+ {$endif}
+ {$ifdef Darwin}
+ set_source_info(system_i386_Darwin_info);
+ {$endif Darwin}
+{$endif cpu86}
+{$ifdef cpux86_64}
+ {$ifdef FreeBSD}
+ set_source_info(system_x86_64_FreeBSD_info);
+ {$endif}
+{$endif}
+{$ifdef cpu68}
+ {$ifdef NetBSD}
+ set_source_info(system_m68k_NetBSD_info);
+ {$endif NetBSD}
+{$endif cpu68}
+{$ifdef cpupowerpc}
+ {$ifdef Darwin}
+ set_source_info(system_powerpc_darwin_info);
+ {$endif Darwin}
+ {$ifdef NetBSD}
+ set_source_info(system_powerpc_netbsd_info);
+ {$endif}
+{$endif cpu68}
+end.
diff --git a/compiler/systems/i_emx.pas b/compiler/systems/i_emx.pas
new file mode 100644
index 0000000000..48d8769c64
--- /dev/null
+++ b/compiler/systems/i_emx.pas
@@ -0,0 +1,114 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ This unit implements support information structures for OS/2 via EMX
+
+ 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.
+ ****************************************************************************
+}
+{ This unit implements support information structures for OS/2 via EMX. }
+unit i_emx;
+
+ interface
+
+ uses
+ systems;
+
+ const
+ res_emxbind_info : tresinfo =
+ (
+ id : res_emxbind;
+ resbin : 'emxbind';
+ rescmd : '-b -r $RES $OBJ'
+ (* Not really used - see TLinkerEMX.SetDefaultInfo in t_emx.pas. *)
+ );
+
+ system_i386_emx_info : tsysteminfo =
+ (
+ system : system_i386_EMX;
+ name : 'OS/2 via EMX';
+ shortname : 'EMX';
+ flags : [tf_need_export,tf_use_8_3];
+ cpu : cpu_i386;
+ unit_env : 'EMXUNITS';
+ extradefines : 'OS2';
+ exeext : '.exe';
+ defext : '.def';
+ scriptext : '.cmd';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.dll';
+ staticlibext : '.a';
+ staticlibprefix : '';
+ sharedlibprefix : '';
+ sharedClibext : '.dll';
+ staticClibext : '.a';
+ staticClibprefix : '';
+ sharedClibprefix : '';
+ p_ext_support : false;
+ Cprefix : '_';
+ newline : #13#10;
+ dirsep : '\';
+ files_case_relevent : false;
+ assem : as_i386_as_aout;
+ assemextern : as_i386_as_aout;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_emxbind;
+ dbg : dbg_stabs;
+ script : script_dos;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 0;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 2;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 256*1024;
+ DllScanSupported: false;
+ use_function_relative_addresses : false
+ );
+
+
+ implementation
+
+initialization
+{$ifdef CPU86}
+ {$ifdef EMX}
+ {$IFNDEF VER1_0}
+ set_source_info(system_i386_emx_info);
+ { OS/2 via EMX can be run under DOS as well }
+ if (OS_Mode=osDOS) or (OS_Mode=osDPMI) then
+ source_info.scriptext := '.bat';
+ {$ENDIF VER1_0}
+ {$endif EMX}
+{$endif CPU86}
+end.
diff --git a/compiler/systems/i_gba.pas b/compiler/systems/i_gba.pas
new file mode 100644
index 0000000000..ef5c1e2013
--- /dev/null
+++ b/compiler/systems/i_gba.pas
@@ -0,0 +1,101 @@
+{
+ This unit implements support information structures for GameBoy Advance
+
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ 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.
+ ****************************************************************************
+}
+{ This unit implements support information structures for gba. }
+unit i_gba;
+
+ interface
+
+ uses
+ systems;
+
+ const
+ system_arm_gba_info : tsysteminfo =
+ (
+ system : system_arm_gba;
+ name : 'GameBoy Advance';
+ shortname : 'gba';
+ flags : [tf_needs_symbol_size];
+ cpu : cpu_arm;
+ unit_env : 'LINUXUNITS';
+ extradefines : 'UNIX;HASUNIX';
+ exeext : '.gba';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 4;
+ localalignmax : 8;
+ recordalignmin : 0;
+ recordalignmax : 4;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 262144;
+ DllScanSupported:false;
+ use_function_relative_addresses : true;
+ abi : abi_default
+ );
+
+ implementation
+
+initialization
+{$ifdef arm}
+ {$ifdef gba}
+ set_source_info(system_arm_gba_info);
+ {$endif gba}
+{$endif arm}
+end.
diff --git a/compiler/systems/i_go32v2.pas b/compiler/systems/i_go32v2.pas
new file mode 100644
index 0000000000..d4989355f4
--- /dev/null
+++ b/compiler/systems/i_go32v2.pas
@@ -0,0 +1,100 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ This unit implements support information structures for go32v2
+
+ 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.
+ ****************************************************************************
+}
+{ This unit implements support information structures for go32v2. }
+unit i_go32v2;
+
+ interface
+
+ uses
+ systems;
+
+ const
+ system_i386_go32v2_info : tsysteminfo =
+ (
+ system : system_i386_GO32V2;
+ name : 'GO32 V2 DOS extender';
+ shortname : 'Go32v2';
+ flags : [tf_use_8_3];
+ cpu : cpu_i386;
+ unit_env : 'GO32V2UNITS';
+ extradefines : 'DPMI';
+ exeext : '.exe';
+ defext : '.def';
+ scriptext : '.bat';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.dll';
+ staticlibext : '.a';
+ staticlibprefix : '';
+ sharedlibprefix : '';
+ sharedClibext : '.dll';
+ staticClibext : '.a';
+ staticClibprefix : '';
+ sharedClibprefix : '';
+ p_ext_support : false;
+ Cprefix : '_';
+ newline : #13#10;
+ dirsep : '\';
+ files_case_relevent : false;
+ assem : as_i386_coff;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_dos;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 0;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 2;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 262144;
+ DllScanSupported : false;
+ use_function_relative_addresses : true
+ );
+
+ implementation
+
+initialization
+{$ifdef cpu86}
+ {$ifdef go32v2}
+ set_source_info(system_i386_go32v2_info);
+ {$endif go32v2}
+{$endif cpu86}
+end.
diff --git a/compiler/systems/i_linux.pas b/compiler/systems/i_linux.pas
new file mode 100644
index 0000000000..b1a7b87da5
--- /dev/null
+++ b/compiler/systems/i_linux.pas
@@ -0,0 +1,658 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ This unit implements support information structures for linux
+
+ 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.
+ ****************************************************************************
+}
+{ This unit implements support information structures for linux. }
+unit i_linux;
+
+ interface
+
+ uses
+ systems;
+
+ const
+ res_elf32_info : tresinfo =
+ (
+ id : res_elf;
+ resbin : 'fpcres';
+ rescmd : '-o $OBJ -i $RES'
+ );
+
+ res_elf64_info : tresinfo =
+ (
+ id : res_elf;
+ resbin : 'fpcres';
+ rescmd : '-o $OBJ -i $RES'
+ );
+
+ system_i386_linux_info : tsysteminfo =
+ (
+ system : system_i386_LINUX;
+ name : 'Linux for i386';
+ shortname : 'Linux';
+ flags : [tf_needs_symbol_size,tf_pic_uses_got{,tf_smartlink_sections},tf_needs_symbol_type];
+ cpu : cpu_i386;
+ unit_env : 'LINUXUNITS';
+ extradefines : 'UNIX;HASUNIX';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_i386_elf32;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_elf;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 16;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 8;
+ varalignmin : 0;
+ varalignmax : 8;
+ localalignmin : 4;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 4;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 262144;
+ DllScanSupported:false;
+ use_function_relative_addresses : true;
+ abi : abi_default
+ );
+
+ system_x86_6432_linux_info : tsysteminfo =
+ (
+ system : system_x86_6432_LINUX;
+ name : 'Linux for x64_6432';
+ shortname : 'Linux6432';
+ flags : [tf_needs_symbol_size,tf_pic_uses_got{,tf_smartlink_sections}];
+ cpu : cpu_x86_64;
+ unit_env : 'LINUXUNITS';
+ extradefines : 'UNIX;HASUNIX';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_i386_elf32;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 16;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 8;
+ varalignmin : 0;
+ varalignmax : 8;
+ localalignmin : 4;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 4;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 262144;
+ DllScanSupported:false;
+ use_function_relative_addresses : true;
+ abi : abi_default
+ );
+
+ system_m68k_linux_info : tsysteminfo =
+ (
+ system : system_m68k_linux;
+ name : 'Linux for m68k';
+ shortname : 'Linux';
+ flags : [tf_needs_symbol_size,tf_needs_symbol_type];
+ cpu : cpu_m68k;
+ unit_env : 'LINUXUNITS';
+ extradefines : 'UNIX;HASUNIX';
+ exeext : '';
+ defext : '';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_big;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 4;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 2;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 32*1024*1024;
+ DllScanSupported:false;
+ use_function_relative_addresses : true;
+ abi : abi_default
+ );
+
+ system_powerpc_linux_info : tsysteminfo =
+ (
+ system : system_powerpc_LINUX;
+ name : 'Linux for PowerPC';
+ shortname : 'Linux';
+ flags : [tf_needs_symbol_size,tf_needs_symbol_type];
+ cpu : cpu_powerpc;
+ unit_env : '';
+ extradefines : 'UNIX;HASUNIX';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_big;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 4;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 4;
+ maxCrecordalign : 8
+ );
+ first_parm_offset : 8;
+ stacksize : 32*1024*1024;
+ DllScanSupported:false;
+ use_function_relative_addresses : true;
+ abi : abi_powerpc_sysv;
+ );
+
+ system_powerpc64_linux_info : tsysteminfo =
+ (
+ system : system_powerpc64_LINUX;
+ name : 'Linux for PowerPC64';
+ shortname : 'Linux';
+ flags : [tf_needs_symbol_size,tf_needs_symbol_type];
+ cpu : cpu_powerpc64;
+ unit_env : '';
+ extradefines : 'UNIX;HASUNIX';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_big;
+ alignment :
+ (
+ procalign : 8;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 8;
+ varalignmin : 0;
+ varalignmax : 8;
+ localalignmin : 4;
+ localalignmax : 8;
+ recordalignmin : 0;
+ recordalignmax : 8;
+ maxCrecordalign : 8
+ );
+ first_parm_offset : 8;
+ stacksize : 32*1024*1024;
+ DllScanSupported:false;
+ use_function_relative_addresses : true;
+ abi : abi_default
+ );
+
+ system_alpha_linux_info : tsysteminfo =
+ (
+ system : system_alpha_LINUX;
+ name : 'Linux for Alpha';
+ shortname : 'Linux';
+ flags : [tf_needs_symbol_size,tf_needs_symbol_type];
+ cpu : cpu_alpha;
+ unit_env : 'LINUXUNITS';
+ extradefines : 'UNIX;HASUNIX';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 4;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 2;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 32*1024*1024;
+ DllScanSupported:false;
+ use_function_relative_addresses : true;
+ abi : abi_default
+ );
+
+ system_x86_64_linux_info : tsysteminfo =
+ (
+ system : system_x86_64_LINUX;
+ name : 'Linux for x86-64';
+ shortname : 'Linux';
+ flags : [tf_needs_symbol_size,tf_needs_dwarf_cfi,
+ tf_library_needs_pic,tf_needs_symbol_type];
+ cpu : cpu_x86_64;
+ unit_env : 'LINUXUNITS';
+ extradefines : 'UNIX;HASUNIX';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 8;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 8;
+ varalignmin : 0;
+ varalignmax : 8;
+ localalignmin : 4;
+ localalignmax : 8;
+ recordalignmin : 0;
+ recordalignmax : 8;
+ maxCrecordalign : 8
+ );
+ first_parm_offset : 16;
+ stacksize : 256*1024;
+ DllScanSupported:false;
+ use_function_relative_addresses : true;
+ abi : abi_default
+ );
+
+ system_sparc_linux_info : tsysteminfo =
+ (
+ system : system_SPARC_Linux;
+ name : 'Linux for SPARC';
+ shortname : 'Linux';
+ flags : [tf_needs_symbol_size,tf_library_needs_pic,tf_needs_symbol_type];
+ cpu : cpu_SPARC;
+ unit_env : 'LINUXUNITS';
+ extradefines : 'UNIX;HASUNIX';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_big;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 8;
+ varalignmin : 0;
+ varalignmax : 8;
+ localalignmin : 4;
+ localalignmax : 8;
+ recordalignmin : 0;
+ recordalignmax : 8;
+ maxCrecordalign : 8
+ );
+ first_parm_offset : 92;
+ stacksize : 262144;
+ DllScanSupported:false;
+ use_function_relative_addresses : true;
+ abi : abi_default
+ );
+
+ system_arm_linux_info : tsysteminfo =
+ (
+ system : system_arm_Linux;
+ name : 'Linux for ARM';
+ shortname : 'Linux';
+ flags : [tf_needs_symbol_size,tf_needs_symbol_type];
+ cpu : cpu_arm;
+ unit_env : 'LINUXUNITS';
+ extradefines : 'UNIX;HASUNIX';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 4;
+ localalignmax : 8;
+ recordalignmin : 0;
+ recordalignmax : 4;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 262144;
+ DllScanSupported:false;
+ use_function_relative_addresses : true;
+ abi : abi_default
+ );
+
+ implementation
+
+initialization
+{$ifdef CPU86}
+ {$ifdef linux}
+ { some FreeBSD versions define linux as well }
+ {$ifndef FreeBSD}
+ set_source_info(system_i386_linux_info);
+ {$endif FreeBSD}
+ {$endif}
+{$endif CPU86}
+{$ifdef CPU68}
+ {$ifdef linux}
+ set_source_info(system_m68k_linux_info);
+ {$endif linux}
+{$endif CPU68}
+{$ifdef CPUX86_64}
+ {$ifdef linux}
+ set_source_info(system_x86_64_linux_info);
+ {$endif linux}
+{$endif CPUX86_64}
+{$ifdef CPUALPHA}
+ {$ifdef linux}
+ set_source_info(system_alpha_linux_info);
+ {$endif linux}
+{$endif CPUALPHA}
+{$ifdef CPUSPARC}
+ {$ifdef linux}
+ set_source_info(system_sparc_linux_info);
+ {$endif linux}
+{$endif CPUSPARC}
+{$ifdef CPUPOWERPC32}
+ {$ifdef linux}
+ set_source_info(system_powerpc_linux_info);
+ {$endif linux}
+{$endif CPUPOWERPC32}
+{$ifdef CPUPOWERPC64}
+ {$ifdef linux}
+ set_source_info(system_powerpc64_linux_info);
+ {$endif linux}
+{$endif CPUPOWERPC64}
+{$ifdef CPUARM}
+ {$ifdef linux}
+ set_source_info(system_arm_linux_info);
+ {$endif linux}
+{$endif CPUARM}
+end.
diff --git a/compiler/systems/i_macos.pas b/compiler/systems/i_macos.pas
new file mode 100644
index 0000000000..cdc387a841
--- /dev/null
+++ b/compiler/systems/i_macos.pas
@@ -0,0 +1,100 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ This unit implements support information structures for MacOS
+
+ 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.
+ ****************************************************************************
+}
+{ This unit implements support information structures for MacOS. }
+unit i_macos;
+
+ interface
+
+ uses
+ systems;
+ const
+ system_powerpc_macos_info : tsysteminfo =
+ (
+ system : system_powerpc_MACOS;
+ name : 'Mac OS for PowerPC';
+ shortname : 'MacOS';
+ flags : [];
+ cpu : cpu_powerpc;
+ unit_env : '';
+ extradefines : '';
+ exeext : '';
+ defext : '';
+ scriptext : '';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : 'Lib';
+ staticlibext : 'Lib';
+ staticlibprefix : '';
+ sharedlibprefix : '';
+ sharedClibext : 'Lib';
+ staticClibext : 'Lib';
+ staticClibprefix : '';
+ sharedClibprefix : '';
+ p_ext_support : true;
+ Cprefix : '';
+ newline : #13;
+ dirsep : ':';
+ files_case_relevent : false;
+ assem : as_powerpc_mpw;
+ assemextern : as_powerpc_mpw;
+ link : nil;
+ linkextern : nil;
+ ar : ar_mpw_ar;
+ res : res_powerpc_mpw;
+ dbg : dbg_stabs;
+ script : script_mpw;
+ endian : endian_big;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 8;
+ localalignmax : 8;
+ recordalignmin : 0;
+ recordalignmax : 2;
+ maxCrecordalign : 16
+ );
+ first_parm_offset : 8;
+ stacksize : 262144;
+ DllScanSupported:false;
+ use_function_relative_addresses : true;
+ abi : abi_powerpc_aix;
+ );
+
+ implementation
+
+initialization
+{$ifdef cpupowerpc}
+ {$ifdef macos}
+ set_source_info(system_powerpc_macos_info);
+ {$endif macos}
+{$endif cpupowerpc}
+end.
diff --git a/compiler/systems/i_morph.pas b/compiler/systems/i_morph.pas
new file mode 100644
index 0000000000..a5d7bb1cdb
--- /dev/null
+++ b/compiler/systems/i_morph.pas
@@ -0,0 +1,101 @@
+{
+ Copyright (c) 2004 by Free Pascal Development Team
+
+ This unit implements support information structures for MorphOS
+
+ 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.
+ ****************************************************************************
+}
+{ This unit implements support information structures for the MorphOS. }
+unit i_morph;
+
+ interface
+
+ uses
+ systems;
+
+ const
+ system_powerpc_MorphOS_info : tsysteminfo =
+ (
+ system : system_powerpc_MorphOS;
+ name : 'MorphOS';
+ shortname : 'MorphOS';
+ flags : [];
+ cpu : cpu_powerpc;
+ unit_env : '';
+ extradefines : '';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.library';
+ staticlibext : '.a';
+ staticlibprefix : 'lib';
+ sharedlibprefix : '';
+ sharedClibext : '.library';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : '';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_amiga;
+ endian : endian_big;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 0;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 4;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 262144;
+ DllScanSupported:false;
+ use_function_relative_addresses : true;
+ abi : abi_powerpc_sysv;
+ );
+
+ implementation
+
+initialization
+{$ifdef CPUPOWERPC}
+ {$ifdef MORPHOS}
+ set_source_info(system_powerpc_MorphOS_info);
+ {$endif MORPHOS}
+{$endif CPUPOWERPC}
+end.
diff --git a/compiler/systems/i_nwl.pas b/compiler/systems/i_nwl.pas
new file mode 100644
index 0000000000..a1abad2f51
--- /dev/null
+++ b/compiler/systems/i_nwl.pas
@@ -0,0 +1,100 @@
+{
+ Copyright (c) 1998-2004 by Peter Vreman
+
+ This unit implements support information structures for Netware (libc) modules
+
+ 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.
+ ****************************************************************************}
+
+{ This unit implements support information structures for Netware libc modules. }
+unit i_nwl;
+
+ interface
+
+ uses
+ systems;
+
+ const
+ system_i386_netwlibc_info : tsysteminfo =
+ (
+ system : system_i386_netwlibc;
+ name : 'Netware for i386(libc)';
+ shortname : 'Netwlibc';
+ flags : [];
+ cpu : cpu_i386;
+ unit_env : 'NETWLIBCUNITS';
+ extradefines : 'NETWARE;NETWARE_LIBC';
+ exeext : '.nlm';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.nlm';
+ staticlibext : '.a';
+ staticlibprefix : '';
+ sharedlibprefix : '';
+ sharedClibext : '.nlm';
+ staticClibext : '.a';
+ staticClibprefix : '';
+ sharedClibprefix : '';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #13#10;
+ dirsep : '/';
+ files_case_relevent : false;
+ assem : as_i386_elf32;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 4;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 4;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 16384;
+ DllScanSupported:false;
+ use_function_relative_addresses : true
+ );
+
+ implementation
+
+initialization
+{$ifdef CPU86}
+ {$ifdef netwlibc}
+ set_source_info(system_i386_netwlibc_info);
+ {$endif netwlibc}
+{$endif CPU86}
+end.
diff --git a/compiler/systems/i_nwm.pas b/compiler/systems/i_nwm.pas
new file mode 100644
index 0000000000..8880accfed
--- /dev/null
+++ b/compiler/systems/i_nwm.pas
@@ -0,0 +1,100 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ This unit implements support information structures for Netware modules
+
+ 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.
+ ****************************************************************************
+}
+{ This unit implements support information structures for Netware modules. }
+unit i_nwm;
+
+ interface
+
+ uses
+ systems;
+
+ const
+ system_i386_netware_info : tsysteminfo =
+ (
+ system : system_i386_netware;
+ name : 'Netware for i386(clib)';
+ shortname : 'Netware';
+ flags : [];
+ cpu : cpu_i386;
+ unit_env : 'NETWAREUNITS';
+ extradefines : 'NETWARE_CLIB';
+ exeext : '.nlm';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.nlm';
+ staticlibext : '.a';
+ staticlibprefix : '';
+ sharedlibprefix : '';
+ sharedClibext : '.nlm';
+ staticClibext : '.a';
+ staticClibprefix : '';
+ sharedClibprefix : '';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #13#10;
+ dirsep : '/';
+ files_case_relevent : false;
+ assem : as_i386_elf32;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 4;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 4;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 16384;
+ DllScanSupported:false;
+ use_function_relative_addresses : true
+ );
+
+ implementation
+
+initialization
+{$ifdef CPU86}
+ {$ifdef netware}
+ set_source_info(system_i386_netware_info);
+ {$endif netware}
+{$endif CPU86}
+end.
diff --git a/compiler/systems/i_os2.pas b/compiler/systems/i_os2.pas
new file mode 100644
index 0000000000..adb306689e
--- /dev/null
+++ b/compiler/systems/i_os2.pas
@@ -0,0 +1,114 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ This unit implements support information structures for OS/2
+
+ 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.
+ ****************************************************************************
+}
+{ This unit implements support information structures for OS/2. }
+unit i_os2;
+
+ interface
+
+ uses
+ systems;
+
+ const
+ res_emxbind_info : tresinfo =
+ (
+ id : res_emxbind;
+ resbin : 'emxbind';
+ rescmd : '-b -r $RES $OBJ'
+ (* Not really used - see TLinkeros2.SetDefaultInfo in t_os2.pas. *)
+ );
+
+ system_i386_os2_info : tsysteminfo =
+ (
+ system : system_i386_OS2;
+ name : 'OS/2';
+ shortname : 'OS2';
+ flags : [tf_need_export,tf_use_8_3];
+ cpu : cpu_i386;
+ unit_env : 'OS2UNITS';
+ extradefines : '';
+ exeext : '.exe';
+ defext : '.def';
+ scriptext : '.cmd';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.dll';
+ staticlibext : '.a';
+ staticlibprefix : '';
+ sharedlibprefix : '';
+ sharedClibext : '.dll';
+ staticClibext : '.a';
+ staticClibprefix : '';
+ sharedClibprefix : '';
+ p_ext_support : false;
+ Cprefix : '_';
+ newline : #13#10;
+ dirsep : '\';
+ files_case_relevent : false;
+ assem : as_i386_as_aout;
+ assemextern : as_i386_as_aout;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_emxbind;
+ dbg : dbg_stabs;
+ script : script_dos;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 0;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 2;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 256*1024;
+ DllScanSupported: false;
+ use_function_relative_addresses : false
+ );
+
+
+ implementation
+
+initialization
+{$ifdef CPU86}
+ {$ifdef os2}
+ {$IFNDEF EMX}
+ set_source_info(system_i386_os2_info);
+ {$ENDIF EMX}
+ {$IFDEF VER1_0}
+ set_source_info(system_i386_os2_info);
+ {$ENDIF VER1_0}
+ {$endif os2}
+{$endif CPU86}
+end.
diff --git a/compiler/systems/i_palmos.pas b/compiler/systems/i_palmos.pas
new file mode 100644
index 0000000000..fda9a52eb3
--- /dev/null
+++ b/compiler/systems/i_palmos.pas
@@ -0,0 +1,90 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ This unit implements support information structures for PalmOS
+
+ 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.
+ ****************************************************************************
+}
+{ This unit implements support information structures for PalmOS. }
+unit i_palmos;
+
+ interface
+
+ uses
+ systems;
+
+ const
+ system_m68k_palmos_info : tsysteminfo =
+ (
+ system : system_m68k_PalmOS;
+ name : 'PalmOS';
+ shortname : 'PalmOS';
+ flags : [tf_code_small,tf_static_a5_based];
+ cpu : cpu_m68k;
+ short_name : 'PALMOS';
+ unit_env : 'PALMUNITS';
+ extradefines : '';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ exeext : '';
+ defext : '';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '_';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : ld_m68k_palmos;
+ linkextern : ld_m68k_palmos;
+ ar : ar_m68k_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_big;
+ stackalignment : 2;
+ maxCrecordalignment : 4;
+ stacksize : 8192;
+ DllScanSupported:false;
+ use_function_relative_addresses : false
+ );
+
+ res_m68k_palmos_info : tresinfo =
+ (
+ id : res_m68k_palmos;
+ resbin : 'pilrc';
+ rescmd : '-I $INC $RES'
+ );
+
+implementation
+
+initialization
+{$ifdef cpu68}
+ {$ifdef palmos}
+ set_source_info(system_m68k_palmos_info);
+ {$endif palmos}
+{$endif cpu68}
+end.
diff --git a/compiler/systems/i_sunos.pas b/compiler/systems/i_sunos.pas
new file mode 100644
index 0000000000..073a3e4bfa
--- /dev/null
+++ b/compiler/systems/i_sunos.pas
@@ -0,0 +1,168 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ This unit implements support information structures for solaris
+
+ 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.
+ ****************************************************************************
+}
+{ This unit implements support information structures for solaris. }
+unit i_sunos;
+
+ interface
+
+ uses
+ systems;
+
+ const
+ system_i386_solaris_info : tsysteminfo =
+ (
+ system : system_i386_solaris;
+ name : 'Solaris for i386';
+ shortname : 'solaris';
+ flags : [tf_under_development];
+ cpu : cpu_i386;
+ unit_env : 'SOLARISUNITS';
+ extradefines : 'UNIX;LIBC';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 1;
+ varalignmin : 0;
+ varalignmax : 1;
+ localalignmin : 0;
+ localalignmax : 1;
+ recordalignmin : 0;
+ recordalignmax : 2;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 262144;
+ DllScanSupported:false;
+ use_function_relative_addresses : true
+ );
+
+ system_sparc_solaris_info : tsysteminfo =
+ (
+ system : system_sparc_solaris;
+ name : 'Solaris for SPARC';
+ shortname : 'solaris';
+ flags : [tf_needs_symbol_size];
+ cpu : cpu_SPARC;
+ unit_env : 'SOLARISUNITS';
+ extradefines : 'UNIX;LIBC;';
+ exeext : '';
+ defext : '.def';
+ scriptext : '.sh';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.so';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : 'lib';
+ sharedClibext : '.so';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : 'lib';
+ p_ext_support : false;
+ Cprefix : '';
+ newline : #10;
+ dirsep : '/';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_unix;
+ endian : endian_big;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 8;
+ varalignmin : 0;
+ varalignmax : 8;
+ localalignmin : 4;
+ localalignmax : 8;
+ recordalignmin : 0;
+ recordalignmax : 8;
+ maxCrecordalign : 8
+ );
+ first_parm_offset : 92;
+ stacksize : 262144;
+ DllScanSupported:false;
+ use_function_relative_addresses : true
+ );
+
+ implementation
+
+initialization
+{$ifdef CPU86}
+ {$ifdef solaris}
+ set_source_info(system_i386_solaris_info);
+ {$endif solaris}
+{$endif CPU86}
+{$ifdef CPUSparc}
+ {$ifdef solaris}
+ set_source_info(system_sparc_solaris_info);
+ {$endif solaris}
+{$endif CPUSparc}
+
+end.
diff --git a/compiler/systems/i_watcom.pas b/compiler/systems/i_watcom.pas
new file mode 100644
index 0000000000..751357102b
--- /dev/null
+++ b/compiler/systems/i_watcom.pas
@@ -0,0 +1,102 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ This unit implements support information structures for Watcom
+
+ 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.
+ ****************************************************************************
+}
+{ This unit implements support information structures for Watcom. }
+unit i_watcom;
+
+{$i fpcdefs.inc}
+
+ interface
+
+ uses
+ systems;
+
+ const
+ system_i386_watcom_info : tsysteminfo =
+ (
+ system : system_i386_Watcom;
+ name : 'Watcom compatible DOS extenders';
+ shortname : 'WATCOM';
+ flags : [tf_use_8_3];
+ cpu : cpu_i386;
+ unit_env : 'WATCOMUNITS';
+ extradefines : 'DPMI';
+ exeext : '.exe';
+ defext : '.def';
+ scriptext : '.bat';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.asm';
+ objext : '.obj';
+ resext : '.res';
+ resobjext : '.or';
+ sharedlibext : '.dll';
+ staticlibext : '.a';
+ staticlibprefix : '';
+ sharedlibprefix : '';
+ sharedClibext : '.dll';
+ staticClibext : '.a';
+ staticClibprefix : '';
+ sharedClibprefix : '';
+ p_ext_support : false;
+ Cprefix : '_';
+ newline : #13#10;
+ dirsep : '\';
+ files_case_relevent : false;
+ assem : as_i386_wasm;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_none;
+ dbg : dbg_stabs;
+ script : script_dos;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 0;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 2;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 16384;
+ DllScanSupported : false;
+ use_function_relative_addresses : true
+ );
+
+ implementation
+
+initialization
+{$ifdef cpu86}
+ {$ifdef watcom}
+ set_source_info(system_i386_watcom_info);
+ {$endif watcom}
+{$endif cpu86}
+end.
diff --git a/compiler/systems/i_wdosx.pas b/compiler/systems/i_wdosx.pas
new file mode 100644
index 0000000000..75091db330
--- /dev/null
+++ b/compiler/systems/i_wdosx.pas
@@ -0,0 +1,102 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ This unit implements support information structures for win32
+
+ 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.
+ ****************************************************************************
+}
+{ This unit implements support information structures for wdosx. }
+unit i_wdosx;
+
+ interface
+
+ uses
+ systems;
+
+ const
+ system_i386_wdosx_info : tsysteminfo =
+ (
+ system : system_i386_wdosx;
+ name : 'WDOSX DOS extender';
+ shortname : 'WDOSX';
+ flags : [tf_use_8_3];
+ cpu : cpu_i386;
+ unit_env : 'WDOSXUNITS';
+ extradefines : 'MSWINDOWS';
+ exeext : '.exe';
+ defext : '.def';
+ scriptext : '.bat';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.rc';
+ resobjext : '.or';
+ sharedlibext : '.dll';
+ staticlibext : '.a';
+ staticlibprefix : '';
+ sharedlibprefix : '';
+ sharedClibext : '.dll';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : '';
+ p_ext_support : false;
+ Cprefix : '_';
+ newline : #13#10;
+ dirsep : '\';
+ files_case_relevent : false;
+ assem : as_i386_pecoffwdosx;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_gnu_windres;
+ dbg : dbg_stabs;
+ script : script_dos;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 0;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 2;
+ maxCrecordalign : 16
+ );
+ first_parm_offset : 8;
+ stacksize : 32*1024*1024;
+ DllScanSupported:true;
+ use_function_relative_addresses : true
+ );
+
+ implementation
+
+initialization
+{$ifdef CPU86}
+ {$ifdef WIN32}
+ {$ifdef WDOSX}
+ set_source_info(system_i386_wdosx_info);
+ {$endif WDOSX}
+ {$endif WIN32}
+{$endif CPU86}
+end.
diff --git a/compiler/systems/i_win.pas b/compiler/systems/i_win.pas
new file mode 100644
index 0000000000..b5a7192a5a
--- /dev/null
+++ b/compiler/systems/i_win.pas
@@ -0,0 +1,306 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ This unit implements support information structures for win32
+
+ 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.
+ ****************************************************************************
+}
+{ This unit implements support information structures for win32. }
+unit i_win;
+
+ interface
+
+ uses
+ systems;
+
+ const
+ system_i386_win32_info : tsysteminfo =
+ (
+ system : system_i386_WIN32;
+ name : 'Win32 for i386';
+ shortname : 'Win32';
+ flags : [];
+ cpu : cpu_i386;
+ unit_env : 'WIN32UNITS';
+ extradefines : 'MSWINDOWS';
+ exeext : '.exe';
+ defext : '.def';
+ scriptext : '.bat';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.rc';
+ resobjext : '.or';
+ sharedlibext : '.dll';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : '';
+ sharedClibext : '.dll';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : '';
+ p_ext_support : false;
+ Cprefix : '_';
+ newline : #13#10;
+ dirsep : '\';
+ files_case_relevent : true;
+ assem : as_i386_pecoff;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_gnu_windres;
+ dbg : dbg_stabs;
+ script : script_dos;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 4;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 4;
+ maxCrecordalign : 16
+ );
+ first_parm_offset : 8;
+ stacksize : 262144;
+ DllScanSupported:true;
+ use_function_relative_addresses : true
+ );
+
+ system_x64_win64_info : tsysteminfo =
+ (
+ system : system_x86_64_win64;
+ name : 'Win64 for x64';
+ shortname : 'Win64';
+ flags : [];
+ cpu : cpu_x86_64;
+ unit_env : 'WIN64UNITS';
+ extradefines : 'MSWINDOWS';
+ exeext : '.exe';
+ defext : '.def';
+ scriptext : '.bat';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.rc';
+ resobjext : '.or';
+ sharedlibext : '.dll';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : '';
+ sharedClibext : '.dll';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : '';
+ p_ext_support : false;
+ Cprefix : '_';
+ newline : #13#10;
+ dirsep : '\';
+ files_case_relevent : true;
+ assem : as_x86_64_pecoff;
+ assemextern : as_x86_64_masm;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_gnu_windres;
+ dbg : dbg_stabs;
+ script : script_dos;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 8;
+ loopalign : 8;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 8;
+ varalignmin : 0;
+ varalignmax : 8;
+ localalignmin : 8;
+ localalignmax : 8;
+ recordalignmin : 0;
+ recordalignmax : 8;
+ maxCrecordalign : 16
+ );
+ first_parm_offset : 16;
+ stacksize : 262144;
+ DllScanSupported:true;
+ use_function_relative_addresses : true
+ );
+
+ system_arm_wince_info : tsysteminfo =
+ (
+ system : system_arm_wince;
+ name : 'WinCE for ARM';
+ shortname : 'WinCE';
+ flags : [];
+ cpu : cpu_arm;
+ unit_env : '';
+ extradefines : 'UNDER_CE';
+ exeext : '.exe';
+ defext : '.def';
+ scriptext : '.bat';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.rc';
+ resobjext : '.or';
+ sharedlibext : '.dll';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : '';
+ sharedClibext : '.dll';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : '';
+ p_ext_support : false;
+ Cprefix : '_';
+ newline : #13#10;
+ dirsep : '\';
+ files_case_relevent : true;
+ assem : as_gas;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_gnu_wince_windres;
+ dbg : dbg_stabs;
+ script : script_dos;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 0;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 2;
+ maxCrecordalign : 4
+ );
+ first_parm_offset : 8;
+ stacksize : 262144;
+ DllScanSupported:false;
+ use_function_relative_addresses : true
+ );
+
+ system_i386_wince_info : tsysteminfo =
+ (
+ system : system_i386_wince;
+ name : 'WinCE for i386';
+ shortname : 'WinCE';
+ flags : [];
+ cpu : cpu_i386;
+ unit_env : '';
+ extradefines : 'UNDER_CE';
+ exeext : '.exe';
+ defext : '.def';
+ scriptext : '.bat';
+ smartext : '.sl';
+ unitext : '.ppu';
+ unitlibext : '.ppl';
+ asmext : '.s';
+ objext : '.o';
+ resext : '.rc';
+ resobjext : '.or';
+ sharedlibext : '.dll';
+ staticlibext : '.a';
+ staticlibprefix : 'libp';
+ sharedlibprefix : '';
+ sharedClibext : '.dll';
+ staticClibext : '.a';
+ staticClibprefix : 'lib';
+ sharedClibprefix : '';
+ p_ext_support : false;
+ Cprefix : '_';
+ newline : #13#10;
+ dirsep : '\';
+ files_case_relevent : true;
+ assem : as_i386_pecoffwince;
+ assemextern : as_gas;
+ link : nil;
+ linkextern : nil;
+ ar : ar_gnu_ar;
+ res : res_gnu_windres;
+ dbg : dbg_stabs;
+ script : script_dos;
+ endian : endian_little;
+ alignment :
+ (
+ procalign : 4;
+ loopalign : 4;
+ jumpalign : 0;
+ constalignmin : 0;
+ constalignmax : 4;
+ varalignmin : 0;
+ varalignmax : 4;
+ localalignmin : 4;
+ localalignmax : 4;
+ recordalignmin : 0;
+ recordalignmax : 4;
+ maxCrecordalign : 16
+ );
+ first_parm_offset : 8;
+ stacksize : 262144;
+ DllScanSupported:true;
+ use_function_relative_addresses : true
+ );
+
+
+ implementation
+
+initialization
+{$ifdef CPU86}
+ {$ifdef WIN32}
+ {$ifndef WDOSX}
+ set_source_info(system_i386_win32_info);
+ {$endif WDOSX}
+ {$endif WIN32}
+ {$ifdef WINCE}
+ set_source_info(system_i386_wince_info);
+ {$endif WINCE}
+{$endif CPU86}
+
+{$ifdef CPUX86_64}
+ {$ifdef WIN64}
+ {$ifndef WDOSX}
+ set_source_info(system_x64_win64_info);
+ {$endif WDOSX}
+ {$endif WIN64}
+{$endif CPUX86_64}
+
+{$ifdef CPUARM}
+ {$ifdef WINCE}
+ set_source_info(system_arm_wince_info);
+ {$endif WINCE}
+{$endif CPUARM}
+end.
diff --git a/compiler/systems/mac_crea.txt b/compiler/systems/mac_crea.txt
new file mode 100644
index 0000000000..5372652cbc
--- /dev/null
+++ b/compiler/systems/mac_crea.txt
@@ -0,0 +1,71 @@
+FrŒn: devprograms@apple.com
+Till: <olle.raab@freepascal.org>
+Datum: mŒndag 10 januari 2005 22.33
+€mne: Re: Creator Registration Request
+
+Please include the line below in follow-up emails for this request.
+
+Follow-up: 6855616
+
+Re: Creator Registration Request
+
+Dear Olle Raab,
+
+Thank you for registering your application creator information. We appreciate your continued product development and support of Apple Computer! The following product information has been registered:
+
+Company: Free Pascal Team
+Contact: Olle Raab
+Address: VikingavŠgen 28 A
+S-224 77 Lund
+Sweden
+
+
+Application: Free Pascal Compiler
+Phone: +46-46-120053
+EMail Address: olle.raab@freepascal.org
+
+Application Signatures:
+FPas (Hex) 46506173
+
+This letter serves as your confirmation. Please keep it on file. Additionally, you should review the information for accuracy. If you locate discrepancies, please contact Developer Support at devprograms@apple.com with your corrections.
+
+Thanks for supporting Apple!
+
+Best regards,
+
+Elisa Molson
+Apple Developer Connection
+-----------------------------------
+Spotlight, 64-bit Support, Dashboard, Automator, and more.
+Start developing today with the powerful new technologies in Mac OS X Tiger.
+
+REQUEST ------------------------------------------------------------------------
+
+WEB CREATOR/FILE TYPE Registration Request
+==========================================
+%UNIQUE REGISTRATION%:
+%NAME%: Olle Raab
+%COMPANY%: Free Pascal Team
+%ADDRESS%: VikingavŠgen 28 A
+S-224 77 Lund
+Sweden
+%TELEPHONE%: +46-46-120053
+%E-MAIL%: olle.raab@freepascal.org
+%PRODUCT NAME%: Free Pascal Compiler
+%DEVICE DRIVER%:
+%SIGNATURE (HEX)%: 46506173
+%END
+
+
+DB REFERENCE -------------------------------------------------------------------
+
+TIME IN: 10-Jan-2005 10:45 PST
+TIME OUT: 10-Jan-2005 13:16 PST
+
+Copyright 2005, Apple Computer, Inc.
+
+SECURITY: NON-DISCLOSURE USE ONLY
+
+
+
+
diff --git a/compiler/systems/t_amiga.pas b/compiler/systems/t_amiga.pas
new file mode 100644
index 0000000000..95e9d340b9
--- /dev/null
+++ b/compiler/systems/t_amiga.pas
@@ -0,0 +1,43 @@
+{
+ Copyright (c) 2001-2002 by Peter Vreman
+
+ This unit implements support import,export,link routines
+ for the (m68k/powerpc) Amiga 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_amiga;
+
+{$i fpcdefs.inc}
+
+interface
+
+
+implementation
+
+ uses
+ link,
+ cutils,cclasses,
+ globtype,globals,systems,verbose,script,fmodule,i_amiga;
+
+{*****************************************************************************
+ Initialize
+*****************************************************************************}
+
+initialization
+ RegisterTarget(system_m68k_amiga_info);
+end.
diff --git a/compiler/systems/t_atari.pas b/compiler/systems/t_atari.pas
new file mode 100644
index 0000000000..5833ac8129
--- /dev/null
+++ b/compiler/systems/t_atari.pas
@@ -0,0 +1,43 @@
+{
+ Copyright (c) 2001-2002 by Peter Vreman
+
+ This unit implements support import,export,link routines
+ for the (i386) Amiga 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_atari;
+
+{$i fpcdefs.inc}
+
+interface
+
+
+implementation
+
+ uses
+ link,
+ cutils,cclasses,
+ globtype,globals,systems,verbose,script,fmodule,i_atari;
+
+{*****************************************************************************
+ Initialize
+*****************************************************************************}
+
+initialization
+ RegisterTarget(system_m68k_atari_info);
+end.
diff --git a/compiler/systems/t_beos.pas b/compiler/systems/t_beos.pas
new file mode 100644
index 0000000000..5e9ea9f54e
--- /dev/null
+++ b/compiler/systems/t_beos.pas
@@ -0,0 +1,495 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ This unit implements support import,export,link routines
+ for the (i386) BeOS 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_beos;
+
+{$i fpcdefs.inc}
+
+interface
+
+ uses
+ symsym,symdef,
+ import,export,link;
+
+ type
+ timportlibbeos=class(timportlib)
+ procedure preparelib(const s:string);override;
+ procedure importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);override;
+ procedure importvariable(vs:tglobalvarsym;const name,module:string);override;
+ procedure generatelib;override;
+ end;
+
+ texportlibbeos=class(texportlib)
+ procedure preparelib(const s : string);override;
+ procedure exportprocedure(hp : texported_item);override;
+ procedure exportvar(hp : texported_item);override;
+ procedure generatelib;override;
+ end;
+
+ tlinkerbeos=class(texternallinker)
+ private
+ Function WriteResponseFile(isdll:boolean;makelib:boolean) : Boolean;
+ public
+ constructor Create;override;
+ procedure SetDefaultInfo;override;
+ function MakeExecutable:boolean;override;
+ function MakeSharedLibrary:boolean;override;
+ end;
+
+
+implementation
+
+ uses
+ dos,
+ cutils,cclasses,
+ verbose,systems,globtype,globals,
+ symconst,script,
+ fmodule,aasmbase,aasmtai,aasmcpu,cpubase,i_beos;
+
+{*****************************************************************************
+ TIMPORTLIBBEOS
+*****************************************************************************}
+
+procedure timportlibbeos.preparelib(const s : string);
+begin
+end;
+
+
+procedure timportlibbeos.importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);
+begin
+ { insert sharedlibrary }
+ current_module.linkothersharedlibs.add(SplitName(module),link_allways);
+end;
+
+
+procedure timportlibbeos.importvariable(vs:tglobalvarsym;const name,module:string);
+begin
+ { insert sharedlibrary }
+ current_module.linkothersharedlibs.add(SplitName(module),link_allways);
+ { reset the mangledname and turn off the dll_var option }
+ vs.set_mangledname(name);
+ exclude(vs.varoptions,vo_is_dll_var);
+end;
+
+
+procedure timportlibbeos.generatelib;
+begin
+end;
+
+
+{*****************************************************************************
+ TEXPORTLIBBEOS
+*****************************************************************************}
+
+procedure texportlibbeos.preparelib(const s:string);
+begin
+end;
+
+
+procedure texportlibbeos.exportprocedure(hp : texported_item);
+var
+ hp2 : texported_item;
+begin
+ { first test the index value }
+ if (hp.options and eo_index)<>0 then
+ begin
+ Message1(parser_e_no_export_with_index_for_target,'beos');
+ exit;
+ end;
+ { now place in correct order }
+ hp2:=texported_item(current_module._exports.first);
+ while assigned(hp2) and
+ (hp.name^>hp2.name^) do
+ hp2:=texported_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=texported_item(current_module._exports.first) then
+ current_module._exports.concat(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 texportlibbeos.exportvar(hp : texported_item);
+begin
+ hp.is_var:=true;
+ exportprocedure(hp);
+end;
+
+
+procedure texportlibbeos.generatelib;
+var
+ hp2 : texported_item;
+begin
+ hp2:=texported_item(current_module._exports.first);
+ while assigned(hp2) do
+ begin
+ if (not hp2.is_var) and
+ (hp2.sym.typ=procsym) then
+ begin
+ { the manglednames can already be the same when the procedure
+ is declared with cdecl }
+ if tprocsym(hp2.sym).first_procdef.mangledname<>hp2.name^ then
+ begin
+{$ifdef i386}
+ { place jump in al_procedures }
+ asmlist[al_procedures].concat(Tai_align.Create_op(4,$90));
+ asmlist[al_procedures].concat(Tai_symbol.Createname_global(hp2.name^,AT_FUNCTION,0));
+ asmlist[al_procedures].concat(Taicpu.Op_sym(A_JMP,S_NO,objectlibrary.newasmsymbol(tprocsym(hp2.sym).first_procdef.mangledname,AB_EXTERNAL,AT_FUNCTION)));
+ asmlist[al_procedures].concat(Tai_symbol_end.Createname(hp2.name^));
+{$endif i386}
+ end;
+ end
+ else
+ Message1(parser_e_no_export_of_variables_for_target,'beos');
+ hp2:=texported_item(hp2.next);
+ end;
+end;
+
+
+{*****************************************************************************
+ TLINKERBEOS
+*****************************************************************************}
+
+Constructor TLinkerBeos.Create;
+var
+ s : string;
+ i : integer;
+begin
+ Inherited Create;
+ s:=GetEnv('BELIBRARIES');
+ { convert to correct format in case under unix system }
+ for i:=1 to length(s) do
+ if s[i] = ':' then
+ s[i] := ';';
+ { just in case we have a single path : add the ending ; }
+ { since that is what the compiler expects. }
+ if pos(';',s) = 0 then
+ s:=s+';';
+ LibrarySearchPath.AddPath(s,true); {format:'path1;path2;...'}
+end;
+
+
+procedure TLinkerBeOS.SetDefaultInfo;
+begin
+ with Info do
+ begin
+ ExeCmd[1]:='ld $OPT $DYNLINK $STATIC $STRIP -L. -o $EXE `cat $RES`';
+ DllCmd[1]:='ld $OPT $INIT $FINI $SONAME -shared -L. -o $EXE `cat $RES`';
+ DllCmd[2]:='strip --strip-unneeded $EXE';
+(*
+ ExeCmd[1]:='sh $RES $EXE $OPT $STATIC $STRIP -L.';
+{ ExeCmd[1]:='sh $RES $EXE $OPT $DYNLINK $STATIC $STRIP -L.';}
+ DllCmd[1]:='sh $RES $EXE $OPT -L.';
+
+{ DllCmd[1]:='sh $RES $EXE $OPT -L. -g -nostart -soname=$EXE';
+ } DllCmd[2]:='strip --strip-unneeded $EXE';
+{ DynamicLinker:='/lib/ld-beos.so.2';}
+*)
+ end;
+end;
+
+
+function TLinkerBeOS.WriteResponseFile(isdll:boolean;makelib:boolean) : Boolean;
+Var
+ linkres : TLinkRes;
+ i : integer;
+ cprtobj,
+ prtobj : string[80];
+ HPath : TStringListItem;
+ s : string;
+ linklibc : boolean;
+begin
+ WriteResponseFile:=False;
+{ set special options for some targets }
+ linklibc:=(SharedLibFiles.Find('root')<>nil);
+
+ prtobj:='prt0';
+ cprtobj:='cprt0';
+ if (cs_profile in aktmoduleswitches) or
+ (not SharedLibFiles.Empty) then
+ begin
+ AddSharedLibrary('root');
+ linklibc:=true;
+ end;
+
+ if (not linklibc) and makelib then
+ begin
+ linklibc:=true;
+ cprtobj:='dllprt.o';
+ end;
+
+ if linklibc then
+ prtobj:=cprtobj;
+
+ { Open link.res file }
+ LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
+ {
+ if not isdll then
+ LinkRes.Add('ld -o $1 $2 $3 $4 $5 $6 $7 $8 $9 \')
+ else
+ LinkRes.Add('ld -o $1 -e 0 $2 $3 $4 $5 $6 $7 $8 $9\');
+ }
+ LinkRes.Add('-m elf_i386_be -shared -Bsymbolic');
+
+ { Write path to search libraries }
+ HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
+ while assigned(HPath) do
+ begin
+ LinkRes.Add(maybequoted('-L'+HPath.Str));
+ HPath:=TStringListItem(HPath.Next);
+ end;
+ HPath:=TStringListItem(LibrarySearchPath.First);
+ while assigned(HPath) do
+ begin
+ LinkRes.Add(maybequoted('-L'+HPath.Str));
+ HPath:=TStringListItem(HPath.Next);
+ end;
+
+ { try to add crti and crtbegin if linking to C }
+ if linklibc then
+ begin
+ if librarysearchpath.FindFile('crti.o',s) then
+ LinkRes.AddFileName(s);
+ if librarysearchpath.FindFile('crtbegin.o',s) then
+ LinkRes.AddFileName(s);
+{ s:=librarysearchpath.FindFile('start_dyn.o',found)+'start_dyn.o';
+ if found then LinkRes.AddFileName(s+' \');}
+
+ if prtobj<>'' then
+ LinkRes.AddFileName(FindObjectFile(prtobj,'',false));
+
+ if isdll then
+ LinkRes.AddFileName(FindObjectFile('func.o','',false));
+
+ if librarysearchpath.FindFile('init_term_dyn.o',s) then
+ LinkRes.AddFileName(s);
+ end
+ else
+ begin
+ if prtobj<>'' then
+ LinkRes.AddFileName(FindObjectFile(prtobj,'',false));
+ end;
+
+ { main objectfiles }
+ while not ObjectFiles.Empty do
+ begin
+ s:=ObjectFiles.GetFirst;
+ if s<>'' then
+ LinkRes.AddFileName(maybequoted(s));
+ end;
+
+{ LinkRes.Add('-lroot \');
+ LinkRes.Add('/boot/develop/tools/gnupro/lib/gcc-lib/i586-beos/2.9-beos-991026/crtend.o \');
+ LinkRes.Add('/boot/develop/lib/x86/crtn.o \');}
+
+ { Write staticlibraries }
+ if not StaticLibFiles.Empty then
+ begin
+ While not StaticLibFiles.Empty do
+ begin
+ S:=StaticLibFiles.GetFirst;
+ LinkRes.AddFileName(maybequoted(s))
+ end;
+ end;
+
+ { Write sharedlibraries like -l<lib> }
+ if not SharedLibFiles.Empty then
+ begin
+ While not SharedLibFiles.Empty do
+ begin
+ S:=SharedLibFiles.GetFirst;
+ if s<>'c' then
+ begin
+ i:=Pos(target_info.sharedlibext,S);
+ if i>0 then
+ Delete(S,i,255);
+ LinkRes.Add('-l'+s);
+ end
+ else
+ begin
+ linklibc:=true;
+ end;
+ end;
+ { be sure that libc is the last lib }
+{ if linklibc then
+ LinkRes.Add('-lroot');}
+{ if linkdynamic and (Info.DynamicLinker<>'') then
+ LinkRes.AddFileName(Info.DynamicLinker);}
+ end;
+ if isdll then
+ LinkRes.Add('-lroot');
+
+ { objects which must be at the end }
+ if linklibc then
+ begin
+ if librarysearchpath.FindFile('crtend.o',s) then
+ LinkRes.AddFileName(s);
+ if librarysearchpath.FindFile('crtn.o',s) then
+ LinkRes.AddFileName(s);
+ end;
+
+{ Write and Close response }
+ linkres.Add(' ');
+ linkres.writetodisk;
+ linkres.free;
+
+ WriteResponseFile:=True;
+end;
+
+
+function TLinkerBeOS.MakeExecutable:boolean;
+var
+ binstr : String;
+ cmdstr : TcmdStr;
+ success : boolean;
+ DynLinkStr : string[60];
+ StaticStr,
+ StripStr : string[40];
+begin
+ if not(cs_link_extern in aktglobalswitches) then
+ Message1(exec_i_linking,current_module.exefilename^);
+
+{ Create some replacements }
+ StaticStr:='';
+ StripStr:='';
+ DynLinkStr:='';
+ if (cs_link_staticflag in aktglobalswitches) then
+ StaticStr:='-static';
+ if (cs_link_strip in aktglobalswitches) then
+ StripStr:='-s';
+ If (cs_profile in aktmoduleswitches) or
+ ((Info.DynamicLinker<>'') and (not SharedLibFiles.Empty)) then
+ begin
+ DynLinkStr:='-dynamic-linker='+Info.DynamicLinker;
+ if cshared Then
+ DynLinkStr:='--shared ' + DynLinkStr;
+ if rlinkpath<>'' Then
+ DynLinkStr:='--rpath-link '+rlinkpath + ' '+ DynLinkStr;
+ End;
+
+{ Write used files and libraries }
+ WriteResponseFile(false,false);
+
+{ Call linker }
+ SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
+ Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename^));
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+ Replace(cmdstr,'$STATIC',StaticStr);
+ Replace(cmdstr,'$STRIP',StripStr);
+ Replace(cmdstr,'$DYNLINK',DynLinkStr);
+ success:=DoExec(FindUtil(utilsprefix+BinStr),CmdStr,true,true);
+
+{ Remove ReponseFile }
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ RemoveFile(outputexedir+Info.ResName);
+
+ MakeExecutable:=success; { otherwise a recursive call to link method }
+end;
+
+
+Function TLinkerBeOS.MakeSharedLibrary:boolean;
+var
+ binstr : String;
+ cmdstr : TCmdStr;
+ success : boolean;
+ DynLinkStr : string[60];
+ StaticStr,
+ StripStr : string[40];
+
+ begin
+ MakeSharedLibrary:=false;
+ if not(cs_link_extern in aktglobalswitches) then
+ Message1(exec_i_linking,current_module.sharedlibfilename^);
+
+{ Create some replacements }
+ StaticStr:='';
+ StripStr:='';
+ DynLinkStr:='';
+ if (cs_link_staticflag in aktglobalswitches) then
+ StaticStr:='-static';
+ if (cs_link_strip in aktglobalswitches) then
+ StripStr:='-s';
+ If (cs_profile in aktmoduleswitches) or
+ ((Info.DynamicLinker<>'') and (not SharedLibFiles.Empty)) then
+ begin
+ DynLinkStr:='-dynamic-linker='+Info.DynamicLinker;
+ if cshared Then
+ DynLinkStr:='--shared ' + DynLinkStr;
+ if rlinkpath<>'' Then
+ DynLinkStr:='--rpath-link '+rlinkpath + ' '+ DynLinkStr;
+ End;
+{ Write used files and libraries }
+ WriteResponseFile(true,true);
+
+{ Call linker }
+ SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
+ Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename^));
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+ Replace(cmdstr,'$STATIC',StaticStr);
+ Replace(cmdstr,'$STRIP',StripStr);
+ Replace(cmdstr,'$DYNLINK',DynLinkStr);
+ success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,true);
+
+{ Strip the library ? }
+ if success and (cs_link_strip in aktglobalswitches) then
+ begin
+ SplitBinCmd(Info.DllCmd[2],binstr,cmdstr);
+ Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename^));
+ success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
+ end;
+
+{ Remove ReponseFile }
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ RemoveFile(outputexedir+Info.ResName);
+
+ MakeSharedLibrary:=success; { otherwise a recursive call to link method }
+end;
+
+
+{*****************************************************************************
+ Initialize
+*****************************************************************************}
+
+initialization
+{$ifdef i386}
+ RegisterExternalLinker(system_i386_beos_info,TLinkerbeos);
+ RegisterImport(system_i386_beos,timportlibbeos);
+ RegisterExport(system_i386_beos,texportlibbeos);
+ RegisterTarget(system_i386_beos_info);
+{$endif i386}
+end.
diff --git a/compiler/systems/t_bsd.pas b/compiler/systems/t_bsd.pas
new file mode 100644
index 0000000000..1d59a6d4ea
--- /dev/null
+++ b/compiler/systems/t_bsd.pas
@@ -0,0 +1,655 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman (original Linux)
+ (c) 2000 by Marco van de Voort (FreeBSD mods)
+
+ This unit implements support import,export,link routines
+ for the (i386)FreeBSD 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_bsd;
+
+{$i fpcdefs.inc}
+
+interface
+
+
+implementation
+
+ uses
+ cutils,cclasses,
+ verbose,systems,globtype,globals,
+ symconst,script,
+ fmodule,aasmbase,aasmtai,aasmcpu,cpubase,symsym,symdef,
+ import,export,link,i_bsd,
+ cgutils,cgbase,cgobj,cpuinfo;
+
+ type
+ tdarwinimported_item = class(timported_item)
+ procdef : tprocdef;
+ end;
+
+ timportlibdarwin=class(timportlib)
+ procedure preparelib(const s:string);override;
+ procedure importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);override;
+ procedure importvariable(vs:tglobalvarsym;const name,module:string);override;
+ procedure generatelib;override;
+ procedure generatesmartlib;override;
+ end;
+
+ timportlibbsd=class(timportlib)
+ procedure preparelib(const s:string);override;
+ procedure importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);override;
+ procedure importvariable(vs:tglobalvarsym;const name,module:string);override;
+ procedure generatelib;override;
+ end;
+
+ texportlibbsd=class(texportlib)
+ procedure preparelib(const s : string);override;
+ procedure exportprocedure(hp : texported_item);override;
+ procedure exportvar(hp : texported_item);override;
+ procedure generatelib;override;
+ end;
+
+ tlinkerbsd=class(texternallinker)
+ private
+ LdSupportsNoResponseFile : boolean;
+ LibrarySuffix : Char;
+ Function WriteResponseFile(isdll:boolean) : Boolean;
+ public
+ constructor Create;override;
+ procedure SetDefaultInfo;override;
+ function MakeExecutable:boolean;override;
+ function MakeSharedLibrary:boolean;override;
+ end;
+
+
+
+{*****************************************************************************
+ TIMPORTLIBDARWIN
+*****************************************************************************}
+
+ procedure timportlibdarwin.preparelib(const s : string);
+ begin
+ if asmlist[al_imports]=nil then
+ asmlist[al_imports]:=TAAsmoutput.create;
+ end;
+
+
+ procedure timportlibdarwin.importprocedure(aprocdef:tprocdef;const module : string;index : longint;const name : string);
+ begin
+ { insert sharedlibrary }
+{ current_module.linkothersharedlibs.add(SplitName(module),link_allways); }
+ end;
+
+
+ procedure timportlibdarwin.importvariable(vs:tglobalvarsym;const name,module:string);
+ begin
+ { insert sharedlibrary }
+{ current_module.linkothersharedlibs.add(SplitName(module),link_allways); }
+ { the rest is handled in the nppcld.pas tppcloadnode }
+ vs.set_mangledname(name);
+ end;
+
+
+ procedure timportlibdarwin.generatesmartlib;
+ begin
+ generatelib;
+ end;
+
+
+ procedure timportlibdarwin.generatelib;
+ begin
+ end;
+
+
+{*****************************************************************************
+ TIMPORTLIBBSD
+*****************************************************************************}
+
+procedure timportlibbsd.preparelib(const s : string);
+begin
+end;
+
+
+procedure timportlibbsd.importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);
+begin
+ { insert sharedlibrary }
+ current_module.linkothersharedlibs.add(SplitName(module),link_allways);
+end;
+
+
+procedure timportlibbsd.importvariable(vs:tglobalvarsym;const name,module:string);
+begin
+ { insert sharedlibrary }
+ current_module.linkothersharedlibs.add(SplitName(module),link_allways);
+ { reset the mangledname and turn off the dll_var option }
+ vs.set_mangledname(name);
+ exclude(vs.varoptions,vo_is_dll_var);
+end;
+
+
+procedure timportlibbsd.generatelib;
+begin
+end;
+
+
+{*****************************************************************************
+ TEXPORTLIBBSD
+*****************************************************************************}
+
+procedure texportlibbsd.preparelib(const s:string);
+begin
+end;
+
+
+procedure texportlibbsd.exportprocedure(hp : texported_item);
+var
+ hp2 : texported_item;
+begin
+ { first test the index value }
+ if (hp.options and eo_index)<>0 then
+ begin
+ Message1(parser_e_no_export_with_index_for_target,'*bsd/darwin');
+ exit;
+ end;
+ { now place in correct order }
+ hp2:=texported_item(current_module._exports.first);
+ while assigned(hp2) and
+ (hp.name^>hp2.name^) do
+ hp2:=texported_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=texported_item(current_module._exports.first) then
+ current_module._exports.concat(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 texportlibbsd.exportvar(hp : texported_item);
+begin
+ hp.is_var:=true;
+ exportprocedure(hp);
+end;
+
+
+procedure texportlibbsd.generatelib;
+var
+ hp2 : texported_item;
+begin
+ hp2:=texported_item(current_module._exports.first);
+ while assigned(hp2) do
+ begin
+ if (not hp2.is_var) and
+ (hp2.sym.typ=procsym) then
+ begin
+ { the manglednames can already be the same when the procedure
+ is declared with cdecl }
+ if tprocsym(hp2.sym).first_procdef.mangledname<>hp2.name^ then
+ begin
+{$ifdef i386}
+ { place jump in al_procedures }
+ asmlist[al_procedures].concat(Tai_align.Create_op(4,$90));
+ asmlist[al_procedures].concat(Tai_symbol.Createname_global(hp2.name^,AT_FUNCTION,0));
+ asmlist[al_procedures].concat(Taicpu.Op_sym(A_JMP,S_NO,objectlibrary.newasmsymbol(tprocsym(hp2.sym).first_procdef.mangledname,AB_EXTERNAL,AT_FUNCTION)));
+ asmlist[al_procedures].concat(Tai_symbol_end.Createname(hp2.name^));
+{$endif i386}
+{$ifdef powerpc}
+ asmlist[al_procedures].concat(Tai_align.create(16));
+ asmlist[al_procedures].concat(Tai_symbol.Createname_global(hp2.name^,AT_FUNCTION,0));
+ asmlist[al_procedures].concat(Taicpu.Op_sym(A_B,objectlibrary.newasmsymbol(tprocsym(hp2.sym).first_procdef.mangledname,AB_EXTERNAL,AT_FUNCTION)));
+ asmlist[al_procedures].concat(Tai_symbol_end.Createname(hp2.name^));
+{$endif powerpc}
+ end;
+ end
+ else
+ Message1(parser_e_no_export_of_variables_for_target,'*bsd/darwin');
+ hp2:=texported_item(hp2.next);
+ end;
+end;
+
+
+{*****************************************************************************
+ TLINKERLINUX
+*****************************************************************************}
+
+Constructor TLinkerBSD.Create;
+begin
+ Inherited Create;
+ if not Dontlinkstdlibpath Then
+ if (target_info.system <> system_powerpc_darwin) then
+ LibrarySearchPath.AddPath('/lib;/usr/lib;/usr/X11R6/lib',true)
+ else
+ { Mac OS X doesn't have a /lib }
+ LibrarySearchPath.AddPath('/usr/lib',true)
+end;
+
+
+procedure TLinkerBSD.SetDefaultInfo;
+{
+ This will also detect which libc version will be used
+}
+begin
+ LibrarySuffix:=' ';
+ LdSupportsNoResponseFile := (target_info.system in [system_m68k_netbsd,system_powerpc_darwin]);
+ with Info do
+ begin
+ if LdSupportsNoResponseFile then
+ begin
+ if (target_info.system <> system_powerpc_darwin) then
+ begin
+ ExeCmd[1]:='ld $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE `cat $RES`';
+ DllCmd[1]:='ld $OPT -shared -L. -o $EXE `cat $RES`'
+ end
+ else
+ begin
+ ExeCmd[1]:='ld $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE `cat $RES`';
+ DllCmd[1]:='libtool $OPT -dynamic -init PASCALMAIN -multiply_defined suppress -L. -o $EXE `cat $RES`'
+ end
+ end
+ else
+ begin
+ ExeCmd[1]:='ld $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $RES';
+ DllCmd[1]:='ld $OPT $INIT $FINI $SONAME -shared -L. -o $EXE $RES';
+ end;
+ if (target_info.system <> system_powerpc_darwin) then
+ DllCmd[2]:='strip --strip-unneeded $EXE'
+ else
+ DllCmd[2]:='strip -x $EXE';
+ { first try glibc2 }
+{$ifdef GLIBC2} {Keep linux code in place. FBSD might go to a different
+ glibc too once}
+ DynamicLinker:='/lib/ld-linux.so.2';
+ if FileExists(DynamicLinker) then
+ begin
+ Glibc2:=true;
+ { Check for 2.0 files, else use the glibc 2.1 stub }
+ if FileExists('/lib/ld-2.0.*') then
+ Glibc21:=false
+ else
+ Glibc21:=true;
+ end
+ else
+ DynamicLinker:='/lib/ld-linux.so.1';
+{$else}
+ DynamicLinker:='';
+{$endif}
+ end;
+end;
+
+
+Function TLinkerBSD.WriteResponseFile(isdll:boolean) : Boolean;
+Var
+ linkres : TLinkRes;
+ i : longint;
+ cprtobj,
+ gprtobj,
+ prtobj : string[80];
+ HPath : TStringListItem;
+ s,s1,s2 : string;
+ linkpthread,
+ linkdynamic,
+ linklibc : boolean;
+ Fl1,Fl2 : Boolean;
+
+begin
+ WriteResponseFile:=False;
+{ set special options for some targets }
+ if target_info.system <> system_powerpc_darwin then
+ begin
+ linkdynamic:=not(SharedLibFiles.empty);
+ linklibc:=(SharedLibFiles.Find('c')<>nil);
+ linkpthread:=(SharedLibFiles.Find('pthread')<>nil);
+ if (target_info.system =system_i386_freebsd) and linkpthread Then
+ Begin
+ if not (cs_link_pthread in aktglobalswitches) Then
+ begin
+ {delete pthreads from list, in this case it is in libc_r}
+ SharedLibFiles.Remove(SharedLibFiles.Find('pthread').str);
+ LibrarySuffix:='r';
+ end;
+ End;
+ prtobj:='prt0';
+ cprtobj:='cprt0';
+ gprtobj:='gprt0';
+ if cs_profile in aktmoduleswitches then
+ begin
+ prtobj:=gprtobj;
+ AddSharedLibrary('c');
+ LibrarySuffix:='p';
+ linklibc:=true;
+ end
+ else
+ begin
+ if linklibc then
+ prtobj:=cprtobj;
+ end;
+ end
+ else
+ begin
+ { for darwin: always link dynamically against libc }
+ linklibc := true;
+ if not(isdll) then
+ if not(cs_profile in aktmoduleswitches) then
+ prtobj:='/usr/lib/crt1.o'
+ else
+ prtobj:='/usr/lib/gcrt1.o'
+ else
+ prtobj:='';
+ end;
+
+
+ { Open link.res file }
+ LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
+
+ { Write path to search libraries }
+ HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
+ while assigned(HPath) do
+ begin
+ if LdSupportsNoResponseFile then
+ LinkRes.Add(maybequoted('-L'+HPath.Str))
+ else
+ LinkRes.Add('SEARCH_DIR('+maybequoted(HPath.Str)+')');
+ HPath:=TStringListItem(HPath.Next);
+ end;
+ HPath:=TStringListItem(LibrarySearchPath.First);
+ while assigned(HPath) do
+ begin
+ if LdSupportsNoResponseFile then
+ LinkRes.Add(maybequoted('-L'+HPath.Str))
+ else
+ LinkRes.Add('SEARCH_DIR('+maybequoted(HPath.Str)+')');
+ HPath:=TStringListItem(HPath.Next);
+ end;
+
+ if not LdSupportsNoResponseFile then
+ LinkRes.Add('INPUT(');
+ { add objectfiles, start with prt0 always }
+ if prtobj<>'' then
+ LinkRes.AddFileName(FindObjectFile(prtobj,'',false));
+ { try to add crti and crtbegin if linking to C }
+ if linklibc and
+ (target_info.system <> system_powerpc_darwin) then
+ begin
+ if librarysearchpath.FindFile('crtbegin.o',s) then
+ LinkRes.AddFileName(s);
+ if librarysearchpath.FindFile('crti.o',s) then
+ LinkRes.AddFileName(s);
+ end;
+ { main objectfiles }
+ while not ObjectFiles.Empty do
+ begin
+ s:=ObjectFiles.GetFirst;
+ if s<>'' then
+ LinkRes.AddFileName(maybequoted(s));
+ end;
+ if not LdSupportsNoResponseFile then
+ LinkRes.Add(')');
+
+ { Write staticlibraries }
+ if not StaticLibFiles.Empty then
+ begin
+ if not LdSupportsNoResponseFile then
+ LinkRes.Add('GROUP(');
+ While not StaticLibFiles.Empty do
+ begin
+ S:=StaticLibFiles.GetFirst;
+ LinkRes.AddFileName(maybequoted(s))
+ end;
+ if not LdSupportsNoResponseFile then
+ LinkRes.Add(')');
+ end;
+
+ { Write sharedlibraries like -l<lib>, also add the needed dynamic linker
+ here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
+ if not SharedLibFiles.Empty then
+ begin
+ if not LdSupportsNoResponseFile then
+ LinkRes.Add('INPUT(');
+ While not SharedLibFiles.Empty do
+ begin
+ S:=SharedLibFiles.GetFirst;
+ if s<>'c' then
+ begin
+ i:=Pos(target_info.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
+ Begin
+ If LibrarySuffix=' ' Then
+ LinkRes.Add('-lc')
+ else
+ LinkRes.Add('-lc_'+LibrarySuffix);
+ If LibrarySuffix='r' Then
+ LinkRes.Add('-lc');
+ end;
+ { when we have -static for the linker the we also need libgcc }
+ if (cs_link_staticflag in aktglobalswitches) then
+ LinkRes.Add('-lgcc');
+ if linkdynamic and (Info.DynamicLinker<>'') then
+ LinkRes.AddFileName(Info.DynamicLinker);
+ if not LdSupportsNoResponseFile then
+ LinkRes.Add(')');
+ end;
+ { objects which must be at the end }
+ if linklibc and
+ (target_info.system <> system_powerpc_darwin) then
+ begin
+ Fl1:=librarysearchpath.FindFile('crtend.o',s1);
+ Fl2:=librarysearchpath.FindFile('crtn.o',s2);
+ if Fl1 or Fl2 then
+ begin
+ LinkRes.Add('INPUT(');
+ If Fl1 Then
+ LinkRes.AddFileName(s1);
+ If Fl2 Then
+ LinkRes.AddFileName(s2);
+ LinkRes.Add(')');
+ end;
+ end;
+ { ignore the fact that our relocations are in non-writable sections, }
+ { will be fixed once we have pic support }
+ if isdll and
+ (target_info.system = system_powerpc_darwin) then
+ LinkRes.Add('-read_only_relocs suppress');
+{ Write and Close response }
+ linkres.writetodisk;
+ linkres.Free;
+
+ WriteResponseFile:=True;
+end;
+
+
+function TLinkerBSD.MakeExecutable:boolean;
+var
+ binstr : String;
+ cmdstr : TCmdStr;
+ success : boolean;
+ DynLinkStr : string[60];
+ GCSectionsStr,
+ StaticStr,
+ StripStr : string[40];
+begin
+ if not(cs_link_extern in aktglobalswitches) then
+ Message1(exec_i_linking,current_module.exefilename^);
+
+{ Create some replacements }
+ StaticStr:='';
+ StripStr:='';
+ DynLinkStr:='';
+ GCSectionsStr:='';
+ if (cs_link_staticflag in aktglobalswitches) then
+ begin
+ if (target_info.system=system_m68k_netbsd) and
+ ((cs_link_on_target in aktglobalswitches) or
+ (target_info.system=source_info.system)) then
+ StaticStr:='-Bstatic'
+ else
+ StaticStr:='-static';
+ end;
+ if (cs_link_strip in aktglobalswitches) then
+ if (target_info.system <> system_powerpc_darwin) then
+ StripStr:='-s'
+ else
+ StripStr:='-x';
+
+ if (cs_link_smart in aktglobalswitches) and
+ (tf_smartlink_sections in target_info.flags) then
+ GCSectionsStr:='--gc-sections';
+
+ If (cs_profile in aktmoduleswitches) or
+ ((Info.DynamicLinker<>'') and (not SharedLibFiles.Empty)) then
+ DynLinkStr:='-dynamic-linker='+Info.DynamicLinker;
+
+ if CShared Then
+ DynLinKStr:=DynLinkStr+' --shared';
+{ Write used files and libraries }
+ WriteResponseFile(false);
+
+{ Call linker }
+ SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
+ Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename^));
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+ Replace(cmdstr,'$STATIC',StaticStr);
+ Replace(cmdstr,'$STRIP',StripStr);
+ Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
+ Replace(cmdstr,'$DYNLINK',DynLinkStr);
+ success:=DoExec(FindUtil(utilsprefix+BinStr),CmdStr,true,LdSupportsNoResponseFile);
+
+{ Remove ReponseFile }
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ RemoveFile(outputexedir+Info.ResName);
+
+ MakeExecutable:=success; { otherwise a recursive call to link method }
+end;
+
+
+Function TLinkerBSD.MakeSharedLibrary:boolean;
+var
+ InitStr,
+ FiniStr,
+ SoNameStr : string[80];
+ binstr : String;
+ cmdstr : TCmdStr;
+ 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);
+
+ InitStr:='-init FPC_LIB_START';
+ FiniStr:='-fini FPC_LIB_EXIT';
+ SoNameStr:='-soname '+SplitFileName(current_module.sharedlibfilename^);
+
+{ Call linker }
+ SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
+ Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename^));
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+ Replace(cmdstr,'$INIT',InitStr);
+ Replace(cmdstr,'$FINI',FiniStr);
+ Replace(cmdstr,'$SONAME',SoNameStr);
+
+ success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,LdSupportsNoResponseFile);
+
+{ Strip the library ? }
+ if success and (cs_link_strip in aktglobalswitches) then
+ begin
+ SplitBinCmd(Info.DllCmd[2],binstr,cmdstr);
+ Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename^));
+ success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
+ end;
+
+{ Remove ReponseFile }
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ RemoveFile(outputexedir+Info.ResName);
+
+ MakeSharedLibrary:=success; { otherwise a recursive call to link method }
+end;
+
+
+{*****************************************************************************
+ Initialize
+*****************************************************************************}
+
+initialization
+{$ifdef x86_64}
+ RegisterExternalLinker(system_x86_64_FreeBSD_info,TLinkerBSD);
+ RegisterImport(system_x86_64_freebsd,timportlibbsd);
+ RegisterExport(system_x86_64_freebsd,texportlibbsd);
+ RegisterTarget(system_x86_64_freebsd_info);
+{$endif}
+{$ifdef i386}
+ RegisterExternalLinker(system_i386_FreeBSD_info,TLinkerBSD);
+ RegisterExternalLinker(system_i386_NetBSD_info,TLinkerBSD);
+ RegisterExternalLinker(system_i386_OpenBSD_info,TLinkerBSD);
+ RegisterImport(system_i386_freebsd,timportlibbsd);
+ RegisterExport(system_i386_freebsd,texportlibbsd);
+ RegisterTarget(system_i386_freebsd_info);
+ RegisterImport(system_i386_netbsd,timportlibbsd);
+ RegisterExport(system_i386_netbsd,texportlibbsd);
+ RegisterTarget(system_i386_netbsd_info);
+ RegisterImport(system_i386_openbsd,timportlibbsd);
+ RegisterExport(system_i386_openbsd,texportlibbsd);
+ RegisterTarget(system_i386_openbsd_info);
+{$endif i386}
+{$ifdef m68k}
+// RegisterExternalLinker(system_m68k_FreeBSD_info,TLinkerBSD);
+ RegisterExternalLinker(system_m68k_NetBSD_info,TLinkerBSD);
+ RegisterImport(system_m68k_netbsd,timportlibbsd);
+ RegisterExport(system_m68k_netbsd,texportlibbsd);
+ RegisterTarget(system_m68k_netbsd_info);
+{$endif m68k}
+{$ifdef powerpc}
+// RegisterExternalLinker(system_m68k_FreeBSD_info,TLinkerBSD);
+ RegisterExternalLinker(system_powerpc_darwin_info,TLinkerBSD);
+ RegisterImport(system_powerpc_darwin,timportlibdarwin);
+ RegisterExport(system_powerpc_darwin,texportlibbsd);
+ RegisterTarget(system_powerpc_darwin_info);
+ RegisterExternalLinker(system_powerpc_netbsd_info,TLinkerBSD);
+ RegisterImport(system_powerpc_netbsd,timportlibbsd);
+ RegisterExport(system_powerpc_netbsd,texportlibbsd);
+ RegisterTarget(system_powerpc_netbsd_info);
+{$endif powerpc}
+end.
diff --git a/compiler/systems/t_emx.pas b/compiler/systems/t_emx.pas
new file mode 100644
index 0000000000..44427e627f
--- /dev/null
+++ b/compiler/systems/t_emx.pas
@@ -0,0 +1,516 @@
+{
+ Copyright (c) 1998-2002 by Daniel Mantione
+ Portions Copyright (c) 1998-2002 Eberhard Mattes
+
+ Unit to write out import libraries and def files for OS/2 via EMX
+
+ 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.
+
+ ****************************************************************************
+}
+{
+ A lot of code in this unit has been ported from C to Pascal from the
+ emximp utility, part of the EMX development system. Emximp is copyrighted
+ by Eberhard Mattes. Note: Eberhard doesn't know much about the Pascal
+ port, please send questions to Daniel Mantione
+ <d.s.p.mantione@twi.tudelft.nl>.
+}
+unit t_emx;
+
+{$i fpcdefs.inc}
+
+interface
+
+
+implementation
+
+ uses
+ strings,
+ dos,
+ cutils,cclasses,
+ globtype,comphook,systems,symconst,symsym,symdef,
+ globals,verbose,fmodule,script,
+ import,link,i_emx,ppu;
+
+ type
+ TImportLibEMX=class(timportlib)
+ procedure preparelib(const s:string);override;
+ procedure importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);override;
+ procedure generatelib;override;
+ end;
+
+ TLinkerEMX=class(texternallinker)
+ private
+ Function WriteResponseFile(isdll:boolean) : Boolean;
+ public
+ constructor Create;override;
+ procedure SetDefaultInfo;override;
+ function MakeExecutable:boolean;override;
+ end;
+
+
+const profile_flag:boolean=false;
+
+const n_ext = 1;
+ n_abs = 2;
+ n_text = 4;
+ n_data = 6;
+ n_bss = 8;
+ n_imp1 = $68;
+ n_imp2 = $6a;
+
+type reloc=packed record {This is the layout of a relocation table
+ entry.}
+ address:longint; {Fixup location}
+ remaining:longint;
+ {Meaning of bits for remaining:
+ 0..23: Symbol number or segment
+ 24: Self-relative fixup if non-zero
+ 25..26: Fixup size (0: 1 byte, 1: 2, 2: 4 bytes)
+ 27: Reference to symbol or segment
+ 28..31 Not used}
+ end;
+
+ nlist=packed record {This is the layout of a symbol table entry.}
+ strofs:longint; {Offset in string table}
+ typ:byte; {Type of the symbol}
+ other:byte; {Other information}
+ desc:word; {More information}
+ value:longint; {Value (address)}
+ end;
+
+ a_out_header=packed record
+ magic:word; {Magic word, must be $0107}
+ machtype:byte; {Machine type}
+ flags:byte; {Flags}
+ text_size:longint; {Length of text, in bytes}
+ data_size:longint; {Length of initialized data, in bytes}
+ bss_size:longint; {Length of uninitialized data, in bytes}
+ sym_size:longint; {Length of symbol table, in bytes}
+ entry:longint; {Start address (entry point)}
+ trsize:longint; {Length of relocation info for text, bytes}
+ drsize:longint; {Length of relocation info for data, bytes}
+ end;
+
+ ar_hdr=packed record
+ ar_name:array[0..15] of char;
+ ar_date:array[0..11] of char;
+ ar_uid:array[0..5] of char;
+ ar_gid:array[0..5] of char;
+ ar_mode:array[0..7] of char;
+ ar_size:array[0..9] of char;
+ ar_fmag:array[0..1] of char;
+ end;
+
+var aout_str_size:longint;
+ aout_str_tab:array[0..2047] of byte;
+ aout_sym_count:longint;
+ aout_sym_tab:array[0..5] of nlist;
+
+ aout_text:array[0..63] of byte;
+ aout_text_size:longint;
+
+ aout_treloc_tab:array[0..1] of reloc;
+ aout_treloc_count:longint;
+
+ aout_size:longint;
+ seq_no:longint;
+
+ ar_member_size:longint;
+
+ out_file:file;
+
+procedure write_ar(const name:string;size:longint);
+
+var ar:ar_hdr;
+ time:datetime;
+ dummy:word;
+ numtime:longint;
+ tmp:string[19];
+
+
+begin
+ ar_member_size:=size;
+ fillchar(ar.ar_name,sizeof(ar.ar_name),' ');
+ move(name[1],ar.ar_name,length(name));
+ getdate(time.year,time.month,time.day,dummy);
+ gettime(time.hour,time.min,time.sec,dummy);
+ packtime(time,numtime);
+ str(numtime,tmp);
+ fillchar(ar.ar_date,sizeof(ar.ar_date),' ');
+ move(tmp[1],ar.ar_date,length(tmp));
+ ar.ar_uid:='0 ';
+ ar.ar_gid:='0 ';
+ ar.ar_mode:='100666'#0#0;
+ str(size,tmp);
+ fillchar(ar.ar_size,sizeof(ar.ar_size),' ');
+ move(tmp[1],ar.ar_size,length(tmp));
+ ar.ar_fmag:='`'#10;
+ blockwrite(out_file,ar,sizeof(ar));
+end;
+
+procedure finish_ar;
+
+var a:byte;
+
+begin
+ a:=0;
+ if odd(ar_member_size) then
+ blockwrite(out_file,a,1);
+end;
+
+procedure aout_init;
+
+begin
+ aout_str_size:=sizeof(longint);
+ aout_sym_count:=0;
+ aout_text_size:=0;
+ aout_treloc_count:=0;
+end;
+
+function aout_sym(const name:string;typ,other:byte;desc:word;
+ value:longint):longint;
+
+begin
+ if aout_str_size+length(name)+1>sizeof(aout_str_tab) then
+ internalerror(200504241);
+ if aout_sym_count>=sizeof(aout_sym_tab) div sizeof(aout_sym_tab[0]) then
+ internalerror(200504242);
+ aout_sym_tab[aout_sym_count].strofs:=aout_str_size;
+ aout_sym_tab[aout_sym_count].typ:=typ;
+ aout_sym_tab[aout_sym_count].other:=other;
+ aout_sym_tab[aout_sym_count].desc:=desc;
+ aout_sym_tab[aout_sym_count].value:=value;
+ strPcopy(@aout_str_tab[aout_str_size],name);
+ aout_str_size:=aout_str_size+length(name)+1;
+ aout_sym:=aout_sym_count;
+ inc(aout_sym_count);
+end;
+
+procedure aout_text_byte(b:byte);
+
+begin
+ if aout_text_size>=sizeof(aout_text) then
+ internalerror(200504243);
+ aout_text[aout_text_size]:=b;
+ inc(aout_text_size);
+end;
+
+procedure aout_text_dword(d:longint);
+
+type li_ar=array[0..3] of byte;
+
+begin
+ aout_text_byte(li_ar(d)[0]);
+ aout_text_byte(li_ar(d)[1]);
+ aout_text_byte(li_ar(d)[2]);
+ aout_text_byte(li_ar(d)[3]);
+end;
+
+procedure aout_treloc(address,symbolnum,pcrel,len,ext:longint);
+
+begin
+ if aout_treloc_count>=sizeof(aout_treloc_tab) div sizeof(reloc) then
+ internalerror(200504244);
+ aout_treloc_tab[aout_treloc_count].address:=address;
+ aout_treloc_tab[aout_treloc_count].remaining:=symbolnum+pcrel shl 24+
+ len shl 25+ext shl 27;
+ inc(aout_treloc_count);
+end;
+
+procedure aout_finish;
+
+begin
+ while (aout_text_size and 3)<>0 do
+ aout_text_byte ($90);
+ aout_size:=sizeof(a_out_header)+aout_text_size+aout_treloc_count*
+ sizeof(reloc)+aout_sym_count*sizeof(aout_sym_tab[0])+aout_str_size;
+end;
+
+procedure aout_write;
+
+var ao:a_out_header;
+
+begin
+ ao.magic:=$0107;
+ ao.machtype:=0;
+ ao.flags:=0;
+ ao.text_size:=aout_text_size;
+ ao.data_size:=0;
+ ao.bss_size:=0;
+ ao.sym_size:=aout_sym_count*sizeof(aout_sym_tab[0]);
+ ao.entry:=0;
+ ao.trsize:=aout_treloc_count*sizeof(reloc);
+ ao.drsize:=0;
+ blockwrite(out_file,ao,sizeof(ao));
+ blockwrite(out_file,aout_text,aout_text_size);
+ blockwrite(out_file,aout_treloc_tab,sizeof(reloc)*aout_treloc_count);
+ blockwrite(out_file,aout_sym_tab,sizeof(aout_sym_tab[0])*aout_sym_count);
+ longint((@aout_str_tab)^):=aout_str_size;
+ blockwrite(out_file,aout_str_tab,aout_str_size);
+end;
+
+procedure TImportLibEMX.preparelib(const s:string);
+
+{This code triggers a lot of bugs in the compiler.
+const armag='!<arch>'#10;
+ ar_magic:array[1..length(armag)] of char=armag;}
+const ar_magic:array[1..8] of char='!<arch>'#10;
+var
+ libname : string;
+begin
+ LibName:=FixFileName(S + Target_Info.StaticCLibExt);
+ seq_no:=1;
+ current_module.linkotherstaticlibs.add(libname,link_allways);
+ assign(out_file,current_module.outputpath^+libname);
+ rewrite(out_file,1);
+ blockwrite(out_file,ar_magic,sizeof(ar_magic));
+end;
+
+procedure TImportLibEMX.importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);
+{func = Name of function to import.
+ module = Name of DLL to import from.
+ index = Index of function in DLL. Use 0 to import by name.
+ name = Name of function in DLL. Ignored when index=0;}
+var tmp1,tmp2,tmp3:string;
+ sym_mcount,sym_import:longint;
+ fixup_mcount,fixup_import:longint;
+ func : string;
+begin
+ { force the current mangledname }
+ include(aprocdef.procoptions,po_has_mangledname);
+ func:=aprocdef.mangledname;
+
+ aout_init;
+ tmp2:=func;
+ if profile_flag and not (copy(func,1,4)='_16_') then
+ begin
+ {sym_entry:=aout_sym(func,n_text+n_ext,0,0,aout_text_size);}
+ sym_mcount:=aout_sym('__mcount',n_ext,0,0,0);
+ {Use, say, "_$U_DosRead" for "DosRead" to import the
+ non-profiled function.}
+ tmp2:='__$U_'+func;
+ sym_import:=aout_sym(tmp2,n_ext,0,0,0);
+ aout_text_byte($55); {push ebp}
+ aout_text_byte($89); {mov ebp, esp}
+ aout_text_byte($e5);
+ aout_text_byte($e8); {call _mcount}
+ fixup_mcount:=aout_text_size;
+ aout_text_dword(0-(aout_text_size+4));
+ aout_text_byte($5d); {pop ebp}
+ aout_text_byte($e9); {jmp _$U_DosRead}
+ fixup_import:=aout_text_size;
+ aout_text_dword(0-(aout_text_size+4));
+
+ aout_treloc(fixup_mcount,sym_mcount,1,2,1);
+ aout_treloc (fixup_import, sym_import,1,2,1);
+ end;
+ str(seq_no,tmp1);
+ tmp1:='IMPORT#'+tmp1;
+ if name='' then
+ begin
+ str(index,tmp3);
+ tmp3:=func+'='+module+'.'+tmp3;
+ end
+ else
+ tmp3:=func+'='+module+'.'+name;
+ aout_sym(tmp2,n_imp1+n_ext,0,0,0);
+ aout_sym(tmp3,n_imp2+n_ext,0,0,0);
+ aout_finish;
+ write_ar(tmp1,aout_size);
+ aout_write;
+ finish_ar;
+ inc(seq_no);
+end;
+
+procedure TImportLibEMX.GenerateLib;
+
+begin
+ close(out_file);
+end;
+
+
+{****************************************************************************
+ TLinkerEMX
+****************************************************************************}
+
+Constructor TLinkerEMX.Create;
+begin
+ Inherited Create;
+ { allow duplicated libs (PM) }
+ SharedLibFiles.doubles:=true;
+ StaticLibFiles.doubles:=true;
+end;
+
+
+procedure TLinkerEMX.SetDefaultInfo;
+begin
+ with Info do
+ begin
+ ExeCmd[1]:='ld $OPT -o $OUT @$RES';
+ ExeCmd[2]:='emxbind -b $STRIP $APPTYPE $RSRC -k$STACKKB -h$HEAPMB -o $EXE $OUT -aim -s$DOSHEAPKB';
+ if source_info.script = script_dos then
+ ExeCmd[3]:='del $OUT';
+ end;
+end;
+
+
+Function TLinkerEMX.WriteResponseFile(isdll:boolean) : Boolean;
+Var
+ linkres : TLinkRes;
+ i : longint;
+ HPath : TStringListItem;
+ s : string;
+begin
+ WriteResponseFile:=False;
+
+ { Open link.res file }
+ LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
+
+ { Write path to search libraries }
+ HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
+ while assigned(HPath) do
+ begin
+ LinkRes.Add('-L'+HPath.Str);
+ HPath:=TStringListItem(HPath.Next);
+ end;
+ HPath:=TStringListItem(LibrarySearchPath.First);
+ while assigned(HPath) do
+ begin
+ LinkRes.Add('-L'+HPath.Str);
+ HPath:=TStringListItem(HPath.Next);
+ end;
+
+ { add objectfiles, start with prt0 always }
+ LinkRes.AddFileName(FindObjectFile('prt0','',false));
+ while not ObjectFiles.Empty do
+ begin
+ s:=ObjectFiles.GetFirst;
+ if s<>'' then
+ LinkRes.AddFileName(s);
+ end;
+
+ { Write staticlibraries }
+ { No group !! This will not work correctly PM }
+ While not StaticLibFiles.Empty do
+ begin
+ S:=StaticLibFiles.GetFirst;
+ 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.GetFirst;
+ i:=Pos(target_info.sharedlibext,S);
+ if i>0 then
+ Delete(S,i,255);
+ LinkRes.Add('-l'+s);
+ end;
+
+{ Write and Close response }
+ linkres.writetodisk;
+ LinkRes.Free;
+
+ WriteResponseFile:=True;
+end;
+
+
+function TLinkerEMX.MakeExecutable:boolean;
+var
+ binstr : String;
+ cmdstr : TCmdStr;
+ success : boolean;
+ i : longint;
+ AppTypeStr,
+ StripStr: string[40];
+ RsrcStr : string;
+ DS: DirStr;
+ NS: NameStr;
+ ES: ExtStr;
+ OutName: PathStr;
+begin
+ if not(cs_link_extern in aktglobalswitches) then
+ Message1(exec_i_linking,current_module.exefilename^);
+
+{ Create some replacements }
+ FSplit (current_module.exefilename^, DS, NS, ES);
+ OutName := DS + NS + '.out';
+ if (cs_link_strip in aktglobalswitches) then
+ StripStr := '-s'
+ else
+ StripStr := '';
+ if (usewindowapi) or (AppType = app_gui) then
+ AppTypeStr := '-p'
+ else if AppType = app_fs then
+ AppTypeStr := '-f'
+ else AppTypeStr := '-w';
+ if not (Current_module.ResourceFiles.Empty) then
+ RsrcStr := '-r ' + Current_module.ResourceFiles.GetFirst
+ else
+ RsrcStr := '';
+(* Only one resource file supported, discard everything else
+ (should be already empty anyway, though). *)
+ Current_module.ResourceFiles.Clear;
+{ Write used files and libraries }
+ WriteResponseFile(false);
+
+{ Call linker }
+ success:=false;
+ for i:=1 to 3 do
+ begin
+ SplitBinCmd(Info.ExeCmd[i],binstr,cmdstr);
+ if binstr<>'' then
+ begin
+ { Is this really required? Not anymore according to my EMX docs }
+ Replace(cmdstr,'$HEAPMB',tostr((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+1023) shr 10));
+ Replace(cmdstr,'$STRIP',StripStr);
+ Replace(cmdstr,'$APPTYPE',AppTypeStr);
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
+ Replace(cmdstr,'$RSRC',RsrcStr);
+ Replace(cmdstr,'$OUT',maybequoted(OutName));
+ Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename^));
+ if i<>3 then
+ success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,(i=1),false)
+ else
+ success:=DoExec(binstr,cmdstr,(i=1),true);
+ end;
+ end;
+
+{ Remove ReponseFile }
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ RemoveFile(outputexedir+Info.ResName);
+
+ MakeExecutable:=success; { otherwise a recursive call to link method }
+end;
+
+
+{*****************************************************************************
+ Initialize
+*****************************************************************************}
+
+initialization
+ RegisterExternalLinker(system_i386_emx_info,TLinkerEMX);
+ RegisterImport(system_i386_emx,TImportLibEMX);
+ RegisterRes(res_emxbind_info);
+ RegisterTarget(system_i386_emx_info);
+end.
diff --git a/compiler/systems/t_gba.pas b/compiler/systems/t_gba.pas
new file mode 100644
index 0000000000..c937ca2a6d
--- /dev/null
+++ b/compiler/systems/t_gba.pas
@@ -0,0 +1,300 @@
+{
+ This unit implements support import,export,link routines
+ for the (arm) GameBoy Advance target
+
+ Copyright (c) 2001-2002 by Peter Vreman
+
+ 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_gba;
+
+{$i fpcdefs.inc}
+
+
+interface
+
+ uses
+ symsym,symdef,
+ import,export,link;
+
+ type
+ tlinkergba=class(texternallinker)
+ private
+ libctype:(libc5,glibc2,glibc21,uclibc);
+ Function WriteResponseFile : Boolean;
+ public
+ constructor Create;override;
+ procedure SetDefaultInfo;override;
+ function MakeExecutable:boolean;override;
+ end;
+
+
+implementation
+
+
+ uses
+ cutils,cclasses,verbose,systems,globtype,globals,
+ symconst,script,fmodule,dos,aasmbase,aasmtai,aasmcpu,
+ cpubase,cgobj,i_gba;
+
+
+
+{*****************************************************************************
+ TLINKERLINUX
+*****************************************************************************}
+
+Constructor TLinkerGba.Create;
+begin
+ Inherited Create;
+ if not Dontlinkstdlibpath Then
+ LibrarySearchPath.AddPath('/lib;/usr/lib;/usr/X11R6/lib',true);
+end;
+
+
+procedure TLinkerGba.SetDefaultInfo;
+{
+ This will also detect which libc version will be used
+}
+begin
+ with Info do
+ begin
+ //ExeCmd[1]:='ld $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $RES';
+ // Here we call ld with right options for GBA
+ ExeCmd[1]:='ld $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -Ttext 0x08000000 -Tbss 0x03000000 -L. -o $EXE $RES';
+ DllCmd[1]:='ld $OPT $INIT $FINI $SONAME -shared -L. -o $EXE $RES';
+ DllCmd[2]:='strip --strip-unneeded $EXE';
+ DynamicLinker:='/lib/ld-linux.so.2';
+ libctype:=glibc2;
+ end;
+end;
+
+
+Function TLinkerGba.WriteResponseFile: Boolean;
+Var
+ linkres : TLinkRes;
+ i : longint;
+ cprtobj,
+ gprtobj,
+ prtobj : string[80];
+ HPath : TStringListItem;
+ s,s1,s2 : string;
+ found1,
+ found2,
+ linklibc : boolean;
+begin
+ WriteResponseFile:=False;
+{ set special options for some targets }
+ linklibc:=(SharedLibFiles.Find('c')<>nil);
+ prtobj:='prt0';
+ case libctype of
+ glibc21:
+ begin
+ cprtobj:='cprt21';
+ gprtobj:='gprt21';
+ end;
+ uclibc:
+ begin
+ cprtobj:='ucprt0';
+ gprtobj:='ugprt0';
+ end
+ else
+ cprtobj:='cprt0';
+ gprtobj:='gprt0';
+ end;
+
+ if cs_profile in aktmoduleswitches then
+ begin
+ prtobj:=gprtobj;
+ if not(libctype in [glibc2,glibc21]) then
+ AddSharedLibrary('gmon');
+ AddSharedLibrary('c');
+ linklibc:=true;
+ end
+ else
+ begin
+ if linklibc then
+ prtobj:=cprtobj;
+ end;
+
+ { Open link.res file }
+ LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
+
+ { Write path to search libraries }
+ HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
+ while assigned(HPath) do
+ begin
+ LinkRes.Add('SEARCH_DIR('+maybequoted(HPath.Str)+')');
+ HPath:=TStringListItem(HPath.Next);
+ end;
+ HPath:=TStringListItem(LibrarySearchPath.First);
+ while assigned(HPath) do
+ begin
+ LinkRes.Add('SEARCH_DIR('+maybequoted(HPath.Str)+')');
+ HPath:=TStringListItem(HPath.Next);
+ end;
+
+ LinkRes.Add('INPUT(');
+ { add objectfiles, start with prt0 always }
+ if prtobj<>'' then
+ LinkRes.AddFileName(maybequoted(FindObjectFile(prtobj,'',false)));
+ { try to add crti and crtbegin if linking to C }
+ if linklibc then
+ begin
+ if librarysearchpath.FindFile('crtbegin.o',s) then
+ LinkRes.AddFileName(s);
+ if librarysearchpath.FindFile('crti.o',s) then
+ LinkRes.AddFileName(s);
+ end;
+ { main objectfiles }
+ while not ObjectFiles.Empty do
+ begin
+ s:=ObjectFiles.GetFirst;
+ if s<>'' then
+ LinkRes.AddFileName(maybequoted(s));
+ end;
+ LinkRes.Add(')');
+
+ { Write staticlibraries }
+ if not StaticLibFiles.Empty then
+ begin
+ LinkRes.Add('GROUP(');
+ While not StaticLibFiles.Empty do
+ begin
+ S:=StaticLibFiles.GetFirst;
+ LinkRes.AddFileName(maybequoted(s))
+ end;
+ LinkRes.Add(')');
+ end;
+
+ { Write sharedlibraries like -l<lib>, also add the needed dynamic linker
+ here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
+ if not SharedLibFiles.Empty then
+ begin
+ LinkRes.Add('INPUT(');
+ While not SharedLibFiles.Empty do
+ begin
+ S:=SharedLibFiles.GetFirst;
+ if s<>'c' then
+ begin
+ i:=Pos(target_info.sharedlibext,S);
+ if i>0 then
+ Delete(S,i,255);
+ LinkRes.Add('-l'+s);
+ end
+ else
+ begin
+ linklibc:=true;
+ end;
+ end;
+ { be sure that libc is the last lib }
+ if linklibc then
+ LinkRes.Add('-lc');
+ { when we have -static for the linker the we also need libgcc }
+ if (cs_link_staticflag in aktglobalswitches) then
+ LinkRes.Add('-lgcc');
+ LinkRes.Add(')');
+ end;
+
+ { objects which must be at the end }
+ if linklibc and (libctype<>uclibc) then
+ begin
+ found1:=librarysearchpath.FindFile('crtend.o',s1);
+ found2:=librarysearchpath.FindFile('crtn.o',s2);
+ if found1 or found2 then
+ begin
+ LinkRes.Add('INPUT(');
+ if found1 then
+ LinkRes.AddFileName(s1);
+ if found2 then
+ LinkRes.AddFileName(s2);
+ LinkRes.Add(')');
+ end;
+ end;
+{ Write and Close response }
+ linkres.writetodisk;
+ linkres.Free;
+
+ WriteResponseFile:=True;
+end;
+
+
+function TLinkerGba.MakeExecutable:boolean;
+var
+ binstr : String;
+ cmdstr : TCmdStr;
+ success : boolean;
+ DynLinkStr : string[60];
+ GCSectionsStr,
+ StaticStr,
+ StripStr : string[40];
+begin
+ if not(cs_link_extern in aktglobalswitches) then
+ Message1(exec_i_linking,current_module.exefilename^);
+
+{ Create some replacements }
+ StaticStr:='';
+ StripStr:='';
+ GCSectionsStr:='';
+ DynLinkStr:='';
+ if (cs_link_staticflag in aktglobalswitches) then
+ StaticStr:='-static';
+ if (cs_link_strip in aktglobalswitches) then
+ StripStr:='-s';
+ if (cs_link_smart in aktglobalswitches) and
+ (tf_smartlink_sections in target_info.flags) then
+ GCSectionsStr:='--gc-sections';
+ If (cs_profile in aktmoduleswitches) or
+ ((Info.DynamicLinker<>'') and (not SharedLibFiles.Empty)) then
+ begin
+ DynLinkStr:='-dynamic-linker='+Info.DynamicLinker;
+ if cshared Then
+ DynLinkStr:='--shared ' + DynLinkStr;
+ if rlinkpath<>'' Then
+ DynLinkStr:='--rpath-link '+rlinkpath + ' '+ DynLinkStr;
+ End;
+
+{ Write used files and libraries }
+ WriteResponseFile;
+
+{ Call linker }
+ SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
+ Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename^));
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+ Replace(cmdstr,'$STATIC',StaticStr);
+ Replace(cmdstr,'$STRIP',StripStr);
+ Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
+ Replace(cmdstr,'$DYNLINK',DynLinkStr);
+ success:=DoExec(FindUtil(utilsprefix+BinStr),CmdStr,true,false);
+
+{ Remove ReponseFile }
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ RemoveFile(outputexedir+Info.ResName);
+
+ MakeExecutable:=success; { otherwise a recursive call to link method }
+end;
+
+
+
+{*****************************************************************************
+ Initialize
+*****************************************************************************}
+
+initialization
+ RegisterExternalLinker(system_arm_gba_info,TLinkerGba);
+ RegisterTarget(system_arm_gba_info);
+end.
diff --git a/compiler/systems/t_go32v2.pas b/compiler/systems/t_go32v2.pas
new file mode 100644
index 0000000000..c627d5cb82
--- /dev/null
+++ b/compiler/systems/t_go32v2.pas
@@ -0,0 +1,364 @@
+{
+ Copyright (c) 1998-2002 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;
+
+{$i fpcdefs.inc}
+
+interface
+
+
+implementation
+
+ uses
+ link,
+ cutils,cclasses,
+ globtype,globals,systems,verbose,script,fmodule,i_go32v2,ogcoff;
+
+ type
+ tlinkergo32v2=class(texternallinker)
+ private
+ Function WriteResponseFile(isdll:boolean) : Boolean;
+ Function WriteScript(isdll:boolean) : Boolean;
+ public
+ constructor Create;override;
+ procedure SetDefaultInfo;override;
+ function MakeExecutable:boolean;override;
+ end;
+
+
+{****************************************************************************
+ TLinkerGo32v2
+****************************************************************************}
+
+Constructor TLinkerGo32v2.Create;
+begin
+ Inherited Create;
+ { allow duplicated libs (PM) }
+ SharedLibFiles.doubles:=true;
+ StaticLibFiles.doubles:=true;
+end;
+
+
+procedure TLinkerGo32v2.SetDefaultInfo;
+begin
+ with Info do
+ begin
+ ExeCmd[1]:='ld $SCRIPT $OPT $STRIP -o $EXE $RES';
+ end;
+end;
+
+
+Function TLinkerGo32v2.WriteResponseFile(isdll:boolean) : Boolean;
+Var
+ linkres : TLinkRes;
+ i : longint;
+ s : string;
+ linklibc : boolean;
+begin
+ WriteResponseFile:=False;
+
+ { Open link.res file }
+ LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
+
+ { Write staticlibraries }
+ if not StaticLibFiles.Empty then
+ begin
+ LinkRes.Add('-(');
+ While not StaticLibFiles.Empty do
+ begin
+ S:=StaticLibFiles.GetFirst;
+ LinkRes.AddFileName(GetShortName(s))
+ end;
+ LinkRes.Add('-)');
+ end;
+
+ { Write sharedlibraries like -l<lib>, also add the needed dynamic linker
+ here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
+ linklibc:=false;
+ While not SharedLibFiles.Empty do
+ begin
+ S:=SharedLibFiles.GetFirst;
+ if s<>'c' then
+ begin
+ i:=Pos(target_info.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 and Close response }
+ linkres.writetodisk;
+ LinkRes.Free;
+
+ WriteResponseFile:=True;
+end;
+
+
+Function TLinkerGo32v2.WriteScript(isdll:boolean) : Boolean;
+Var
+ scriptres : TLinkRes;
+ HPath : TStringListItem;
+ s : string;
+begin
+ WriteScript:=False;
+
+ { Open link.res file }
+ ScriptRes:=TLinkRes.Create(outputexedir+Info.ScriptName);
+ ScriptRes.Add('OUTPUT_FORMAT("coff-go32-exe")');
+ ScriptRes.Add('ENTRY(start)');
+
+ ScriptRes.Add('SECTIONS');
+ ScriptRes.Add('{');
+ ScriptRes.Add(' .text 0x1000+SIZEOF_HEADERS : {');
+ ScriptRes.Add(' . = ALIGN(16);');
+ { add objectfiles, start with prt0 always }
+ ScriptRes.Add(' '+GetShortName(FindObjectFile('prt0','',false))+'(.text)');
+ while not ObjectFiles.Empty do
+ begin
+ s:=ObjectFiles.GetFirst;
+ if s<>'' then
+ begin
+ ScriptRes.Add(' . = ALIGN(16);');
+ ScriptRes.Add(' '+GetShortName(s)+'(.text)');
+ end;
+ end;
+ ScriptRes.Add(' *(.text)');
+ ScriptRes.Add(' etext = . ; _etext = .;');
+ ScriptRes.Add(' . = ALIGN(0x200);');
+ ScriptRes.Add(' }');
+ ScriptRes.Add(' .data ALIGN(0x200) : {');
+ ScriptRes.Add(' djgpp_first_ctor = . ;');
+ ScriptRes.Add(' *(.ctor)');
+ ScriptRes.Add(' djgpp_last_ctor = . ;');
+ ScriptRes.Add(' djgpp_first_dtor = . ;');
+ ScriptRes.Add(' *(.dtor)');
+ ScriptRes.Add(' djgpp_last_dtor = . ;');
+ ScriptRes.Add(' *(.data)');
+ ScriptRes.Add(' *(.gcc_exc)');
+ ScriptRes.Add(' ___EH_FRAME_BEGIN__ = . ;');
+ ScriptRes.Add(' *(.eh_fram)');
+ ScriptRes.Add(' ___EH_FRAME_END__ = . ;');
+ ScriptRes.Add(' LONG(0)');
+ ScriptRes.Add(' edata = . ; _edata = .;');
+ ScriptRes.Add(' . = ALIGN(0x200);');
+ ScriptRes.Add(' }');
+ ScriptRes.Add(' .bss SIZEOF(.data) + ADDR(.data) :');
+ ScriptRes.Add(' {');
+ ScriptRes.Add(' _object.2 = . ;');
+ ScriptRes.Add(' . += 24 ;');
+ ScriptRes.Add(' *(.bss)');
+ ScriptRes.Add(' *(COMMON)');
+ ScriptRes.Add(' end = . ; _end = .;');
+ ScriptRes.Add(' . = ALIGN(0x200);');
+ ScriptRes.Add(' }');
+ ScriptRes.Add(' }');
+
+ { Write path to search libraries }
+ HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
+ while assigned(HPath) do
+ begin
+ ScriptRes.Add('SEARCH_DIR("'+GetShortName(HPath.Str)+'")');
+ HPath:=TStringListItem(HPath.Next);
+ end;
+ HPath:=TStringListItem(LibrarySearchPath.First);
+ while assigned(HPath) do
+ begin
+ ScriptRes.Add('SEARCH_DIR("'+GetShortName(HPath.Str)+'")');
+ HPath:=TStringListItem(HPath.Next);
+ end;
+
+{ Write and Close response }
+ ScriptRes.WriteToDisk;
+ ScriptRes.Free;
+
+ WriteScript:=True;
+end;
+
+
+
+function TLinkerGo32v2.MakeExecutable:boolean;
+var
+ binstr : String;
+ cmdstr : TCmdStr;
+ 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 and our own ld script }
+ WriteScript(false);
+ WriteResponsefile(false);
+
+{ Call linker }
+ SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
+ Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename^));
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
+ if source_info.system=system_i386_go32v2 then
+ Replace(cmdstr,'$RES','@'+maybequoted(outputexedir+Info.ResName))
+ else
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+ Replace(cmdstr,'$STRIP',StripStr);
+ Replace(cmdstr,'$SCRIPT','--script='+maybequoted(outputexedir+Info.ScriptName));
+ success:=DoExec(FindUtil(utilsprefix+BinStr),cmdstr,true,false);
+
+{ Remove ReponseFile }
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ begin
+ RemoveFile(outputexedir+Info.ResName);
+ RemoveFile(outputexedir+Info.ScriptName);
+ end;
+
+ 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}
+
+
+{*****************************************************************************
+ Initialize
+*****************************************************************************}
+
+initialization
+ RegisterExternalLinker(system_i386_go32v2_info,TLinkerGo32v2);
+ RegisterInternalLinker(system_i386_go32v2_info,TCoffLinker);
+ RegisterTarget(system_i386_go32v2_info);
+end.
diff --git a/compiler/systems/t_linux.pas b/compiler/systems/t_linux.pas
new file mode 100644
index 0000000000..ba47cd141e
--- /dev/null
+++ b/compiler/systems/t_linux.pas
@@ -0,0 +1,755 @@
+{
+ Copyright (c) 1998-2002 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;
+
+{$i fpcdefs.inc}
+
+interface
+
+ uses
+ symsym,symdef,ppu,
+ import,export,link;
+
+ type
+ timportliblinux=class(timportlib)
+ procedure preparelib(const s:string);override;
+ procedure importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);override;
+ procedure importvariable(vs:tglobalvarsym;const name,module:string);override;
+ procedure generatelib;override;
+ end;
+
+ texportliblinux=class(texportlib)
+ procedure preparelib(const s : string);override;
+ procedure exportprocedure(hp : texported_item);override;
+ procedure exportvar(hp : texported_item);override;
+ procedure generatelib;override;
+ end;
+
+ tlinkerlinux=class(texternallinker)
+ private
+ libctype:(libc5,glibc2,glibc21,uclibc);
+ Function WriteResponseFile(isdll:boolean) : Boolean;
+ public
+ constructor Create;override;
+ procedure SetDefaultInfo;override;
+ function MakeExecutable:boolean;override;
+ function MakeSharedLibrary:boolean;override;
+ function postprocessexecutable(const fn : string;isdll:boolean):boolean;
+ end;
+
+
+implementation
+
+ uses
+ cutils,cclasses,
+ verbose,systems,globtype,globals,
+ symconst,script,
+ fmodule,dos
+ ,aasmbase,aasmtai,aasmcpu,cpubase,cgobj
+ ,i_linux
+ ;
+
+{*****************************************************************************
+ TIMPORTLIBLINUX
+*****************************************************************************}
+
+procedure timportliblinux.preparelib(const s : string);
+begin
+end;
+
+
+procedure timportliblinux.importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);
+begin
+ { insert sharedlibrary }
+ current_module.linkothersharedlibs.add(SplitName(module),link_allways);
+end;
+
+
+procedure timportliblinux.importvariable(vs:tglobalvarsym;const name,module:string);
+begin
+ { insert sharedlibrary }
+ current_module.linkothersharedlibs.add(SplitName(module),link_allways);
+ { reset the mangledname and turn off the dll_var option }
+ vs.set_mangledname(name);
+ exclude(vs.varoptions,vo_is_dll_var);
+end;
+
+
+procedure timportliblinux.generatelib;
+begin
+end;
+
+
+{*****************************************************************************
+ TEXPORTLIBLINUX
+*****************************************************************************}
+
+procedure texportliblinux.preparelib(const s:string);
+begin
+end;
+
+
+procedure texportliblinux.exportprocedure(hp : texported_item);
+var
+ hp2 : texported_item;
+begin
+ { first test the index value }
+ if (hp.options and eo_index)<>0 then
+ begin
+ Message1(parser_e_no_export_with_index_for_target,'linux');
+ exit;
+ end;
+ { now place in correct order }
+ hp2:=texported_item(current_module._exports.first);
+ while assigned(hp2) and
+ (hp.name^>hp2.name^) do
+ hp2:=texported_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=texported_item(current_module._exports.first) then
+ current_module._exports.concat(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 : texported_item);
+begin
+ hp.is_var:=true;
+ exportprocedure(hp);
+end;
+
+
+procedure texportliblinux.generatelib;
+var
+ hp2 : texported_item;
+begin
+ new_section(asmlist[al_procedures],sec_code,'',0);
+ hp2:=texported_item(current_module._exports.first);
+ while assigned(hp2) do
+ begin
+ if (not hp2.is_var) and
+ (hp2.sym.typ=procsym) then
+ begin
+ { the manglednames can already be the same when the procedure
+ is declared with cdecl }
+ if tprocsym(hp2.sym).first_procdef.mangledname<>hp2.name^ then
+ begin
+ { place jump in al_procedures }
+ asmlist[al_procedures].concat(tai_align.create(target_info.alignment.procalign));
+ asmlist[al_procedures].concat(Tai_symbol.Createname_global(hp2.name^,AT_FUNCTION,0));
+ cg.a_jmp_name(asmlist[al_procedures],tprocsym(hp2.sym).first_procdef.mangledname);
+ asmlist[al_procedures].concat(Tai_symbol_end.Createname(hp2.name^));
+ end;
+ end
+ else
+ message1(parser_e_no_export_of_variables_for_target,'linux');
+ hp2:=texported_item(hp2.next);
+ end;
+end;
+
+
+{*****************************************************************************
+ TLINKERLINUX
+*****************************************************************************}
+
+Constructor TLinkerLinux.Create;
+begin
+ Inherited Create;
+ if not Dontlinkstdlibpath Then
+{$ifdef x86_64}
+ LibrarySearchPath.AddPath('/lib64;/usr/lib64;/usr/X11R6/lib64',true);
+{$else}
+{$ifdef powerpc64}
+ LibrarySearchPath.AddPath('/lib64;/usr/lib64;/usr/X11R6/lib64',true);
+{$else powerpc64}
+ LibrarySearchPath.AddPath('/lib;/usr/lib;/usr/X11R6/lib',true);
+{$endif powerpc64}
+{$endif x86_64}
+end;
+
+
+procedure TLinkerLinux.SetDefaultInfo;
+{
+ This will also detect which libc version will be used
+}
+
+const
+{$ifdef i386} platform_select='-b elf32-i386 -m elf_i386';{$endif}
+{$ifdef x86_64} platform_select='-b elf64-x86-64 -m elf_x86_64';{$endif}
+{$ifdef powerpc}platform_select='-b elf32-powerpc -m elf32ppclinux';{$endif}
+{$ifdef POWERPC64} platform_select='-b elf64-powerpc -m elf64ppc';{$endif}
+{$ifdef sparc} platform_select='-b elf32-sparc -m elf32_sparc';{$endif}
+{$ifdef arm} platform_select='';{$endif} {unknown :( }
+{$ifdef m68k} platform_select='';{$endif} {unknown :( }
+
+{$ifdef m68k}
+var
+ St : SearchRec;
+{$endif m68k}
+begin
+ with Info do
+ begin
+ ExeCmd[1]:='ld '+platform_select+' $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $RES';
+ DllCmd[1]:='ld '+platform_select+' $OPT $INIT $FINI $SONAME -shared -L. -o $EXE $RES';
+ DllCmd[2]:='strip --strip-unneeded $EXE';
+{$ifdef m68k}
+ libctype:=glibc2;
+ FindFirst('/lib/ld*',AnyFile,st);
+ while DosError=0 do
+ begin
+ if copy(st.name,1,5)='ld-2.' then
+ begin
+ DynamicLinker:='/lib/'+St.name;
+ if st.name[6]<>'0' then
+ libctype:=glibc21;
+ break;
+ end;
+ FindNext(St);
+ end;
+ FindClose(St);
+{$endif m68k}
+
+{$ifdef i386}
+ { first try glibc2 }
+ DynamicLinker:='/lib/ld-linux.so.2';
+ if FileExists(DynamicLinker) then
+ { Check for 2.0 files, else use the glibc 2.1 stub }
+ if FileExists('/lib/ld-2.0.*') then
+ libctype:=glibc2
+ else
+ libctype:=glibc21
+ else
+ if fileexists('/lib/ld-uClibc.so.0') then
+ begin
+ libctype:=uclibc;
+ dynamiclinker:='/lib/ld-uClibc.so.0';
+ end
+ else if fileexists('/lib/ld-linux.so.1') then
+ DynamicLinker:='/lib/ld-linux.so.1'
+ else
+ libctype:=glibc21;
+{$endif i386}
+
+{$ifdef x86_64}
+ DynamicLinker:='/lib64/ld-linux-x86-64.so.2';
+ libctype:=glibc2;
+{$endif x86_64}
+
+{$ifdef sparc}
+ DynamicLinker:='/lib/ld-linux.so.2';
+ libctype:=glibc2;
+{$endif sparc}
+
+{$ifdef powerpc}
+ DynamicLinker:='/lib/ld.so.1';
+ libctype:=glibc2;
+{$endif powerpc}
+
+{$ifdef powerpc64}
+ DynamicLinker:='/lib64/ld64.so.1';
+ libctype:=glibc2;
+{$endif powerpc64}
+
+{$ifdef arm}
+ DynamicLinker:='/lib/ld-linux.so.2';
+ libctype:=glibc2;
+{$endif arm}
+ end;
+end;
+
+
+Function TLinkerLinux.WriteResponseFile(isdll:boolean) : Boolean;
+Var
+ linkres : TLinkRes;
+ i : longint;
+ cprtobj,
+ gprtobj,
+ prtobj : string[80];
+ HPath : TStringListItem;
+ s,s1,s2 : string;
+ found1,
+ found2,
+ linklibc : boolean;
+begin
+ WriteResponseFile:=False;
+{ set special options for some targets }
+ linklibc:=(SharedLibFiles.Find('c')<>nil);
+ if isdll then
+ begin
+ prtobj:='dllprt0';
+ cprtobj:='dllprt0';
+ gprtobj:='dllprt0';
+ end
+ else
+ begin
+ prtobj:='prt0';
+ case libctype of
+ glibc21:
+ begin
+ cprtobj:='cprt21';
+ gprtobj:='gprt21';
+ end;
+ uclibc:
+ begin
+ cprtobj:='ucprt0';
+ gprtobj:='ugprt0';
+ end
+ else
+ cprtobj:='cprt0';
+ gprtobj:='gprt0';
+ end;
+ end;
+ if cs_profile in aktmoduleswitches then
+ begin
+ prtobj:=gprtobj;
+ if not(libctype in [glibc2,glibc21]) then
+ AddSharedLibrary('gmon');
+ AddSharedLibrary('c');
+ linklibc:=true;
+ end
+ else
+ begin
+ if linklibc then
+ prtobj:=cprtobj;
+ end;
+
+ { Open link.res file }
+ LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
+
+ { Write path to search libraries }
+ HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
+ while assigned(HPath) do
+ begin
+ LinkRes.Add('SEARCH_DIR('+maybequoted(HPath.Str)+')');
+ HPath:=TStringListItem(HPath.Next);
+ end;
+ HPath:=TStringListItem(LibrarySearchPath.First);
+ while assigned(HPath) do
+ begin
+ LinkRes.Add('SEARCH_DIR('+maybequoted(HPath.Str)+')');
+ HPath:=TStringListItem(HPath.Next);
+ end;
+
+ LinkRes.Add('INPUT(');
+ { add objectfiles, start with prt0 always }
+ if prtobj<>'' then
+ LinkRes.AddFileName(maybequoted(FindObjectFile(prtobj,'',false)));
+ { try to add crti and crtbegin if linking to C }
+ if linklibc then
+ begin
+ if librarysearchpath.FindFile('crtbegin.o',s) then
+ LinkRes.AddFileName(s);
+ if librarysearchpath.FindFile('crti.o',s) then
+ LinkRes.AddFileName(s);
+ end;
+ { main objectfiles }
+ while not ObjectFiles.Empty do
+ begin
+ s:=ObjectFiles.GetFirst;
+ if s<>'' then
+ LinkRes.AddFileName(maybequoted(s));
+ end;
+ LinkRes.Add(')');
+
+ { Write staticlibraries }
+ if not StaticLibFiles.Empty then
+ begin
+ LinkRes.Add('GROUP(');
+ While not StaticLibFiles.Empty do
+ begin
+ S:=StaticLibFiles.GetFirst;
+ LinkRes.AddFileName(maybequoted(s))
+ end;
+ LinkRes.Add(')');
+ end;
+
+ { Write sharedlibraries like -l<lib>, also add the needed dynamic linker
+ here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
+ if not SharedLibFiles.Empty then
+ begin
+ LinkRes.Add('INPUT(');
+ While not SharedLibFiles.Empty do
+ begin
+ S:=SharedLibFiles.GetFirst;
+ if s<>'c' then
+ begin
+ i:=Pos(target_info.sharedlibext,S);
+ if i>0 then
+ Delete(S,i,255);
+ LinkRes.Add('-l'+s);
+ end
+ else
+ begin
+ linklibc:=true;
+ end;
+ end;
+ { be sure that libc is the last lib }
+ if linklibc then
+ LinkRes.Add('-lc');
+ { when we have -static for the linker the we also need libgcc }
+ if (cs_link_staticflag in aktglobalswitches) then
+ LinkRes.Add('-lgcc');
+ LinkRes.Add(')');
+ end;
+
+ { objects which must be at the end }
+ if linklibc and (libctype<>uclibc) then
+ begin
+ found1:=librarysearchpath.FindFile('crtend.o',s1);
+ found2:=librarysearchpath.FindFile('crtn.o',s2);
+ if found1 or found2 then
+ begin
+ LinkRes.Add('INPUT(');
+ if found1 then
+ LinkRes.AddFileName(s1);
+ if found2 then
+ LinkRes.AddFileName(s2);
+ LinkRes.Add(')');
+ end;
+ end;
+ {Entry point.}
+ linkres.add('ENTRY(_start)');
+
+ {Sections.}
+{
+ commented out because it cause problems on several machines with different ld versions (FK)
+ linkres.add('SECTIONS');
+ linkres.add('{');
+ {Read-only sections, merged into text segment:}
+ linkres.add(' PROVIDE (__executable_start = 0x010000); . = 0x010000 +0x100;');
+ linkres.add(' .interp : { *(.interp) }');
+ linkres.add(' .hash : { *(.hash) }');
+ linkres.add(' .dynsym : { *(.dynsym) }');
+ linkres.add(' .dynstr : { *(.dynstr) }');
+ linkres.add(' .gnu.version : { *(.gnu.version) }');
+ linkres.add(' .gnu.version_d : { *(.gnu.version_d) }');
+ linkres.add(' .gnu.version_r : { *(.gnu.version_r) }');
+ linkres.add(' .rel.dyn :');
+ linkres.add(' {');
+ linkres.add(' *(.rel.init)');
+ linkres.add(' *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)');
+ linkres.add(' *(.rel.fini)');
+ linkres.add(' *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)');
+ linkres.add(' *(.rel.data.rel.ro*)');
+ linkres.add(' *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)');
+ linkres.add(' *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)');
+ linkres.add(' *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)');
+ linkres.add(' *(.rel.got)');
+ linkres.add(' *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)');
+ linkres.add(' }');
+ linkres.add(' .rela.dyn :');
+ linkres.add(' {');
+ linkres.add(' *(.rela.init)');
+ linkres.add(' *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)');
+ linkres.add(' *(.rela.fini)');
+ linkres.add(' *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)');
+ linkres.add(' *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)');
+ linkres.add(' *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)');
+ linkres.add(' *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)');
+ linkres.add(' *(.rela.got)');
+ linkres.add(' *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)');
+ linkres.add(' }');
+ linkres.add(' .rel.plt : { *(.rel.plt) }');
+ linkres.add(' .rela.plt : { *(.rela.plt) }');
+ linkres.add(' .init :');
+ linkres.add(' {');
+ linkres.add(' KEEP (*(.init))');
+ linkres.add(' } =0x90909090');
+ linkres.add(' .plt : { *(.plt) }');
+ linkres.add(' .text :');
+ linkres.add(' {');
+ linkres.add(' *(.text .stub .text.* .gnu.linkonce.t.*)');
+ linkres.add(' KEEP (*(.text.*personality*))');
+ {.gnu.warning sections are handled specially by elf32.em.}
+ linkres.add(' *(.gnu.warning)');
+ linkres.add(' } =0x90909090');
+ linkres.add(' .fini :');
+ linkres.add(' {');
+ linkres.add(' KEEP (*(.fini))');
+ linkres.add(' } =0x90909090');
+ linkres.add(' PROVIDE (_etext = .);');
+ linkres.add(' .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }');
+ {Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up.}
+ linkres.add(' . = ALIGN (0x1000) - ((0x1000 - .) & (0x1000 - 1)); . = DATA_SEGMENT_ALIGN (0x1000, 0x1000);');
+ linkres.add(' .dynamic : { *(.dynamic) }');
+ linkres.add(' .got : { *(.got) }');
+ linkres.add(' .got.plt : { *(.got.plt) }');
+ linkres.add(' .data :');
+ linkres.add(' {');
+ linkres.add(' *(.data .data.* .gnu.linkonce.d.*)');
+ linkres.add(' KEEP (*(.gnu.linkonce.d.*personality*))');
+ linkres.add(' }');
+ linkres.add(' _edata = .;');
+ linkres.add(' PROVIDE (edata = .);');
+{$ifdef zsegment_threadvars}
+ linkres.add(' _z = .;');
+ linkres.add(' .threadvar 0 : AT (_z) { *(.threadvar .threadvar.* .gnu.linkonce.tv.*) }');
+ linkres.add(' PROVIDE (_threadvar_size = SIZEOF(.threadvar));');
+ linkres.add(' . = _z + SIZEOF (.threadvar);');
+{$else}
+ linkres.add(' .threadvar : { *(.threadvar .threadvar.* .gnu.linkonce.tv.*) }');
+{$endif}
+ linkres.add(' __bss_start = .;');
+ linkres.add(' .bss :');
+ linkres.add(' {');
+ linkres.add(' *(.dynbss)');
+ linkres.add(' *(.bss .bss.* .gnu.linkonce.b.*)');
+ linkres.add(' *(COMMON)');
+ {Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections.}
+ linkres.add(' . = ALIGN(32 / 8);');
+ linkres.add(' }');
+ linkres.add(' . = ALIGN(32 / 8);');
+ linkres.add(' _end = .;');
+ linkres.add(' PROVIDE (end = .);');
+ linkres.add(' . = DATA_SEGMENT_END (.);');
+ {Stabs debugging sections.}
+ linkres.add(' .stab 0 : { *(.stab) }');
+ linkres.add(' .stabstr 0 : { *(.stabstr) }');
+ linkres.add('}');
+}
+
+{ Write and Close response }
+ LinkRes.writetodisk;
+ LinkRes.Free;
+
+ WriteResponseFile:=True;
+end;
+
+
+function TLinkerLinux.MakeExecutable:boolean;
+var
+ binstr : String;
+ cmdstr : TCmdStr;
+ success : boolean;
+ DynLinkStr : string[60];
+ GCSectionsStr,
+ StaticStr,
+ StripStr : string[40];
+begin
+ if not(cs_link_extern in aktglobalswitches) then
+ Message1(exec_i_linking,current_module.exefilename^);
+
+{ Create some replacements }
+ StaticStr:='';
+ StripStr:='';
+ GCSectionsStr:='';
+ DynLinkStr:='';
+ if (cs_link_staticflag in aktglobalswitches) then
+ StaticStr:='-static';
+ if (cs_link_strip in aktglobalswitches) then
+ StripStr:='-s';
+ if (af_smartlink_sections in target_asm.flags) and
+ (tf_smartlink_sections in target_info.flags) then
+ GCSectionsStr:='--gc-sections';
+ If (cs_profile in aktmoduleswitches) or
+ ((Info.DynamicLinker<>'') and (not SharedLibFiles.Empty)) then
+ begin
+ DynLinkStr:='-dynamic-linker='+Info.DynamicLinker;
+ if cshared Then
+ DynLinkStr:='--shared ' + DynLinkStr;
+ if rlinkpath<>'' Then
+ DynLinkStr:='--rpath-link '+rlinkpath + ' '+ DynLinkStr;
+ End;
+
+{ Write used files and libraries }
+ WriteResponseFile(false);
+
+{ Call linker }
+ SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
+ Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename^));
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+ Replace(cmdstr,'$STATIC',StaticStr);
+ Replace(cmdstr,'$STRIP',StripStr);
+ Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
+ Replace(cmdstr,'$DYNLINK',DynLinkStr);
+ success:=DoExec(FindUtil(utilsprefix+BinStr),CmdStr,true,false);
+
+{ Remove ReponseFile }
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ RemoveFile(outputexedir+Info.ResName);
+
+ if (success) then
+ success:=PostProcessExecutable(current_module.exefilename^,false);
+
+
+ MakeExecutable:=success; { otherwise a recursive call to link method }
+end;
+
+
+Function TLinkerLinux.MakeSharedLibrary:boolean;
+var
+ InitStr,
+ FiniStr,
+ SoNameStr : string[80];
+ binstr : String;
+ cmdstr : TCmdStr;
+ 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);
+
+ { Create some replacements }
+ InitStr:='-init FPC_LIB_START';
+ FiniStr:='-fini FPC_LIB_EXIT';
+ SoNameStr:='-soname '+SplitFileName(current_module.sharedlibfilename^);
+
+{ Call linker }
+ SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
+ Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename^));
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+ Replace(cmdstr,'$INIT',InitStr);
+ Replace(cmdstr,'$FINI',FiniStr);
+ Replace(cmdstr,'$SONAME',SoNameStr);
+ success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
+
+{ Strip the library ? }
+ if success and (cs_link_strip in aktglobalswitches) then
+ begin
+ { only remove non global symbols and debugging info for a library }
+ Info.DllCmd[2]:='strip --discard-all --strip-debug $EXE';
+ SplitBinCmd(Info.DllCmd[2],binstr,cmdstr);
+ Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename^));
+ success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
+ end;
+
+{ Remove ReponseFile }
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ RemoveFile(outputexedir+Info.ResName);
+
+ MakeSharedLibrary:=success; { otherwise a recursive call to link method }
+end;
+
+function tlinkerLinux.postprocessexecutable(const fn : string;isdll:boolean):boolean;
+
+Var
+ cmdstr: string;
+ found : boolean;
+ hp : tused_unit;
+
+begin
+ postprocessexecutable:=True;
+ if target_res.id=res_elf then
+ begin
+ found:=((current_module.flags and uf_has_resourcefiles)=uf_has_resourcefiles);
+ if not found then
+ begin
+ hp:=tused_unit(usedunits.first);
+ While Assigned(hp) and not Found do
+ begin
+ Found:=((hp.u.flags and uf_has_resourcefiles)=uf_has_resourcefiles);
+ hp:=tused_unit(hp.next);
+ end;
+ end;
+ if found then
+ begin
+ cmdstr:=' -f -i '+maybequoted(fn);
+ postprocessexecutable:=DoExec(FindUtil(utilsprefix+'fpcres'),cmdstr,false,false);
+ end;
+ end;
+end;
+
+
+{*****************************************************************************
+ Initialize
+*****************************************************************************}
+
+initialization
+{$ifdef i386}
+ RegisterExternalLinker(system_i386_linux_info,TLinkerLinux);
+ RegisterImport(system_i386_linux,timportliblinux);
+ RegisterExport(system_i386_linux,texportliblinux);
+ RegisterTarget(system_i386_linux_info);
+ RegisterRes(res_elf32_info);
+
+ RegisterExternalLinker(system_x86_6432_linux_info,TLinkerLinux);
+ RegisterImport(system_x86_6432_linux,timportliblinux);
+ RegisterExport(system_x86_6432_linux,texportliblinux);
+ RegisterTarget(system_x86_6432_linux_info);
+{$endif i386}
+{$ifdef m68k}
+ RegisterExternalLinker(system_m68k_linux_info,TLinkerLinux);
+ RegisterImport(system_m68k_linux,timportliblinux);
+ RegisterExport(system_m68k_linux,texportliblinux);
+ RegisterTarget(system_m68k_linux_info);
+{$endif m68k}
+{$ifdef powerpc}
+ RegisterExternalLinker(system_powerpc_linux_info,TLinkerLinux);
+ RegisterImport(system_powerpc_linux,timportliblinux);
+ RegisterExport(system_powerpc_linux,texportliblinux);
+ RegisterTarget(system_powerpc_linux_info);
+{$endif powerpc}
+{$ifdef powerpc64}
+ RegisterExternalLinker(system_powerpc64_linux_info,TLinkerLinux);
+ RegisterImport(system_powerpc64_linux,timportliblinux);
+ RegisterExport(system_powerpc64_linux,texportliblinux);
+ RegisterTarget(system_powerpc64_linux_info);
+{$endif powerpc64}
+{$ifdef alpha}
+ RegisterExternalLinker(system_alpha_linux_info,TLinkerLinux);
+ RegisterImport(system_alpha_linux,timportliblinux);
+ RegisterExport(system_alpha_linux,texportliblinux);
+ RegisterTarget(system_alpha_linux_info);
+{$endif alpha}
+{$ifdef x86_64}
+ RegisterExternalLinker(system_x86_64_linux_info,TLinkerLinux);
+ RegisterImport(system_x86_64_linux,timportliblinux);
+ RegisterExport(system_x86_64_linux,texportliblinux);
+ RegisterTarget(system_x86_64_linux_info);
+ RegisterRes(res_elf64_info);
+{$endif x86_64}
+{$ifdef SPARC}
+ RegisterExternalLinker(system_sparc_linux_info,TLinkerLinux);
+ RegisterImport(system_SPARC_linux,timportliblinux);
+ RegisterExport(system_SPARC_linux,texportliblinux);
+ RegisterTarget(system_SPARC_linux_info);
+{$endif SPARC}
+{$ifdef ARM}
+ RegisterExternalLinker(system_arm_linux_info,TLinkerLinux);
+ RegisterImport(system_arm_linux,timportliblinux);
+ RegisterExport(system_arm_linux,texportliblinux);
+ RegisterTarget(system_arm_linux_info);
+{$endif ARM}
+end.
diff --git a/compiler/systems/t_macos.pas b/compiler/systems/t_macos.pas
new file mode 100644
index 0000000000..115fbbc330
--- /dev/null
+++ b/compiler/systems/t_macos.pas
@@ -0,0 +1,273 @@
+{
+ Copyright (c) 2001-2002 by Peter Vreman
+
+ This unit implements support import,export,link routines for MacOS.
+
+ 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_macos;
+
+{$i fpcdefs.inc}
+
+interface
+
+ uses
+ import,symsym,symdef,link;
+
+ type
+ timportlibmacos=class(timportlib)
+ procedure preparelib(const s:string);override;
+ procedure importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);override;
+ procedure importvariable(vs:tglobalvarsym;const name,module:string);override;
+ procedure generatelib;override;
+ end;
+
+ tlinkermpw=class(texternallinker)
+ private
+ Function WriteResponseFile(isdll:boolean) : Boolean;
+ public
+ constructor Create;override;
+ procedure SetDefaultInfo;override;
+ function MakeExecutable:boolean;override;
+ end;
+
+implementation
+
+ uses
+ cutils,cclasses,
+ globtype,globals,systems,verbose,script,fmodule,i_macos,
+ symconst;
+
+{*****************************************************************************
+ TIMPORTLIBMACOS
+*****************************************************************************}
+
+procedure timportlibmacos.preparelib(const s : string);
+begin
+end;
+
+
+procedure timportlibmacos.importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);
+begin
+ { insert sharedlibrary }
+ current_module.linkothersharedlibs.add(SplitName(module),link_allways);
+end;
+
+
+procedure timportlibmacos.importvariable(vs:tglobalvarsym;const name,module:string);
+begin
+ { insert sharedlibrary }
+ current_module.linkothersharedlibs.add(SplitName(module),link_allways);
+ { reset the mangledname and turn off the dll_var option }
+ vs.set_mangledname(name);
+ exclude(vs.varoptions,vo_is_dll_var);
+end;
+
+
+procedure timportlibmacos.generatelib;
+begin
+end;
+
+{*****************************************************************************
+ TLINKERMPW
+*****************************************************************************}
+
+Constructor TLinkerMPW.Create;
+begin
+ Inherited Create;
+ //LibrarySearchPath.AddPath('/lib;/usr/lib;/usr/X11R6/lib',true);
+end;
+
+
+procedure TLinkerMPW.SetDefaultInfo;
+
+begin
+ with Info do
+ begin
+ ExeCmd[1]:='Execute $RES'; {The link.res file contains the whole link command.}
+ //ExeCmd[1]:='PPCLink $OPT $DYNLINK $STATIC $STRIP -tocdataref off -dead on -o $EXE -@filelist $RES';
+ //DllCmd[1]:='PPCLink $OPT $INIT $FINI $SONAME -shared -o $EXE -@filelist $RES';
+ end;
+end;
+
+
+Function TLinkerMPW.WriteResponseFile(isdll:boolean) : Boolean;
+Var
+ linkres : TLinkRes;
+ s,heapsizestr: string;
+
+begin
+ WriteResponseFile:=False;
+ { Open link.res file }
+ linkRes:=TLinkRes.Create(outputexedir+Info.ResName);
+
+ with linkRes do
+ begin
+ {#182 is escape char in MPW (analog to backslash in unix). The space}
+ {ensures there is whitespace separating items.}
+ Add('PPCLink '#182);
+
+ { Add MPW standard libraries}
+ if apptype = app_cui then
+ Add('"{PPCLibraries}PPCSIOW.o" '#182);
+
+ {Even GUI apps must link to PPCToolLibs, because of the System unit
+ which can be used by MPW tools as well as by GUI apps.}
+ Add('"{PPCLibraries}PPCToolLibs.o" '#182);
+ Add('"{SharedLibraries}InterfaceLib" '#182);
+ Add('"{SharedLibraries}StdCLib" '#182);
+ Add('"{SharedLibraries}MathLib" '#182);
+ Add('"{PPCLibraries}StdCRuntime.o" '#182);
+ Add('"{PPCLibraries}PPCCRuntime.o" '#182);
+
+ {Add main objectfiles}
+ while not ObjectFiles.Empty do
+ begin
+ s:=ObjectFiles.GetFirst;
+ if s<>'' then
+ Add(s+' '#182);
+ end;
+
+ {Add last lines of the link command}
+ if apptype = app_tool then
+ Add('-t "MPST" -c "MPS " '#182);
+
+ if apptype = app_cui then {If SIOW, to avoid some warnings.}
+ Add('-ignoredups __start -ignoredups .__start -ignoredups main -ignoredups .main -ignoredups qd '#182);
+
+ Add('-tocdataref off -sym on -dead on -o '+ ScriptFixFileName(current_module.exefilename^));
+
+ Add('Exit If "{Status}" != 0');
+
+ if heapsize = 0 then
+ heapsizestr:= HexStr(384000, 8)
+ else
+ heapsizestr:= HexStr(heapsize, 8);
+
+ {Add a SIZE resource on the fly. It controls:
+ * backgrounding is enabled, to facilitate debuging with Power Mac Debugger
+ * it is signaled it is a 32 bit app. (perhaps not nessecary on PowerPC)
+ * heapsize }
+ if apptype <> app_tool then
+ begin
+ Add('Echo "data ''SIZE'' (-1) '#182'{ $'#182'"1080 ' + heapsizestr + ' ' + heapsizestr +
+ #182'" '#182'};" | Rez -a -o ' + ScriptFixFileName(current_module.exefilename^));
+ Add('Exit If "{Status}" != 0');
+ end;
+
+ {Add mac resources}
+ if apptype = app_cui then
+ begin
+ Add('Rez -a "{RIncludes}"SIOW.r -o ' + ScriptFixFileName(current_module.exefilename^));
+ Add('Exit If "{Status}" != 0');
+ end;
+
+ while not (current_module.ResourceFiles.Empty) do
+ begin
+ s := Current_module.ResourceFiles.GetFirst;
+ if Copy(s,Length(s)-1,Length(s)) = '.r' then
+ Add('Rez -a ' + s + ' -o ' + ScriptFixFileName(current_module.exefilename^))
+ else
+ Add('DeRez ' + s + ' | Rez -a -o ' + ScriptFixFileName(current_module.exefilename^));
+ Add('Exit If "{Status}" != 0');
+ end;
+
+ end;
+
+ { Write and Close response }
+ linkres.writetodisk;
+ linkres.Free;
+
+ WriteResponseFile:=True;
+end;
+
+
+function TLinkerMPW.MakeExecutable:boolean;
+var
+ binstr : string;
+ cmdstr : TCmdStr;
+ success : boolean;
+ DynLinkStr : string[60];
+ StaticStr,
+ StripStr : string[40];
+
+ s: string;
+
+begin
+ //TODO Only external link in MPW is possible, otherwise yell.
+
+ if not(cs_link_extern in aktglobalswitches) then
+ Message1(exec_i_linking,current_module.exefilename^);
+
+{ Create some replacements }
+ StripStr:='';
+(*
+ StaticStr:='';
+ DynLinkStr:='';
+ if (cs_link_staticflag in aktglobalswitches) then
+ StaticStr:='-static';
+ if (cs_link_strip in aktglobalswitches) then
+ StripStr:='-s';
+ If (cs_profile in aktmoduleswitches) or
+ ((Info.DynamicLinker<>'') and (not SharedLibFiles.Empty)) then
+ DynLinkStr:='-dynamic-linker='+Info.DynamicLinker;
+*)
+
+{ Prepare linking }
+ SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
+ Replace(cmdstr,'$EXE',maybequoted(ScriptFixFileName(current_module.exefilename^)));
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
+ Replace(cmdstr,'$RES',maybequoted(ScriptFixFileName(outputexedir+Info.ResName)));
+ Replace(cmdstr,'$STATIC',StaticStr);
+ Replace(cmdstr,'$STRIP',StripStr);
+ Replace(cmdstr,'$DYNLINK',DynLinkStr);
+
+ WriteResponseFile(false);
+
+ success:= true;
+ if cs_link_on_target in aktglobalswitches then
+ success:=DoExec('SetFile', ' -c ''MPS '' -t ''TEXT'' ' +
+ ScriptFixFileName(outputexedir+Info.ResName),true,false);
+
+{ Call linker }
+ if success then
+ success:=DoExec('Execute',CmdStr,true,false);
+
+{ Remove ReponseFile }
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ RemoveFile(outputexedir+Info.ResName);
+
+ MakeExecutable:=success; { otherwise a recursive call to link method }
+end;
+
+
+
+{*****************************************************************************
+ Initialize
+*****************************************************************************}
+
+initialization
+{$ifdef m68k}
+ RegisterTarget(system_m68k_macos_info);
+ RegisterImport(system_m68k_macos,timportlibmacos);
+{$endif m68k}
+{$ifdef powerpc}
+ RegisterExternalLinker(system_powerpc_macos_info,TLinkerMPW);
+ RegisterTarget(system_powerpc_macos_info);
+ RegisterImport(system_powerpc_macos,timportlibmacos);
+{$endif powerpc}
+end.
diff --git a/compiler/systems/t_morph.pas b/compiler/systems/t_morph.pas
new file mode 100644
index 0000000000..0657f808ab
--- /dev/null
+++ b/compiler/systems/t_morph.pas
@@ -0,0 +1,269 @@
+{
+ Copyright (c) 2004 by Free Pascal Development Team
+
+ This unit implements support import, export, link routines
+ for the MorphOS (PowerPC) 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_morph;
+
+{$i fpcdefs.inc}
+
+interface
+
+
+implementation
+
+ uses
+ link,
+ cutils,cclasses,
+ globtype,globals,systems,verbose,script,fmodule,i_morph;
+
+ type
+ PlinkerMorphOS=^TlinkerMorphOS;
+ TlinkerMorphOS=class(texternallinker)
+ private
+ Function WriteResponseFile(isdll:boolean) : Boolean;
+ public
+ constructor Create; override;
+ procedure SetDefaultInfo; override;
+ function MakeExecutable:boolean; override;
+ end;
+
+{$IFDEF MORPHOS}
+{ * PathConv is implemented in the system unit! * }
+function PathConv(path: string): string; external name 'PATHCONV';
+{$ELSE}
+function PathConv(path: string): string;
+begin
+ PathConv:=path;
+end;
+{$ENDIF}
+
+{****************************************************************************
+ TLinkerMorphOS
+****************************************************************************}
+
+Constructor TLinkerMorphOS.Create;
+begin
+ Inherited Create;
+ { allow duplicated libs (PM) }
+ SharedLibFiles.doubles:=true;
+ StaticLibFiles.doubles:=true;
+end;
+
+
+procedure TLinkerMorphOS.SetDefaultInfo;
+begin
+ with Info do
+ begin
+ if (cs_link_on_target in aktglobalswitches) then
+ begin
+ ExeCmd[1]:='ld $OPT -o $EXE $RES';
+ ExeCmd[2]:='strip --strip-unneeded --remove-section .comment $EXE';
+ end
+ else
+ begin
+ ExeCmd[1]:='fpcvlink -b elf32amiga $OPT $STRIP -o $EXE -T $RES';
+ end;
+ end;
+end;
+
+
+Function TLinkerMorphOS.WriteResponseFile(isdll:boolean) : Boolean;
+Var
+ linkres : TLinkRes;
+ i : longint;
+ HPath : TStringListItem;
+ s : string;
+ linklibc : boolean;
+begin
+ WriteResponseFile:=False;
+
+ { Open link.res file }
+ LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
+
+ { Write path to search libraries }
+ HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
+ while assigned(HPath) do
+ begin
+ s:=HPath.Str;
+ if (cs_link_on_target in aktglobalswitches) then
+ s:=ScriptFixFileName(s);
+ LinkRes.Add('-L'+s);
+ HPath:=TStringListItem(HPath.Next);
+ end;
+ HPath:=TStringListItem(LibrarySearchPath.First);
+ while assigned(HPath) do
+ begin
+ s:=HPath.Str;
+ if s<>'' then
+ LinkRes.Add('SEARCH_DIR('+PathConv(maybequoted(s))+')');
+ HPath:=TStringListItem(HPath.Next);
+ end;
+
+ LinkRes.Add('INPUT (');
+ { add objectfiles, start with prt0 always }
+ s:=FindObjectFile('prt0','',false);
+ LinkRes.AddFileName(s);
+ while not ObjectFiles.Empty do
+ begin
+ s:=ObjectFiles.GetFirst;
+ if s<>'' then
+ begin
+ { vlink doesn't use SEARCH_DIR for object files }
+ if not(cs_link_on_target in aktglobalswitches) then
+ s:=FindObjectFile(s,'',false);
+ LinkRes.AddFileName(PathConv(maybequoted(s)));
+ end;
+ end;
+
+ { Write staticlibraries }
+ if not StaticLibFiles.Empty then
+ begin
+ { vlink doesn't need, and doesn't support GROUP }
+ if (cs_link_on_target in aktglobalswitches) then
+ begin
+ LinkRes.Add(')');
+ LinkRes.Add('GROUP(');
+ end;
+ while not StaticLibFiles.Empty do
+ begin
+ S:=StaticLibFiles.GetFirst;
+ LinkRes.AddFileName(PathConv(maybequoted(s)));
+ end;
+ end;
+
+ if (cs_link_on_target in aktglobalswitches) then
+ begin
+ LinkRes.Add(')');
+
+ { 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) }
+ linklibc:=false;
+ while not SharedLibFiles.Empty do
+ begin
+ S:=SharedLibFiles.GetFirst;
+ if s<>'c' then
+ begin
+ i:=Pos(target_info.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;
+ end
+ else
+ begin
+ while not SharedLibFiles.Empty do
+ begin
+ S:=SharedLibFiles.GetFirst;
+ LinkRes.Add('lib'+s+target_info.staticlibext);
+ end;
+ LinkRes.Add(')');
+ end;
+
+
+{ Write and Close response }
+ linkres.writetodisk;
+ linkres.free;
+
+ WriteResponseFile:=True;
+
+end;
+
+
+function TLinkerMorphOS.MakeExecutable:boolean;
+var
+ binstr : string;
+ cmdstr : TCmdStr;
+ success : boolean;
+ StripStr: string[40];
+begin
+
+ if not(cs_link_extern in aktglobalswitches) then
+ Message1(exec_i_linking,current_module.exefilename^);
+
+ if not (cs_link_on_target in aktglobalswitches) then
+ begin
+ StripStr:='';
+ if (cs_link_strip in aktglobalswitches) then
+ StripStr:='-s -P __abox__';
+ end;
+
+{ Write used files and libraries }
+ WriteResponseFile(false);
+
+{ Call linker }
+ SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
+ if not(cs_link_on_target in aktglobalswitches) then
+ begin
+ Replace(cmdstr,'$EXE',PathConv(maybequoted(ScriptFixFileName(current_module.exefilename^))));
+ Replace(cmdstr,'$RES',PathConv(maybequoted(ScriptFixFileName(outputexedir+Info.ResName))));
+ Replace(cmdstr,'$STRIP',StripStr);
+ end
+ else
+ begin
+ Replace(cmdstr,'$EXE',maybequoted(ScriptFixFileName(current_module.exefilename^)));
+ Replace(cmdstr,'$RES',maybequoted(ScriptFixFileName(outputexedir+Info.ResName)));
+ end;
+ success:=DoExec(FindUtil(BinStr),cmdstr,true,false);
+
+{ Stripping Enabled? }
+ { For MorphOS a separate strip command is needed, to avoid stripping }
+ { __abox__ symbol, which is required to be present in current MorphOS }
+ { executables. }
+ if (cs_link_on_target in aktglobalswitches) then
+ begin
+ if success and (cs_link_strip in aktglobalswitches) then
+ begin
+ SplitBinCmd(Info.ExeCmd[2],binstr,cmdstr);
+ Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename^));
+ success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
+ end;
+ end;
+
+{ Remove ReponseFile }
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ RemoveFile(outputexedir+Info.ResName);
+
+ MakeExecutable:=success; { otherwise a recursive call to link method }
+
+end;
+
+
+{*****************************************************************************
+ Initialize
+*****************************************************************************}
+
+initialization
+ RegisterExternalLinker(system_powerpc_morphos_info,TLinkerMorphOS);
+ RegisterTarget(system_powerpc_morphos_info);
+end.
diff --git a/compiler/systems/t_nwl.pas b/compiler/systems/t_nwl.pas
new file mode 100644
index 0000000000..78e1ba0d93
--- /dev/null
+++ b/compiler/systems/t_nwl.pas
@@ -0,0 +1,645 @@
+{
+ Copyright (c) 1998-2004 by Peter Vreman
+
+ This unit implements support import,export,link routines
+ for the (i386) Netware libc 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.
+
+ Currently generating NetWare-NLM's only work under Linux and win32.
+ (see http://home.arcor.de/armin.diehl/fpcnw for binutils working
+ with win32) while not included in fpc-releases.
+
+ The following compiler-swiches are supported for NetWare:
+ $DESCRIPTION : NLM-Description, will be displayed at load-time
+ $M : For Stack-Size, Heap-Size will be ignored
+ 32K is the accepted minimum
+ $VERSION x.x.x : Sets Major, Minor and Revision
+ $SCREENNAME : Sets the ScreenName
+ $THREADNAME : Sets current threadname
+
+ Additional parameters for the nlmvonv-inputfile can be passed with
+ -k, i.e. -kREENTRANT will add the option REENTRANT to the nlmconv
+ inputfile. A ; will be converted into a newline
+
+ Exports will be handled like in win32:
+ procedure bla; cdecl;
+ begin
+ end;
+
+ exports foo name 'Bar';
+
+ The path to the import-Files must be specified by the library-path.
+ All external modules are defined as autoload. (Note: the import-files have
+ to be in unix-format for exe2nlm)
+ By default, the most import files are included in freepascal.
+
+ e.g. function getgrnam(name:Pchar):Pgroup;cdecl;external 'libc' 'getgrnam';
+ sets IMPORT @libc.imp and MODULE libc.
+ To avoid setting the autoload, use ! in the name, e.g.
+ procedure EnterDebugger;cdecl;external '!netware' name 'EnterDebugger';
+
+ Function simply defined as external work without generating autoload and
+ IMPORT but you will get a warning from nlmconv.
+
+ If you dont have nlmconv, compile gnu-binutils with
+ ./configure --enable-targets=i386-netware
+ make all
+
+ Debugging is possible with gdb and a converter from gdb to ndi available
+ at http://home.arcor.de/armin.diehl/gdbnw
+
+ A sample program:
+
+ Program Hello;
+ (*$DESCRIPTION HelloWorldNlm*)
+ (*$VERSION 1.2.3*)
+ (*$ScreenName Hello*)
+ (*$M 60000,60000*)
+ begin
+ writeLn ('hello world');
+ end.
+
+ compile with:
+ ppc386 -Tnetwlibc hello
+
+ Libraries are supported but this needs at least netware 5.1 sp6,
+ 6.0 sp3 or netware 6.5
+
+ In case there is a xdc file with the same name as the nlm name,
+ this file will be used for nlmconv. Otherwise a temp xdc will
+ be created and used.
+
+****************************************************************************
+}
+unit t_nwl;
+
+{$i fpcdefs.inc}
+
+interface
+
+
+implementation
+
+{$ifdef netwlibc}
+{$define netware}
+{$endif}
+
+ uses
+ cutils,
+ verbose,systems,globtype,globals,
+ symconst,script,
+ fmodule,aasmbase,aasmtai,aasmcpu,cpubase,symsym,symdef,
+ import,export,link,i_nwl
+ {$ifdef netware} ,dos {$endif}
+ ;
+
+ type
+ timportlibnetwlibc=class(timportlib)
+ procedure preparelib(const s:string);override;
+ procedure importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);override;
+ procedure importvariable(vs:tglobalvarsym;const name,module:string);override;
+ procedure generatelib;override;
+ end;
+
+ texportlibnetwlibc=class(texportlib)
+ procedure preparelib(const s : string);override;
+ procedure exportprocedure(hp : texported_item);override;
+ procedure exportvar(hp : texported_item);override;
+ procedure generatelib;override;
+ end;
+
+ tlinkernetwlibc=class(texternallinker)
+ private
+ NLMConvLinkFile: TLinkRes; {for second pass, fist pass is ld}
+ Function WriteResponseFile(isdll:boolean) : Boolean;
+ public
+ constructor Create;override;
+ procedure SetDefaultInfo;override;
+ function MakeNetwareLoadableModule (isLib : boolean):boolean;
+ function MakeExecutable:boolean;override;
+ function MakeSharedLibrary:boolean;override;
+ end;
+
+Const tmpLinkFileName = '~link~tmp.o';
+ minStackSize = 32768;
+
+{*****************************************************************************
+ TIMPORTLIBNETWARE
+*****************************************************************************}
+
+procedure timportlibnetwlibc.preparelib(const s : string);
+begin
+end;
+
+
+procedure timportlibnetwlibc.importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);
+begin
+ { insert sharedlibrary }
+ current_module.linkothersharedlibs.add(SplitName(module),link_allways);
+end;
+
+
+procedure timportlibnetwlibc.importvariable(vs:tglobalvarsym;const name,module:string);
+begin
+ { insert sharedlibrary }
+ current_module.linkothersharedlibs.add(SplitName(module),link_allways);
+ { reset the mangledname and turn off the dll_var option }
+ vs.set_mangledname(name);
+ exclude(vs.varoptions,vo_is_dll_var);
+end;
+
+
+procedure timportlibnetwlibc.generatelib;
+begin
+end;
+
+
+{*****************************************************************************
+ TEXPORTLIBNETWARE
+*****************************************************************************}
+
+procedure texportlibnetwlibc.preparelib(const s:string);
+begin
+end;
+
+
+procedure texportlibnetwlibc.exportprocedure(hp : texported_item);
+var
+ hp2 : texported_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 netware');
+ 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:=texported_item(current_module._exports.first);
+ while assigned(hp2) and
+ (hp.name^>hp2.name^) do
+ hp2:=texported_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=texported_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 texportlibnetwlibc.exportvar(hp : texported_item);
+begin
+ hp.is_var:=true;
+ exportprocedure(hp);
+end;
+
+
+procedure texportlibnetwlibc.generatelib;
+var
+ hp2 : texported_item;
+begin
+ hp2:=texported_item(current_module._exports.first);
+ while assigned(hp2) do
+ begin
+ if (not hp2.is_var) and
+ (hp2.sym.typ=procsym) then
+ begin
+ { the manglednames can already be the same when the procedure
+ is declared with cdecl }
+ if tprocsym(hp2.sym).first_procdef.mangledname<>hp2.name^ then
+ begin
+{$ifdef i386}
+ { place jump in al_procedures }
+ asmlist[al_procedures].concat(Tai_align.Create_op(4,$90));
+ asmlist[al_procedures].concat(Tai_symbol.Createname_global(hp2.name^,AT_FUNCTION,0));
+ asmlist[al_procedures].concat(Taicpu.Op_sym(A_JMP,S_NO,objectlibrary.newasmsymbol(tprocsym(hp2.sym).first_procdef.mangledname,AB_EXTERNAL,AT_FUNCTION)));
+ asmlist[al_procedures].concat(Tai_symbol_end.Createname(hp2.name^));
+{$endif i386}
+ end;
+ end
+ else
+ //Comment(V_Error,'Exporting of variables is not supported under netware');
+ Message1(parser_e_no_export_of_variables_for_target,'netware');
+ hp2:=texported_item(hp2.next);
+ end;
+end;
+
+
+{*****************************************************************************
+ TLINKERNETWARE
+*****************************************************************************}
+
+Constructor TLinkerNetwlibc.Create;
+begin
+ Inherited Create;
+end;
+
+
+procedure TLinkerNetwlibc.SetDefaultInfo;
+begin
+ with Info do
+ begin
+ {$ifndef netware}
+ ExeCmd[1]:= FindUtil(utilsprefix+'ld') + ' -Ur -T $RES $STRIP -o $TMPOBJ';
+ ExeCmd[2]:= FindUtil(utilsprefix+'nlmconv') + ' -T$RES';
+ {$else}
+ {for running on netware we need absolute pathes since ld has another working directory}
+ ExeCmd[1]:= FindUtil(utilsprefix+'ld') + ' -Ur -T '+FExpand(outputexedir+Info.ResName)+' $STRIP -o '+Fexpand(outputexedir+tmpLinkFileName);
+ ExeCmd[2]:= FindUtil(utilsprefix+'nlmconv') + ' -T'+FExpand(outputexedir+'n'+Info.ResName);
+ {$endif}
+ end;
+end;
+
+
+Function TLinkerNetwlibc.WriteResponseFile(isdll:boolean) : Boolean;
+Var
+ linkres : TLinkRes;
+ i : longint;
+ s,s2,s3 : string;
+ ProgNam : string [80];
+ NlmNam : string [80];
+ hp2 : texported_item; { for exports }
+ p : byte;
+begin
+ WriteResponseFile:=False;
+
+ ProgNam := current_module.exefilename^;
+ i:=Pos(target_info.exeext,ProgNam);
+ if i>0 then
+ Delete(ProgNam,i,255);
+ NlmNam := ProgNam + target_info.exeext;
+
+ { Open link.res file }
+ LinkRes:=TLinkRes.Create(outputexedir+Info.ResName); {for ld}
+ NLMConvLinkFile:=TLinkRes.Create(outputexedir+'n'+Info.ResName); {for nlmconv, written in CreateExeFile}
+
+ p := Pos ('"', Description);
+ while (p > 0) do
+ begin
+ delete (Description,p,1);
+ p := Pos ('"', Description);
+ end;
+ if Description <> '' then
+ NLMConvLinkFile.Add('DESCRIPTION "' + Description + '"');
+ NLMConvLinkFile.Add('VERSION '+tostr(dllmajor)+','+tostr(dllminor)+','+tostr(dllrevision));
+
+ p := Pos ('"', nwscreenname);
+ while (p > 0) do
+ begin
+ delete (nwscreenname,p,1);
+ p := Pos ('"', nwscreenname);
+ end;
+ p := Pos ('"', nwthreadname);
+ while (p > 0) do
+ begin
+ delete (nwthreadname,p,1);
+ p := Pos ('"', nwthreadname);
+ end;
+ p := Pos ('"', nwcopyright);
+ while (p > 0) do
+ begin
+ delete (nwcopyright,p,1);
+ p := Pos ('"', nwcopyright);
+ end;
+
+ if nwscreenname <> '' then
+ NLMConvLinkFile.Add('SCREENNAME "' + nwscreenname + '"');
+ if nwthreadname <> '' then
+ NLMConvLinkFile.Add('THREADNAME "' + nwthreadname + '"');
+ if nwcopyright <> '' then
+ NLMConvLinkFile.Add('COPYRIGHT "' + nwcopyright + '"');
+
+ if stacksize < minStackSize then stacksize := minStackSize;
+ str (stacksize, s);
+ NLMConvLinkFile.Add ('STACKSIZE '+s);
+ {$ifndef netware}
+ NLMConvLinkFile.Add ('INPUT '+outputexedir+tmpLinkFileName);
+ {$else}
+ NLMConvLinkFile.Add ('INPUT '+FExpand(outputexedir+tmpLinkFileName));
+ {$endif}
+
+ { add objectfiles, start with nwpre always }
+ LinkRes.Add ('INPUT(');
+ s2 := FindObjectFile('nwplibc','',false);
+ if s2 = '' then
+ s2 := FindObjectFile('libcpre.gcc','',false);
+ Comment (V_Debug,'adding Object File '+s2);
+ {$ifndef netware} LinkRes.Add (s2); {$else} LinkRes.Add (FExpand(s2)); {$endif}
+
+ if isDll then {needed to provide main}
+ s2 := FindObjectFile('nwl_dlle','',false)
+ else
+ s2 := FindObjectFile('nwl_main','',false);
+ Comment (V_Debug,'adding Object File '+s2);
+ {$ifndef netware} LinkRes.Add (s2); {$else} LinkRes.Add (FExpand(s2)); {$endif}
+
+ { main objectfiles, add to linker input }
+ while not ObjectFiles.Empty do
+ begin
+ s:=ObjectFiles.GetFirst;
+ if s<>'' then
+ begin
+ s2 := FindObjectFile (s,'',false);
+ Comment (V_Debug,'adding Object File '+s2);
+ {$ifndef netware} LinkRes.Add (s2); {$else} LinkRes.Add (FExpand(s2)); {$endif}
+ end;
+ end;
+ LinkRes.Add (')');
+
+ { output file (nlm), add to nlmconv }
+ {$ifndef netware}
+ NLMConvLinkFile.Add ('OUTPUT ' + NlmNam);
+ {$else}
+ NLMConvLinkFile.Add ('OUTPUT ' + FExpand(NlmNam));
+ {$endif}
+
+ { start and stop-procedures }
+ NLMConvLinkFile.Add ('START _LibCPrelude');
+ NLMConvLinkFile.Add ('EXIT _LibCPostlude');
+ NLMConvLinkFile.Add ('CHECK _LibCCheckUnload');
+ NLMConvLinkFile.Add ('REENTRANT'); { needed by older libc versions }
+
+ if not (cs_link_strip in aktglobalswitches) then
+ begin
+ NLMConvLinkFile.Add ('DEBUG');
+ Comment(V_Debug,'DEBUG');
+ end;
+
+ { Write staticlibraries }
+ if not StaticLibFiles.Empty then
+ begin
+ LinkRes.Add ('GROUP(');
+ While not StaticLibFiles.Empty do
+ begin
+ S:=lower (StaticLibFiles.GetFirst);
+ if s<>'' then
+ begin
+ {ad: that's a hack !
+ whith -XX we get the .a files as static libs (in addition to the
+ imported libraries}
+ if (pos ('.a',s) <> 0) OR (pos ('.A', s) <> 0) then
+ begin
+ S2 := FindObjectFile(s,'',false);
+ {$ifndef netware} LinkRes.Add (s2); {$else} LinkRes.Add (FExpand(s2)); {$endif}
+ Comment(V_Debug,'adding Object File (StaticLibFiles) '+S2);
+ end else
+ begin
+ i:=Pos(target_info.staticlibext,S);
+ if i>0 then
+ Delete(S,i,255);
+ S := S + '.imp'; S2 := '';
+ librarysearchpath.FindFile(S,S2);
+ {$ifdef netware}
+ Comment(V_Debug,'IMPORT @'+s2);
+ s2 := FExpand (S2);
+ {$endif}
+ NLMConvLinkFile.Add('IMPORT @'+S2);
+ Comment(V_Debug,'IMPORT @'+s2);
+ end;
+ end
+ end;
+ LinkRes.Add (')');
+ end;
+
+ if not SharedLibFiles.Empty then
+ begin
+ While not SharedLibFiles.Empty do
+ begin
+ {becuase of upper/lower case mix, we may get duplicate
+ names but nlmconv ignores that.
+ Here we are setting the import-files for nlmconv. I.e. for
+ the module libc or libc.nlm we add IMPORT @libc.imp and also
+ the module libc.nlm (autoload)
+ If a lib name begins with !, only the IMPORT will be generated
+ ? may it be better to set autoload's via StaticLibFiles ? }
+ S:=lower (SharedLibFiles.GetFirst);
+ if s<>'' then
+ begin
+ s2:=s;
+ i:=Pos(target_info.sharedlibext,S);
+ if i>0 then
+ Delete(S,i,255);
+ if s[1] = '!' then
+ begin // special, with ! only the imp will be included but no module is autoloaded, needed i.e. for netware.imp inlcuded in libc ndk
+ delete (s,1,1);
+ S := S + '.imp';
+ librarysearchpath.FindFile(S,S3);
+ {$ifdef netware}
+ Comment(V_Debug,'IMPORT @'+S3);
+ S3 := FExpand (S3);
+ {$endif}
+ NLMConvLinkFile.Add('IMPORT @'+S3);
+ Comment(V_Debug,'IMPORT @'+S3);
+ end else
+ begin
+ S := S + '.imp';
+ librarysearchpath.FindFile(S,S3);
+ {$ifdef netware}
+ Comment(V_Debug,'IMPORT @'+S3);
+ S3 := FExpand (S3);
+ {$endif}
+ NLMConvLinkFile.Add('IMPORT @'+S3);
+ NLMConvLinkFile.Add('MODULE '+s2);
+ Comment(V_Debug,'MODULE '+S2);
+ Comment(V_Debug,'IMPORT @'+S3);
+ end;
+ end
+ end;
+ end;
+
+ { write exports }
+ hp2:=texported_item(current_module._exports.first);
+ while assigned(hp2) do
+ begin
+ if not hp2.is_var then
+ begin
+ { Export the Symbol }
+ Comment(V_Debug,'EXPORT '+hp2.name^);
+ NLMConvLinkFile.Add ('EXPORT '+hp2.name^);
+ end
+ else
+ { really, i think it is possible }
+ {Comment(V_Error,'Exporting of variables is not supported under netware');}
+ Message1(parser_e_no_export_of_variables_for_target,'netware');
+ hp2:=texported_item(hp2.next);
+ end;
+
+{ Write and Close response for ld, response for nlmconv is in NLMConvLinkFile(not written) }
+ linkres.writetodisk;
+ LinkRes.Free;
+
+{ pass options from -k to nlmconv, ; is interpreted as newline }
+ s := ParaLinkOptions;
+ while(Length(s) > 0) and (s[1] = ' ') do
+ delete (s,1,1);
+ p := pos ('"',s);
+ while p > 0 do
+ begin
+ delete (s,p,1);
+ p := pos ('"',s);
+ end;
+
+ p := pos (';',s);
+ while p > 0 do
+ begin
+ s2 := copy(s,1,p-1);
+ comment (V_Debug,'adding "'+s2+'" to nlmvonv input');
+ NLMConvLinkFile.Add(s2);
+ delete (s,1,p);
+ p := pos (';',s);
+ end;
+ if s <> '' then
+ begin
+ comment (V_Debug,'adding "'+s+'" to nlmvonv input');
+ NLMConvLinkFile.Add(s);
+ end;
+
+ WriteResponseFile:=True;
+end;
+
+Const
+ xdc : Array[0..127] of char = (
+ 'B','A','G','F',#2,#0,#0,#0,#1,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,
+ #0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#2,#0,#0,#0,#0,#0,#0,#0,#16,#0,#0,
+ #0,#7,'M','P','K','_','B','a','g',#0,#0,#0,#0,#0,#0,#0,#0,#11,'M','T',
+ ' ','S','a','f','e',' ','N','L','M',#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,
+ #0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,
+ #0,#0,#0,#0,#0,#0,#1,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0);
+
+
+function TLinkerNetwlibc.MakeNetwareLoadableModule (isLib : boolean):boolean;
+var
+ binstr : String;
+ cmdstr : TcmdStr;
+ xdcname : string;
+ success : boolean;
+ StripStr : string[2];
+ xdcpresent,usexdc : boolean;
+ f : file;
+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 and create Headerfile for
+ nlmconv in NLMConvLinkFile }
+ WriteResponseFile(isLib);
+ if isLib then
+ NLMConvLinkFile.Add('FLAG_ON 1024'); {0x400 Specifies whether the NLM is a shared library.}
+
+{ if we have a xdc file, dont touch it, otherwise create a new
+ one and remove it after nlmconv }
+ xdcname := ForceExtension(current_module.exefilename^,'.xdc');
+ xdcpresent := FileExists (xdcname);
+ if not xdcpresent then
+ begin
+ assign (f,xdcname);
+ rewrite(f,1);
+ if ioresult = 0 then
+ begin
+ blockwrite (f,xdc,sizeof(xdc));
+ close(f);
+ usexdc := (IOResult = 0);
+ end else
+ usexdc := false;
+ end else
+ usexdc := true;
+
+ if usexdc then
+ NLMConvLinkFile.Add('XDCDATA '+xdcname);
+
+{ Call linker, this will generate a new object file that will be passed
+ to nlmconv. Otherwise we could not create nlms without debug info }
+ SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
+ Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename^));
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+ Replace(cmdstr,'$STRIP',StripStr);
+ Replace(cmdstr,'$TMPOBJ',maybequoted(outputexedir+tmpLinkFileName));
+ Comment (v_debug,'Executing '+BinStr+' '+cmdstr);
+ success:=DoExec(FindUtil(BinStr),CmdStr,true,false);
+
+ { Remove ReponseFile }
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ RemoveFile(outputexedir+Info.ResName);
+
+{ Call nlmconv }
+ if success then
+ begin
+ NLMConvLinkFile.writetodisk;
+ NLMConvLinkFile.Free;
+ SplitBinCmd(Info.ExeCmd[2],binstr,cmdstr);
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+'n'+Info.ResName));
+ Comment (v_debug,'Executing '+BinStr+' '+cmdstr);
+ success:=DoExec(FindUtil(BinStr),CmdStr,true,false);
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ begin
+ RemoveFile(outputexedir+'n'+Info.ResName);
+ RemoveFile(outputexedir+tmpLinkFileName);
+ if not xdcpresent then
+ if usexdc then
+ RemoveFile (xdcname);
+ end;
+ end;
+
+ MakeNetwareLoadableModule:=success; { otherwise a recursive call to link method }
+end;
+
+function TLinkerNetwlibc.MakeExecutable:boolean;
+begin
+ MakeExecutable := MakeNetwareLoadableModule (false);
+end;
+
+
+function TLinkerNetwlibc.MakeSharedLibrary:boolean;
+begin
+ MakeSharedLibrary := MakeNetwareLoadableModule (true);
+end;
+
+{*****************************************************************************
+ Initialize
+*****************************************************************************}
+
+
+initialization
+ RegisterExternalLinker(system_i386_netwlibc_info,TLinkerNetwlibc);
+ RegisterImport(system_i386_netwlibc,TImportLibNetwlibc);
+ RegisterExport(system_i386_netwlibc,TExportLibNetwlibc);
+ RegisterTarget(system_i386_netwlibc_info);
+end.
diff --git a/compiler/systems/t_nwm.pas b/compiler/systems/t_nwm.pas
new file mode 100644
index 0000000000..d231a67c98
--- /dev/null
+++ b/compiler/systems/t_nwm.pas
@@ -0,0 +1,576 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ This unit implements support import,export,link routines
+ for the (i386) Netware 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.
+
+ Currently generating NetWare-NLM's only work under Linux and win32.
+ (see http://home.arcor.de/armin.diehl/fpcnw for binutils working
+ with win32) while not included in fpc-releases.
+
+ The following compiler-swiches are supported for NetWare:
+ $DESCRIPTION : NLM-Description, will be displayed at load-time
+ $M : For Stack-Size, Heap-Size will be ignored
+ 32K is the accepted minimum
+ $VERSION x.x.x : Sets Major, Minor and Revision
+ $SCREENNAME : Sets the ScreenName
+ $THREADNAME : Sets current threadname
+
+ Displaying copyright does not work with nlmconv from gnu bunutils
+ version less that 2.13
+
+ Additional parameters for the nlmvonv-inputfile can be passed with
+ -k, i.e. -kREENTRANT will add the option REENTRANT to the nlmconv
+ inputfile. A ; will be converted into a newline
+
+ Exports will be handled like in win32:
+ procedure bla;
+ begin
+ end;
+
+ exports foo name 'Bar';
+
+ The path to the import-Files must be specified by the library-path.
+ All external modules are defined as autoload. (Note: the import-files have
+ to be in unix-format for exe2nlm)
+ By default, the most import files are included in freepascal.
+
+ i.e. Procedure ConsolePrintf (p:pchar); cdecl; external 'clib.nlm';
+ sets IMPORT @clib.imp and MODULE clib.
+
+ Function simply defined as external work without generating autoload but
+ you will get a warnung from nlmconv.
+
+ If you dont have nlmconv, compile gnu-binutils with
+ ./configure --enable-targets=i386-linux,i386-netware
+ make all
+
+ Debugging is possible with gdb and a converter from gdb to ndi available
+ at http://home.arcor.de/armin.diehl/gdbnw
+
+ A sample program:
+
+ Program Hello;
+ (*$DESCRIPTION HelloWorldNlm*)
+ (*$VERSION 1.2.3*)
+ (*$ScreenName Hello*)
+ (*$M 60000,60000*)
+ begin
+ writeLn ('hello world');
+ end.
+
+ compile with:
+ ppc386 -Tnetware hello
+
+ ToDo:
+ - No duplicate imports and autoloads
+ - libc support (needs new target)
+
+****************************************************************************
+}
+unit t_nwm;
+
+{$i fpcdefs.inc}
+
+interface
+
+
+implementation
+
+ uses
+ cutils,
+ verbose,systems,globtype,globals,
+ symconst,script,
+ fmodule,aasmbase,aasmtai,aasmcpu,cpubase,symsym,symdef,
+ import,export,link,i_nwm
+ {$ifdef netware} ,dos {$endif}
+ ;
+
+ type
+ timportlibnetware=class(timportlib)
+ procedure preparelib(const s:string);override;
+ procedure importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);override;
+ procedure importvariable(vs:tglobalvarsym;const name,module:string);override;
+ procedure generatelib;override;
+ end;
+
+ texportlibnetware=class(texportlib)
+ procedure preparelib(const s : string);override;
+ procedure exportprocedure(hp : texported_item);override;
+ procedure exportvar(hp : texported_item);override;
+ procedure generatelib;override;
+ end;
+
+ tlinkernetware=class(texternallinker)
+ private
+ NLMConvLinkFile: TLinkRes; {for second pass, fist pass is ld}
+ Function WriteResponseFile(isdll:boolean) : Boolean;
+ public
+ constructor Create;override;
+ procedure SetDefaultInfo;override;
+ function MakeExecutable:boolean;override;
+ end;
+
+Const tmpLinkFileName = 'link~tmp._o_';
+ minStackSize = 32768;
+
+{*****************************************************************************
+ TIMPORTLIBNETWARE
+*****************************************************************************}
+
+procedure timportlibnetware.preparelib(const s : string);
+begin
+end;
+
+
+procedure timportlibnetware.importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);
+begin
+ { insert sharedlibrary }
+ current_module.linkothersharedlibs.add(SplitName(module),link_allways);
+end;
+
+
+procedure timportlibnetware.importvariable(vs:tglobalvarsym;const name,module:string);
+begin
+ { insert sharedlibrary }
+ current_module.linkothersharedlibs.add(SplitName(module),link_allways);
+ { reset the mangledname and turn off the dll_var option }
+ vs.set_mangledname(name);
+ exclude(vs.varoptions,vo_is_dll_var);
+end;
+
+
+procedure timportlibnetware.generatelib;
+begin
+end;
+
+
+{*****************************************************************************
+ TEXPORTLIBNETWARE
+*****************************************************************************}
+
+procedure texportlibnetware.preparelib(const s:string);
+begin
+end;
+
+
+procedure texportlibnetware.exportprocedure(hp : texported_item);
+var
+ hp2 : texported_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 netware');
+ 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:=texported_item(current_module._exports.first);
+ while assigned(hp2) and
+ (hp.name^>hp2.name^) do
+ hp2:=texported_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=texported_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 texportlibnetware.exportvar(hp : texported_item);
+begin
+ hp.is_var:=true;
+ exportprocedure(hp);
+end;
+
+
+procedure texportlibnetware.generatelib;
+var
+ hp2 : texported_item;
+begin
+ hp2:=texported_item(current_module._exports.first);
+ while assigned(hp2) do
+ begin
+ if (not hp2.is_var) and
+ (hp2.sym.typ=procsym) then
+ begin
+ { the manglednames can already be the same when the procedure
+ is declared with cdecl }
+ if tprocsym(hp2.sym).first_procdef.mangledname<>hp2.name^ then
+ begin
+{$ifdef i386}
+ { place jump in al_procedures }
+ asmlist[al_procedures].concat(Tai_align.Create_op(4,$90));
+ asmlist[al_procedures].concat(Tai_symbol.Createname_global(hp2.name^,AT_FUNCTION,0));
+ asmlist[al_procedures].concat(Taicpu.Op_sym(A_JMP,S_NO,objectlibrary.newasmsymbol(tprocsym(hp2.sym).first_procdef.mangledname,AB_EXTERNAL,AT_FUNCTION)));
+ asmlist[al_procedures].concat(Tai_symbol_end.Createname(hp2.name^));
+{$endif i386}
+ end;
+ end
+ else
+ //Comment(V_Error,'Exporting of variables is not supported under netware');
+ Message1(parser_e_no_export_of_variables_for_target,'netware');
+ hp2:=texported_item(hp2.next);
+ end;
+end;
+
+
+{*****************************************************************************
+ TLINKERNETWARE
+*****************************************************************************}
+
+Constructor TLinkerNetware.Create;
+begin
+ Inherited Create;
+end;
+
+
+procedure TLinkerNetware.SetDefaultInfo;
+begin
+ with Info do
+ begin
+ {$ifndef netware}
+ ExeCmd[1]:= FindUtil(utilsprefix+'ld') + ' -Ur -T $RES $STRIP -o $TMPOBJ';
+ ExeCmd[2]:= FindUtil(utilsprefix+'nlmconv') + ' -T$RES';
+ {$else}
+ {for running on netware we need absolute pathes since ld has another working directory}
+ ExeCmd[1]:= FindUtil(utilsprefix+'ld') + ' -Ur -T '+FExpand(outputexedir+Info.ResName)+' $STRIP -o '+Fexpand(outputexedir+tmpLinkFileName);
+ ExeCmd[2]:= FindUtil(utilsprefix+'nlmconv') + ' -T'+FExpand(outputexedir+'n'+Info.ResName);
+ {$endif}
+ end;
+end;
+
+
+Function TLinkerNetware.WriteResponseFile(isdll:boolean) : Boolean;
+Var
+ linkres : TLinkRes;
+ i : longint;
+ s,s2,s3 : string;
+ ProgNam : string [80];
+ NlmNam : string [80];
+ hp2 : texported_item; { for exports }
+ p : byte;
+begin
+ WriteResponseFile:=False;
+
+ ProgNam := current_module.exefilename^;
+ i:=Pos(target_info.exeext,ProgNam);
+ if i>0 then
+ Delete(ProgNam,i,255);
+ NlmNam := ProgNam + target_info.exeext;
+
+ { Open link.res file }
+ LinkRes:=TLinkRes.Create(outputexedir+Info.ResName); {for ld}
+ NLMConvLinkFile:=TLinkRes.Create(outputexedir+'n'+Info.ResName); {for nlmconv, written in CreateExeFile}
+
+ p := Pos ('"', Description);
+ while (p > 0) do
+ begin
+ delete (Description,p,1);
+ p := Pos ('"', Description);
+ end;
+ if Description <> '' then
+ NLMConvLinkFile.Add('DESCRIPTION "' + Description + '"');
+ NLMConvLinkFile.Add('VERSION '+tostr(dllmajor)+','+tostr(dllminor)+','+tostr(dllrevision));
+
+ p := Pos ('"', nwscreenname);
+ while (p > 0) do
+ begin
+ delete (nwscreenname,p,1);
+ p := Pos ('"', nwscreenname);
+ end;
+ p := Pos ('"', nwthreadname);
+ while (p > 0) do
+ begin
+ delete (nwthreadname,p,1);
+ p := Pos ('"', nwthreadname);
+ end;
+ p := Pos ('"', nwcopyright);
+ while (p > 0) do
+ begin
+ delete (nwcopyright,p,1);
+ p := Pos ('"', nwcopyright);
+ end;
+
+ if nwscreenname <> '' then
+ NLMConvLinkFile.Add('SCREENNAME "' + nwscreenname + '"');
+ if nwthreadname <> '' then
+ NLMConvLinkFile.Add('THREADNAME "' + nwthreadname + '"');
+ if nwcopyright <> '' then
+ NLMConvLinkFile.Add('COPYRIGHT "' + nwcopyright + '"');
+
+ if stacksize < minStackSize then stacksize := minStackSize;
+ str (stacksize, s);
+ NLMConvLinkFile.Add ('STACKSIZE '+s);
+ {$ifndef netware}
+ NLMConvLinkFile.Add ('INPUT '+outputexedir+tmpLinkFileName);
+ {$else}
+ NLMConvLinkFile.Add ('INPUT '+FExpand(outputexedir+tmpLinkFileName));
+ {$endif}
+
+ { add objectfiles, start with nwpre always }
+ LinkRes.Add ('INPUT(');
+ s2 := FindObjectFile('nwpre','',false);
+ Comment (V_Debug,'adding Object File '+s2);
+ {$ifndef netware} LinkRes.Add (s2); {$else} LinkRes.Add (FExpand(s2)); {$endif}
+
+ { main objectfiles, add to linker input }
+ while not ObjectFiles.Empty do
+ begin
+ s:=ObjectFiles.GetFirst;
+ if s<>'' then
+ begin
+ s2 := FindObjectFile (s,'',false);
+ Comment (V_Debug,'adding Object File '+s2);
+ {$ifndef netware} LinkRes.Add (s2); {$else} LinkRes.Add (FExpand(s2)); {$endif}
+ end;
+ end;
+ LinkRes.Add (')');
+
+ { output file (nlm), add to nlmconv }
+ {$ifndef netware}
+ NLMConvLinkFile.Add ('OUTPUT ' + NlmNam);
+ {$else}
+ NLMConvLinkFile.Add ('OUTPUT ' + FExpand(NlmNam));
+ {$endif}
+
+ { start and stop-procedures }
+ NLMConvLinkFile.Add ('START _Prelude'); { defined in rtl/netware/nwpre.as }
+ NLMConvLinkFile.Add ('EXIT _Stop'); { nwpre.as }
+ NLMConvLinkFile.Add ('CHECK FPC_NW_CHECKFUNCTION'); { system.pp }
+
+ if not (cs_link_strip in aktglobalswitches) then
+ begin
+ NLMConvLinkFile.Add ('DEBUG');
+ Comment(V_Debug,'DEBUG');
+ end;
+
+ { Write staticlibraries }
+ if not StaticLibFiles.Empty then
+ begin
+ LinkRes.Add ('GROUP(');
+ While not StaticLibFiles.Empty do
+ begin
+ S:=lower (StaticLibFiles.GetFirst);
+ if s<>'' then
+ begin
+ {ad: that's a hack !
+ whith -XX we get the .a files as static libs (in addition to the
+ imported libraries}
+ if (pos ('.a',s) <> 0) OR (pos ('.A', s) <> 0) then
+ begin
+ S2 := FindObjectFile(s,'',false);
+ {$ifndef netware} LinkRes.Add (s2); {$else} LinkRes.Add (FExpand(s2)); {$endif}
+ Comment(V_Debug,'adding Object File (StaticLibFiles) '+S2);
+ end else
+ begin
+ i:=Pos(target_info.staticlibext,S);
+ if i>0 then
+ Delete(S,i,255);
+ S := S + '.imp'; S2 := '';
+ librarysearchpath.FindFile(S,S2);
+ {$ifdef netware}
+ Comment(V_Debug,'IMPORT @'+s2);
+ s2 := FExpand (S2);
+ {$endif}
+ NLMConvLinkFile.Add('IMPORT @'+S2);
+ Comment(V_Debug,'IMPORT @'+s2);
+ end;
+ end
+ end;
+ LinkRes.Add (')');
+ end;
+
+ if not SharedLibFiles.Empty then
+ begin
+ While not SharedLibFiles.Empty do
+ begin
+ {becuase of upper/lower case mix, we may get duplicate
+ names but nlmconv ignores that.
+ Here we are setting the import-files for nlmconv. I.e. for
+ the module clib or clib.nlm we add IMPORT @clib.imp and also
+ the module clib.nlm (autoload)
+ ? may it be better to set autoload's via StaticLibFiles ? }
+ S:=lower (SharedLibFiles.GetFirst);
+ if s<>'' then
+ begin
+ s2:=s;
+ i:=Pos(target_info.sharedlibext,S);
+ if i>0 then
+ Delete(S,i,255);
+ if s[1] = '!' then
+ begin // special, with ! only the imp will be included but no module is autoloaded, needed i.e. for netware.imp
+ S := copy(S,2,255) + '.imp';
+ librarysearchpath.FindFile(S,S3);
+ {$ifdef netware}
+ Comment(V_Debug,'IMPORT @'+S3);
+ S3 := FExpand (S3);
+ {$endif}
+ NLMConvLinkFile.Add('IMPORT @'+S3);
+ Comment(V_Debug,'IMPORT @'+S3);
+ end else
+ begin
+ S := S + '.imp';
+ librarysearchpath.FindFile(S,S3);
+ {$ifdef netware}
+ Comment(V_Debug,'IMPORT @'+S3);
+ S3 := FExpand (S3);
+ {$endif}
+ NLMConvLinkFile.Add('IMPORT @'+S3);
+ NLMConvLinkFile.Add('MODULE '+s2);
+ Comment(V_Debug,'MODULE '+S2);
+ Comment(V_Debug,'IMPORT @'+S3);
+ end;
+ end;
+ end;
+ end;
+
+ { write exports }
+ hp2:=texported_item(current_module._exports.first);
+ while assigned(hp2) do
+ begin
+ if not hp2.is_var then
+ begin
+ { Export the Symbol }
+ Comment(V_Debug,'EXPORT '+hp2.name^);
+ NLMConvLinkFile.Add ('EXPORT '+hp2.name^);
+ end
+ else
+ { really, i think it is possible }
+ Message1(parser_e_no_export_of_variables_for_target,'netware');
+ hp2:=texported_item(hp2.next);
+ end;
+
+{ Write and Close response for ld, response for nlmconv is in NLMConvLinkFile(not written) }
+ linkres.writetodisk;
+ LinkRes.Free;
+
+{ pass options from -k to nlmconv, ; is interpreted as newline }
+ s := ParaLinkOptions;
+ while(Length(s) > 0) and (s[1] = ' ') do
+ delete (s,1,1);
+ p := pos ('"',s);
+ while p > 0 do
+ begin
+ delete (s,p,1);
+ p := pos ('"',s);
+ end;
+
+ p := pos (';',s);
+ while p > 0 do
+ begin
+ s2 := copy(s,1,p-1);
+ comment (V_Debug,'adding "'+s2+'" to nlmvonv input');
+ NLMConvLinkFile.Add(s2);
+ delete (s,1,p);
+ p := pos (';',s);
+ end;
+ if s <> '' then
+ begin
+ comment (V_Debug,'adding "'+s+'" to nlmvonv input');
+ NLMConvLinkFile.Add(s);
+ end;
+
+ WriteResponseFile:=True;
+end;
+
+
+function TLinkerNetware.MakeExecutable:boolean;
+var
+ binstr : String;
+ cmdstr : TCmdStr;
+ success : boolean;
+ StripStr : string[2];
+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 and create Headerfile for
+ nlmconv in NLMConvLinkFile }
+ WriteResponseFile(false);
+
+{ Call linker, this will generate a new object file that will be passed
+ to nlmconv. Otherwise we could not create nlms without debug info }
+ SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
+ Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename^));
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+ Replace(cmdstr,'$STRIP',StripStr);
+ Replace(cmdstr,'$TMPOBJ',maybequoted(outputexedir+tmpLinkFileName));
+ Comment (v_debug,'Executing '+BinStr+' '+cmdstr);
+ success:=DoExec(FindUtil(BinStr),CmdStr,true,false);
+
+ { Remove ReponseFile }
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ RemoveFile(outputexedir+Info.ResName);
+
+{ Call nlmconv }
+ if success then
+ begin
+ NLMConvLinkFile.writetodisk;
+ NLMConvLinkFile.Free;
+ SplitBinCmd(Info.ExeCmd[2],binstr,cmdstr);
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+'n'+Info.ResName));
+ Comment (v_debug,'Executing '+BinStr+' '+cmdstr);
+ success:=DoExec(FindUtil(BinStr),CmdStr,true,false);
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ begin
+ RemoveFile(outputexedir+'n'+Info.ResName);
+ RemoveFile(outputexedir+tmpLinkFileName);
+ end;
+ end;
+
+ MakeExecutable:=success; { otherwise a recursive call to link method }
+end;
+
+
+{*****************************************************************************
+ Initialize
+*****************************************************************************}
+
+
+initialization
+ RegisterExternalLinker(system_i386_netware_info,TLinkerNetware);
+ RegisterImport(system_i386_netware,TImportLibNetware);
+ RegisterExport(system_i386_netware,TExportLibNetware);
+ RegisterTarget(system_i386_netware_info);
+end.
diff --git a/compiler/systems/t_os2.pas b/compiler/systems/t_os2.pas
new file mode 100644
index 0000000000..ed86fe5e21
--- /dev/null
+++ b/compiler/systems/t_os2.pas
@@ -0,0 +1,516 @@
+{
+ Copyright (c) 1998-2002 by Daniel Mantione
+ Portions Copyright (c) 1998-2002 Eberhard Mattes
+
+ Unit to write out import libraries and def files for OS/2
+
+ 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.
+
+ ****************************************************************************
+}
+{
+ A lot of code in this unit has been ported from C to Pascal from the
+ emximp utility, part of the EMX development system. Emximp is copyrighted
+ by Eberhard Mattes. Note: Eberhard doesn't know much about the Pascal
+ port, please send questions to Daniel Mantione
+ <d.s.p.mantione@twi.tudelft.nl>.
+}
+unit t_os2;
+
+{$i fpcdefs.inc}
+
+interface
+
+
+implementation
+
+ uses
+ strings,
+ dos,
+ cutils,cclasses,
+ globtype,systems,symconst,symdef,
+ globals,verbose,fmodule,script,
+ import,link,i_os2;
+
+ type
+ timportlibos2=class(timportlib)
+ procedure preparelib(const s:string);override;
+ procedure importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);override;
+ procedure generatelib;override;
+ end;
+
+ tlinkeros2=class(texternallinker)
+ private
+ Function WriteResponseFile(isdll:boolean) : Boolean;
+ public
+ constructor Create;override;
+ procedure SetDefaultInfo;override;
+ function MakeExecutable:boolean;override;
+ end;
+
+
+const profile_flag:boolean=false;
+
+const n_ext = 1;
+ n_abs = 2;
+ n_text = 4;
+ n_data = 6;
+ n_bss = 8;
+ n_imp1 = $68;
+ n_imp2 = $6a;
+
+type reloc=packed record {This is the layout of a relocation table
+ entry.}
+ address:longint; {Fixup location}
+ remaining:longint;
+ {Meaning of bits for remaining:
+ 0..23: Symbol number or segment
+ 24: Self-relative fixup if non-zero
+ 25..26: Fixup size (0: 1 byte, 1: 2, 2: 4 bytes)
+ 27: Reference to symbol or segment
+ 28..31 Not used}
+ end;
+
+ nlist=packed record {This is the layout of a symbol table entry.}
+ strofs:longint; {Offset in string table}
+ typ:byte; {Type of the symbol}
+ other:byte; {Other information}
+ desc:word; {More information}
+ value:longint; {Value (address)}
+ end;
+
+ a_out_header=packed record
+ magic:word; {Magic word, must be $0107}
+ machtype:byte; {Machine type}
+ flags:byte; {Flags}
+ text_size:longint; {Length of text, in bytes}
+ data_size:longint; {Length of initialized data, in bytes}
+ bss_size:longint; {Length of uninitialized data, in bytes}
+ sym_size:longint; {Length of symbol table, in bytes}
+ entry:longint; {Start address (entry point)}
+ trsize:longint; {Length of relocation info for text, bytes}
+ drsize:longint; {Length of relocation info for data, bytes}
+ end;
+
+ ar_hdr=packed record
+ ar_name:array[0..15] of char;
+ ar_date:array[0..11] of char;
+ ar_uid:array[0..5] of char;
+ ar_gid:array[0..5] of char;
+ ar_mode:array[0..7] of char;
+ ar_size:array[0..9] of char;
+ ar_fmag:array[0..1] of char;
+ end;
+
+var aout_str_size:longint;
+ aout_str_tab:array[0..2047] of byte;
+ aout_sym_count:longint;
+ aout_sym_tab:array[0..5] of nlist;
+
+ aout_text:array[0..63] of byte;
+ aout_text_size:longint;
+
+ aout_treloc_tab:array[0..1] of reloc;
+ aout_treloc_count:longint;
+
+ aout_size:longint;
+ seq_no:longint;
+
+ ar_member_size:longint;
+
+ out_file:file;
+
+procedure write_ar(const name:string;size:longint);
+
+var ar:ar_hdr;
+ time:datetime;
+ dummy:word;
+ numtime:longint;
+ tmp:string[19];
+
+
+begin
+ ar_member_size:=size;
+ fillchar(ar.ar_name,sizeof(ar.ar_name),' ');
+ move(name[1],ar.ar_name,length(name));
+ getdate(time.year,time.month,time.day,dummy);
+ gettime(time.hour,time.min,time.sec,dummy);
+ packtime(time,numtime);
+ str(numtime,tmp);
+ fillchar(ar.ar_date,sizeof(ar.ar_date),' ');
+ move(tmp[1],ar.ar_date,length(tmp));
+ ar.ar_uid:='0 ';
+ ar.ar_gid:='0 ';
+ ar.ar_mode:='100666'#0#0;
+ str(size,tmp);
+ fillchar(ar.ar_size,sizeof(ar.ar_size),' ');
+ move(tmp[1],ar.ar_size,length(tmp));
+ ar.ar_fmag:='`'#10;
+ blockwrite(out_file,ar,sizeof(ar));
+end;
+
+procedure finish_ar;
+
+var a:byte;
+
+begin
+ a:=0;
+ if odd(ar_member_size) then
+ blockwrite(out_file,a,1);
+end;
+
+procedure aout_init;
+
+begin
+ aout_str_size:=sizeof(longint);
+ aout_sym_count:=0;
+ aout_text_size:=0;
+ aout_treloc_count:=0;
+end;
+
+function aout_sym(const name:string;typ,other:byte;desc:word;
+ value:longint):longint;
+
+begin
+ if aout_str_size+length(name)+1>sizeof(aout_str_tab) then
+ internalerror(200504245);
+ if aout_sym_count>=sizeof(aout_sym_tab) div sizeof(aout_sym_tab[0]) then
+ internalerror(200504246);
+ aout_sym_tab[aout_sym_count].strofs:=aout_str_size;
+ aout_sym_tab[aout_sym_count].typ:=typ;
+ aout_sym_tab[aout_sym_count].other:=other;
+ aout_sym_tab[aout_sym_count].desc:=desc;
+ aout_sym_tab[aout_sym_count].value:=value;
+ strPcopy(@aout_str_tab[aout_str_size],name);
+ aout_str_size:=aout_str_size+length(name)+1;
+ aout_sym:=aout_sym_count;
+ inc(aout_sym_count);
+end;
+
+procedure aout_text_byte(b:byte);
+
+begin
+ if aout_text_size>=sizeof(aout_text) then
+ internalerror(200504247);
+ aout_text[aout_text_size]:=b;
+ inc(aout_text_size);
+end;
+
+procedure aout_text_dword(d:longint);
+
+type li_ar=array[0..3] of byte;
+
+begin
+ aout_text_byte(li_ar(d)[0]);
+ aout_text_byte(li_ar(d)[1]);
+ aout_text_byte(li_ar(d)[2]);
+ aout_text_byte(li_ar(d)[3]);
+end;
+
+procedure aout_treloc(address,symbolnum,pcrel,len,ext:longint);
+
+begin
+ if aout_treloc_count>=sizeof(aout_treloc_tab) div sizeof(reloc) then
+ internalerror(200504248);
+ aout_treloc_tab[aout_treloc_count].address:=address;
+ aout_treloc_tab[aout_treloc_count].remaining:=symbolnum+pcrel shl 24+
+ len shl 25+ext shl 27;
+ inc(aout_treloc_count);
+end;
+
+procedure aout_finish;
+
+begin
+ while (aout_text_size and 3)<>0 do
+ aout_text_byte ($90);
+ aout_size:=sizeof(a_out_header)+aout_text_size+aout_treloc_count*
+ sizeof(reloc)+aout_sym_count*sizeof(aout_sym_tab[0])+aout_str_size;
+end;
+
+procedure aout_write;
+
+var ao:a_out_header;
+
+begin
+ ao.magic:=$0107;
+ ao.machtype:=0;
+ ao.flags:=0;
+ ao.text_size:=aout_text_size;
+ ao.data_size:=0;
+ ao.bss_size:=0;
+ ao.sym_size:=aout_sym_count*sizeof(aout_sym_tab[0]);
+ ao.entry:=0;
+ ao.trsize:=aout_treloc_count*sizeof(reloc);
+ ao.drsize:=0;
+ blockwrite(out_file,ao,sizeof(ao));
+ blockwrite(out_file,aout_text,aout_text_size);
+ blockwrite(out_file,aout_treloc_tab,sizeof(reloc)*aout_treloc_count);
+ blockwrite(out_file,aout_sym_tab,sizeof(aout_sym_tab[0])*aout_sym_count);
+ longint((@aout_str_tab)^):=aout_str_size;
+ blockwrite(out_file,aout_str_tab,aout_str_size);
+end;
+
+procedure timportlibos2.preparelib(const s:string);
+
+{This code triggers a lot of bugs in the compiler.
+const armag='!<arch>'#10;
+ ar_magic:array[1..length(armag)] of char=armag;}
+const ar_magic:array[1..8] of char='!<arch>'#10;
+var
+ libname : string;
+begin
+ libname:=FixFileName(S + Target_Info.StaticCLibExt);
+ seq_no:=1;
+ current_module.linkotherstaticlibs.add(libname,link_allways);
+ assign(out_file,current_module.outputpath^+libname);
+ rewrite(out_file,1);
+ blockwrite(out_file,ar_magic,sizeof(ar_magic));
+end;
+
+procedure timportlibos2.importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);
+{func = Name of function to import.
+ module = Name of DLL to import from.
+ index = Index of function in DLL. Use 0 to import by name.
+ name = Name of function in DLL. Ignored when index=0;}
+var tmp1,tmp2,tmp3:string;
+ sym_mcount,sym_import:longint;
+ fixup_mcount,fixup_import:longint;
+ func : string;
+begin
+ { force the current mangledname }
+ include(aprocdef.procoptions,po_has_mangledname);
+ func:=aprocdef.mangledname;
+
+ aout_init;
+ tmp2:=func;
+ if profile_flag and not (copy(func,1,4)='_16_') then
+ begin
+ {sym_entry:=aout_sym(func,n_text+n_ext,0,0,aout_text_size);}
+ sym_mcount:=aout_sym('__mcount',n_ext,0,0,0);
+ {Use, say, "_$U_DosRead" for "DosRead" to import the
+ non-profiled function.}
+ tmp2:='__$U_'+func;
+ sym_import:=aout_sym(tmp2,n_ext,0,0,0);
+ aout_text_byte($55); {push ebp}
+ aout_text_byte($89); {mov ebp, esp}
+ aout_text_byte($e5);
+ aout_text_byte($e8); {call _mcount}
+ fixup_mcount:=aout_text_size;
+ aout_text_dword(0-(aout_text_size+4));
+ aout_text_byte($5d); {pop ebp}
+ aout_text_byte($e9); {jmp _$U_DosRead}
+ fixup_import:=aout_text_size;
+ aout_text_dword(0-(aout_text_size+4));
+
+ aout_treloc(fixup_mcount,sym_mcount,1,2,1);
+ aout_treloc (fixup_import, sym_import,1,2,1);
+ end;
+ str(seq_no,tmp1);
+ tmp1:='IMPORT#'+tmp1;
+ if name='' then
+ begin
+ str(index,tmp3);
+ tmp3:=func+'='+module+'.'+tmp3;
+ end
+ else
+ tmp3:=func+'='+module+'.'+name;
+ aout_sym(tmp2,n_imp1+n_ext,0,0,0);
+ aout_sym(tmp3,n_imp2+n_ext,0,0,0);
+ aout_finish;
+ write_ar(tmp1,aout_size);
+ aout_write;
+ finish_ar;
+ inc(seq_no);
+end;
+
+procedure timportlibos2.generatelib;
+
+begin
+ close(out_file);
+end;
+
+
+{****************************************************************************
+ TLinkeros2
+****************************************************************************}
+
+Constructor TLinkeros2.Create;
+begin
+ Inherited Create;
+ { allow duplicated libs (PM) }
+ SharedLibFiles.doubles:=true;
+ StaticLibFiles.doubles:=true;
+end;
+
+
+procedure TLinkeros2.SetDefaultInfo;
+begin
+ with Info do
+ begin
+ ExeCmd[1]:='ld $OPT -o $OUT @$RES';
+ ExeCmd[2]:='emxbind -b $STRIP $APPTYPE $RSRC -k$STACKKB -h1 -o $EXE $OUT -ai -s8';
+ if Source_Info.Script = script_dos then
+ ExeCmd[3]:='del $OUT';
+ end;
+end;
+
+
+Function TLinkeros2.WriteResponseFile(isdll:boolean) : Boolean;
+Var
+ linkres : TLinkRes;
+ i : longint;
+ HPath : TStringListItem;
+ s : string;
+begin
+ WriteResponseFile:=False;
+
+ { Open link.res file }
+ LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
+
+ { Write path to search libraries }
+ HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
+ while assigned(HPath) do
+ begin
+ LinkRes.Add('-L'+HPath.Str);
+ HPath:=TStringListItem(HPath.Next);
+ end;
+ HPath:=TStringListItem(LibrarySearchPath.First);
+ while assigned(HPath) do
+ begin
+ LinkRes.Add('-L'+HPath.Str);
+ HPath:=TStringListItem(HPath.Next);
+ end;
+
+ { add objectfiles, start with prt0 always }
+ LinkRes.AddFileName(FindObjectFile('prt0','',false));
+ while not ObjectFiles.Empty do
+ begin
+ s:=ObjectFiles.GetFirst;
+ if s<>'' then
+ LinkRes.AddFileName(s);
+ end;
+
+ { Write staticlibraries }
+ { No group !! This will not work correctly PM }
+ While not StaticLibFiles.Empty do
+ begin
+ S:=StaticLibFiles.GetFirst;
+ 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.GetFirst;
+ i:=Pos(target_info.sharedlibext,S);
+ if i>0 then
+ Delete(S,i,255);
+ LinkRes.Add('-l'+s);
+ end;
+
+{ Write and Close response }
+ linkres.writetodisk;
+ LinkRes.Free;
+
+ WriteResponseFile:=True;
+end;
+
+
+function TLinkeros2.MakeExecutable:boolean;
+var
+ binstr : String;
+ cmdstr : TCmdStr;
+ success : boolean;
+ i : longint;
+ AppTypeStr,
+ StripStr: string[40];
+ RsrcStr : string;
+ DS: DirStr;
+ NS: NameStr;
+ ES: ExtStr;
+ OutName: PathStr;
+begin
+ if not(cs_link_extern in aktglobalswitches) then
+ Message1(exec_i_linking,current_module.exefilename^);
+
+{ Create some replacements }
+ FSplit (current_module.exefilename^, DS, NS, ES);
+ OutName := DS + NS + '.out';
+ if (cs_link_strip in aktglobalswitches) then
+ StripStr := '-s'
+ else
+ StripStr := '';
+ if (usewindowapi) or (AppType = app_gui) then
+ AppTypeStr := '-p'
+ else if AppType = app_fs then
+ AppTypeStr := '-f'
+ else AppTypeStr := '-w';
+ if not (Current_module.ResourceFiles.Empty) then
+ RsrcStr := '-r ' + Current_module.ResourceFiles.GetFirst
+ else
+ RsrcStr := '';
+(* Only one resource file supported, discard everything else
+ (should be already empty anyway, though). *)
+ Current_module.ResourceFiles.Clear;
+{ Write used files and libraries }
+ WriteResponseFile(false);
+
+{ Call linker }
+ success:=false;
+ for i:=1 to 3 do
+ begin
+ SplitBinCmd(Info.ExeCmd[i],binstr,cmdstr);
+ if binstr<>'' then
+ begin
+ { Is this really required? Not anymore according to my EMX docs }
+ Replace(cmdstr,'$HEAPMB',tostr((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+1023) shr 10));
+ Replace(cmdstr,'$STRIP',StripStr);
+ Replace(cmdstr,'$APPTYPE',AppTypeStr);
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
+ Replace(cmdstr,'$RSRC',RsrcStr);
+ Replace(cmdstr,'$OUT',maybequoted(OutName));
+ Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename^));
+ if i<>3 then
+ success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,(i=1),false)
+ else
+ success:=DoExec(binstr,cmdstr,(i=1),true);
+ end;
+ end;
+
+{ Remove ReponseFile }
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ RemoveFile(outputexedir+Info.ResName);
+
+ MakeExecutable:=success; { otherwise a recursive call to link method }
+end;
+
+
+{*****************************************************************************
+ Initialize
+*****************************************************************************}
+
+initialization
+ RegisterExternalLinker(system_i386_os2_info,TLinkerOS2);
+ RegisterImport(system_i386_os2,TImportLibOS2);
+{ RegisterRes(res_emxbind_info);}
+ RegisterTarget(system_i386_os2_info);
+end.
diff --git a/compiler/systems/t_palmos.pas b/compiler/systems/t_palmos.pas
new file mode 100644
index 0000000000..b2e4a6e2eb
--- /dev/null
+++ b/compiler/systems/t_palmos.pas
@@ -0,0 +1,212 @@
+{
+ Copyright (c) 2001-2002 by Peter Vreman
+
+ This unit implements support import,export,link routines
+ for the (i386) Amiga 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_palmos;
+
+{$i fpcdefs.inc}
+
+interface
+
+ uses
+ link;
+
+ type
+ tlinkerPalmOS=class(texternallinker)
+ private
+ Function WriteResponseFile : Boolean;
+ public
+ constructor Create;override;
+ procedure SetDefaultInfo;override;
+ function MakeExecutable:boolean;override;
+ end;
+
+
+implementation
+
+ uses
+ cutils,cclasses,
+ globtype,globals,systems,verbose,script,fmodule,i_palmos;
+
+{****************************************************************************
+ TLinkerPalmOS
+****************************************************************************}
+
+Constructor TLinkerPalmOS.Create;
+begin
+ Inherited Create;
+ { allow duplicated libs (PM) }
+ SharedLibFiles.doubles:=true;
+ StaticLibFiles.doubles:=true;
+end;
+
+
+procedure TLinkerPalmOS.SetDefaultInfo;
+begin
+ with Info do
+ begin
+ ExeCmd[1]:='ldpalm $OPT $STRIP -N -dy -T $SCRIPT -o $EXE @$RES';
+ ExeCmd[2]:='build-prc $EXE.prc "$APPNAME" $APPID $EXE *.bin';
+ end;
+end;
+
+
+Function TLinkerPalmOS.WriteResponseFile : Boolean;
+Var
+ linkres : TLinkRes;
+ i : longint;
+ HPath : PStringQueueItem;
+ s : string;
+ linklibc : boolean;
+begin
+ WriteResponseFile:=False;
+
+ { Open link.res file }
+ LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
+
+ { Write path to search libraries }
+ HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
+ while assigned(HPath) do
+ begin
+ LinkRes.Add('-L'+HPath.Str);
+ HPath:=TStringListItem(HPath.Next);
+ end;
+ HPath:=TStringListItem(LibrarySearchPath.First);
+ while assigned(HPath) do
+ begin
+ LinkRes.Add('-L'+HPath.Str);
+ HPath:=TStringListItem(HPath.Next);
+ end;
+
+ { add objectfiles, start with crt0 always }
+ { using crt0, we should stick C compatible }
+ LinkRes.AddFileName(FindObjectFile('crt0',''));
+
+ { main objectfiles }
+ while not ObjectFiles.Empty do
+ begin
+ s:=ObjectFiles.GetFirst;
+ if s<>'' then
+ LinkRes.AddFileName(s);
+ end;
+
+ { Write staticlibraries }
+ if not StaticLibFiles.Empty then
+ begin
+ LinkRes.Add('-(');
+ While not StaticLibFiles.Empty do
+ begin
+ S:=StaticLibFiles.GetFirst;
+ LinkRes.AddFileName(s)
+ end;
+ LinkRes.Add('-)');
+ end;
+
+ { currently the PalmOS target must be linked always against the C lib }
+ LinkRes.Add('-lcrt');
+
+ { 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) }
+ linklibc:=false;
+ While not SharedLibFiles.Empty do
+ begin
+ S:=SharedLibFiles.GetFirst;
+ if s<>'c' then
+ begin
+ i:=Pos(target_info.sharedlibext,S);
+ if i>0 then
+ Delete(S,i,255);
+ LinkRes.Add('-l'+s);
+ end
+ else
+ linklibc:=true;
+ end;
+ { be sure that libc is the last lib }
+ if linklibc then
+ begin
+ LinkRes.Add('-lc');
+ LinkRes.Add('-lgcc');
+ end;
+
+{ Write and Close response }
+ linkres.writetodisk;
+ linkres.Free;
+
+ WriteResponseFile:=True;
+end;
+
+
+function TLinkerPalmOS.MakeExecutable:boolean;
+var
+ binstr,
+ cmdstr : string;
+ success : boolean;
+ StripStr : string[40];
+ i : longint;
+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;
+
+{ Call linker }
+ success:=false;
+ for i:=1 to 2 do
+ begin
+ SplitBinCmd(Info.ExeCmd[i],binstr,cmdstr);
+ if binstr<>'' then
+ begin
+ Replace(cmdstr,'$EXE',MaybeQuote(current_module.exefilename^));
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+ Replace(cmdstr,'$STRIP',StripStr);
+ Replace(cmdstr,'$SCRIPT',FindUtil('palm.ld'));
+ Replace(cmdstr,'$APPNAME',palmos_applicationname);
+ Replace(cmdstr,'$APPID',palmos_applicationid);
+ 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(outputexedir+Info.ResName);
+
+ MakeExecutable:=success; { otherwise a recursive call to link method }
+end;
+
+{*****************************************************************************
+ Initialize
+*****************************************************************************}
+
+initialization
+{$ifdef m68k}
+ RegisterTarget(target_m68k_palmos_info);
+ RegisterRes(res_m68k_palmos_info);
+{$endif m68k}
+end.
diff --git a/compiler/systems/t_sunos.pas b/compiler/systems/t_sunos.pas
new file mode 100644
index 0000000000..d600f5d9a0
--- /dev/null
+++ b/compiler/systems/t_sunos.pas
@@ -0,0 +1,490 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ This unit implements support import,export,link routines
+ for the (i386) solaris 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_sunos;
+
+{$i fpcdefs.inc}
+
+interface
+
+{ copy from t_linux
+// Up to now we use gld since the solaris ld seems not support .res-files}
+{-$DEFINE LinkTest} { DON't del link.res and write Info }
+{$DEFINE GnuLd} {The other is not implemented }
+
+implementation
+
+ uses
+ cutils,cclasses,
+ verbose,systems,globtype,globals,
+ symconst,script,
+ fmodule,aasmbase,aasmtai,aasmcpu,cpubase,symsym,symdef,
+ cgobj,
+ import,export,link,i_sunos;
+
+ type
+ timportlibsolaris=class(timportlib)
+ procedure preparelib(const s:string);override;
+ procedure importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);override;
+ procedure importvariable(vs:tglobalvarsym;const name,module:string);override;
+ procedure generatelib;override;
+ end;
+
+ texportlibsolaris=class(texportlib)
+ procedure preparelib(const s : string);override;
+ procedure exportprocedure(hp : texported_item);override;
+ procedure exportvar(hp : texported_item);override;
+ procedure generatelib;override;
+ end;
+
+ tlinkersolaris=class(texternallinker)
+ private
+ Glibc2,
+ Glibc21 : boolean;
+ Function WriteResponseFile(isdll:boolean) : Boolean;
+ public
+ constructor Create;override;
+ procedure SetDefaultInfo;override;
+ function MakeExecutable:boolean;override;
+ function MakeSharedLibrary:boolean;override;
+ end;
+
+
+{*****************************************************************************
+ TIMPORTLIBsolaris
+*****************************************************************************}
+
+procedure timportlibsolaris.preparelib(const s : string);
+begin
+{$ifDef LinkTest}
+ WriteLN('Prepare import: ',s);
+{$EndIf}
+end;
+
+
+procedure timportlibsolaris.importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);
+begin
+ { insert sharedlibrary }
+{$ifDef LinkTest}
+ WriteLN('Import: f:',func,' m:',module,' n:',name);
+{$EndIf}
+ current_module.linkothersharedlibs.add(SplitName(module),link_allways);
+end;
+
+
+procedure timportlibsolaris.importvariable(vs:tglobalvarsym;const name,module:string);
+begin
+ { insert sharedlibrary }
+ current_module.linkothersharedlibs.add(SplitName(module),link_allways);
+ { reset the mangledname and turn off the dll_var option }
+ vs.set_mangledname(name);
+ exclude(vs.varoptions,vo_is_dll_var);
+end;
+
+
+procedure timportlibsolaris.generatelib;
+begin
+end;
+
+
+{*****************************************************************************
+ TEXPORTLIBsolaris
+*****************************************************************************}
+
+procedure texportlibsolaris.preparelib(const s:string);
+begin
+end;
+
+
+procedure texportlibsolaris.exportprocedure(hp : texported_item);
+var
+ hp2 : texported_item;
+begin
+ { first test the index value }
+ if (hp.options and eo_index)<>0 then
+ begin
+ Message1(parser_e_no_export_with_index_for_target,'solaris');
+ 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:=texported_item(current_module._exports.first);
+ while assigned(hp2) and
+ (hp.name^>hp2.name^) do
+ hp2:=texported_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=texported_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 texportlibsolaris.exportvar(hp : texported_item);
+begin
+ hp.is_var:=true;
+ exportprocedure(hp);
+end;
+
+
+procedure texportlibsolaris.generatelib;
+var
+ hp2 : texported_item;
+begin
+ new_section(asmlist[al_procedures],sec_code,'',0);
+ hp2:=texported_item(current_module._exports.first);
+ while assigned(hp2) do
+ begin
+ if (not hp2.is_var) and
+ (hp2.sym.typ=procsym) then
+ begin
+ { the manglednames can already be the same when the procedure
+ is declared with cdecl }
+ if tprocsym(hp2.sym).first_procdef.mangledname<>hp2.name^ then
+ begin
+ { place jump in al_procedures }
+ asmlist[al_procedures].concat(tai_align.create(target_info.alignment.procalign));
+ asmlist[al_procedures].concat(Tai_symbol.Createname_global(hp2.name^,AT_FUNCTION,0));
+ cg.a_jmp_name(asmlist[al_procedures],tprocsym(hp2.sym).first_procdef.mangledname);
+ asmlist[al_procedures].concat(Tai_symbol_end.Createname(hp2.name^));
+ end;
+ end
+ else
+ Message1(parser_e_no_export_of_variables_for_target,'linux');
+ hp2:=texported_item(hp2.next);
+ end;
+end;
+
+
+{*****************************************************************************
+ TLINKERsolaris
+*****************************************************************************}
+
+Constructor TLinkersolaris.Create;
+begin
+ Inherited Create;
+ if NOT Dontlinkstdlibpath Then
+ LibrarySearchPath.AddPath('/lib;/usr/lib;/usr/X11R6/lib;/opt/sfw/lib',true);
+{$ifdef LinkTest}
+ if (cs_link_staticflag in aktglobalswitches) then WriteLN('ForceLinkStaticFlag');
+ if (cs_link_static in aktglobalswitches) then WriteLN('LinkStatic-Flag');
+ if (cs_link_shared in aktglobalswitches) then WriteLN('LinkSynamicFlag');
+{$EndIf}
+end;
+
+
+procedure TLinkersolaris.SetDefaultInfo;
+{
+ This will also detect which libc version will be used
+}
+begin
+ Glibc2:=false;
+ Glibc21:=false;
+ with Info do
+ begin
+{$IFDEF GnuLd}
+ ExeCmd[1]:='gld $OPT $DYNLINK $STATIC $STRIP -L. -o $EXE $RES';
+ DllCmd[1]:='gld $OPT -shared -L. -o $EXE $RES';
+ DllCmd[2]:='strip --strip-unneeded $EXE';
+ DynamicLinker:=''; { Gnu uses the default }
+ Glibc21:=false;
+{$ELSE}
+ Not Implememted
+{$ENDIF}
+(* Linux Stuff not needed?
+ { first try glibc2 } // muss noch gendert werden
+ if FileExists(DynamicLinker) then
+ begin
+ Glibc2:=true;
+ { Check for 2.0 files, else use the glibc 2.1 stub }
+ if FileExists('/lib/ld-2.0.*') then
+ Glibc21:=false
+ else
+ Glibc21:=true;
+ end
+ else
+ DynamicLinker:='/lib/ld-linux.so.1';
+*)
+ end;
+
+end;
+
+
+Function TLinkersolaris.WriteResponseFile(isdll:boolean) : Boolean;
+Var
+ linkres : TLinkRes;
+ i : longint;
+ cprtobj,
+ gprtobj,
+ prtobj : string[80];
+ HPath : TStringListItem;
+ s,s2 : string;
+ linkdynamic,
+ linklibc : boolean;
+begin
+ WriteResponseFile:=False;
+{ set special options for some targets }
+ linkdynamic:=not(SharedLibFiles.empty);
+{ linkdynamic:=false; // da nicht getestet }
+ linklibc:=(SharedLibFiles.Find('c')<>nil);
+ prtobj:='prt0';
+ cprtobj:='cprt0';
+ gprtobj:='gprt0';
+ 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
+ else
+ AddSharedLibrary('c'); { quick hack: this solaris implementation needs alwys libc }
+ end;
+
+ { Open link.res file }
+ LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
+
+ { Write path to search libraries }
+ HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
+ while assigned(HPath) do
+ begin
+ LinkRes.Add('SEARCH_DIR('+maybequoted(HPath.Str)+')');
+ HPath:=TStringListItem(HPath.Next);
+ end;
+ HPath:=TStringListItem(LibrarySearchPath.First);
+ while assigned(HPath) do
+ begin
+ LinkRes.Add('SEARCH_DIR('+maybequoted(HPath.Str)+')');
+ HPath:=TStringListItem(HPath.Next);
+ end;
+
+ LinkRes.Add('INPUT(');
+ { add objectfiles, start with prt0 always }
+ if prtobj<>'' then
+ LinkRes.AddFileName(FindObjectFile(prtobj,'',false));
+ { try to add crti and crtbegin if linking to C }
+ if linklibc then { Needed in solaris? }
+ begin
+{ if librarysearchpath.FindFile('crtbegin.o',s) then
+ LinkRes.AddFileName(s);}
+ if librarysearchpath.FindFile('crti.o',s) then
+ LinkRes.AddFileName(s);
+ end;
+ { main objectfiles }
+ while not ObjectFiles.Empty do
+ begin
+ s:=ObjectFiles.GetFirst;
+ if s<>'' then
+ LinkRes.AddFileName(maybequoted(s));
+ end;
+ LinkRes.Add(')');
+
+ { Write staticlibraries }
+ if not StaticLibFiles.Empty then
+ begin
+ LinkRes.Add('GROUP(');
+ While not StaticLibFiles.Empty do
+ begin
+ S:=StaticLibFiles.GetFirst;
+ LinkRes.AddFileName(maybequoted(s))
+ end;
+ LinkRes.Add(')');
+ end;
+
+ { Write sharedlibraries like -l<lib>, also add the needed dynamic linker
+ here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
+ if not SharedLibFiles.Empty then
+ begin
+ LinkRes.Add('INPUT(');
+ While not SharedLibFiles.Empty do
+ begin
+ S:=SharedLibFiles.GetFirst;
+ if s<>'c' then
+ begin
+ i:=Pos(target_info.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-solaris (war ld-linux) for us }
+ end;
+ end;
+ { be sure that libc is the last lib }
+ if linklibc then
+ LinkRes.Add('-lc');
+ { when we have -static for the linker the we also need libgcc }
+ if (cs_link_staticflag in aktglobalswitches) then begin
+ LinkRes.Add('-lgcc');
+ end;
+ if linkdynamic and (Info.DynamicLinker<>'') then { gld has a default, DynamicLinker is not set in solaris }
+ LinkRes.AddFileName(Info.DynamicLinker);
+ LinkRes.Add(')');
+ end;
+ { objects which must be at the end }
+ if linklibc then {needed in solaris ? }
+ begin
+ if {librarysearchpath.FindFile('crtend.o',s1) or}
+ librarysearchpath.FindFile('crtn.o',s2) then
+ begin
+ LinkRes.Add('INPUT(');
+{ LinkRes.AddFileName(s1);}
+ LinkRes.AddFileName(s2);
+ LinkRes.Add(')');
+ end;
+ end;
+{ Write and Close response }
+ linkres.writetodisk;
+ LinkRes.Free;
+
+ WriteResponseFile:=True;
+end;
+
+
+function TLinkersolaris.MakeExecutable:boolean;
+var
+ binstr : String;
+ cmdstr : TCmdStr;
+ success : boolean;
+ DynLinkStr : string[60];
+ StaticStr,
+ StripStr : string[40];
+begin
+ if not(cs_link_extern in aktglobalswitches) then
+ Message1(exec_i_linking,current_module.exefilename^);
+
+{ Create some replacements }
+ StaticStr:='';
+ StripStr:='';
+ DynLinkStr:='';
+ if (cs_link_staticflag in aktglobalswitches) then
+ StaticStr:='-Bstatic';
+ if (cs_link_strip in aktglobalswitches) then
+ StripStr:='-s';
+ If (cs_profile in aktmoduleswitches) or
+ ((Info.DynamicLinker<>'') and (not SharedLibFiles.Empty)) then
+ DynLinkStr:='-dynamic-linker='+Info.DynamicLinker;
+ { solaris sets DynamicLinker, but gld will (hopefully) defaults to -Bdynamic and add the default-linker }
+{ Write used files and libraries }
+ WriteResponseFile(false);
+
+{ Call linker }
+ SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
+ Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename^));
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+ Replace(cmdstr,'$STATIC',StaticStr);
+ Replace(cmdstr,'$STRIP',StripStr);
+ Replace(cmdstr,'$DYNLINK',DynLinkStr);
+ success:=DoExec(FindUtil(utilsprefix+BinStr),CmdStr,true,false);
+
+{ Remove ReponseFile }
+{$IFNDEF LinkTest}
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ RemoveFile(outputexedir+Info.ResName);
+{$ENDIF}
+ MakeExecutable:=success; { otherwise a recursive call to link method }
+end;
+
+
+Function TLinkersolaris.MakeSharedLibrary:boolean;
+var
+ binstr : String;
+ cmdstr : TCmdStr;
+ 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',maybequoted(current_module.sharedlibfilename^));
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+ success:=DoExec(FindUtil(utilsprefix+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',maybequoted(current_module.sharedlibfilename^));
+ success:=DoExec(utilsprefix+FindUtil(binstr),cmdstr,true,false);
+ end;
+
+{ Remove ReponseFile }
+{$IFNDEF LinkTest}
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ RemoveFile(outputexedir+Info.ResName);
+{$ENDIF}
+ MakeSharedLibrary:=success; { otherwise a recursive call to link method }
+end;
+
+
+{*****************************************************************************
+ Initialize
+*****************************************************************************}
+
+initialization
+{$ifdef i386}
+ RegisterExternalLinker(system_i386_solaris_info,TLinkersolaris);
+ RegisterImport(system_i386_solaris,TImportLibsolaris);
+ RegisterExport(system_i386_solaris,TExportLibsolaris);
+ RegisterTarget(system_i386_solaris_info);
+{$endif i386}
+
+{$ifdef sparc}
+ RegisterExternalLinker(system_sparc_solaris_info,TLinkersolaris);
+ RegisterImport(system_sparc_solaris,TImportLibsolaris);
+ RegisterExport(system_sparc_solaris,TExportLibsolaris);
+ RegisterTarget(system_sparc_solaris_info);
+{$endif sparc}
+end.
diff --git a/compiler/systems/t_watcom.pas b/compiler/systems/t_watcom.pas
new file mode 100644
index 0000000000..ba9886e6bf
--- /dev/null
+++ b/compiler/systems/t_watcom.pas
@@ -0,0 +1,178 @@
+{
+ Copyright (c) 2003 by Wiktor Sywula
+
+ This unit implements support import, export, link routines
+ for the (i386) Watcom 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_watcom;
+
+{$i fpcdefs.inc}
+
+interface
+
+
+implementation
+
+ uses
+ link,
+ cclasses,cutils,strings,globtype,globals,
+ systems,verbose,script,fmodule,i_watcom;
+
+
+ type
+ tlinkerwatcom=class(texternallinker)
+ private
+ Function WriteResponseFile(isdll:boolean) : Boolean;
+ public
+ constructor Create;override;
+ procedure SetDefaultInfo;override;
+ function MakeExecutable:boolean;override;
+{ function MakeSharedLibrary:boolean;override;}
+ end;
+
+
+{****************************************************************************
+ TLinkerWatcom
+****************************************************************************}
+
+Constructor TLinkerWatcom.Create;
+begin
+ Inherited Create;
+ SharedLibFiles.doubles:=true;
+ StaticLibFiles.doubles:=true;
+end;
+
+
+procedure TLinkerWatcom.SetDefaultInfo;
+begin
+ with Info do
+ ExeCmd[1]:='wlink system causeway option quiet option nocaseexact $OPT $STRIP name $EXE @$RES';
+end;
+
+Function TLinkerWatcom.WriteResponseFile(isdll:boolean) : Boolean;
+Var
+ linkres : TLinkRes;
+ i : longint;
+ s : string;
+ linklibc : boolean;
+begin
+ WriteResponseFile:=False;
+
+ { Open link.res file }
+ LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
+
+ { Write object files, start with prt0 }
+ LinkRes.Add('file '+GetShortName(FindObjectFile('prt0','',false)));
+ if not ObjectFiles.Empty then
+ While not ObjectFiles.Empty do
+ begin
+ S:=ObjectFiles.GetFirst;
+ LinkRes.AddFileName('file '+GetShortName(s));
+ end;
+
+ { Write staticlibraries }
+ if not StaticLibFiles.Empty then
+ While not StaticLibFiles.Empty do
+ begin
+ S:=StaticLibFiles.GetFirst;
+ LinkRes.AddFileName('file '+GetShortName(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) }
+ linklibc:=false;
+ 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 and Close response }
+ linkres.writetodisk;
+ linkres.free;
+
+ WriteResponseFile:=True;
+end;
+
+
+function TLinkerWatcom.MakeExecutable:boolean;
+var
+ binstr : String;
+ cmdstr : TCmdStr;
+ 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:='debug dwarf all';
+ if (cs_link_strip in aktglobalswitches) then
+ StripStr:='';
+
+{ Write used files and libraries }
+ WriteResponseFile(false);
+
+{ Call linker }
+ SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
+ Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename^));
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+ Replace(cmdstr,'$STRIP',StripStr);
+ success:=DoExec(FindUtil(utilsprefix+BinStr),cmdstr,true,false);
+
+{ Remove ReponseFile }
+ if (success) and not(cs_link_extern in aktglobalswitches) then
+ RemoveFile(outputexedir+Info.ResName);
+
+ MakeExecutable:=success; { otherwise a recursive call to link method }
+end;
+
+{function TLinkerWatcom.MakeSharedLibrary:boolean;
+begin
+ MakeSharedLibrary:=false;
+end;}
+
+{*****************************************************************************
+ Initialize
+*****************************************************************************}
+
+initialization
+ RegisterExternalLinker(system_i386_watcom_info,TLinkerWatcom);
+ RegisterTarget(system_i386_watcom_info);
+end.
diff --git a/compiler/systems/t_wdosx.pas b/compiler/systems/t_wdosx.pas
new file mode 100644
index 0000000000..4eaa9eaf68
--- /dev/null
+++ b/compiler/systems/t_wdosx.pas
@@ -0,0 +1,84 @@
+{
+ Copyright (c) 2001-2002 Pavel ??????
+
+ This unit implements support import,export,link routines
+ for the (i386) WDOSX 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_wdosx;
+
+{$i fpcdefs.inc}
+
+interface
+
+
+implementation
+
+ uses
+ cutils,
+ fmodule,globals,systems,
+ import,export,link,t_win,i_wdosx;
+
+ type
+ timportlibwdosx=class(timportlibwin32)
+ end;
+
+ texportlibwdosx=texportlibwin32;
+
+ tlinkerwdosx=class(tlinkerwin32)
+ public
+ function MakeExecutable:boolean;override;
+ end;
+
+ tDLLScannerWdosx=class(tDLLScannerWin32)
+ end;
+
+
+{*****************************************************************************
+ TIMPORTLIBWDOSX
+*****************************************************************************}
+
+{*****************************************************************************
+ TLINKERWDOSX
+*****************************************************************************}
+function TLinkerWdosx.MakeExecutable:boolean;
+var
+ b: boolean;
+begin
+ b := Inherited MakeExecutable;
+ if b then
+ DoExec(FindUtil('stubit'),current_module.exefilename^,false,false);
+ Result := b;
+end;
+
+{****************************************************************************
+ TDLLScannerWdosx
+****************************************************************************}
+
+{*****************************************************************************
+ Initialize
+*****************************************************************************}
+
+initialization
+ RegisterExternalLinker(system_i386_wdosx_info,TLinkerWdosx);
+ RegisterImport(system_i386_wdosx,TImportLibWdosx);
+ RegisterExport(system_i386_wdosx,TExportLibWdosx);
+ RegisterDLLScanner(system_i386_wdosx,TDLLScannerWdosx);
+ {RegisterAr(ar_gnu_arw_info);}
+ {RegisterRes(res_gnu_windres_info);}
+ RegisterTarget(system_i386_wdosx_info);
+end.
diff --git a/compiler/systems/t_win.pas b/compiler/systems/t_win.pas
new file mode 100644
index 0000000000..3d6e435ae7
--- /dev/null
+++ b/compiler/systems/t_win.pas
@@ -0,0 +1,1673 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ 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
+ 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_win;
+
+{$i fpcdefs.inc}
+
+interface
+ uses
+ dos,
+ cutils,cclasses,
+ aasmbase,aasmtai,aasmcpu,fmodule,globtype,globals,systems,verbose,
+ symconst,symdef,symsym,
+ script,gendef,
+ cpubase,
+ import,export,link,cgobj,i_win;
+
+
+ const
+ MAX_DEFAULT_EXTENSIONS = 3;
+
+ type
+ tStr4=array[1..MAX_DEFAULT_EXTENSIONS] of string[4];
+ pStr4=^tStr4;
+
+ twin32imported_item = class(timported_item)
+ procdef : tprocdef;
+ end;
+
+ timportlibwin32=class(timportlib)
+ private
+ procedure win32importproc(aprocdef:tprocdef;const func,module : string;index : longint;const name : string);
+ procedure importvariable_str(const s:string;const name,module:string);
+ procedure importprocedure_str(const func,module:string;index:longint;const name:string);
+ public
+ procedure preparelib(const s:string);override;
+ procedure importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);override;
+ procedure importvariable(vs:tglobalvarsym;const name,module:string);override;
+ procedure generatelib;override;
+ procedure generatenasmlib;virtual;
+ procedure generatesmartlib;override;
+ end;
+
+ texportlibwin32=class(texportlib)
+ st : string;
+ EList_indexed:tList;
+ EList_nonindexed:tList;
+ procedure preparelib(const s:string);override;
+ procedure exportprocedure(hp : texported_item);override;
+ procedure exportvar(hp : texported_item);override;
+ procedure exportfromlist(hp : texported_item);
+ procedure generatelib;override;
+ procedure generatenasmlib;virtual;
+ end;
+
+ tlinkerwin32=class(texternallinker)
+ private
+ Function WriteResponseFile(isdll:boolean) : Boolean;
+ Function PostProcessExecutable(const fn:string;isdll:boolean) : Boolean;
+ public
+ Constructor Create;override;
+ Procedure SetDefaultInfo;override;
+ function MakeExecutable:boolean;override;
+ function MakeSharedLibrary:boolean;override;
+ end;
+
+ tDLLScannerWin32=class(tDLLScanner)
+ private
+ cstring : array[0..127]of char;
+ function DOSstubOK(var x:cardinal):boolean;
+ function FindDLL(const s:string;var founddll:string):boolean;
+ function ExtractDllName(Const Name : string) : string;
+ public
+ function isSuitableFileType(x:cardinal):longbool;override;
+ function GetEdata(HeaderEntry:cardinal):longbool;override;
+ function Scan(const binname:string):longbool;override;
+ end;
+
+implementation
+
+ uses
+ cpuinfo,cgutils,dbgbase;
+
+
+ const
+ res_gnu_windres_info : tresinfo =
+ (
+ id : res_gnu_windres;
+ resbin : 'windres';
+ rescmd : '--include $INC -O coff -o $OBJ $RES'
+ );
+
+ res_gnu_wince_windres_info : tresinfo =
+ (
+ id : res_gnu_wince_windres;
+ resbin : 'windres';
+ rescmd : '--include $INC -O coff -o $OBJ $RES'
+ );
+
+{*****************************************************************************
+ TIMPORTLIBWIN32
+*****************************************************************************}
+
+ procedure timportlibwin32.preparelib(const s : string);
+ begin
+ if asmlist[al_imports]=nil then
+ asmlist[al_imports]:=TAAsmoutput.create;
+ end;
+
+
+ procedure timportlibwin32.win32importproc(aprocdef:tprocdef;const func,module : string;index : longint;const name : string);
+ var
+ hp1 : timportlist;
+ hp2 : twin32imported_item;
+ hs : string;
+ begin
+ { procdef or funcname must be give, not both }
+ if assigned(aprocdef) and (func<>'') then
+ internalerror(200411161);
+ { append extension if required }
+ hs:=AddExtension(module,target_info.sharedlibext);
+ { search for the module }
+ hp1:=timportlist(current_module.imports.first);
+ while assigned(hp1) do
+ begin
+ if hs=hp1.dllname^ then
+ break;
+ hp1:=timportlist(hp1.next);
+ end;
+ { generate a new item ? }
+ if not(assigned(hp1)) then
+ begin
+ hp1:=timportlist.create(hs);
+ current_module.imports.concat(hp1);
+ end;
+ { search for reuse of old import item }
+ if assigned(aprocdef) then
+ begin
+ hp2:=twin32imported_item(hp1.imported_items.first);
+ while assigned(hp2) do
+ begin
+ if (hp2.procdef=aprocdef) then
+ break;
+ hp2:=twin32imported_item(hp2.next);
+ end;
+ end
+ else
+ begin
+ hp2:=twin32imported_item(hp1.imported_items.first);
+ while assigned(hp2) do
+ begin
+ if (hp2.func^=func) then
+ break;
+ hp2:=twin32imported_item(hp2.next);
+ end;
+ end;
+ if not assigned(hp2) then
+ begin
+ hp2:=twin32imported_item.create(func,name,index);
+ hp2.procdef:=aprocdef;
+ hp1.imported_items.concat(hp2);
+ end;
+ end;
+
+
+ procedure timportlibwin32.importprocedure(aprocdef:tprocdef;const module : string;index : longint;const name : string);
+ begin
+ win32importproc(aprocdef,'',module,index,name);
+ end;
+
+
+ procedure timportlibwin32.importprocedure_str(const func,module : string;index : longint;const name : string);
+ begin
+ win32importproc(nil,func,module,index,name);
+ end;
+
+
+ procedure timportlibwin32.importvariable(vs:tglobalvarsym;const name,module:string);
+ begin
+ importvariable_str(vs.mangledname,name,module);
+ end;
+
+
+ procedure timportlibwin32.importvariable_str(const s:string;const name,module:string);
+ var
+ hp1 : timportlist;
+ hp2 : twin32imported_item;
+ hs : string;
+ begin
+ hs:=AddExtension(module,target_info.sharedlibext);
+ { search for the module }
+ hp1:=timportlist(current_module.imports.first);
+ while assigned(hp1) do
+ begin
+ if hs=hp1.dllname^ then
+ break;
+ hp1:=timportlist(hp1.next);
+ end;
+ { generate a new item ? }
+ if not(assigned(hp1)) then
+ begin
+ hp1:=timportlist.create(hs);
+ current_module.imports.concat(hp1);
+ end;
+ hp2:=twin32imported_item.create_var(s,name);
+ hp2.procdef:=nil;
+ hp1.imported_items.concat(hp2);
+ end;
+
+ procedure timportlibwin32.generatenasmlib;
+ var
+ hp1 : timportlist;
+ hp2 : twin32imported_item;
+ begin
+ new_section(asmlist[al_imports],sec_code,'',0);
+ hp1:=timportlist(current_module.imports.first);
+ while assigned(hp1) do
+ begin
+ hp2:=twin32imported_item(hp1.imported_items.first);
+ while assigned(hp2) do
+ begin
+ asmlist[al_imports].concat(tai_directive.create(asd_extern,hp2.func^));
+ asmlist[al_imports].concat(tai_directive.create(asd_nasm_import,hp2.func^+' '+hp1.dllname^+' '+hp2.name^));
+ hp2:=twin32imported_item(hp2.next);
+ end;
+ hp1:=timportlist(hp1.next);
+ end;
+ end;
+
+
+ procedure timportlibwin32.generatesmartlib;
+ var
+ hp1 : timportlist;
+ mangledstring : string;
+ importname : string;
+ suffix : integer;
+ hp2 : twin32imported_item;
+ lhead,lname,lcode, {$ifdef ARM} lpcode, {$endif ARM}
+ lidata4,lidata5 : tasmlabel;
+ href : treference;
+ begin
+ if (target_asm.id in [as_i386_masm,as_i386_tasm,as_i386_nasmwin32]) then
+ begin
+ generatenasmlib;
+ exit;
+ end;
+ hp1:=timportlist(current_module.imports.first);
+ while assigned(hp1) do
+ begin
+ { Get labels for the sections }
+ objectlibrary.getdatalabel(lhead);
+ objectlibrary.getdatalabel(lname);
+ objectlibrary.getaddrlabel(lidata4);
+ objectlibrary.getaddrlabel(lidata5);
+ { create header for this importmodule }
+ asmlist[al_imports].concat(Tai_cutobject.Create_begin);
+ new_section(asmlist[al_imports],sec_idata2,'',0);
+ asmlist[al_imports].concat(Tai_label.Create(lhead));
+ { pointer to procedure names }
+ asmlist[al_imports].concat(Tai_const.Create_rva_sym(lidata4));
+ { two empty entries follow }
+ asmlist[al_imports].concat(Tai_const.Create_32bit(0));
+ asmlist[al_imports].concat(Tai_const.Create_32bit(0));
+ { pointer to dll name }
+ asmlist[al_imports].concat(Tai_const.Create_rva_sym(lname));
+ { pointer to fixups }
+ asmlist[al_imports].concat(Tai_const.Create_rva_sym(lidata5));
+ { first write the name references }
+ new_section(asmlist[al_imports],sec_idata4,'',0);
+ asmlist[al_imports].concat(Tai_const.Create_32bit(0));
+ asmlist[al_imports].concat(Tai_label.Create(lidata4));
+ { then the addresses and create also the indirect jump }
+ new_section(asmlist[al_imports],sec_idata5,'',0);
+ asmlist[al_imports].concat(Tai_const.Create_32bit(0));
+ asmlist[al_imports].concat(Tai_label.Create(lidata5));
+
+ { create procedures }
+ hp2:=twin32imported_item(hp1.imported_items.first);
+ while assigned(hp2) do
+ begin
+ { insert cuts }
+ asmlist[al_imports].concat(Tai_cutobject.Create);
+ { create indirect jump }
+ if not hp2.is_var then
+ begin
+ objectlibrary.getjumplabel(lcode);
+ {$ifdef ARM}
+ objectlibrary.getjumplabel(lpcode);
+ {$endif ARM}
+ { place jump in al_procedures, insert a code section in the
+ al_imports to reduce the amount of .s files (PFV) }
+ new_section(asmlist[al_imports],sec_code,'',0);
+ if assigned(hp2.procdef) then
+ mangledstring:=hp2.procdef.mangledname
+ else
+ mangledstring:=hp2.func^;
+ asmlist[al_imports].concat(Tai_symbol.Createname_global(mangledstring,AT_FUNCTION,0));
+ asmlist[al_imports].concat(Tai_function_name.Create(''));
+ {$ifdef ARM}
+ reference_reset_symbol(href,lpcode,0);
+ asmlist[al_imports].concat(Taicpu.op_reg_ref(A_LDR,NR_R12,href));
+ reference_reset_base(href,NR_R12,0);
+ asmlist[al_imports].concat(Taicpu.op_reg_ref(A_LDR,NR_R15,href));
+ asmlist[al_imports].concat(Tai_label.Create(lpcode));
+ reference_reset_symbol(href,lcode,0);
+ asmlist[al_imports].concat(tai_const.create_sym_offset(href.symbol,href.offset));
+ {$else ARM}
+ reference_reset_symbol(href,lcode,0);
+ asmlist[al_imports].concat(Taicpu.Op_ref(A_JMP,S_NO,href));
+ asmlist[al_imports].concat(Tai_align.Create_op(4,$90));
+ {$endif ARM}
+ end;
+ { create head link }
+ new_section(asmlist[al_imports],sec_idata7,'',0);
+ asmlist[al_imports].concat(Tai_const.Create_rva_sym(lhead));
+ { fixup }
+ objectlibrary.getjumplabel(tasmlabel(hp2.lab));
+ new_section(asmlist[al_imports],sec_idata4,'',0);
+ asmlist[al_imports].concat(Tai_const.Create_rva_sym(hp2.lab));
+ { add jump field to al_imports }
+ new_section(asmlist[al_imports],sec_idata5,'',0);
+ if hp2.is_var then
+ asmlist[al_imports].concat(Tai_symbol.Createname_global(hp2.func^,AT_FUNCTION,0))
+ else
+ asmlist[al_imports].concat(Tai_label.Create(lcode));
+ if (cs_debuginfo in aktmoduleswitches) then
+ begin
+ if assigned(hp2.name) then
+ begin
+ importname:='__imp_'+hp2.name^;
+ suffix:=0;
+ while assigned(objectlibrary.getasmsymbol(importname)) do
+ begin
+ inc(suffix);
+ importname:='__imp_'+hp2.name^+'_'+tostr(suffix);
+ end;
+ asmlist[al_imports].concat(tai_symbol.createname(importname,AT_FUNCTION,4));
+ end
+ else
+ begin
+ importname:='__imp_by_ordinal'+tostr(hp2.ordnr);
+ suffix:=0;
+ while assigned(objectlibrary.getasmsymbol(importname)) do
+ begin
+ inc(suffix);
+ importname:='__imp_by_ordinal'+tostr(hp2.ordnr)+'_'+tostr(suffix);
+ end;
+ asmlist[al_imports].concat(tai_symbol.createname(importname,AT_FUNCTION,4));
+ end;
+ end;
+ if hp2.name^<>'' then
+ asmlist[al_imports].concat(Tai_const.Create_rva_sym(hp2.lab))
+ else
+ asmlist[al_imports].concat(Tai_const.Create_32bit(longint($80000000) or longint(hp2.ordnr)));
+ { finally the import information }
+ new_section(asmlist[al_imports],sec_idata6,'',0);
+ asmlist[al_imports].concat(Tai_label.Create(hp2.lab));
+ asmlist[al_imports].concat(Tai_const.Create_16bit(hp2.ordnr));
+ asmlist[al_imports].concat(Tai_string.Create(hp2.name^+#0));
+ asmlist[al_imports].concat(Tai_align.Create_op(2,0));
+ hp2:=twin32imported_item(hp2.next);
+ end;
+
+ { write final section }
+ asmlist[al_imports].concat(Tai_cutobject.Create_end);
+ { end of name references }
+ new_section(asmlist[al_imports],sec_idata4,'',0);
+ asmlist[al_imports].concat(Tai_const.Create_32bit(0));
+ { end if addresses }
+ new_section(asmlist[al_imports],sec_idata5,'',0);
+ asmlist[al_imports].concat(Tai_const.Create_32bit(0));
+ { dllname }
+ new_section(asmlist[al_imports],sec_idata7,'',0);
+ asmlist[al_imports].concat(Tai_label.Create(lname));
+ asmlist[al_imports].concat(Tai_string.Create(hp1.dllname^+#0));
+
+ hp1:=timportlist(hp1.next);
+ end;
+ end;
+
+
+ procedure timportlibwin32.generatelib;
+ var
+ hp1 : timportlist;
+ hp2 : twin32imported_item;
+ l1,l2,l3,l4 {$ifdef ARM} ,l5 {$endif ARM} : tasmlabel;
+ mangledstring : string;
+ importname : string;
+ suffix : integer;
+ href : treference;
+ begin
+ if (target_asm.id in [as_i386_masm,as_i386_tasm,as_i386_nasmwin32]) then
+ begin
+ generatenasmlib;
+ exit;
+ end;
+ hp1:=timportlist(current_module.imports.first);
+ while assigned(hp1) do
+ begin
+ { align al_procedures for the jumps }
+ new_section(asmlist[al_imports],sec_code,'',sizeof(aint));
+ { Get labels for the sections }
+ objectlibrary.getjumplabel(l1);
+ objectlibrary.getjumplabel(l2);
+ objectlibrary.getjumplabel(l3);
+ new_section(asmlist[al_imports],sec_idata2,'',0);
+ { pointer to procedure names }
+ asmlist[al_imports].concat(Tai_const.Create_rva_sym(l2));
+ { two empty entries follow }
+ asmlist[al_imports].concat(Tai_const.Create_32bit(0));
+ asmlist[al_imports].concat(Tai_const.Create_32bit(0));
+ { pointer to dll name }
+ asmlist[al_imports].concat(Tai_const.Create_rva_sym(l1));
+ { pointer to fixups }
+ asmlist[al_imports].concat(Tai_const.Create_rva_sym(l3));
+
+ { only create one section for each else it will
+ create a lot of idata* }
+
+ { first write the name references }
+ new_section(asmlist[al_imports],sec_idata4,'',0);
+ asmlist[al_imports].concat(Tai_label.Create(l2));
+
+ hp2:=twin32imported_item(hp1.imported_items.first);
+ while assigned(hp2) do
+ begin
+ objectlibrary.getjumplabel(tasmlabel(hp2.lab));
+ if hp2.name^<>'' then
+ asmlist[al_imports].concat(Tai_const.Create_rva_sym(hp2.lab))
+ else
+ asmlist[al_imports].concat(Tai_const.Create_32bit(longint($80000000) or hp2.ordnr));
+ hp2:=twin32imported_item(hp2.next);
+ end;
+ { finalize the names ... }
+ asmlist[al_imports].concat(Tai_const.Create_32bit(0));
+
+ { then the addresses and create also the indirect jump }
+ new_section(asmlist[al_imports],sec_idata5,'',0);
+ asmlist[al_imports].concat(Tai_label.Create(l3));
+ hp2:=twin32imported_item(hp1.imported_items.first);
+ while assigned(hp2) do
+ begin
+ if not hp2.is_var then
+ begin
+ objectlibrary.getjumplabel(l4);
+ {$ifdef ARM}
+ objectlibrary.getjumplabel(l5);
+ {$endif ARM}
+ { create indirect jump and }
+ { place jump in al_procedures }
+ new_section(asmlist[al_imports],sec_code,'',0);
+ if assigned(hp2.procdef) then
+ mangledstring:=hp2.procdef.mangledname
+ else
+ mangledstring:=hp2.func^;
+ asmlist[al_imports].concat(Tai_symbol.Createname_global(mangledstring,AT_FUNCTION,0));
+ asmlist[al_imports].concat(tai_function_name.create(''));
+ {$ifdef ARM}
+ reference_reset_symbol(href,l5,0);
+ asmlist[al_imports].concat(Taicpu.op_reg_ref(A_LDR,NR_R12,href));
+ reference_reset_base(href,NR_R12,0);
+ asmlist[al_imports].concat(Taicpu.op_reg_ref(A_LDR,NR_R15,href));
+ asmlist[al_imports].concat(Tai_label.Create(l5));
+ reference_reset_symbol(href,l4,0);
+ asmlist[al_imports].concat(tai_const.create_sym_offset(href.symbol,href.offset));
+ {$else ARM}
+ reference_reset_symbol(href,l4,0);
+ asmlist[al_imports].concat(Taicpu.Op_ref(A_JMP,S_NO,href));
+ asmlist[al_imports].concat(Tai_align.Create_op(4,$90));
+ {$endif ARM}
+ { add jump field to al_imports }
+ new_section(asmlist[al_imports],sec_idata5,'',0);
+ if (cs_debuginfo in aktmoduleswitches) then
+ begin
+ if assigned(hp2.name) then
+ begin
+ importname:='__imp_'+hp2.name^;
+ suffix:=0;
+ while assigned(objectlibrary.getasmsymbol(importname)) do
+ begin
+ inc(suffix);
+ importname:='__imp_'+hp2.name^+'_'+tostr(suffix);
+ end;
+ asmlist[al_imports].concat(tai_symbol.createname(importname,AT_FUNCTION,4));
+ end
+ else
+ begin
+ importname:='__imp_by_ordinal'+tostr(hp2.ordnr);
+ suffix:=0;
+ while assigned(objectlibrary.getasmsymbol(importname)) do
+ begin
+ inc(suffix);
+ importname:='__imp_by_ordinal'+tostr(hp2.ordnr)+'_'+tostr(suffix);
+ end;
+ asmlist[al_imports].concat(tai_symbol.createname(importname,AT_FUNCTION,4));
+ end;
+ end;
+ asmlist[al_imports].concat(Tai_label.Create(l4));
+ end
+ else
+ begin
+ asmlist[al_imports].concat(Tai_symbol.Createname_global(hp2.func^,AT_DATA,0));
+ end;
+ asmlist[al_imports].concat(Tai_const.Create_rva_sym(hp2.lab));
+ hp2:=twin32imported_item(hp2.next);
+ end;
+ { finalize the addresses }
+ asmlist[al_imports].concat(Tai_const.Create_32bit(0));
+
+ { finally the import information }
+ new_section(asmlist[al_imports],sec_idata6,'',0);
+ hp2:=twin32imported_item(hp1.imported_items.first);
+ while assigned(hp2) do
+ begin
+ asmlist[al_imports].concat(Tai_label.Create(hp2.lab));
+ { the ordinal number }
+ asmlist[al_imports].concat(Tai_const.Create_16bit(hp2.ordnr));
+ asmlist[al_imports].concat(Tai_string.Create(hp2.name^+#0));
+ asmlist[al_imports].concat(Tai_align.Create_op(2,0));
+ hp2:=twin32imported_item(hp2.next);
+ end;
+ { create import dll name }
+ new_section(asmlist[al_imports],sec_idata7,'',0);
+ asmlist[al_imports].concat(Tai_label.Create(l1));
+ asmlist[al_imports].concat(Tai_string.Create(hp1.dllname^+#0));
+
+ hp1:=timportlist(hp1.next);
+ end;
+ end;
+
+
+{*****************************************************************************
+ TEXPORTLIBWIN32
+*****************************************************************************}
+
+ procedure texportlibwin32.preparelib(const s:string);
+ begin
+ if asmlist[al_exports]=nil then
+ asmlist[al_exports]:=TAAsmoutput.create;
+ EList_indexed:=tList.Create;
+ EList_nonindexed:=tList.Create;
+ objectlibrary.getdatalabel(edatalabel);
+ end;
+
+
+ procedure texportlibwin32.exportvar(hp : texported_item);
+ begin
+ { same code used !! PM }
+ exportprocedure(hp);
+ end;
+
+ var
+ Gl_DoubleIndex:boolean;
+ Gl_DoubleIndexValue:longint;
+
+ function IdxCompare(Item1, Item2: Pointer): Integer;
+ var
+ I1:texported_item absolute Item1;
+ I2:texported_item absolute Item2;
+ begin
+ Result:=I1.index-I2.index;
+ if(Result=0)and(Item1<>Item2)then
+ begin
+ Gl_DoubleIndex:=true;
+ Gl_DoubleIndexValue:=I1.index;
+ end;
+ end;
+
+
+ procedure texportlibwin32.exportprocedure(hp : texported_item);
+ begin
+ if ((hp.options and eo_index)<>0)and((hp.index<=0) or (hp.index>$ffff)) then
+ begin
+ message1(parser_e_export_invalid_index,tostr(hp.index));
+ exit;
+ end;
+ if hp.options and eo_index=eo_index then
+ EList_indexed.Add(hp)
+ else
+ EList_nonindexed.Add(hp);
+ end;
+
+
+ procedure texportlibwin32.exportfromlist(hp : texported_item);
+ //formerly texportlibwin32.exportprocedure
+ { must be ordered at least for win32 !! }
+ var
+ hp2 : texported_item;
+ begin
+ hp2:=texported_item(current_module._exports.first);
+ while assigned(hp2) and
+ (hp.name^>hp2.name^) do
+ hp2:=texported_item(hp2.next);
+ { insert hp there !! }
+ if hp2=nil then
+ current_module._exports.concat(hp)
+ else
+ begin
+ if hp2.name^=hp.name^ then
+ begin
+ { this is not allowed !! }
+ message1(parser_e_export_name_double,hp.name^);
+ exit;
+ end;
+ current_module._exports.insertbefore(hp,hp2);
+ end;
+ end;
+
+
+ procedure texportlibwin32.generatelib;
+ var
+ ordinal_base,ordinal_max,ordinal_min : longint;
+ current_index : longint;
+ entries,named_entries : longint;
+ name_label,dll_name_label,export_address_table : tasmlabel;
+ export_name_table_pointers,export_ordinal_table : tasmlabel;
+ hp,hp2 : texported_item;
+ temtexport : TLinkedList;
+ address_table,name_table_pointers,
+ name_table,ordinal_table : TAAsmoutput;
+ i,autoindex,ni_high : longint;
+ hole : boolean;
+
+ begin
+ Gl_DoubleIndex:=false;
+ ELIst_indexed.Sort(@IdxCompare);
+
+ if Gl_DoubleIndex then
+ begin
+ message1(parser_e_export_ordinal_double,tostr(Gl_DoubleIndexValue));
+ EList_indexed.Free;
+ EList_nonindexed.Free;
+ exit;
+ end;
+
+ autoindex:=1;
+ while EList_nonindexed.Count>0 do
+ begin
+ hole:=(EList_indexed.Count>0)and(texported_item(EList_indexed.Items[0]).index>1);
+ if not hole then
+ for i:=autoindex to pred(EList_indexed.Count)do
+ if texported_item(EList_indexed.Items[i]).index-texported_item(EList_indexed.Items[pred(i)]).index>1 then
+ begin
+ autoindex:=succ(texported_item(EList_indexed.Items[pred(i)]).index);
+ hole:=true;
+ break;
+ end;
+ ni_high:=pred(EList_nonindexed.Count);
+ if not hole then
+ begin
+ autoindex:=succ(EList_indexed.Count);
+ EList_indexed.Add(EList_nonindexed.Items[ni_high]);
+ end
+ else
+ EList_indexed.Insert(pred(AutoIndex),EList_nonindexed.Items[ni_high]);
+ EList_nonindexed.Delete(ni_high);
+ texported_item(EList_indexed.Items[pred(AutoIndex)]).index:=autoindex;
+ end;
+ EList_nonindexed.Free;
+ for i:=0 to pred(EList_indexed.Count)do
+ exportfromlist(texported_item(EList_indexed.Items[i]));
+ EList_indexed.Free;
+
+ if (target_asm.id in [as_i386_masm,as_i386_tasm,as_i386_nasmwin32]) then
+ begin
+ generatenasmlib;
+ exit;
+ end;
+
+ hp:=texported_item(current_module._exports.first);
+ if not assigned(hp) then
+ exit;
+
+ ordinal_max:=0;
+ ordinal_min:=$7FFFFFFF;
+ entries:=0;
+ named_entries:=0;
+ objectlibrary.getjumplabel(dll_name_label);
+ objectlibrary.getjumplabel(export_address_table);
+ objectlibrary.getjumplabel(export_name_table_pointers);
+ objectlibrary.getjumplabel(export_ordinal_table);
+
+ { count entries }
+ while assigned(hp) do
+ begin
+ inc(entries);
+ if (hp.index>ordinal_max) then
+ ordinal_max:=hp.index;
+ if (hp.index>0) and (hp.index<ordinal_min) then
+ ordinal_min:=hp.index;
+ if assigned(hp.name) then
+ inc(named_entries);
+ hp:=texported_item(hp.next);
+ end;
+
+ { no support for higher ordinal base yet !! }
+ ordinal_base:=1;
+ current_index:=ordinal_base;
+ { we must also count the holes !! }
+ entries:=ordinal_max-ordinal_base+1;
+
+ new_section(asmlist[al_exports],sec_edata,'',0);
+ { create label to reference from main so smartlink will include
+ the .edata section }
+ asmlist[al_exports].concat(Tai_symbol.Create_global(edatalabel,0));
+ { export flags }
+ asmlist[al_exports].concat(Tai_const.Create_32bit(0));
+ { date/time stamp }
+ asmlist[al_exports].concat(Tai_const.Create_32bit(0));
+ { major version }
+ asmlist[al_exports].concat(Tai_const.Create_16bit(0));
+ { minor version }
+ asmlist[al_exports].concat(Tai_const.Create_16bit(0));
+ { pointer to dll name }
+ asmlist[al_exports].concat(Tai_const.Create_rva_sym(dll_name_label));
+ { ordinal base normally set to 1 }
+ asmlist[al_exports].concat(Tai_const.Create_32bit(ordinal_base));
+ { number of entries }
+ asmlist[al_exports].concat(Tai_const.Create_32bit(entries));
+ { number of named entries }
+ asmlist[al_exports].concat(Tai_const.Create_32bit(named_entries));
+ { address of export address table }
+ asmlist[al_exports].concat(Tai_const.Create_rva_sym(export_address_table));
+ { address of name pointer pointers }
+ asmlist[al_exports].concat(Tai_const.Create_rva_sym(export_name_table_pointers));
+ { address of ordinal number pointers }
+ asmlist[al_exports].concat(Tai_const.Create_rva_sym(export_ordinal_table));
+ { the name }
+ asmlist[al_exports].concat(Tai_label.Create(dll_name_label));
+ if st='' then
+ asmlist[al_exports].concat(Tai_string.Create(current_module.modulename^+target_info.sharedlibext+#0))
+ else
+ asmlist[al_exports].concat(Tai_string.Create(st+target_info.sharedlibext+#0));
+
+ { export address table }
+ address_table:=TAAsmoutput.create;
+ address_table.concat(Tai_align.Create_op(4,0));
+ address_table.concat(Tai_label.Create(export_address_table));
+ name_table_pointers:=TAAsmoutput.create;
+ name_table_pointers.concat(Tai_align.Create_op(4,0));
+ name_table_pointers.concat(Tai_label.Create(export_name_table_pointers));
+ ordinal_table:=TAAsmoutput.create;
+ ordinal_table.concat(Tai_align.Create_op(4,0));
+ ordinal_table.concat(Tai_label.Create(export_ordinal_table));
+ name_table:=TAAsmoutput.Create;
+ name_table.concat(Tai_align.Create_op(4,0));
+ { write each address }
+ hp:=texported_item(current_module._exports.first);
+ while assigned(hp) do
+ begin
+ if (hp.options and eo_name)<>0 then
+ begin
+ objectlibrary.getjumplabel(name_label);
+ name_table_pointers.concat(Tai_const.Create_rva_sym(name_label));
+ ordinal_table.concat(Tai_const.Create_16bit(hp.index-ordinal_base));
+ name_table.concat(Tai_align.Create_op(2,0));
+ name_table.concat(Tai_label.Create(name_label));
+ name_table.concat(Tai_string.Create(hp.name^+#0));
+ end;
+ hp:=texported_item(hp.next);
+ end;
+ { order in increasing ordinal values }
+ { into temtexport list }
+ temtexport:=TLinkedList.Create;
+ hp:=texported_item(current_module._exports.first);
+ while assigned(hp) do
+ begin
+ current_module._exports.remove(hp);
+ hp2:=texported_item(temtexport.first);
+ while assigned(hp2) and (hp.index>hp2.index) do
+ hp2:=texported_item(hp2.next);
+ if hp2=nil then
+ temtexport.concat(hp)
+ else
+ temtexport.insertbefore(hp,hp2);
+ hp:=texported_item(current_module._exports.first);;
+ end;
+
+ { write the export adress table }
+ current_index:=ordinal_base;
+ hp:=texported_item(temtexport.first);
+ while assigned(hp) do
+ begin
+ { fill missing values }
+ while current_index<hp.index do
+ begin
+ address_table.concat(Tai_const.Create_32bit(0));
+ inc(current_index);
+ end;
+ case hp.sym.typ of
+ globalvarsym :
+ address_table.concat(Tai_const.Createname_rva(tglobalvarsym(hp.sym).mangledname));
+ typedconstsym :
+ address_table.concat(Tai_const.Createname_rva(ttypedconstsym(hp.sym).mangledname));
+ procsym :
+ address_table.concat(Tai_const.Createname_rva(tprocsym(hp.sym).first_procdef.mangledname));
+ end;
+ inc(current_index);
+ hp:=texported_item(hp.next);
+ end;
+
+ asmlist[al_exports].concatlist(address_table);
+ asmlist[al_exports].concatlist(name_table_pointers);
+ asmlist[al_exports].concatlist(ordinal_table);
+ asmlist[al_exports].concatlist(name_table);
+ address_table.Free;
+ name_table_pointers.free;
+ ordinal_table.free;
+ name_table.free;
+ temtexport.free;
+ end;
+
+ procedure texportlibwin32.generatenasmlib;
+ var
+ hp : texported_item;
+ p : pchar;
+ s : string;
+ begin
+ new_section(asmlist[al_exports],sec_code,'',0);
+ hp:=texported_item(current_module._exports.first);
+ while assigned(hp) do
+ begin
+ case hp.sym.typ of
+ globalvarsym :
+ s:=tglobalvarsym(hp.sym).mangledname;
+ typedconstsym :
+ s:=ttypedconstsym(hp.sym).mangledname;
+ procsym :
+ s:=tprocsym(hp.sym).first_procdef.mangledname;
+ else
+ s:='';
+ end;
+ p:=strpnew(#9+'export '+s+' '+hp.name^+' '+tostr(hp.index));
+ {asmlist[al_exports].concat(tai_direct.create(p));}
+ hp:=texported_item(hp.next);
+ end;
+ end;
+
+
+{****************************************************************************
+ TLINKERWIN32
+****************************************************************************}
+
+
+Constructor TLinkerWin32.Create;
+begin
+ Inherited Create;
+ { allow duplicated libs (PM) }
+ SharedLibFiles.doubles:=true;
+ StaticLibFiles.doubles:=true;
+end;
+
+
+Procedure TLinkerWin32.SetDefaultInfo;
+var
+ targetopts: string;
+begin
+ with Info do
+ begin
+ {$ifdef ARM}
+ targetopts:='-m armpe';
+ {$else ARM}
+ targetopts:='-b pe-i386 -m i386pe';
+ {$endif ARM}
+ ExeCmd[1]:='ld '+targetopts+' $OPT $STRIP $APPTYPE $IMAGEBASE $RELOC -o $EXE $RES';
+ DllCmd[1]:='ld '+targetopts+' $OPT $STRIP --dll $APPTYPE $IMAGEBASE $RELOC -o $EXE $RES';
+ { ExeCmd[2]:='dlltool --as $ASBIN --dllname $EXE --output-exp exp.$$$ $RELOC $DEF';
+ use short forms to avoid 128 char limitation problem }
+ ExeCmd[2]:='dlltool -S $ASBIN -D $EXE -e exp.$$$ $RELOC $DEF';
+ ExeCmd[3]:='ld '+targetopts+' $OPT $STRIP $APPTYPE $IMAGEBASE -o $EXE $RES exp.$$$';
+ { DllCmd[2]:='dlltool --as $ASBIN --dllname $EXE --output-exp exp.$$$ $RELOC $DEF'; }
+ DllCmd[2]:='dlltool -S $ASBIN -D $EXE -e exp.$$$ $RELOC $DEF';
+ DllCmd[3]:='ld '+targetopts+' $OPT $STRIP --dll $APPTYPE $IMAGEBASE -o $EXE $RES exp.$$$';
+ end;
+end;
+
+
+
+Function TLinkerWin32.WriteResponseFile(isdll:boolean) : Boolean;
+Var
+ linkres : TLinkRes;
+ HPath : TStringListItem;
+ s,s2 : string;
+ i : integer;
+ linklibcygwin : boolean;
+begin
+ WriteResponseFile:=False;
+ linklibcygwin:=(SharedLibFiles.Find('cygwin')<>nil);
+
+ { Open link.res file }
+ LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
+
+ { Write path to search libraries }
+ HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
+ while assigned(HPath) do
+ begin
+ LinkRes.Add('SEARCH_DIR('+MaybeQuoted(HPath.Str)+')');
+ HPath:=TStringListItem(HPath.Next);
+ end;
+ HPath:=TStringListItem(LibrarySearchPath.First);
+ while assigned(HPath) do
+ begin
+ LinkRes.Add('SEARCH_DIR('+MaybeQuoted(HPath.Str)+')');
+ HPath:=TStringListItem(HPath.Next);
+ end;
+
+ { add objectfiles, start with prt0 always }
+ { profiling of shared libraries is currently not supported }
+ LinkRes.Add('INPUT(');
+ if isdll then
+ LinkRes.AddFileName(MaybeQuoted(FindObjectFile('wdllprt0','',false)))
+ else
+ if (cs_profile in aktmoduleswitches) then
+ LinkRes.AddFileName(MaybeQuoted(FindObjectFile('gprt0','',false)))
+ else
+ begin
+ if linklibcygwin then
+ LinkRes.AddFileName(MaybeQuoted(FindObjectFile('wcygprt0','',false)))
+ else
+ LinkRes.AddFileName(MaybeQuoted(FindObjectFile('wprt0','',false)));
+ end;
+
+ while not ObjectFiles.Empty do
+ begin
+ s:=ObjectFiles.GetFirst;
+ if s<>'' then
+ LinkRes.AddFileName(MaybeQuoted(s));
+ end;
+ LinkRes.Add(')');
+
+
+ { Write staticlibraries }
+ if (not StaticLibFiles.Empty) or (cs_profile in aktmoduleswitches) then
+ begin
+ LinkRes.Add('GROUP(');
+ if (cs_profile in aktmoduleswitches) then
+ begin
+ LinkRes.Add('-lc');
+ LinkRes.Add('-lgcc');
+ LinkRes.Add('-lgmon');
+ LinkRes.Add('-lkernel32');
+ end;
+ While not StaticLibFiles.Empty do
+ begin
+ S:=StaticLibFiles.GetFirst;
+ LinkRes.AddFileName(MaybeQuoted(s));
+ end;
+ LinkRes.Add(')');
+ end;
+
+ { Write sharedlibraries }
+ if not SharedLibFiles.Empty then
+ begin
+ LinkRes.Add('INPUT(') ;
+ While not SharedLibFiles.Empty do
+ begin
+ S:=SharedLibFiles.GetFirst;
+ if FindLibraryFile(s,target_info.staticClibprefix,target_info.staticClibext,s2) then
+ begin
+ LinkRes.Add(MaybeQuoted(s2));
+ continue;
+ end;
+ if pos(target_info.sharedlibprefix,s)=1 then
+ s:=copy(s,length(target_info.sharedlibprefix)+1,255);
+ i:=Pos(target_info.sharedlibext,S);
+ if i>0 then
+ Delete(S,i,255);
+ LinkRes.Add('-l'+s);
+ end;
+ LinkRes.Add(')');
+ end;
+
+{ Write and Close response }
+ linkres.writetodisk;
+ LinkRes.Free;
+
+ WriteResponseFile:=True;
+end;
+
+
+function TLinkerWin32.MakeExecutable:boolean;
+var
+ binstr : String;
+ cmdstr : TCmdStr;
+ success : boolean;
+ cmds,i : longint;
+ AsBinStr : string[80];
+ 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:='';
+ AsBinStr:=FindUtil(utilsprefix+'as');
+ if RelocSection then
+ RelocStr:='--base-file base.$$$';
+ if target_info.system in [system_arm_wince,system_i386_wince] then
+ begin
+ AppTypeStr:='--subsystem wince';
+ if apptype <> app_gui then
+ AppTypeStr:=AppTypeStr + ' --entry=mainCRTStartup';
+ end
+ else
+ if apptype=app_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;
+ if RelocSection or (not Deffile.empty) then
+ cmds:=3
+ else
+ cmds:=1;
+ for i:=1 to cmds do
+ begin
+ SplitBinCmd(Info.ExeCmd[i],binstr,cmdstr);
+ if binstr<>'' then
+ begin
+ Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename^));
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+ Replace(cmdstr,'$APPTYPE',AppTypeStr);
+ Replace(cmdstr,'$ASBIN',AsbinStr);
+ Replace(cmdstr,'$RELOC',RelocStr);
+ Replace(cmdstr,'$IMAGEBASE',ImageBaseStr);
+ Replace(cmdstr,'$STRIP',StripStr);
+ if not DefFile.Empty then
+ begin
+ DefFile.WriteFile;
+ Replace(cmdstr,'$DEF','-d '+maybequoted(deffile.fname));
+ end
+ else
+ Replace(cmdstr,'$DEF','');
+ success:=DoExec(FindUtil(utilsprefix+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(outputexedir+Info.ResName);
+ RemoveFile('base.$$$');
+ RemoveFile('exp.$$$');
+ RemoveFile('deffile.$$$');
+ end;
+
+ MakeExecutable:=success; { otherwise a recursive call to link method }
+end;
+
+
+Function TLinkerWin32.MakeSharedLibrary:boolean;
+var
+ binstr : String;
+ cmdstr : TCmdStr;
+ success : boolean;
+ cmds,
+ i : longint;
+ AsBinStr : string[80];
+ 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:='';
+ AsBinStr:=FindUtil(utilsprefix+'as');
+ if RelocSection then
+ RelocStr:='--base-file base.$$$';
+ if apptype=app_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;
+ if RelocSection or (not Deffile.empty) then
+ cmds:=3
+ else
+ cmds:=1;
+ for i:=1 to cmds do
+ begin
+ SplitBinCmd(Info.DllCmd[i],binstr,cmdstr);
+ if binstr<>'' then
+ begin
+ Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename^));
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
+ Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+ Replace(cmdstr,'$APPTYPE',AppTypeStr);
+ Replace(cmdstr,'$ASBIN',AsbinStr);
+ Replace(cmdstr,'$RELOC',RelocStr);
+ Replace(cmdstr,'$IMAGEBASE',ImageBaseStr);
+ Replace(cmdstr,'$STRIP',StripStr);
+ if not DefFile.Empty then
+ begin
+ DefFile.WriteFile;
+ Replace(cmdstr,'$DEF','-d '+maybequoted(deffile.fname));
+ end
+ else
+ Replace(cmdstr,'$DEF','');
+ success:=DoExec(FindUtil(utilsprefix+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(outputexedir+Info.ResName);
+ RemoveFile('base.$$$');
+ RemoveFile('exp.$$$');
+ RemoveFile('deffile.$$$');
+ 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;
+ cmdstr : string;
+ dosheader : tdosheader;
+ peheader : tpeheader;
+ firstsecpos,
+ maxfillsize,
+ 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
+ case apptype of
+ app_native :
+ cmdstr:='--subsystem native';
+ app_gui :
+ cmdstr:='--subsystem gui';
+ app_cui :
+ cmdstr:='--subsystem console';
+ end;
+ if dllversion<>'' then
+ cmdstr:=cmdstr+' --version '+dllversion;
+ cmdstr:=cmdstr+' --input '+maybequoted(fn);
+ cmdstr:=cmdstr+' --stack '+tostr(stacksize);
+ DoExec(FindUtil(utilsprefix+'postw32'),cmdstr,false,false);
+ 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 }
+ { wincegui=9 }
+ if target_info.system in [system_arm_wince,system_i386_wince] then
+ peheader.Subsystem:=9
+ else
+ case apptype of
+ app_native :
+ peheader.Subsystem:=1;
+ app_gui :
+ peheader.Subsystem:=2;
+ app_cui :
+ peheader.Subsystem:=3;
+ end;
+ if dllversion<>'' then
+ begin
+ peheader.MajorImageVersion:=dllmajor;
+ peheader.MinorImageVersion:=dllminor;
+ end;
+ { reset timestamp }
+ peheader.TimeDateStamp:=0;
+ { write header back }
+ 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:=1 to 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+}
+ if ioresult<>0 then;
+ postprocessexecutable:=true;
+end;
+
+
+{****************************************************************************
+ TDLLScannerWin32
+****************************************************************************}
+
+ function tDLLScannerWin32.DOSstubOK(var x:cardinal):boolean;
+ begin
+ blockread(f,TheWord,2,loaded);
+ if loaded<>2 then
+ DOSstubOK:=false
+ else
+ begin
+ DOSstubOK:=(TheWord='MZ');
+ seek(f,$3C);
+ blockread(f,x,4,loaded);
+ if(loaded<>4)or(longint(x)>filesize(f))then
+ DOSstubOK:=false;
+ end;
+ end;
+
+ function TDLLScannerWin32.FindDLL(const s:string;var founddll:string):boolean;
+ var
+ sysdir : string;
+ Found : boolean;
+ begin
+ Found:=false;
+ { Look for DLL in:
+ 1. Current dir
+ 2. Library Path
+ 3. windir,windir/system,windir/system32 }
+ Found:=FindFile(s,'.'+source_info.DirSep,founddll);
+ if (not found) then
+ Found:=librarysearchpath.FindFile(s,founddll);
+ if (not found) then
+ begin
+ sysdir:=FixPath(GetEnv('windir'),false);
+ Found:=FindFile(s,sysdir+';'+sysdir+'system'+source_info.DirSep+';'+sysdir+'system32'+source_info.DirSep,founddll);
+ end;
+ if (not found) then
+ begin
+ message1(exec_w_libfile_not_found,s);
+ FoundDll:=s;
+ end;
+ FindDll:=Found;
+ end;
+
+
+ function tDLLScannerWin32.ExtractDllName(Const Name : string) : string;
+ var n : string;
+ begin
+ n:=Upper(SplitExtension(Name));
+ if (n='.DLL') or (n='.DRV') or (n='.EXE') then
+ ExtractDllName:=Name
+ else
+ ExtractDllName:=Name+target_info.sharedlibext;
+ end;
+
+
+
+function tDLLScannerWin32.isSuitableFileType(x:cardinal):longbool;
+ begin
+ seek(f,x);
+ blockread(f,TheWord,2,loaded);
+ isSuitableFileType:=(loaded=2)and(TheWord='PE');
+ end;
+
+
+function tDLLScannerWin32.GetEdata(HeaderEntry:cardinal):longbool;
+ type
+ TObjInfo=packed record
+ ObjName:array[0..7]of char;
+ VirtSize,
+ VirtAddr,
+ RawSize,
+ RawOffset,
+ Reloc,
+ LineNum:cardinal;
+ RelCount,
+ LineCount:word;
+ flags:cardinal;
+ end;
+ var
+ i:cardinal;
+ ObjOfs:cardinal;
+ Obj:TObjInfo;
+ APE_obj,APE_Optsize:word;
+ ExportRVA:cardinal;
+ delta:cardinal;
+ const
+ IMAGE_SCN_CNT_CODE=$00000020;
+ var
+ _d:dirstr;
+ _n:namestr;
+ _e:extstr;
+ function isUsedFunction(name:pchar):longbool;
+ var
+ hp:tExternalsItem;
+ begin
+ isUsedFunction:=false;
+ hp:=tExternalsItem(current_module.Externals.first);
+ while assigned(hp)do
+ begin
+ if(assigned(hp.data))and(not hp.found)then
+ if hp.data^=StrPas(name)then
+ begin
+ isUsedFunction:=true;
+ hp.found:=true;
+ exit;
+ end;
+ hp:=tExternalsItem(hp.next);
+ end;
+ end;
+
+ procedure Store(index:cardinal;name:pchar;isData:longbool);
+ begin
+ if not isUsedFunction(name)then
+ exit;
+ if not(current_module.uses_imports) then
+ begin
+ current_module.uses_imports:=true;
+ importlib.preparelib(current_module.modulename^);
+ end;
+ if IsData then
+ timportlibwin32(importlib).importvariable_str(name,_n,name)
+ else
+ timportlibwin32(importlib).importprocedure_str(name,_n,index,name);
+ end;
+
+ procedure ProcessEdata;
+ type
+ a8=array[0..7]of char;
+ function GetSectionName(rva:cardinal;var Flags:cardinal):a8;
+ var
+ i:cardinal;
+ LocObjOfs:cardinal;
+ LocObj:TObjInfo;
+ begin
+ GetSectionName:='';
+ Flags:=0;
+ LocObjOfs:=APE_OptSize+HeaderOffset+24;
+ for i:=1 to APE_obj do
+ begin
+ seek(f,LocObjOfs);
+ blockread(f,LocObj,sizeof(LocObj));
+ if(rva>=LocObj.VirtAddr)and(rva<=LocObj.VirtAddr+LocObj.RawSize)then
+ begin
+ GetSectionName:=a8(LocObj.ObjName);
+ Flags:=LocObj.flags;
+ end;
+ end;
+ end;
+ var
+ j,Fl:cardinal;
+ ulongval,procEntry:cardinal;
+ Ordinal:word;
+ isData:longbool;
+ ExpDir:packed record
+ flag,
+ stamp:cardinal;
+ Major,
+ Minor:word;
+ Name,
+ Base,
+ NumFuncs,
+ NumNames,
+ AddrFuncs,
+ AddrNames,
+ AddrOrds:cardinal;
+ end;
+ begin
+ with Obj do
+ begin
+ seek(f,RawOffset+delta);
+ blockread(f,ExpDir,sizeof(ExpDir));
+ fsplit(impname,_d,_n,_e);
+ for j:=0 to pred(ExpDir.NumNames)do
+ begin
+{ Don't know why but this gives serious problems with overflow checking on }
+{$IFOPT Q+}
+{$DEFINE OVERFLOW_CHECK_WAS_ON}
+{$ENDIF}
+{$Q-}
+ seek(f,RawOffset-VirtAddr+ExpDir.AddrOrds+j*2);
+ blockread(f,Ordinal,2);
+ seek(f,RawOffset-VirtAddr+ExpDir.AddrFuncs+cardinal(Ordinal)*4);
+ blockread(f,ProcEntry,4);
+ seek(f,RawOffset-VirtAddr+ExpDir.AddrNames+j*4);
+ blockread(f,ulongval,4);
+ seek(f,RawOffset-VirtAddr+ulongval);
+ blockread(f,cstring,sizeof(cstring));
+ isData:=GetSectionName(procentry,Fl)='';
+{$IFDEF OVERFLOW_CHECK_WAS_ON}
+{$Q+}
+{$ENDIF}
+ if not isData then
+ isData:=Fl and IMAGE_SCN_CNT_CODE<>IMAGE_SCN_CNT_CODE;
+ Store(succ(Ordinal),cstring,isData);
+ end;
+ end;
+ end;
+ begin
+ GetEdata:=false;
+ seek(f,HeaderEntry+120);
+ blockread(f,ExportRVA,4);
+ seek(f,HeaderEntry+6);
+ blockread(f,APE_Obj,2);
+ seek(f,HeaderEntry+20);
+ blockread(f,APE_OptSize,2);
+ ObjOfs:=APE_OptSize+HeaderOffset+24;
+ for i:=1 to APE_obj do
+ begin
+ seek(f,ObjOfs);
+ blockread(f,Obj,sizeof(Obj));
+ inc(ObjOfs,sizeof(Obj));
+ with Obj do
+ if(VirtAddr<=ExportRva)and(ExportRva<VirtAddr+VirtSize)then
+ begin
+ delta:=ExportRva-VirtAddr;
+ ProcessEdata;
+ GetEdata:=true;
+ end;
+ end;
+ end;
+
+function tDLLScannerWin32.scan(const binname:string):longbool;
+ var
+ OldFileMode:longint;
+ hs,
+ foundimp : string;
+ begin
+ Scan:=false;
+ { is there already an import library the we will use that one }
+ if FindLibraryFile(binname,target_info.staticClibprefix,target_info.staticClibext,foundimp) then
+ exit;
+ { check if we can find the dll }
+ hs:=AddExtension(binname,target_info.sharedlibext);
+ if not FindDll(hs,impname) then
+ exit;
+ { read the dll file }
+ assign(f,impname);
+ OldFileMode:=filemode;
+ filemode:=0;
+ reset(f,1);
+ filemode:=OldFileMode;
+ if not DOSstubOK(HeaderOffset)then
+ scan:=false
+ else if not isSuitableFileType(HeaderOffset)then
+ scan:=false
+ else
+ scan:=GetEdata(HeaderOffset);
+ close(f);
+ end;
+
+
+{*****************************************************************************
+ Initialize
+*****************************************************************************}
+
+initialization
+{$ifdef i386}
+ RegisterExternalLinker(system_i386_win32_info,TLinkerWin32);
+ RegisterImport(system_i386_win32,TImportLibWin32);
+ RegisterExport(system_i386_win32,TExportLibWin32);
+ RegisterDLLScanner(system_i386_win32,TDLLScannerWin32);
+ RegisterRes(res_gnu_windres_info);
+ RegisterTarget(system_i386_win32_info);
+
+ RegisterExternalLinker(system_i386_wince_info,TLinkerWin32);
+ RegisterImport(system_i386_wince,TImportLibWin32);
+ RegisterExport(system_i386_wince,TExportLibWin32);
+ RegisterDLLScanner(system_i386_wince,TDLLScannerWin32);
+ RegisterTarget(system_i386_wince_info);
+{$endif i386}
+{$ifdef x86_64}
+ RegisterExternalLinker(system_x64_win64_info,TLinkerWin32);
+ RegisterImport(system_x86_64_win64,TImportLibWin32);
+ RegisterExport(system_x86_64_win64,TExportLibWin32);
+ RegisterDLLScanner(system_x86_64_win64,TDLLScannerWin32);
+ RegisterRes(res_gnu_windres_info);
+ RegisterTarget(system_x64_win64_info);
+{$endif x86_64}
+{$ifdef arm}
+ RegisterExternalLinker(system_arm_wince_info,TLinkerWin32);
+ RegisterImport(system_arm_wince,TImportLibWin32);
+ RegisterExport(system_arm_wince,TExportLibWin32);
+ RegisterRes(res_gnu_wince_windres_info);
+ RegisterTarget(system_arm_wince_info);
+{$endif arm}
+end.