summaryrefslogtreecommitdiff
path: root/compiler/systems
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/systems')
-rw-r--r--compiler/systems/i_nwm.pas10
-rw-r--r--compiler/systems/i_wii.pas2
-rw-r--r--compiler/systems/t_embed.pas2
-rw-r--r--compiler/systems/t_nwm.pas437
-rw-r--r--compiler/systems/t_wii.pas3
5 files changed, 440 insertions, 14 deletions
diff --git a/compiler/systems/i_nwm.pas b/compiler/systems/i_nwm.pas
index 8d729bf88c..307f2fee8f 100644
--- a/compiler/systems/i_nwm.pas
+++ b/compiler/systems/i_nwm.pas
@@ -34,7 +34,7 @@ unit i_nwm;
system : system_i386_netware;
name : 'Netware for i386(clib)';
shortname : 'Netware';
- flags : [tf_smartlink_library];
+ flags : [tf_smartlink_library,tf_smartlink_sections,tf_dwarf_only_local_labels];
cpu : cpu_i386;
unit_env : 'NETWAREUNITS';
extradefines : 'NETWARE_CLIB';
@@ -50,18 +50,18 @@ unit i_nwm;
resobjext : '.or';
sharedlibext : '.nlm';
staticlibext : '.a';
- staticlibprefix : '';
+ staticlibprefix : 'libp';
sharedlibprefix : '';
sharedClibext : '.nlm';
staticClibext : '.a';
- staticClibprefix : '';
+ staticClibprefix : 'lib';
sharedClibprefix : '';
- importlibprefix : 'imp';
+ importlibprefix : 'libimp';
importlibext : '.a';
Cprefix : '';
newline : #13#10;
dirsep : '/';
- assem : as_i386_elf32;
+ assem : as_i386_nlmcoff; // as_i386_elf32;
assemextern : as_gas;
link : nil;
linkextern : nil;
diff --git a/compiler/systems/i_wii.pas b/compiler/systems/i_wii.pas
index 848480bf64..c9c7a8c1cd 100644
--- a/compiler/systems/i_wii.pas
+++ b/compiler/systems/i_wii.pas
@@ -86,7 +86,7 @@ unit i_wii;
maxCrecordalign : 8
);
first_parm_offset : 8;
- stacksize : 32*1024*1024;
+ stacksize : 131072; // 128 kb
abi : abi_powerpc_sysv;
);
diff --git a/compiler/systems/t_embed.pas b/compiler/systems/t_embed.pas
index 7a7fd67a53..a1a2c52fb5 100644
--- a/compiler/systems/t_embed.pas
+++ b/compiler/systems/t_embed.pas
@@ -267,7 +267,7 @@ begin
Add('{');
Add(' .text :');
Add(' {');
- Add(' *(.init, .init.*)');
+ Add(' KEEP(*(.init, .init.*))');
Add(' *(.text, .text.*)');
Add(' *(.strings)');
Add(' *(.rodata, .rodata.*)');
diff --git a/compiler/systems/t_nwm.pas b/compiler/systems/t_nwm.pas
index a371343f02..f85619df5b 100644
--- a/compiler/systems/t_nwm.pas
+++ b/compiler/systems/t_nwm.pas
@@ -97,7 +97,7 @@ implementation
verbose,systems,globtype,globals,
symconst,script,
fmodule,aasmbase,aasmtai,aasmdata,aasmcpu,cpubase,symsym,symdef,
- import,export,link,i_nwm,ogbase
+ import,export,link,i_nwm,ogbase, ogcoff, ognlm, cclasses
{$ifdef netware} ,dos {$endif}
;
@@ -123,6 +123,16 @@ implementation
function MakeExecutable:boolean;override;
end;
+ TInternalLinkerNetware = class(TInternalLinker)
+ prelude : string;
+ constructor create;override;
+ destructor destroy;override;
+ procedure DefaultLinkScript;override;
+ procedure InitSysInitUnitName;override;
+ procedure ConcatEntryName; virtual;
+ Function MakeSharedLibrary:boolean;override;
+ end;
+
Const tmpLinkFileName = 'link~tmp._o_';
minStackSize = 32768;
@@ -330,10 +340,26 @@ begin
{ add objectfiles, start with nwpre always }
LinkRes.Add ('INPUT(');
- s2 := FindObjectFile('nwpre','',false);
+ if target_info.system = system_i386_netwlibc then
+ begin
+ s2 := FindObjectFile('nwplibc','',false);
+ if s2 = '' then
+ s2 := FindObjectFile('libcpre.gcc','',false);
+ end else
+ s2 := FindObjectFile('nwpre','',false);
Comment (V_Debug,'adding Object File '+s2);
{$ifndef netware} LinkRes.Add (s2); {$else} LinkRes.Add (FExpand(s2)); {$endif}
+ if target_info.system = system_i386_netwlibc then
+ begin
+ 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}
+ end;
+
{ main objectfiles, add to linker input }
while not ObjectFiles.Empty do
begin
@@ -355,9 +381,20 @@ begin
{$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 target_info.system = system_i386_netwlibc then
+ begin
+ NLMConvLinkFile.Add ('START _LibCPrelude');
+ NLMConvLinkFile.Add ('EXIT _LibCPostlude');
+ NLMConvLinkFile.Add ('CHECK _LibCCheckUnload');
+ NLMConvLinkFile.Add ('REENTRANT'); { needed by older libc versions }
+ end else
+ begin
+ NLMConvLinkFile.Add ('START _Prelude'); { defined in rtl/netware/nwpre.as }
+ NLMConvLinkFile.Add ('EXIT _Stop'); { nwpre.as }
+ NLMConvLinkFile.Add ('CHECK FPC_NW_CHECKFUNCTION'); { system.pp }
+ end;
+
if not (cs_link_strip in current_settings.globalswitches) then
begin
@@ -549,6 +586,395 @@ begin
end;
+{****************************************************************************
+ TInternalLinkerNetware
+****************************************************************************}
+
+ constructor TInternalLinkerNetware.Create;
+ begin
+ inherited Create;
+ CExeoutput:=TNLMexeoutput;
+ CObjInput:=TNLMCoffObjInput;
+ nlmSpecialSymbols_Segments := TFPHashList.create;
+ end;
+
+ destructor TInternalLinkerNetware.destroy;
+ begin
+ if assigned(nlmSpecialSymbols_Segments) then
+ begin
+ nlmSpecialSymbols_Segments.Free;
+ nlmSpecialSymbols_Segments := nil;
+ end;
+ inherited destroy;
+ end;
+
+ procedure TInternalLinkerNetware.DefaultLinkScript;
+ var
+ s,s2 : TCmdStr;
+ secname,
+ secnames : string;
+ hasCopyright,
+ hasScreenname,
+ hasThreadname,
+ hasVersion,
+ hasDescription,
+ hasStacksize: boolean;
+ t : text;
+
+
+
+ procedure addLinkerOption(s : string);
+ var op : string;
+ begin
+ if s = '' then exit;
+ if s[1] = '#' then exit;
+ LinkScript.Concat(s);
+ op := upper(GetToken(s,' '));
+ {check for options via -k that can also be specified vie
+ compiler directives in source, -k options will override
+ options in source}
+ if op = 'COPYRIGHT' then hasCopyright := true else
+ if op = 'SCREENNAME' then hasScreenname := true else
+ if op = 'THREADNAME' then hasThreadname := true else
+ if op = 'VERSION' then hasVersion := true else
+ if op = 'DESCRIPTION' then hasDescription := true else
+ if (op = 'STACK') or (op = 'STACKSIZE') then hasStacksize := true;
+ end;
+
+ { add linker scropt specified by -k@FileName }
+ procedure addLinkerOptionsFile (fileName : string);
+ var
+ t : text;
+ option : string;
+ fn : TCmdStr;
+ begin
+ fn := fileName;
+ if not sysutils.fileExists(fn) then
+ if not includesearchpath.FindFile(fileName,true,fn) then
+ begin
+ comment(v_error,'linker options file "'+fileName+'" not found');
+ exit;
+ end;
+ assign(t,fn); reset(t);
+ while not eof(t) do
+ begin
+ readln(t,option);
+ addLinkerOption(option);
+ end;
+ close(t);
+ end;
+
+ { add linker options specified by command line parameter -k }
+ procedure addLinkerOptions;
+ var
+ s,option : string;
+ p : integer;
+ begin
+ s := ParaLinkOptions;
+ option := GetToken(s,';');
+ while option <> '' do
+ begin
+ if copy(option,1,1)='@' then
+ begin
+ delete(option,1,1);
+ addLinkerOptionsFile(option);
+ end else
+ addLinkerOption(option);
+ option := GetToken(s,';');
+ end;
+ end;
+
+ { default: nwpre but can be specified via linker options
+ bacuse this has to be the first object, we have to scan
+ linker options before adding other options }
+
+ function findPreludeInFile (fileName : string):string;
+ var
+ t : text;
+ option,s : string;
+ fn : TCmdStr;
+ begin
+ result := '';
+ fn := fileName;
+ if not sysutils.fileExists(fn) then
+ if not includesearchpath.FindFile(fileName,true,fn) then
+ begin
+ comment(v_error,'linker options file "'+fileName+'" not found');
+ exit;
+ end;
+ assign(t,fn); reset(t);
+ while not eof(t) do
+ begin
+ readln(t,option);
+ option := upper(GetToken(s,' '));
+ if option='PRELUDE' then
+ begin
+ result := getToken(s,' ');
+ close(t);
+ exit;
+ end;
+ end;
+ close(t);
+ end;
+
+ function findPrelude : string;
+ var
+ s,option,keyword : string;
+ p : integer;
+ begin
+ s := ParaLinkOptions;
+ option := GetToken(s,';');
+ while option <> '' do
+ begin
+ if copy(option,1,1)='@' then
+ begin
+ delete(option,1,1);
+ result := findPreludeInFile(option);
+ if result <> '' then exit;
+ end else
+ begin
+ keyword := GetToken(option,' ');
+ if keyword = 'PRELUDE' then
+ begin
+ result := GetToken(option,' ');
+ exit;
+ end;
+ end;
+ option := GetToken(s,';');
+ end;
+ if target_info.system = system_i386_netwlibc then
+ result := 'libcpre'
+ else
+ result := 'nwpre';
+ end;
+
+ begin
+ with LinkScript do
+ begin
+ prelude := findPrelude; // needs to be first object, can be specified by -k"PRELUDE ObjFileName"
+ if prelude = '' then internalerror(201103271);
+ if pos ('.',prelude) = 0 then prelude := prelude + '.o';
+ s2 := FindObjectFile(prelude,'',false);
+ Comment (V_Debug,'adding init Object File '+s2);
+ Concat('READOBJECT '+MaybeQuoted(s2));
+ while not ObjectFiles.Empty do
+ begin
+ s:=ObjectFiles.GetFirst;
+ if s<>'' then
+ begin
+ Concat('READOBJECT '+MaybeQuoted(s));
+ Comment (V_Debug,'adding Object File '+s);
+ end;
+ end;
+ while not StaticLibFiles.Empty do
+ begin
+ s:=StaticLibFiles.GetFirst;
+ if s<>'' then
+ begin
+ Comment (V_Debug,'adding StaticLibFile '+s);
+ Concat('READSTATICLIBRARY '+MaybeQuoted(s));
+ end;
+ end;
+ { While not SharedLibFiles.Empty do
+ begin
+ S:=SharedLibFiles.GetFirst;
+ if FindLibraryFile(s,target_info.staticClibprefix,target_info.importlibext,s2) then
+ begin
+ Comment (V_Debug,'adding LibraryFile '+s);
+ Concat('READSTATICLIBRARY '+MaybeQuoted(s2));
+ end else
+ Comment(V_Error,'Import library not found for '+S);
+ end;}
+ if IsSharedLibrary then
+ Concat('ISSHAREDLIBRARY');
+ ConcatEntryName;
+ Concat('IMAGEBASE $' + hexStr(0, SizeOf(imagebase)*2));
+ Concat('HEADER');
+ Concat('EXESECTION .text');
+ Concat(' SYMBOL __text_start__'); nlmSpecialSymbols_Segments.Add('__text_start__',pointer(ptruint(Section_text)));
+ Concat(' OBJSECTION .text*');
+ Concat(' SYMBOL ___CTOR_LIST__'); nlmSpecialSymbols_Segments.Add('___CTOR_LIST__',pointer(ptruint(Section_text)));
+ Concat(' SYMBOL __CTOR_LIST__'); nlmSpecialSymbols_Segments.Add('__CTOR_LIST__',pointer(ptruint(Section_text)));
+ Concat(' LONG -1');
+ Concat(' OBJSECTION .ctor*');
+ Concat(' LONG 0');
+ Concat(' SYMBOL ___DTOR_LIST__'); nlmSpecialSymbols_Segments.Add('___DTOR_LIST__',pointer(ptruint(Section_text)));
+ Concat(' SYMBOL __DTOR_LIST__'); nlmSpecialSymbols_Segments.Add('__DTOR_LIST__',pointer(ptruint(Section_text)));
+ Concat(' LONG -1');
+ Concat(' OBJSECTION .dtor*');
+ Concat(' LONG 0');
+ Concat(' SYMBOL etext'); nlmSpecialSymbols_Segments.Add('etext',pointer(ptruint(Section_text)));
+ Concat('ENDEXESECTION');
+
+ Concat('EXESECTION .data');
+ Concat(' SYMBOL __data_start__'); nlmSpecialSymbols_Segments.Add('__data_start__',pointer(ptruint(Section_data)));
+ Concat(' OBJSECTION .data*');
+ Concat(' OBJSECTION .fpc*');
+ Concat(' SYMBOL edata'); nlmSpecialSymbols_Segments.Add('edata',pointer(ptruint(Section_data)));
+ Concat(' SYMBOL __data_end__'); nlmSpecialSymbols_Segments.Add('__data_end__',pointer(ptruint(Section_data)));
+ Concat('ENDEXESECTION');
+
+ Concat('EXESECTION .bss');
+ Concat(' SYMBOL __bss_start__'); nlmSpecialSymbols_Segments.Add('__bss_start__',pointer(ptruint(Section_data)));
+ Concat(' OBJSECTION .bss*');
+ Concat(' SYMBOL __bss_end__'); nlmSpecialSymbols_Segments.Add('__bss_end__',pointer(ptruint(Section_data)));
+ Concat('ENDEXESECTION');
+
+ Concat('EXESECTION .imports');
+ Concat(' SYMBOL __imports_start__');
+ Concat(' OBJSECTION .imports*');
+ Concat(' SYMBOL __imports_end__');
+ Concat('ENDEXESECTION');
+
+ Concat('EXESECTION .modules');
+ Concat(' SYMBOL __modules_start__');
+ Concat(' OBJSECTION .modules*');
+ Concat(' SYMBOL __modules_end__');
+ Concat('ENDEXESECTION');
+
+ Concat('EXESECTION .exports');
+ Concat(' SYMBOL __exports_start__');
+ Concat(' OBJSECTION .exports*');
+ Concat(' SYMBOL __exports_end__');
+ Concat('ENDEXESECTION');
+
+ Concat('EXESECTION .reloc');
+ Concat(' SYMBOL __reloc_start__');
+ Concat(' OBJSECTION .reloc*');
+ Concat(' SYMBOL __reloc_end__');
+ Concat('ENDEXESECTION');
+
+ Concat('EXESECTION .xdc');
+ Concat(' OBJSECTION .xdc*');
+ Concat('ENDEXESECTION');
+
+ Concat('EXESECTION .custom');
+ Concat(' OBJSECTION .custom*');
+ Concat('ENDEXESECTION');
+
+ Concat('EXESECTION .messages');
+ Concat(' OBJSECTION .messages*');
+ Concat('ENDEXESECTION');
+
+ Concat('EXESECTION .help');
+ Concat(' OBJSECTION .help*');
+ Concat('ENDEXESECTION');
+
+ Concat('EXESECTION .rdata');
+ Concat(' SYMBOL ___RUNTIME_PSEUDO_RELOC_LIST__');
+ Concat(' SYMBOL __RUNTIME_PSEUDO_RELOC_LIST__');
+ Concat(' OBJSECTION .rdata_runtime_pseudo_reloc');
+ Concat(' SYMBOL ___RUNTIME_PSEUDO_RELOC_LIST_END__');
+ Concat(' SYMBOL __RUNTIME_PSEUDO_RELOC_LIST_END__');
+ Concat(' OBJSECTION .rdata*');
+ Concat(' OBJSECTION .rodata*');
+ Concat('ENDEXESECTION');
+ Concat('EXESECTION .pdata');
+ Concat(' OBJSECTION .pdata');
+ Concat('ENDEXESECTION');
+ secnames:='.edata,.rsrc,.gnu_debuglink,'+
+ '.debug_aranges,.debug_pubnames,.debug_info,.debug_abbrev,.debug_line,.debug_frame,.debug_str,.debug_loc,'+
+ '.debug_macinfo,.debug_weaknames,.debug_funcnames,.debug_typenames,.debug_varnames,.debug_ranges';
+ repeat
+ secname:=gettoken(secnames,',');
+ if secname='' then
+ break;
+ Concat('EXESECTION '+secname);
+ Concat(' OBJSECTION '+secname+'*');
+ Concat('ENDEXESECTION');
+ until false;
+ { Can't use the generic rules, because that will add also .stabstr to .stab }
+ Concat('EXESECTION .stab');
+ Concat(' OBJSECTION .stab');
+ Concat('ENDEXESECTION');
+ Concat('EXESECTION .stabstr');
+ Concat(' OBJSECTION .stabstr');
+ Concat('ENDEXESECTION');
+ Concat('STABS');
+ Concat('SYMBOLS');
+ Concat('');
+
+ hasCopyright := false;
+ hasScreenname := false;
+ hasThreadname := false;
+ hasVersion := false;
+ hasDescription := false;
+ hasStacksize := false;
+ addLinkerOptions;
+ if not hasCopyright then
+ if nwcopyright <> '' then
+ Concat('COPYRIGHT "'+nwCopyright+'"');
+ if not hasScreenname then
+ if nwscreenname <> '' then
+ Concat('SCREENNAME "'+nwscreenname+'"');
+ if not hasThreadname then
+ if nwthreadname <> '' then
+ Concat('THREADNAME "'+nwthreadname+'"');
+ if not hasVersion then
+ Concat('VERSION '+tostr(dllmajor)+' '+tostr(dllminor)+' '+tostr(dllrevision));
+ if not hasDescription then
+ if description <> '' then
+ Concat ('DESCRIPTION "'+description+'"');
+ if not hasStacksize then
+ if MaxStackSizeSetExplicity then
+ begin
+ if stacksize < minStackSize then stacksize := minStackSize;
+ Concat ('STACKSIZE '+tostr(stacksize));
+ end else
+ Concat ('STACKSIZE '+tostr(minStackSize));
+ if target_info.system = system_i386_netwlibc then
+ Concat ('REENTRANT'); { needed by older libc versions }
+ end;
+
+ // add symbols needed by nwpre. We have not loaded the ppu,
+ // therefore we do not know the externals so read it from nwpre.imp
+ s := ChangeFileExt(prelude,'.imp'); // nwpre.imp
+ if not librarysearchpath.FindFile(s,true,s2) then
+ begin
+ comment(v_error,s+' not found');
+ exit;
+ end;
+ assign(t,s2); reset(t);
+ while not eof(t) do
+ begin
+ readln(t,s);
+ s := trimspace(s);
+ if (length(s) > 0) then
+ if copy(s,1,1) <> '#' then
+ AddImportSymbol('!clib',s,0,false);
+ end;
+ close(t);
+ end;
+
+
+ procedure TInternalLinkerNetware.InitSysInitUnitName;
+ begin
+ //if target_info.system=system_i386_netware then
+ // GlobalInitSysInitUnitName(self);
+ end;
+
+ procedure TInternalLinkerNetware.ConcatEntryName;
+ begin
+ with LinkScript do
+ begin
+ if IsSharedLibrary then
+ begin
+ Concat('ISSHAREDLIBRARY');
+ Concat('ENTRYNAME _Prelude')
+ end
+ else
+ begin
+ Concat('ENTRYNAME _Prelude')
+ end;
+ end;
+ end;
+
+
+ Function TInternalLinkerNetware.MakeSharedLibrary:boolean;
+ begin
+ Comment(V_Error,'Make shared library not supported for netware');
+ end;
+
{*****************************************************************************
Initialize
*****************************************************************************}
@@ -556,6 +982,7 @@ end;
initialization
RegisterExternalLinker(system_i386_netware_info,TLinkerNetware);
+ RegisterInternalLinker(system_i386_netware_info,TInternalLinkerNetware);
RegisterImport(system_i386_netware,TImportLibNetware);
RegisterExport(system_i386_netware,TExportLibNetware);
RegisterTarget(system_i386_netware_info);
diff --git a/compiler/systems/t_wii.pas b/compiler/systems/t_wii.pas
index ee0764bacc..485eb5bc89 100644
--- a/compiler/systems/t_wii.pas
+++ b/compiler/systems/t_wii.pas
@@ -562,9 +562,8 @@ begin
{ Call linker }
SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
- Replace(cmdstr,'$OPT',Info.ExtraOptions);
-
Replace(cmdstr,'$EXE',(maybequoted(ScriptFixFileName(ChangeFileExt(current_module.exefilename^,'.elf')))));
+ Replace(cmdstr,'$OPT',Info.ExtraOptions);
Replace(cmdstr,'$RES',(maybequoted(ScriptFixFileName(outputexedir+Info.ResName))));
Replace(cmdstr,'$STATIC',StaticStr);
Replace(cmdstr,'$STRIP',StripStr);