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:
armin 2011-04-07 19:38:25 +00:00
parent 841357c66e
commit 672d76e636
2 changed files with 100 additions and 24 deletions

View File

@ -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);

View File

@ -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,