Forráskód Böngészése

* 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 -

sergei 12 éve
szülő
commit
d79761c607
4 módosított fájl, 90 hozzáadás és 105 törlés
  1. 19 13
      compiler/i386/cpuelf.pas
  2. 35 68
      compiler/ogelf.pas
  3. 16 11
      compiler/sparc/cpuelf.pas
  4. 20 13
      compiler/x86_64/cpuelf.pas

+ 19 - 13
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.
 

+ 35 - 68
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

+ 16 - 11
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.
 

+ 20 - 13
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.