mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 21:09:24 +02:00
* Changed TElfTarget from class to record, so it can contain data members while remaining statically allocated.
* Moved target-dependent constants into ElfTarget records, eliminates a lot of $ifdef's in ogelf.pas. + Added TElfTarget.loadsection hook and pass unknown sections to it. git-svn-id: trunk@23090 -
This commit is contained in:
parent
66553a253e
commit
d79761c607
@ -29,15 +29,10 @@ implementation
|
||||
|
||||
uses
|
||||
globtype,cclasses,
|
||||
verbose,
|
||||
systems,ogbase,ogelf,assemble;
|
||||
verbose,elfbase,
|
||||
systems,aasmbase,ogbase,ogelf,assemble;
|
||||
|
||||
type
|
||||
TElfTarget386=class(TElfTarget)
|
||||
class function encodereloc(objrel:TObjRelocation):byte;override;
|
||||
class procedure loadreloc(objrel:TObjRelocation);override;
|
||||
end;
|
||||
|
||||
TElfExeOutput386=class(TElfExeOutput)
|
||||
private
|
||||
procedure MaybeWriteGOTEntry(reltyp:byte;relocval:aint;objsym:TObjSymbol);
|
||||
@ -97,10 +92,10 @@ implementation
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
TElfTarget386
|
||||
ELF Target methods
|
||||
****************************************************************************}
|
||||
|
||||
class function TElfTarget386.encodereloc(objrel:TObjRelocation):byte;
|
||||
function elf_i386_encodereloc(objrel:TObjRelocation):byte;
|
||||
begin
|
||||
case objrel.typ of
|
||||
RELOC_NONE :
|
||||
@ -122,7 +117,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
class procedure TElfTarget386.loadreloc(objrel:TObjRelocation);
|
||||
procedure elf_i386_loadreloc(objrel:TObjRelocation);
|
||||
begin
|
||||
end;
|
||||
|
||||
@ -179,7 +174,7 @@ implementation
|
||||
pltrelocsec.writeReloc_internal(gotpltobjsec,got_offset,sizeof(pint),RELOC_ABSOLUTE);
|
||||
got_offset:=(exesym.dynindex shl 8) or R_386_JUMP_SLOT;
|
||||
pltrelocsec.write(got_offset,sizeof(pint));
|
||||
if relocs_use_addend then
|
||||
if ElfTarget.relocs_use_addend then
|
||||
pltrelocsec.writezeros(sizeof(pint));
|
||||
end;
|
||||
|
||||
@ -325,7 +320,7 @@ implementation
|
||||
else
|
||||
reltyp:=objreloc.ftype;
|
||||
|
||||
if relocs_use_addend then
|
||||
if ElfTarget.relocs_use_addend then
|
||||
address:=objreloc.orgsize
|
||||
else
|
||||
begin
|
||||
@ -463,6 +458,17 @@ implementation
|
||||
*****************************************************************************}
|
||||
|
||||
const
|
||||
elf_target_i386 : TElfTarget =
|
||||
(
|
||||
max_page_size: $1000;
|
||||
exe_image_base: $8048000;
|
||||
machine_code: EM_386;
|
||||
relocs_use_addend: false;
|
||||
encodereloc: @elf_i386_encodeReloc;
|
||||
loadreloc: @elf_i386_loadReloc;
|
||||
loadsection: nil;
|
||||
);
|
||||
|
||||
as_i386_elf32_info : tasminfo =
|
||||
(
|
||||
id : as_i386_elf32;
|
||||
@ -483,7 +489,7 @@ implementation
|
||||
initialization
|
||||
RegisterAssembler(as_i386_elf32_info,TElfAssembler);
|
||||
ElfExeOutputClass:=TElfExeOutput386;
|
||||
ElfTarget:=TElfTarget386;
|
||||
ElfTarget:=elf_target_i386;
|
||||
|
||||
end.
|
||||
|
||||
|
@ -102,14 +102,6 @@ interface
|
||||
constructor create(smart:boolean);override;
|
||||
end;
|
||||
|
||||
TElfTarget=class(TObject)
|
||||
public
|
||||
class function encodereloc(objrel:TObjRelocation):byte;virtual;abstract;
|
||||
class procedure loadreloc(objrel:TObjRelocation);virtual;abstract;
|
||||
end;
|
||||
|
||||
TElfTargetClass=class of TElfTarget;
|
||||
|
||||
PSectionRec=^TSectionRec;
|
||||
TSectionRec=record
|
||||
sec: TObjSection;
|
||||
@ -152,6 +144,21 @@ interface
|
||||
class function CanReadObjData(AReader:TObjectreader):boolean;override;
|
||||
end;
|
||||
|
||||
TEncodeRelocProc=function(objrel:TObjRelocation):byte;
|
||||
TLoadRelocProc=procedure(objrel:TObjRelocation);
|
||||
TLoadSectionProc=function(objinput:TElfObjInput;objdata:TObjData;const shdr:TElfsechdr;shindex:longint):boolean;
|
||||
|
||||
TElfTarget=record
|
||||
max_page_size: longword;
|
||||
exe_image_base: longword;
|
||||
machine_code: word;
|
||||
relocs_use_addend: boolean;
|
||||
encodereloc: TEncodeRelocProc;
|
||||
loadreloc: TLoadRelocProc;
|
||||
loadsection: TLoadSectionProc;
|
||||
end;
|
||||
|
||||
|
||||
TElfExeSection=class(TExeSection)
|
||||
public
|
||||
secshidx : longword; { index of the section header }
|
||||
@ -258,20 +265,12 @@ interface
|
||||
|
||||
var
|
||||
ElfExeOutputClass: TExeOutputClass;
|
||||
ElfTarget: TElfTargetClass;
|
||||
ElfTarget: TElfTarget;
|
||||
|
||||
const
|
||||
{ Bits of TObjSymbol.refs field }
|
||||
symref_plt = 1;
|
||||
|
||||
{TODO: should become property of back-end }
|
||||
{$ifdef x86_64}
|
||||
const
|
||||
relocs_use_addend:Boolean=True;
|
||||
{$else x86_64}
|
||||
const
|
||||
relocs_use_addend:Boolean=False;
|
||||
{$endif x86_64}
|
||||
|
||||
|
||||
implementation
|
||||
@ -285,31 +284,6 @@ implementation
|
||||
const
|
||||
symbolresize = 200*18;
|
||||
|
||||
{$ifdef sparc}
|
||||
ELFMACHINE = EM_SPARC;
|
||||
{$endif sparc}
|
||||
{$ifdef i386}
|
||||
ELFMACHINE = EM_386;
|
||||
{$endif i386}
|
||||
{$ifdef m68k}
|
||||
ELFMACHINE = EM_M68K;
|
||||
{$endif m68k}
|
||||
{$ifdef powerpc}
|
||||
ELFMACHINE = EM_PPC;
|
||||
{$endif powerpc}
|
||||
{$ifdef powerpc64}
|
||||
ELFMACHINE = EM_PPC; // TODO
|
||||
{$endif}
|
||||
{$ifdef mips}
|
||||
ELFMACHINE = EM_MIPS;
|
||||
{$endif}
|
||||
{$ifdef arm}
|
||||
ELFMACHINE = EM_ARM;
|
||||
{$endif arm}
|
||||
{$ifdef x86_64}
|
||||
ELFMACHINE = EM_X86_64;
|
||||
{$endif x86_64}
|
||||
|
||||
{$ifdef cpu64bitaddr}
|
||||
const
|
||||
ELFCLASS = ELFCLASS64;
|
||||
@ -341,16 +315,6 @@ implementation
|
||||
end;
|
||||
{$endif cpu64bitaddr}
|
||||
|
||||
{$ifdef x86_64}
|
||||
const
|
||||
ELF_MAXPAGESIZE:longint=$200000;
|
||||
TEXT_SEGMENT_START:longint=$400000;
|
||||
{$else x86_64}
|
||||
const
|
||||
ELF_MAXPAGESIZE:longint=$1000;
|
||||
TEXT_SEGMENT_START:longint=$8048000;
|
||||
{$endif x86_64}
|
||||
|
||||
procedure MayBeSwapHeader(var h : telf32header);
|
||||
begin
|
||||
if source_info.endian<>target_info.endian then
|
||||
@ -619,11 +583,11 @@ implementation
|
||||
constructor TElfObjSection.create_reloc(aobjdata:TObjData;const Aname:string;allocflag:boolean);
|
||||
begin
|
||||
create_ext(aobjdata,
|
||||
relsec_prefix[relocs_use_addend]+aname,
|
||||
relsec_shtype[relocs_use_addend],
|
||||
relsec_prefix[ElfTarget.relocs_use_addend]+aname,
|
||||
relsec_shtype[ElfTarget.relocs_use_addend],
|
||||
SHF_ALLOC*ord(allocflag),
|
||||
sizeof(pint),
|
||||
(2+ord(relocs_use_addend))*sizeof(pint));
|
||||
(2+ord(ElfTarget.relocs_use_addend))*sizeof(pint));
|
||||
end;
|
||||
|
||||
|
||||
@ -638,7 +602,7 @@ implementation
|
||||
dec(offset,len)
|
||||
else if reltype<>RELOC_ABSOLUTE then
|
||||
InternalError(2012062401);
|
||||
if relocs_use_addend then
|
||||
if ElfTarget.relocs_use_addend then
|
||||
begin
|
||||
reloc.orgsize:=offset;
|
||||
offset:=0;
|
||||
@ -799,7 +763,7 @@ implementation
|
||||
objreloc.size:=len;
|
||||
if reltype in [RELOC_RELATIVE{$ifdef x86},RELOC_PLT32{$endif}{$ifdef x86_64},RELOC_GOTPCREL{$endif}] then
|
||||
dec(data,len);
|
||||
if relocs_use_addend then
|
||||
if ElfTarget.relocs_use_addend then
|
||||
begin
|
||||
objreloc.orgsize:=data;
|
||||
data:=0;
|
||||
@ -1029,13 +993,13 @@ implementation
|
||||
objsec,target:TElfObjSection;
|
||||
begin
|
||||
shstrtabsect.writezeros(1);
|
||||
prefixlen:=length('.rel')+ord(relocs_use_addend);
|
||||
prefixlen:=length('.rel')+ord(ElfTarget.relocs_use_addend);
|
||||
for i:=0 to data.ObjSectionList.Count-1 do
|
||||
begin
|
||||
objsec:=TElfObjSection(data.ObjSectionList[i]);
|
||||
{ Alias section names into names of corresponding reloc sections,
|
||||
this is allowed by ELF specs and saves good half of .shstrtab space. }
|
||||
if objsec.shtype=relsec_shtype[relocs_use_addend] then
|
||||
if objsec.shtype=relsec_shtype[ElfTarget.relocs_use_addend] then
|
||||
begin
|
||||
target:=TElfObjSection(data.ObjSectionList[objsec.shinfo-1]);
|
||||
if (target.ObjRelocations.Count=0) or
|
||||
@ -1148,7 +1112,7 @@ implementation
|
||||
|
||||
header.e_ident[EI_VERSION]:=1;
|
||||
header.e_type:=ET_REL;
|
||||
header.e_machine:=ELFMACHINE;
|
||||
header.e_machine:=ElfTarget.machine_code;
|
||||
header.e_version:=1;
|
||||
header.e_shoff:=shoffset;
|
||||
header.e_shstrndx:=shstrtabsect.index;
|
||||
@ -1239,7 +1203,8 @@ implementation
|
||||
if (secrec.relentsize=3*sizeof(pint)) then
|
||||
objrel.orgsize:=rel.addend;
|
||||
{ perform target-specific actions }
|
||||
ElfTarget.loadreloc(objrel);
|
||||
if Assigned(ElfTarget.loadreloc) then
|
||||
ElfTarget.loadreloc(objrel);
|
||||
secrec.sec.ObjRelocations.add(objrel);
|
||||
end
|
||||
else
|
||||
@ -1453,7 +1418,9 @@ implementation
|
||||
else
|
||||
InternalError(2012110706);
|
||||
else
|
||||
InternalError(2012072603);
|
||||
if not (assigned(ElfTarget.loadsection) and
|
||||
ElfTarget.loadsection(self,objdata,shdr,index)) then
|
||||
InternalError(2012072603);
|
||||
end;
|
||||
FLoaded[index]:=True;
|
||||
end;
|
||||
@ -1496,7 +1463,7 @@ implementation
|
||||
InputError('Unknown ELF data version');
|
||||
exit;
|
||||
end;
|
||||
if (header.e_machine<>ELFMACHINE) then
|
||||
if (header.e_machine<>ElfTarget.machine_code) then
|
||||
begin
|
||||
InputError('ELF file is for different CPU');
|
||||
exit;
|
||||
@ -1850,7 +1817,7 @@ implementation
|
||||
header.e_type:=ET_DYN
|
||||
else
|
||||
header.e_type:=ET_EXEC;
|
||||
header.e_machine:=ELFMACHINE;
|
||||
header.e_machine:=ElfTarget.machine_code;
|
||||
header.e_version:=1;
|
||||
header.e_phoff:=sizeof(TElfHeader);
|
||||
header.e_shoff:=shoffset;
|
||||
@ -1966,8 +1933,8 @@ implementation
|
||||
seg.Add(interpobjsec.ExeSection);
|
||||
end;
|
||||
|
||||
textseg:=CreateSegment(PT_LOAD,PF_X or PF_R,ELF_MAXPAGESIZE);
|
||||
dataseg:=CreateSegment(PT_LOAD,PF_R or PF_W,ELF_MAXPAGESIZE);
|
||||
textseg:=CreateSegment(PT_LOAD,PF_X or PF_R,ElfTarget.max_page_size);
|
||||
dataseg:=CreateSegment(PT_LOAD,PF_R or PF_W,ElfTarget.max_page_size);
|
||||
for i:=0 to ExeSectionList.Count-1 do
|
||||
begin
|
||||
exesec:=TExeSection(ExeSectionList[i]);
|
||||
@ -2347,7 +2314,7 @@ implementation
|
||||
if IsSharedLibrary then
|
||||
CurrMemPos:=0
|
||||
else
|
||||
CurrMemPos:=TEXT_SEGMENT_START;
|
||||
CurrMemPos:=ElfTarget.exe_image_base;
|
||||
textseg.MemPos:=CurrMemPos;
|
||||
if assigned(phdrseg) then
|
||||
begin
|
||||
@ -2357,7 +2324,7 @@ implementation
|
||||
CurrMemPos:=CurrMemPos+sizeof(TElfHeader)+segmentlist.count*sizeof(TElfproghdr);
|
||||
MemPos_Segment(textseg);
|
||||
CurrMemPos:=Align(CurrMemPos,SectionDataAlign); {! Data,not MemAlign}
|
||||
CurrMemPos:=CurrMemPos+ELF_MAXPAGESIZE;
|
||||
CurrMemPos:=CurrMemPos+ElfTarget.max_page_size;
|
||||
dataseg.MemPos:=CurrMemPos;
|
||||
MemPos_Segment(dataseg);
|
||||
{ Mempos of unmapped sections is forced to zero, but we have to set positions
|
||||
|
@ -28,15 +28,9 @@ interface
|
||||
implementation
|
||||
|
||||
uses
|
||||
verbose,
|
||||
verbose,elfbase,
|
||||
systems,ogbase,ogelf,assemble;
|
||||
|
||||
type
|
||||
TElfTargetSparc=class(TElfTarget)
|
||||
class function encodereloc(objrel:TObjRelocation):byte;override;
|
||||
class procedure loadreloc(objrel:TObjRelocation);override;
|
||||
end;
|
||||
|
||||
const
|
||||
{ Relocation types }
|
||||
R_SPARC_NONE = 0;
|
||||
@ -68,10 +62,10 @@ implementation
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
TElfTargetSparc
|
||||
ELF Target methods
|
||||
****************************************************************************}
|
||||
|
||||
class function TElfTargetSparc.encodereloc(objrel:TObjRelocation):byte;
|
||||
function elf_sparc_encodereloc(objrel:TObjRelocation):byte;
|
||||
begin
|
||||
case objrel.typ of
|
||||
RELOC_NONE :
|
||||
@ -86,7 +80,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
class procedure TElfTargetSparc.loadreloc(objrel:TObjRelocation);
|
||||
procedure elf_sparc.loadreloc(objrel:TObjRelocation);
|
||||
begin
|
||||
end;
|
||||
|
||||
@ -97,6 +91,17 @@ implementation
|
||||
*****************************************************************************}
|
||||
|
||||
const
|
||||
elf_target_sparc: TElfTarget =
|
||||
(
|
||||
max_page_size: $8000; // fixme
|
||||
exe_image_base: $8000; // fixme
|
||||
machine_code: EM_SPARC;
|
||||
relocs_use_addend: false;
|
||||
encodereloc: @elf_sparc_encodeReloc;
|
||||
loadreloc: @elf_sparc_loadReloc;
|
||||
loadsection: nil;
|
||||
);
|
||||
|
||||
as_sparc_elf32_info : tasminfo =
|
||||
(
|
||||
id : as_sparc_elf32;
|
||||
@ -114,7 +119,7 @@ implementation
|
||||
|
||||
initialization
|
||||
RegisterAssembler(as_sparc_elf32_info,TElfAssembler);
|
||||
ElfTarget:=TElfTargetSparc;
|
||||
ElfTarget:=elf_target_sparc;
|
||||
|
||||
end.
|
||||
|
||||
|
@ -29,15 +29,10 @@ implementation
|
||||
|
||||
uses
|
||||
globtype,cutils,cclasses,
|
||||
verbose,
|
||||
verbose,elfbase,
|
||||
systems,aasmbase,ogbase,ogelf,assemble;
|
||||
|
||||
type
|
||||
TElfTargetx86_64=class(TElfTarget)
|
||||
class function encodereloc(objrel:TObjRelocation):byte;override;
|
||||
class procedure loadreloc(objrel:TObjRelocation);override;
|
||||
end;
|
||||
|
||||
TElfExeOutputx86_64=class(TElfExeOutput)
|
||||
private
|
||||
function RelocName(reltyp:byte):string;
|
||||
@ -148,10 +143,10 @@ implementation
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
TELFTargetx86_64
|
||||
ELF Target methods
|
||||
****************************************************************************}
|
||||
|
||||
class function TElfTargetx86_64.encodereloc(objrel:TObjRelocation):byte;
|
||||
function elf_x86_64_encodereloc(objrel:TObjRelocation):byte;
|
||||
begin
|
||||
case objrel.typ of
|
||||
RELOC_NONE :
|
||||
@ -185,7 +180,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
class procedure TElfTargetx86_64.loadreloc(objrel:TObjRelocation);
|
||||
procedure elf_x86_64_loadreloc(objrel:TObjRelocation);
|
||||
begin
|
||||
end;
|
||||
|
||||
@ -381,7 +376,7 @@ implementation
|
||||
else
|
||||
InternalError(2012092103);
|
||||
|
||||
if relocs_use_addend then
|
||||
if ElfTarget.relocs_use_addend then
|
||||
address:=objreloc.orgsize
|
||||
else
|
||||
begin
|
||||
@ -547,7 +542,7 @@ implementation
|
||||
pltrelocsec.writeReloc_internal(gotpltobjsec,gotpltobjsec.size-sizeof(pint),sizeof(pint),RELOC_ABSOLUTE);
|
||||
got_offset:=(qword(exesym.dynindex) shl 32) or R_X86_64_JUMP_SLOT;
|
||||
pltrelocsec.write(got_offset,sizeof(pint));
|
||||
if relocs_use_addend then
|
||||
if ElfTarget.relocs_use_addend then
|
||||
pltrelocsec.writezeros(sizeof(pint));
|
||||
end;
|
||||
|
||||
@ -585,7 +580,7 @@ implementation
|
||||
ipltrelocsec.writeReloc_internal(gotpltobjsec,gotpltobjsec.size-sizeof(pint),sizeof(pint),RELOC_ABSOLUTE);
|
||||
tmp:=R_X86_64_IRELATIVE;
|
||||
ipltrelocsec.write(tmp,sizeof(pint));
|
||||
if relocs_use_addend then
|
||||
if ElfTarget.relocs_use_addend then
|
||||
ipltrelocsec.writeReloc_internal(targetsym.objsection,targetsym.offset,sizeof(pint),RELOC_ABSOLUTE);
|
||||
end;
|
||||
|
||||
@ -594,6 +589,18 @@ implementation
|
||||
*****************************************************************************}
|
||||
|
||||
const
|
||||
elf_target_x86_64: TElfTarget =
|
||||
(
|
||||
max_page_size: $200000;
|
||||
exe_image_base: $400000;
|
||||
machine_code: EM_X86_64;
|
||||
relocs_use_addend: true;
|
||||
encodereloc: @elf_x86_64_encodeReloc;
|
||||
loadreloc: @elf_x86_64_loadReloc;
|
||||
loadsection: nil;
|
||||
);
|
||||
|
||||
|
||||
as_x86_64_elf64_info : tasminfo =
|
||||
(
|
||||
id : as_x86_64_elf64;
|
||||
@ -610,7 +617,7 @@ implementation
|
||||
|
||||
initialization
|
||||
RegisterAssembler(as_x86_64_elf64_info,TElfAssembler);
|
||||
ElfTarget:=TElfTargetx86_64;
|
||||
ElfTarget:=elf_target_x86_64;
|
||||
ElfExeOutputClass:=TElfExeOutputx86_64;
|
||||
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user