mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-21 04:39:37 +01:00
* fixed and simplified section handling now all sections are
always in objsectionlist git-svn-id: trunk@3135 -
This commit is contained in:
parent
7923a81cfd
commit
780089fb26
@ -46,8 +46,6 @@ interface
|
|||||||
shlink,
|
shlink,
|
||||||
shinfo,
|
shinfo,
|
||||||
shentsize : longint;
|
shentsize : longint;
|
||||||
{ relocation }
|
|
||||||
relocsect : TElfObjSection;
|
|
||||||
constructor create(AList:TFPHashObjectList;const Aname:string;Aalign:shortint;Aoptions:TObjSectionOptions);override;
|
constructor create(AList:TFPHashObjectList;const Aname:string;Aalign:shortint;Aoptions:TObjSectionOptions);override;
|
||||||
constructor create_ext(AList:TFPHashObjectList;const Aname:string;Ashtype,Ashflags,Ashlink,Ashinfo:longint;Aalign:shortint;Aentsize:longint);
|
constructor create_ext(AList:TFPHashObjectList;const Aname:string;Ashtype,Ashflags,Ashlink,Ashinfo:longint;Aalign:shortint;Aentsize:longint);
|
||||||
destructor destroy;override;
|
destructor destroy;override;
|
||||||
@ -55,14 +53,6 @@ interface
|
|||||||
|
|
||||||
TElfObjData = class(TObjData)
|
TElfObjData = class(TObjData)
|
||||||
public
|
public
|
||||||
symtabsect,
|
|
||||||
strtabsect,
|
|
||||||
shstrtabsect,
|
|
||||||
gotpcsect,
|
|
||||||
gotoffsect,
|
|
||||||
goTSect,
|
|
||||||
plTSect,
|
|
||||||
symsect : TElfObjSection;
|
|
||||||
constructor create(const n:string);override;
|
constructor create(const n:string);override;
|
||||||
destructor destroy;override;
|
destructor destroy;override;
|
||||||
function sectionname(atype:TAsmSectiontype;const aname:string):string;override;
|
function sectionname(atype:TAsmSectiontype;const aname:string):string;override;
|
||||||
@ -73,6 +63,14 @@ interface
|
|||||||
|
|
||||||
TElfObjectOutput = class(tObjOutput)
|
TElfObjectOutput = class(tObjOutput)
|
||||||
private
|
private
|
||||||
|
symtabsect,
|
||||||
|
strtabsect,
|
||||||
|
shstrtabsect,
|
||||||
|
gotpcsect,
|
||||||
|
gotoffsect,
|
||||||
|
goTSect,
|
||||||
|
plTSect,
|
||||||
|
symsect : TElfObjSection;
|
||||||
elf32data : TElfObjData;
|
elf32data : TElfObjData;
|
||||||
symidx,
|
symidx,
|
||||||
localsyms : longint;
|
localsyms : longint;
|
||||||
@ -87,14 +85,13 @@ interface
|
|||||||
procedure section_count_sections(p:TObject;arg:pointer);
|
procedure section_count_sections(p:TObject;arg:pointer);
|
||||||
procedure section_create_relocsec(p:TObject;arg:pointer);
|
procedure section_create_relocsec(p:TObject;arg:pointer);
|
||||||
procedure section_set_datapos(p:TObject;arg:pointer);
|
procedure section_set_datapos(p:TObject;arg:pointer);
|
||||||
procedure section_relocsec_set_datapos(p:TObject;arg:pointer);
|
|
||||||
procedure section_write_data(p:TObject;arg:pointer);
|
procedure section_write_data(p:TObject;arg:pointer);
|
||||||
procedure section_write_sechdr(p:TObject;arg:pointer);
|
procedure section_write_sechdr(p:TObject;arg:pointer);
|
||||||
procedure section_write_relocsec(p:TObject;arg:pointer);
|
|
||||||
protected
|
protected
|
||||||
function writedata(data:TObjData):boolean;override;
|
function writedata(data:TObjData):boolean;override;
|
||||||
public
|
public
|
||||||
constructor Create(AWriter:TObjectWriter);override;
|
constructor Create(AWriter:TObjectWriter);override;
|
||||||
|
destructor Destroy;override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TElfAssembler = class(tinternalassembler)
|
TElfAssembler = class(tinternalassembler)
|
||||||
@ -527,7 +524,6 @@ implementation
|
|||||||
shinfo:=0;
|
shinfo:=0;
|
||||||
if name='.stab' then
|
if name='.stab' then
|
||||||
shentsize:=sizeof(TObjStabEntry);
|
shentsize:=sizeof(TObjStabEntry);
|
||||||
relocsect:=nil;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -544,14 +540,11 @@ implementation
|
|||||||
shlink:=Ashlink;
|
shlink:=Ashlink;
|
||||||
shinfo:=Ashinfo;
|
shinfo:=Ashinfo;
|
||||||
shentsize:=Aentsize;
|
shentsize:=Aentsize;
|
||||||
relocsect:=nil;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
destructor TElfObjSection.destroy;
|
destructor TElfObjSection.destroy;
|
||||||
begin
|
begin
|
||||||
if assigned(relocsect) then
|
|
||||||
relocsect.free;
|
|
||||||
inherited destroy;
|
inherited destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -564,13 +557,6 @@ implementation
|
|||||||
begin
|
begin
|
||||||
inherited create(n);
|
inherited create(n);
|
||||||
CObjSection:=TElfObjSection;
|
CObjSection:=TElfObjSection;
|
||||||
{ default sections }
|
|
||||||
symtabsect:=TElfObjSection.create_ext(ObjSectionList,'.symtab',SHT_SYMTAB,0,0,0,4,sizeof(telfsymbol));
|
|
||||||
strtabsect:=TElfObjSection.create_ext(ObjSectionList,'.strtab',SHT_STRTAB,0,0,0,1,0);
|
|
||||||
shstrtabsect:=TElfObjSection.create_ext(ObjSectionList,'.shstrtab',SHT_STRTAB,0,0,0,1,0);
|
|
||||||
{ insert the empty and filename as first in strtab }
|
|
||||||
strtabsect.writestr(#0);
|
|
||||||
strtabsect.writestr(SplitFileName(current_module.mainsource^)+#0);
|
|
||||||
{ we need at least the following sections }
|
{ we need at least the following sections }
|
||||||
createsection(sec_code,'');
|
createsection(sec_code,'');
|
||||||
createsection(sec_data,'');
|
createsection(sec_data,'');
|
||||||
@ -585,9 +571,6 @@ implementation
|
|||||||
|
|
||||||
destructor TElfObjData.destroy;
|
destructor TElfObjData.destroy;
|
||||||
begin
|
begin
|
||||||
symtabsect.free;
|
|
||||||
strtabsect.free;
|
|
||||||
shstrtabsect.free;
|
|
||||||
inherited destroy;
|
inherited destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -701,6 +684,12 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
destructor TElfObjectOutput.destroy;
|
||||||
|
begin
|
||||||
|
inherited destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TElfObjectOutput.createrelocsection(s:TElfObjSection);
|
procedure TElfObjectOutput.createrelocsection(s:TElfObjSection);
|
||||||
var
|
var
|
||||||
i : longint;
|
i : longint;
|
||||||
@ -711,6 +700,7 @@ implementation
|
|||||||
objreloc : TObjRelocation;
|
objreloc : TObjRelocation;
|
||||||
relsym,
|
relsym,
|
||||||
reltyp : longint;
|
reltyp : longint;
|
||||||
|
relocsect : TObjSection;
|
||||||
begin
|
begin
|
||||||
with elf32data do
|
with elf32data do
|
||||||
begin
|
begin
|
||||||
@ -725,9 +715,9 @@ implementation
|
|||||||
{$endif userodata}
|
{$endif userodata}
|
||||||
{ create the reloc section }
|
{ create the reloc section }
|
||||||
{$ifdef i386}
|
{$ifdef i386}
|
||||||
s.relocsect:=TElfObjSection.create_ext(ObjSectionList,'.rel'+s.name,SHT_REL,0,symtabsect.secshidx,s.secshidx,4,sizeof(TElfReloc));
|
relocsect:=TElfObjSection.create_ext(ObjSectionList,'.rel'+s.name,SHT_REL,0,symtabsect.secshidx,s.secshidx,4,sizeof(TElfReloc));
|
||||||
{$else i386}
|
{$else i386}
|
||||||
s.relocsect:=TElfObjSection.create_ext(ObjSectionList,'.rela'+s.name,SHT_RELA,0,symtabsect.secshidx,s.secshidx,4,sizeof(TElfReloc));
|
relocsect:=TElfObjSection.create_ext(ObjSectionList,'.rela'+s.name,SHT_RELA,0,symtabsect.secshidx,s.secshidx,4,sizeof(TElfReloc));
|
||||||
{$endif i386}
|
{$endif i386}
|
||||||
{ add the relocations }
|
{ add the relocations }
|
||||||
for i:=0 to s.Objrelocations.count-1 do
|
for i:=0 to s.Objrelocations.count-1 do
|
||||||
@ -790,9 +780,9 @@ implementation
|
|||||||
{ write reloc }
|
{ write reloc }
|
||||||
{$ifdef ver2_0_0}
|
{$ifdef ver2_0_0}
|
||||||
relnative:=MaybeSwapElfReloc(rel);
|
relnative:=MaybeSwapElfReloc(rel);
|
||||||
s.relocsect.write(relnative,sizeof(rel));
|
relocsect.write(relnative,sizeof(rel));
|
||||||
{$else}
|
{$else}
|
||||||
s.relocsect.write(MaybeSwapElfReloc(rel),sizeof(rel));
|
relocsect.write(MaybeSwapElfReloc(rel),sizeof(rel));
|
||||||
{$endif ver2_0_0}
|
{$endif ver2_0_0}
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -814,9 +804,9 @@ implementation
|
|||||||
inc(localsyms);
|
inc(localsyms);
|
||||||
{$ifdef ver2_0_0}
|
{$ifdef ver2_0_0}
|
||||||
elfsymnative:=MaybeSwapElfSymbol(elfsym);
|
elfsymnative:=MaybeSwapElfSymbol(elfsym);
|
||||||
elf32data.symtabsect.write(elfsymnative,sizeof(elfsym));
|
symtabsect.write(elfsymnative,sizeof(elfsym));
|
||||||
{$else}
|
{$else}
|
||||||
elf32data.symtabsect.write(MaybeSwapElfSymbol(elfsym),sizeof(elfsym));
|
symtabsect.write(MaybeSwapElfSymbol(elfsym),sizeof(elfsym));
|
||||||
{$endif ver2_0_0}
|
{$endif ver2_0_0}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -935,9 +925,7 @@ implementation
|
|||||||
|
|
||||||
procedure TElfObjectOutput.section_write_sh_string(p:TObject;arg:pointer);
|
procedure TElfObjectOutput.section_write_sh_string(p:TObject;arg:pointer);
|
||||||
begin
|
begin
|
||||||
TElfObjSection(p).shstridx:=elf32data.shstrtabsect.writestr(TObjSection(p).name+#0);
|
TElfObjSection(p).shstridx:=shstrtabsect.writestr(TObjSection(p).name+#0);
|
||||||
if assigned(TElfObjSection(p).relocsect) then
|
|
||||||
TElfObjSection(p).relocsect.shstridx:=elf32data.shstrtabsect.writestr(TElfObjSection(p).relocsect.name+#0);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -945,16 +933,10 @@ implementation
|
|||||||
begin
|
begin
|
||||||
with elf32data do
|
with elf32data do
|
||||||
begin
|
begin
|
||||||
with shstrtabsect do
|
shstrtabsect.writestr(#0);
|
||||||
begin
|
|
||||||
writestr(#0);
|
|
||||||
symtabsect.shstridx:=writestr('.symtab'#0);
|
|
||||||
strtabsect.shstridx:=writestr('.strtab'#0);
|
|
||||||
shstrtabsect.shstridx:=writestr('.shstrtab'#0);
|
|
||||||
ObjSectionList.ForEachCall(@section_write_sh_string,nil);
|
ObjSectionList.ForEachCall(@section_write_sh_string,nil);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure TElfObjectOutput.writesectionheader(s:TElfObjSection);
|
procedure TElfObjectOutput.writesectionheader(s:TElfObjSection);
|
||||||
@ -986,6 +968,8 @@ implementation
|
|||||||
procedure TElfObjectOutput.writesectiondata(s:TElfObjSection);
|
procedure TElfObjectOutput.writesectiondata(s:TElfObjSection);
|
||||||
begin
|
begin
|
||||||
FWriter.writezeros(s.dataalignbytes);
|
FWriter.writezeros(s.dataalignbytes);
|
||||||
|
if s.Datapos<>FWriter.ObjSize then
|
||||||
|
internalerror(200604031);
|
||||||
FWriter.writearray(s.data);
|
FWriter.writearray(s.data);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -994,8 +978,6 @@ implementation
|
|||||||
begin
|
begin
|
||||||
TElfObjSection(p).secshidx:=pword(arg)^;
|
TElfObjSection(p).secshidx:=pword(arg)^;
|
||||||
inc(pword(arg)^);
|
inc(pword(arg)^);
|
||||||
if TElfObjSection(p).ObjRelocations.count>0 then
|
|
||||||
inc(pword(arg)^);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1012,13 +994,6 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TElfObjectOutput.section_relocsec_set_datapos(p:TObject;arg:pointer);
|
|
||||||
begin
|
|
||||||
if assigned(TElfObjSection(p).relocsect) then
|
|
||||||
TElfObjSection(p).relocsect.setdatapos(paint(arg)^);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure TElfObjectOutput.section_write_data(p:TObject;arg:pointer);
|
procedure TElfObjectOutput.section_write_data(p:TObject;arg:pointer);
|
||||||
begin
|
begin
|
||||||
if (oso_data in TObjSection(p).secoptions) then
|
if (oso_data in TObjSection(p).secoptions) then
|
||||||
@ -1033,19 +1008,9 @@ implementation
|
|||||||
procedure TElfObjectOutput.section_write_sechdr(p:TObject;arg:pointer);
|
procedure TElfObjectOutput.section_write_sechdr(p:TObject;arg:pointer);
|
||||||
begin
|
begin
|
||||||
writesectionheader(TElfObjSection(p));
|
writesectionheader(TElfObjSection(p));
|
||||||
if assigned(TElfObjSection(p).relocsect) then
|
|
||||||
writesectionheader(TElfObjSection(p).relocsect);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TElfObjectOutput.section_write_relocsec(p:TObject;arg:pointer);
|
|
||||||
begin
|
|
||||||
if assigned(TElfObjSection(p).relocsect) then
|
|
||||||
writesectiondata(TElfObjSection(p).relocsect);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function TElfObjectOutput.writedata(data:TObjData):boolean;
|
function TElfObjectOutput.writedata(data:TObjData):boolean;
|
||||||
var
|
var
|
||||||
{$ifdef ver2_0_0}
|
{$ifdef ver2_0_0}
|
||||||
@ -1060,39 +1025,34 @@ implementation
|
|||||||
elf32data:=TElfObjData(data);
|
elf32data:=TElfObjData(data);
|
||||||
with elf32data do
|
with elf32data do
|
||||||
begin
|
begin
|
||||||
|
{ default sections }
|
||||||
|
symtabsect:=TElfObjSection.create_ext(ObjSectionList,'.symtab',SHT_SYMTAB,0,0,0,4,sizeof(telfsymbol));
|
||||||
|
strtabsect:=TElfObjSection.create_ext(ObjSectionList,'.strtab',SHT_STRTAB,0,0,0,1,0);
|
||||||
|
shstrtabsect:=TElfObjSection.create_ext(ObjSectionList,'.shstrtab',SHT_STRTAB,0,0,0,1,0);
|
||||||
|
{ insert the empty and filename as first in strtab }
|
||||||
|
strtabsect.writestr(#0);
|
||||||
|
strtabsect.writestr(SplitFileName(current_module.mainsource^)+#0);
|
||||||
{ calc amount of sections we have }
|
{ calc amount of sections we have }
|
||||||
nsections:=1;
|
nsections:=1;
|
||||||
{ also create the index in the section header table }
|
{ also create the index in the section header table }
|
||||||
ObjSectionList.ForEachCall(@section_count_sections,@nsections);
|
ObjSectionList.ForEachCall(@section_count_sections,@nsections);
|
||||||
{ add default sections }
|
|
||||||
shstrtabsect.secshidx:=nsections;
|
|
||||||
inc(nsections);
|
|
||||||
symtabsect.secshidx:=nsections;
|
|
||||||
inc(nsections);
|
|
||||||
strtabsect.secshidx:=nsections;
|
|
||||||
inc(nsections);
|
|
||||||
{ create .symtab and .strtab }
|
{ create .symtab and .strtab }
|
||||||
createsymtab;
|
createsymtab;
|
||||||
{ Create the relocation sections }
|
{ Create the relocation sections, this needs valid secidx and symidx }
|
||||||
ObjSectionList.ForEachCall(@section_create_relocsec,nil);
|
ObjSectionList.ForEachCall(@section_create_relocsec,nil);
|
||||||
|
{ recalc nsections to incude the reloc sections }
|
||||||
|
nsections:=1;
|
||||||
|
ObjSectionList.ForEachCall(@section_count_sections,@nsections);
|
||||||
{ create .shstrtab }
|
{ create .shstrtab }
|
||||||
createshstrtab;
|
createshstrtab;
|
||||||
|
|
||||||
{ Calculate the filepositions }
|
{ Calculate the filepositions }
|
||||||
datapos:=$40; { elfheader + alignment }
|
datapos:=$40; { elfheader + alignment }
|
||||||
{ sections first }
|
{ section data }
|
||||||
ObjSectionList.ForEachCall(@section_set_datapos,@datapos);
|
ObjSectionList.ForEachCall(@section_set_datapos,@datapos);
|
||||||
{ shstrtab }
|
|
||||||
shstrtabsect.setdatapos(datapos);
|
|
||||||
{ section headers }
|
{ section headers }
|
||||||
shoffset:=datapos;
|
shoffset:=datapos;
|
||||||
inc(datapos,nsections*sizeof(telfsechdr));
|
inc(datapos,(nsections+1)*sizeof(telfsechdr));
|
||||||
{ symtab }
|
|
||||||
symtabsect.setdatapos(datapos);
|
|
||||||
{ strtab }
|
|
||||||
strtabsect.setdatapos(datapos);
|
|
||||||
{ .rel sections }
|
|
||||||
ObjSectionList.ForEachCall(@section_relocsec_set_datapos,@datapos);
|
|
||||||
|
|
||||||
{ Write ELF Header }
|
{ Write ELF Header }
|
||||||
fillchar(header,sizeof(header),0);
|
fillchar(header,sizeof(header),0);
|
||||||
@ -1143,20 +1103,9 @@ implementation
|
|||||||
writer.writezeros($40-sizeof(header)); { align }
|
writer.writezeros($40-sizeof(header)); { align }
|
||||||
{ Sections }
|
{ Sections }
|
||||||
ObjSectionList.ForEachCall(@section_write_data,nil);
|
ObjSectionList.ForEachCall(@section_write_data,nil);
|
||||||
{ .shstrtab }
|
|
||||||
writesectiondata(shstrtabsect);
|
|
||||||
{ section headers, start with an empty header for sh_undef }
|
{ section headers, start with an empty header for sh_undef }
|
||||||
writer.writezeros(sizeof(telfsechdr));
|
writer.writezeros(sizeof(telfsechdr));
|
||||||
ObjSectionList.ForEachCall(@section_write_sechdr,nil);
|
ObjSectionList.ForEachCall(@section_write_sechdr,nil);
|
||||||
writesectionheader(shstrtabsect);
|
|
||||||
writesectionheader(symtabsect);
|
|
||||||
writesectionheader(strtabsect);
|
|
||||||
{ .symtab }
|
|
||||||
writesectiondata(symtabsect);
|
|
||||||
{ .strtab }
|
|
||||||
writesectiondata(strtabsect);
|
|
||||||
{ .rel sections }
|
|
||||||
ObjSectionList.ForEachCall(@section_write_relocsec,nil);
|
|
||||||
end;
|
end;
|
||||||
result:=true;
|
result:=true;
|
||||||
end;
|
end;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user