mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 22:29:24 +02:00
added a segment table containing segments for symbols defined by linker script (needed for relocs)
git-svn-id: trunk@17268 -
This commit is contained in:
parent
841357c66e
commit
672d76e636
@ -289,7 +289,12 @@ const NLM_MAX_DESCRIPTION_LENGTH = 127;
|
||||
procedure ParseScript (linkscript:TCmdStrList); override;
|
||||
end;
|
||||
|
||||
|
||||
var
|
||||
{for symbols defined in linker script. To generate a fixup we
|
||||
need to know the segment (.text,.bss or .code) of the symbol
|
||||
Pointer in list is used as TsecType
|
||||
Filled by TInternalLinkerNetware.DefaultLinkScript }
|
||||
nlmSpecialSymbols_Segments : TFPHashList;
|
||||
|
||||
type
|
||||
|
||||
@ -346,10 +351,19 @@ type
|
||||
|
||||
function SectionType (aName : string) : TSecType;
|
||||
var s : string;
|
||||
seg: ptruint;
|
||||
begin
|
||||
s := copy(aName,1,5);
|
||||
if s = '.text' then result := Section_text else
|
||||
if (s = '.data') or (copy(s,1,4)='.bss') then result := Section_data else
|
||||
if s[1] <> '.' then
|
||||
begin
|
||||
seg := ptruint(nlmSpecialSymbols_Segments.Find(aName));
|
||||
if seg <> 0 then
|
||||
result := TSecType(seg)
|
||||
else
|
||||
result := Section_other;
|
||||
end else
|
||||
result := Section_other;
|
||||
end;
|
||||
|
||||
@ -514,7 +528,8 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
|
||||
procedure TNLMexeoutput.ExeSectionList_write_Data(p:TObject;arg:pointer);
|
||||
var
|
||||
objsec : TObjSection;
|
||||
i : longint;
|
||||
i,j : longint;
|
||||
b : byte;
|
||||
begin
|
||||
|
||||
with texesection(p) do
|
||||
@ -535,7 +550,8 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
|
||||
if oso_data in objsec.secoptions then
|
||||
begin
|
||||
if assigned(exemap) then
|
||||
exemap.Add(' nlm file offset $'+hexstr(objsec.DataPos,8)+': '+objsec.name);
|
||||
if objsec.data.size > 0 then
|
||||
exemap.Add(' 0x'+hexstr(objsec.DataPos,8)+': '+objsec.name);
|
||||
//writeln (' ',objsec.name,' size:',objsec.size,' relocs:',objsec.ObjRelocations.count,' DataPos:',objsec.DataPos,' MemPos:',objsec.MemPos);
|
||||
{for j := 0 to objsec.ObjRelocations.count-1 do
|
||||
begin
|
||||
@ -550,7 +566,14 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
|
||||
end;}
|
||||
if not assigned(objsec.data) then
|
||||
internalerror(200603042);
|
||||
FWriter.writezeros(objsec.dataalignbytes);
|
||||
if copy (objsec.Name,1,5) = '.text' then
|
||||
begin // write NOP's instead of zero's for .text, makes disassemble possible
|
||||
b := $90; // NOP
|
||||
if objsec.DataAlignBytes > 0 then
|
||||
for j := 1 to objsec.DataAlignBytes do
|
||||
FWriter.write(b,1);
|
||||
end else
|
||||
FWriter.writezeros(objsec.dataalignbytes);
|
||||
//if objsec.dataalignbytes>0 then
|
||||
// writeln (' ',name,' alignbytes: ',objsec.dataalignbytes);
|
||||
if objsec.DataPos<>FWriter.Size then
|
||||
@ -874,6 +897,11 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
|
||||
if FWriter.Size<>totalheadersize+ExeSecsListSize+headerAlignBytes then
|
||||
internalerror(201103062);
|
||||
{ Section data }
|
||||
if assigned(exemap) then
|
||||
begin
|
||||
exemap.Add('');
|
||||
exemap.Add('NLM file offsets:');
|
||||
end;
|
||||
ExeSectionList.ForEachCall(@ExeSectionList_write_data,nil);
|
||||
|
||||
if hassymbols then
|
||||
@ -1046,7 +1074,8 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
|
||||
|
||||
k := objsec.MemPos + objreloc.DataOffset;
|
||||
k := k or $40000000;
|
||||
// TODO: data|code
|
||||
// TODO: data|code if we support importing data symbols
|
||||
// i do not know if this is possible with netware
|
||||
internalobjdata.writebytes(k,sizeof(k)); // address
|
||||
|
||||
// the netware loader requires an offset at the import address
|
||||
@ -1169,8 +1198,11 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
|
||||
targetSectionName := '';
|
||||
if objreloc.symbol <> nil then
|
||||
begin
|
||||
//writeln (' MemPos',objsec.MemPos,' dataOfs:',objreloc.dataoffset,' ',objsec.name,' objreloc.symbol: ',objreloc.symbol.name,' objreloc.symbol.objsection.name: ',objreloc.symbol.objsection.name,' ',objreloc.symbol.Typ,' ',objreloc.symbol.bind,' ',objreloc.Typ);
|
||||
targetSectionName := copy(objreloc.symbol.objsection.name,1,5);
|
||||
// writeln (' MemPos',objsec.MemPos,' dataOfs:',objreloc.dataoffset,' ',objsec.name,' objreloc.symbol: ',objreloc.symbol.name,' objreloc.symbol.objsection.name: ',objreloc.symbol.objsection.name,' ',objreloc.symbol.Typ,' ',objreloc.symbol.bind,' ',objreloc.Typ);
|
||||
if objreloc.symbol.objsection.name[1] <> '.' then
|
||||
targetSectionName := objreloc.symbol.name // specials like __bss_start__
|
||||
else // dont use objsection.name because it begins with *
|
||||
targetSectionName := copy(objreloc.symbol.objsection.name,1,5); // all others begin with .segment, we only have to check for .text, .data or .bss
|
||||
end else
|
||||
internalerror(2011030603);
|
||||
|
||||
|
@ -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, ogcoff, ognlm
|
||||
import,export,link,i_nwm,ogbase, ogcoff, ognlm, cclasses
|
||||
{$ifdef netware} ,dos {$endif}
|
||||
;
|
||||
|
||||
@ -126,6 +126,7 @@ implementation
|
||||
TInternalLinkerNetware = class(TInternalLinker)
|
||||
prelude : string;
|
||||
constructor create;override;
|
||||
destructor destroy;override;
|
||||
procedure DefaultLinkScript;override;
|
||||
procedure InitSysInitUnitName;override;
|
||||
procedure ConcatEntryName; virtual;
|
||||
@ -339,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
|
||||
@ -364,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
|
||||
@ -567,8 +595,18 @@ end;
|
||||
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
|
||||
@ -704,7 +742,10 @@ end;
|
||||
end;
|
||||
option := GetToken(s,';');
|
||||
end;
|
||||
result := 'nwpre';
|
||||
if target_info.system = system_i386_netwlibc then
|
||||
result := 'libcpre'
|
||||
else
|
||||
result := 'nwpre';
|
||||
end;
|
||||
|
||||
begin
|
||||
@ -750,32 +791,33 @@ end;
|
||||
Concat('IMAGEBASE $' + hexStr(0, SizeOf(imagebase)*2));
|
||||
Concat('HEADER');
|
||||
Concat('EXESECTION .text');
|
||||
Concat(' SYMBOL __text_start__');
|
||||
Concat(' SYMBOL __text_start__'); nlmSpecialSymbols_Segments.Add('__text_start__',pointer(ptruint(Section_text)));
|
||||
Concat(' OBJSECTION .text*');
|
||||
Concat(' SYMBOL ___CTOR_LIST__');
|
||||
Concat(' SYMBOL __CTOR_LIST__');
|
||||
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__');
|
||||
Concat(' SYMBOL __DTOR_LIST__');
|
||||
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');
|
||||
Concat(' SYMBOL etext'); nlmSpecialSymbols_Segments.Add('etext',pointer(ptruint(Section_text)));
|
||||
Concat('ENDEXESECTION');
|
||||
|
||||
Concat('EXESECTION .data');
|
||||
Concat(' SYMBOL __data_start__');
|
||||
Concat(' SYMBOL __data_start__'); nlmSpecialSymbols_Segments.Add('__data_start__',pointer(ptruint(Section_data)));
|
||||
Concat(' OBJSECTION .data*');
|
||||
Concat(' OBJSECTION .fpc*');
|
||||
Concat(' SYMBOL edata');
|
||||
Concat(' SYMBOL __data_end__');
|
||||
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__');
|
||||
Concat(' SYMBOL __bss_start__'); nlmSpecialSymbols_Segments.Add('__bss_start__',pointer(ptruint(Section_data)));
|
||||
Concat(' OBJSECTION .bss*');
|
||||
Concat(' SYMBOL __bss_end__');
|
||||
Concat(' SYMBOL __bss_end__'); nlmSpecialSymbols_Segments.Add('__bss_end__',pointer(ptruint(Section_data)));
|
||||
Concat('ENDEXESECTION');
|
||||
|
||||
Concat('EXESECTION .imports');
|
||||
@ -880,6 +922,8 @@ end;
|
||||
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,
|
||||
|
Loading…
Reference in New Issue
Block a user