diff options
-rw-r--r-- | compiler/i386/cpuelf.pas | 32 | ||||
-rw-r--r-- | compiler/ogelf.pas | 103 | ||||
-rw-r--r-- | compiler/sparc/cpuelf.pas | 27 | ||||
-rw-r--r-- | compiler/x86_64/cpuelf.pas | 33 |
4 files changed, 90 insertions, 105 deletions
diff --git a/compiler/i386/cpuelf.pas b/compiler/i386/cpuelf.pas index a68942f50c..12e65ad8ed 100644 --- a/compiler/i386/cpuelf.pas +++ b/compiler/i386/cpuelf.pas @@ -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. 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 diff --git a/compiler/sparc/cpuelf.pas b/compiler/sparc/cpuelf.pas index 15cbc8ad7a..1ceeef8105 100644 --- a/compiler/sparc/cpuelf.pas +++ b/compiler/sparc/cpuelf.pas @@ -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. diff --git a/compiler/x86_64/cpuelf.pas b/compiler/x86_64/cpuelf.pas index 60053fbcb6..f8fcc90457 100644 --- a/compiler/x86_64/cpuelf.pas +++ b/compiler/x86_64/cpuelf.pas @@ -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. |