summaryrefslogtreecommitdiff
path: root/compiler/ogelf.pas
diff options
context:
space:
mode:
authorsergei <sergei@3ad0048d-3df7-0310-abae-a5850022a9f2>2012-12-02 11:15:35 +0000
committersergei <sergei@3ad0048d-3df7-0310-abae-a5850022a9f2>2012-12-02 11:15:35 +0000
commit62558e769201e5a1af196702be75913eac41970f (patch)
tree0c40f2cd25bf8b3ba90d0a65169f231f89923d95 /compiler/ogelf.pas
parent4fb715349d7b43b17fe25719aa73806fead13956 (diff)
downloadfpc-62558e769201e5a1af196702be75913eac41970f.tar.gz
* 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: http://svn.freepascal.org/svn/fpc/trunk@23090 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/ogelf.pas')
-rw-r--r--compiler/ogelf.pas103
1 files changed, 35 insertions, 68 deletions
diff --git a/compiler/ogelf.pas b/compiler/ogelf.pas
index 8e2abee610..5988842cf0 100644
--- a/compiler/ogelf.pas
+++ b/compiler/ogelf.pas
@@ -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