diff options
Diffstat (limited to 'compiler/systems')
-rw-r--r-- | compiler/systems/i_nwm.pas | 10 | ||||
-rw-r--r-- | compiler/systems/i_wii.pas | 2 | ||||
-rw-r--r-- | compiler/systems/t_embed.pas | 2 | ||||
-rw-r--r-- | compiler/systems/t_nwm.pas | 437 | ||||
-rw-r--r-- | compiler/systems/t_wii.pas | 3 |
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); |