mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 10:26:05 +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;
|
procedure ParseScript (linkscript:TCmdStrList); override;
|
||||||
end;
|
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
|
type
|
||||||
|
|
||||||
@ -346,10 +351,19 @@ type
|
|||||||
|
|
||||||
function SectionType (aName : string) : TSecType;
|
function SectionType (aName : string) : TSecType;
|
||||||
var s : string;
|
var s : string;
|
||||||
|
seg: ptruint;
|
||||||
begin
|
begin
|
||||||
s := copy(aName,1,5);
|
s := copy(aName,1,5);
|
||||||
if s = '.text' then result := Section_text else
|
if s = '.text' then result := Section_text else
|
||||||
if (s = '.data') or (copy(s,1,4)='.bss') then result := Section_data 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;
|
result := Section_other;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -514,7 +528,8 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
|
|||||||
procedure TNLMexeoutput.ExeSectionList_write_Data(p:TObject;arg:pointer);
|
procedure TNLMexeoutput.ExeSectionList_write_Data(p:TObject;arg:pointer);
|
||||||
var
|
var
|
||||||
objsec : TObjSection;
|
objsec : TObjSection;
|
||||||
i : longint;
|
i,j : longint;
|
||||||
|
b : byte;
|
||||||
begin
|
begin
|
||||||
|
|
||||||
with texesection(p) do
|
with texesection(p) do
|
||||||
@ -535,7 +550,8 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
|
|||||||
if oso_data in objsec.secoptions then
|
if oso_data in objsec.secoptions then
|
||||||
begin
|
begin
|
||||||
if assigned(exemap) then
|
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);
|
//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
|
{for j := 0 to objsec.ObjRelocations.count-1 do
|
||||||
begin
|
begin
|
||||||
@ -550,7 +566,14 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
|
|||||||
end;}
|
end;}
|
||||||
if not assigned(objsec.data) then
|
if not assigned(objsec.data) then
|
||||||
internalerror(200603042);
|
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
|
//if objsec.dataalignbytes>0 then
|
||||||
// writeln (' ',name,' alignbytes: ',objsec.dataalignbytes);
|
// writeln (' ',name,' alignbytes: ',objsec.dataalignbytes);
|
||||||
if objsec.DataPos<>FWriter.Size then
|
if objsec.DataPos<>FWriter.Size then
|
||||||
@ -874,6 +897,11 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
|
|||||||
if FWriter.Size<>totalheadersize+ExeSecsListSize+headerAlignBytes then
|
if FWriter.Size<>totalheadersize+ExeSecsListSize+headerAlignBytes then
|
||||||
internalerror(201103062);
|
internalerror(201103062);
|
||||||
{ Section data }
|
{ Section data }
|
||||||
|
if assigned(exemap) then
|
||||||
|
begin
|
||||||
|
exemap.Add('');
|
||||||
|
exemap.Add('NLM file offsets:');
|
||||||
|
end;
|
||||||
ExeSectionList.ForEachCall(@ExeSectionList_write_data,nil);
|
ExeSectionList.ForEachCall(@ExeSectionList_write_data,nil);
|
||||||
|
|
||||||
if hassymbols then
|
if hassymbols then
|
||||||
@ -1046,7 +1074,8 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
|
|||||||
|
|
||||||
k := objsec.MemPos + objreloc.DataOffset;
|
k := objsec.MemPos + objreloc.DataOffset;
|
||||||
k := k or $40000000;
|
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
|
internalobjdata.writebytes(k,sizeof(k)); // address
|
||||||
|
|
||||||
// the netware loader requires an offset at the import address
|
// the netware loader requires an offset at the import address
|
||||||
@ -1169,8 +1198,11 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
|
|||||||
targetSectionName := '';
|
targetSectionName := '';
|
||||||
if objreloc.symbol <> nil then
|
if objreloc.symbol <> nil then
|
||||||
begin
|
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);
|
// 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);
|
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
|
end else
|
||||||
internalerror(2011030603);
|
internalerror(2011030603);
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ implementation
|
|||||||
verbose,systems,globtype,globals,
|
verbose,systems,globtype,globals,
|
||||||
symconst,script,
|
symconst,script,
|
||||||
fmodule,aasmbase,aasmtai,aasmdata,aasmcpu,cpubase,symsym,symdef,
|
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}
|
{$ifdef netware} ,dos {$endif}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -126,6 +126,7 @@ implementation
|
|||||||
TInternalLinkerNetware = class(TInternalLinker)
|
TInternalLinkerNetware = class(TInternalLinker)
|
||||||
prelude : string;
|
prelude : string;
|
||||||
constructor create;override;
|
constructor create;override;
|
||||||
|
destructor destroy;override;
|
||||||
procedure DefaultLinkScript;override;
|
procedure DefaultLinkScript;override;
|
||||||
procedure InitSysInitUnitName;override;
|
procedure InitSysInitUnitName;override;
|
||||||
procedure ConcatEntryName; virtual;
|
procedure ConcatEntryName; virtual;
|
||||||
@ -339,10 +340,26 @@ begin
|
|||||||
|
|
||||||
{ add objectfiles, start with nwpre always }
|
{ add objectfiles, start with nwpre always }
|
||||||
LinkRes.Add ('INPUT(');
|
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);
|
Comment (V_Debug,'adding Object File '+s2);
|
||||||
{$ifndef netware} LinkRes.Add (s2); {$else} LinkRes.Add (FExpand(s2)); {$endif}
|
{$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 }
|
{ main objectfiles, add to linker input }
|
||||||
while not ObjectFiles.Empty do
|
while not ObjectFiles.Empty do
|
||||||
begin
|
begin
|
||||||
@ -364,9 +381,20 @@ begin
|
|||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
{ start and stop-procedures }
|
{ start and stop-procedures }
|
||||||
NLMConvLinkFile.Add ('START _Prelude'); { defined in rtl/netware/nwpre.as }
|
|
||||||
NLMConvLinkFile.Add ('EXIT _Stop'); { nwpre.as }
|
if target_info.system = system_i386_netwlibc then
|
||||||
NLMConvLinkFile.Add ('CHECK FPC_NW_CHECKFUNCTION'); { system.pp }
|
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
|
if not (cs_link_strip in current_settings.globalswitches) then
|
||||||
begin
|
begin
|
||||||
@ -567,8 +595,18 @@ end;
|
|||||||
inherited Create;
|
inherited Create;
|
||||||
CExeoutput:=TNLMexeoutput;
|
CExeoutput:=TNLMexeoutput;
|
||||||
CObjInput:=TNLMCoffObjInput;
|
CObjInput:=TNLMCoffObjInput;
|
||||||
|
nlmSpecialSymbols_Segments := TFPHashList.create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
destructor TInternalLinkerNetware.destroy;
|
||||||
|
begin
|
||||||
|
if assigned(nlmSpecialSymbols_Segments) then
|
||||||
|
begin
|
||||||
|
nlmSpecialSymbols_Segments.Free;
|
||||||
|
nlmSpecialSymbols_Segments := nil;
|
||||||
|
end;
|
||||||
|
inherited destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TInternalLinkerNetware.DefaultLinkScript;
|
procedure TInternalLinkerNetware.DefaultLinkScript;
|
||||||
var
|
var
|
||||||
@ -704,7 +742,10 @@ end;
|
|||||||
end;
|
end;
|
||||||
option := GetToken(s,';');
|
option := GetToken(s,';');
|
||||||
end;
|
end;
|
||||||
result := 'nwpre';
|
if target_info.system = system_i386_netwlibc then
|
||||||
|
result := 'libcpre'
|
||||||
|
else
|
||||||
|
result := 'nwpre';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -750,32 +791,33 @@ end;
|
|||||||
Concat('IMAGEBASE $' + hexStr(0, SizeOf(imagebase)*2));
|
Concat('IMAGEBASE $' + hexStr(0, SizeOf(imagebase)*2));
|
||||||
Concat('HEADER');
|
Concat('HEADER');
|
||||||
Concat('EXESECTION .text');
|
Concat('EXESECTION .text');
|
||||||
Concat(' SYMBOL __text_start__');
|
Concat(' SYMBOL __text_start__'); nlmSpecialSymbols_Segments.Add('__text_start__',pointer(ptruint(Section_text)));
|
||||||
Concat(' OBJSECTION .text*');
|
Concat(' OBJSECTION .text*');
|
||||||
Concat(' SYMBOL ___CTOR_LIST__');
|
Concat(' SYMBOL ___CTOR_LIST__'); nlmSpecialSymbols_Segments.Add('___CTOR_LIST__',pointer(ptruint(Section_text)));
|
||||||
Concat(' SYMBOL __CTOR_LIST__');
|
Concat(' SYMBOL __CTOR_LIST__'); nlmSpecialSymbols_Segments.Add('__CTOR_LIST__',pointer(ptruint(Section_text)));
|
||||||
Concat(' LONG -1');
|
Concat(' LONG -1');
|
||||||
Concat(' OBJSECTION .ctor*');
|
Concat(' OBJSECTION .ctor*');
|
||||||
Concat(' LONG 0');
|
Concat(' LONG 0');
|
||||||
Concat(' SYMBOL ___DTOR_LIST__');
|
Concat(' SYMBOL ___DTOR_LIST__'); nlmSpecialSymbols_Segments.Add('___DTOR_LIST__',pointer(ptruint(Section_text)));
|
||||||
Concat(' SYMBOL __DTOR_LIST__');
|
Concat(' SYMBOL __DTOR_LIST__'); nlmSpecialSymbols_Segments.Add('__DTOR_LIST__',pointer(ptruint(Section_text)));
|
||||||
Concat(' LONG -1');
|
Concat(' LONG -1');
|
||||||
Concat(' OBJSECTION .dtor*');
|
Concat(' OBJSECTION .dtor*');
|
||||||
Concat(' LONG 0');
|
Concat(' LONG 0');
|
||||||
Concat(' SYMBOL etext');
|
Concat(' SYMBOL etext'); nlmSpecialSymbols_Segments.Add('etext',pointer(ptruint(Section_text)));
|
||||||
Concat('ENDEXESECTION');
|
Concat('ENDEXESECTION');
|
||||||
|
|
||||||
Concat('EXESECTION .data');
|
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 .data*');
|
||||||
Concat(' OBJSECTION .fpc*');
|
Concat(' OBJSECTION .fpc*');
|
||||||
Concat(' SYMBOL edata');
|
Concat(' SYMBOL edata'); nlmSpecialSymbols_Segments.Add('edata',pointer(ptruint(Section_data)));
|
||||||
Concat(' SYMBOL __data_end__');
|
Concat(' SYMBOL __data_end__'); nlmSpecialSymbols_Segments.Add('__data_end__',pointer(ptruint(Section_data)));
|
||||||
Concat('ENDEXESECTION');
|
Concat('ENDEXESECTION');
|
||||||
|
|
||||||
Concat('EXESECTION .bss');
|
Concat('EXESECTION .bss');
|
||||||
Concat(' SYMBOL __bss_start__');
|
Concat(' SYMBOL __bss_start__'); nlmSpecialSymbols_Segments.Add('__bss_start__',pointer(ptruint(Section_data)));
|
||||||
Concat(' OBJSECTION .bss*');
|
Concat(' OBJSECTION .bss*');
|
||||||
Concat(' SYMBOL __bss_end__');
|
Concat(' SYMBOL __bss_end__'); nlmSpecialSymbols_Segments.Add('__bss_end__',pointer(ptruint(Section_data)));
|
||||||
Concat('ENDEXESECTION');
|
Concat('ENDEXESECTION');
|
||||||
|
|
||||||
Concat('EXESECTION .imports');
|
Concat('EXESECTION .imports');
|
||||||
@ -880,6 +922,8 @@ end;
|
|||||||
Concat ('STACKSIZE '+tostr(stacksize));
|
Concat ('STACKSIZE '+tostr(stacksize));
|
||||||
end else
|
end else
|
||||||
Concat ('STACKSIZE '+tostr(minStackSize));
|
Concat ('STACKSIZE '+tostr(minStackSize));
|
||||||
|
if target_info.system = system_i386_netwlibc then
|
||||||
|
Concat ('REENTRANT'); { needed by older libc versions }
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// add symbols needed by nwpre. We have not loaded the ppu,
|
// add symbols needed by nwpre. We have not loaded the ppu,
|
||||||
|
Loading…
Reference in New Issue
Block a user