Browse Source

* Split most CPU-specific code from ogelf.pas into newly created cpuelf.pas units in CPU subdirectories.

git-svn-id: trunk@22208 -
sergei 13 years ago
parent
commit
c529356693

+ 3 - 0
.gitattributes

@@ -165,6 +165,7 @@ compiler/htypechk.pas svneol=native#text/plain
 compiler/i386/aopt386.pas svneol=native#text/plain
 compiler/i386/cgcpu.pas svneol=native#text/plain
 compiler/i386/cpubase.inc svneol=native#text/plain
+compiler/i386/cpuelf.pas svneol=native#text/plain
 compiler/i386/cpuinfo.pas svneol=native#text/plain
 compiler/i386/cpunode.pas svneol=native#text/plain
 compiler/i386/cpupara.pas svneol=native#text/plain
@@ -539,6 +540,7 @@ compiler/sparc/aoptcpub.pas svneol=native#text/plain
 compiler/sparc/aoptcpud.pas svneol=native#text/plain
 compiler/sparc/cgcpu.pas svneol=native#text/plain
 compiler/sparc/cpubase.pas svneol=native#text/plain
+compiler/sparc/cpuelf.pas svneol=native#text/plain
 compiler/sparc/cpugas.pas svneol=native#text/plain
 compiler/sparc/cpuinfo.pas svneol=native#text/plain
 compiler/sparc/cpunode.pas svneol=native#text/plain
@@ -708,6 +710,7 @@ compiler/x86_64/aoptcpub.pas svneol=native#text/plain
 compiler/x86_64/aoptcpud.pas svneol=native#text/plain
 compiler/x86_64/cgcpu.pas svneol=native#text/plain
 compiler/x86_64/cpubase.inc svneol=native#text/plain
+compiler/x86_64/cpuelf.pas svneol=native#text/plain
 compiler/x86_64/cpuinfo.pas svneol=native#text/plain
 compiler/x86_64/cpunode.pas svneol=native#text/plain
 compiler/x86_64/cpupara.pas svneol=native#text/plain

+ 149 - 0
compiler/i386/cpuelf.pas

@@ -0,0 +1,149 @@
+{
+    Copyright (c) 1998-2006 by Peter Vreman
+
+    Includes ELF-related code specific to i386
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit cpuelf;
+
+{$i fpcdefs.inc}
+
+interface
+
+implementation
+
+  uses
+    verbose,
+    systems,ogbase,ogelf,assemble;
+
+  type
+    TElfObjOutput386=class(TElfObjectOutput)
+      function encodereloc(objrel:TObjRelocation):byte;override;
+    end;
+
+    TElfAssembler386=class(TInternalAssembler)
+      constructor create(smart:boolean);override;
+    end;
+
+  const
+    { Relocation types }
+    R_386_32 = 1;                    { ordinary absolute relocation }
+    R_386_PC32 = 2;                  { PC-relative relocation }
+    R_386_GOT32 = 3;                 { an offset into GOT }
+    R_386_PLT32 = 4;                 { a PC-relative offset into PLT }
+    R_386_COPY = 5;
+    R_386_GLOB_DAT = 6;
+    R_386_JUMP_SLOT = 7;
+    R_386_RELATIVE = 8;
+    R_386_GOTOFF = 9;                { an offset from GOT base }
+    R_386_GOTPC = 10;                { a PC-relative offset _to_ GOT }
+
+    R_386_TLS_TPOFF = 14;
+    R_386_TLS_IE = 15;
+    R_386_TLS_GOTIE = 16;
+    R_386_TLS_LE = 17;
+    R_386_TLS_GD = 18;
+    R_386_TLS_LDM = 19;
+    R_386_16 = 20;
+    R_386_PC16 = 21;
+    R_386_8 = 22;
+    R_386_PC8 = 23;
+    R_386_TLS_GD_32 = 24;
+    R_386_TLS_GD_PUSH = 25;
+    R_386_TLS_GD_CALL = 26;
+    R_386_TLS_GD_POP = 27;
+    R_386_TLS_LDM_32 = 28;
+    R_386_TLS_LDM_PUSH = 29;
+    R_386_TLS_LDM_CALL = 30;
+    R_386_TLS_LDM_POP = 31;
+    R_386_TLS_LDO_32 = 32;
+    R_386_TLS_IE_32 = 33;
+    R_386_TLS_LE_32 = 34;
+    R_386_TLS_DTPMOD32 = 35;
+    R_386_TLS_DTPOFF32 = 36;
+    R_386_TLS_TPOFF32 = 37;
+    { 38 is unused }
+    R_386_TLS_GOTDESC = 39;
+    R_386_TLS_DESC_CALL = 40;
+    R_386_TLS_DESC = 41;
+    R_386_IRELATIVE = 42;
+    R_386_GNU_VTINHERIT = 250;
+    R_386_GNU_VTENTRY = 251;
+
+
+{****************************************************************************
+                               TElfObjOutput386
+****************************************************************************}
+
+  function TElfObjOutput386.encodereloc(objrel:TObjRelocation):byte;
+    begin
+      case objrel.typ of
+        RELOC_RELATIVE :
+          result:=R_386_PC32;
+        RELOC_ABSOLUTE :
+          result:=R_386_32;
+        RELOC_GOT32 :
+          result:=R_386_GOT32;
+        RELOC_GOTPC :
+          result:=R_386_GOTPC;
+        RELOC_PLT32 :
+          result:=R_386_PLT32;
+      else
+        result:=0;
+        InternalError(2012082301);
+      end;
+    end;
+
+{****************************************************************************
+                               TElfAssembler386
+****************************************************************************}
+
+  constructor TElfAssembler386.create(smart:boolean);
+    begin
+      inherited Create(smart);
+      CObjOutput:=TElfObjOutput386;
+    end;
+
+
+{*****************************************************************************
+                                    Initialize
+*****************************************************************************}
+
+  const
+    as_i386_elf32_info : tasminfo =
+       (
+         id     : as_i386_elf32;
+         idtxt  : 'ELF';
+         asmbin : '';
+         asmcmd : '';
+         supported_targets : [system_i386_linux,system_i386_beos,
+                              system_i386_freebsd,system_i386_haiku,
+                              system_i386_openbsd,system_i386_netbsd,
+                              system_i386_Netware,system_i386_netwlibc,
+                              system_i386_solaris,system_i386_embedded];
+         flags : [af_outputbinary,af_smartlink_sections,af_supports_dwarf];
+         labelprefix : '.L';
+         comment : '';
+         dollarsign: '$';
+       );
+
+initialization
+  RegisterAssembler(as_i386_elf32_info,TElfAssembler386);
+
+end.
+

+ 1 - 0
compiler/i386/cputarg.pas

@@ -101,6 +101,7 @@ implementation
       ,ogcoff
       ,ogelf
       ,ogmacho
+      ,cpuelf
 
 {**************************************
         Assembler Readers

+ 38 - 237
compiler/ogelf.pas

@@ -85,14 +85,12 @@ interface
          procedure section_create_relocsec(p:TObject;arg:pointer);
          procedure section_write_sechdr(p:TObject;arg:pointer);
        protected
+         function encodereloc(objrel:TObjRelocation):byte;virtual;abstract;
          function writedata(data:TObjData):boolean;override;
        public
          constructor Create(AWriter:TObjectWriter);override;
        end;
 
-       TElfAssembler = class(tinternalassembler)
-         constructor create(smart:boolean);override;
-       end;
 
 
 implementation
@@ -106,75 +104,6 @@ implementation
       symbolresize = 200*18;
 
     const
-      { Relocation types }
-{$ifdef i386}
-      R_386_32 = 1;                    { ordinary absolute relocation }
-      R_386_PC32 = 2;                  { PC-relative relocation }
-      R_386_GOT32 = 3;                 { an offset into GOT }
-      R_386_PLT32 = 4;                 { a PC-relative offset into PLT }
-      R_386_COPY = 5;
-      R_386_GLOB_DAT = 6;
-      R_386_JUMP_SLOT = 7;
-      R_386_RELATIVE = 8;
-      R_386_GOTOFF = 9;                { an offset from GOT base }
-      R_386_GOTPC = 10;                { a PC-relative offset _to_ GOT }
-      R_386_GNU_VTINHERIT = 250;
-      R_386_GNU_VTENTRY = 251;
-{$endif i386}
-{$ifdef sparc}
-      R_SPARC_32 = 3;
-      R_SPARC_WDISP30 = 7;
-      R_SPARC_HI22 = 9;
-      R_SPARC_LO10 = 12;
-      R_SPARC_GNU_VTINHERIT = 250;
-      R_SPARC_GNU_VTENTRY = 251;
-{$endif sparc}
-{$ifdef x86_64}
-      R_X86_64_NONE = 0;
-      R_X86_64_64 = 1;                 { Direct 64 bit   }
-      R_X86_64_PC32 = 2;               { PC relative 32 bit signed  }
-      R_X86_64_GOT32 = 3;              { 32 bit GOT entry  }
-      R_X86_64_PLT32 = 4;              { 32 bit PLT address  }
-      R_X86_64_COPY = 5;               { Copy symbol at runtime  }
-      R_X86_64_GLOB_DAT = 6;           { Create GOT entry  }
-      R_X86_64_JUMP_SLOT = 7;          { Create PLT entry  }
-      R_X86_64_RELATIVE = 8;           { Adjust by program base  }
-      R_X86_64_GOTPCREL = 9;           { 32 bit signed PC relative offset to GOT  }
-      R_X86_64_32 = 10;                { Direct 32 bit zero extended  }
-      R_X86_64_32S = 11;               { Direct 32 bit sign extended  }
-      R_X86_64_16 = 12;                { Direct 16 bit zero extended  }
-      R_X86_64_PC16 = 13;              { 16 bit sign extended PC relative  }
-      R_X86_64_8 = 14;                 { Direct 8 bit sign extended   }
-      R_X86_64_PC8 = 15;               { 8 bit sign extended PC relative  }
-      R_X86_64_DTPMOD64 = 16;          { ID of module containing symbol  }
-      R_X86_64_DTPOFF64 = 17;          { Offset in module's TLS block  }
-      R_X86_64_TPOFF64 = 18;           { Offset in initial TLS block  }
-      { 32 bit signed PC relative offset to two GOT entries for GD symbol  }
-      R_X86_64_TLSGD = 19;
-      { 32 bit signed PC relative offset to two GOT entries for LD symbol  }
-      R_X86_64_TLSLD = 20;
-      R_X86_64_DTPOFF32 = 21;          { Offset in TLS block  }
-      { 32 bit signed PC relative offset to GOT entry for IE symbol  }
-      R_X86_64_GOTTPOFF = 22;
-      R_X86_64_TPOFF32 = 23;           { Offset in initial TLS block  }
-      R_X86_64_PC64 = 24;              { PC relative 64-bit signed }
-      R_X86_64_GOTOFF64 = 25;          { 64-bit offset from GOT base }
-      R_X86_64_GOTPC32 = 26;           { PC-relative offset GOT }
-      R_X86_64_GOT64  = 27;            { 64-bit GOT entry offset }
-      R_X86_64_GOTPCREL64 = 28;        { 64-bit PC relative offset to GOT entry }
-      R_X86_64_GOTPC64 = 29;           { 64-bit PC relative offset to GOT }
-      R_X86_64_GOTPLT64 = 30;          { Like GOT64, indicates that PLT entry needed }
-      R_X86_64_PLTOFF64 = 31;          { 64-bit GOT relative offset to PLT entry }
-      R_X86_64_SIZE32 = 32;
-      R_X86_64_SIZE64 = 33;
-      R_X86_64_GOTPC32_TLSDESC = 34;
-      R_X86_64_TLSDESC_CALL = 35;
-      R_X86_64_TLSDESC = 36;
-      R_X86_64_IRELATIVE = 37;
-      R_X86_64_GNU_VTINHERIT = 250;    { GNU extension to record C++ vtable hierarchy }
-      R_X86_64_GNU_VTENTRY = 251;      { GNU extension to record C++ vtable member usage }
-{$endif x86_64}
-
       { ELFHeader.file_class }
       ELFCLASSNONE  = 0;
       ELFCLASS32    = 1;
@@ -1029,7 +958,7 @@ implementation
         if assigned(objreloc) then
           begin
             objreloc.size:=len;
-            if reltype in [RELOC_RELATIVE,RELOC_PLT32{$ifdef x86_64},RELOC_GOTPCREL{$endif}] then
+            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
               begin
@@ -1165,95 +1094,45 @@ implementation
         i    : longint;
         rel  : telfreloc;
         objreloc : TObjRelocation;
-        relsym,
-        reltyp   : longint;
+        relsym   : longint;
         relocsect : TElfObjSection;
       begin
-        with data do
-         begin
-           { create the reloc section }
-           relocsect:=TElfObjSection.create_reloc(data,s.name,false);
-           relocsect.shlink:=symtabsect.index;
-           relocsect.shinfo:=s.index;
-           { add the relocations }
-           for i:=0 to s.Objrelocations.count-1 do
-             begin
-               objreloc:=TObjRelocation(s.Objrelocations[i]);
-               fillchar(rel,sizeof(rel),0);
-               rel.address:=objreloc.dataoffset;
-               rel.addend:=objreloc.orgsize;
-
-               { when things settle down, we can create processor specific
-                 derived classes }
-               case objreloc.typ of
-{$ifdef i386}
-                 RELOC_RELATIVE :
-                   reltyp:=R_386_PC32;
-                 RELOC_ABSOLUTE :
-                   reltyp:=R_386_32;
-                 RELOC_GOT32 :
-                   reltyp:=R_386_GOT32;
-                 RELOC_GOTPC :
-                   reltyp:=R_386_GOTPC;
-                 RELOC_PLT32 :
-                   reltyp:=R_386_PLT32;
-{$endif i386}
-{$ifdef sparc}
-                 RELOC_ABSOLUTE :
-                   reltyp:=R_SPARC_32;
-{$endif sparc}
-{$ifdef x86_64}
-    { Note: 8 and 16-bit relocations are known to be non-conformant with
-      AMD64 ABI, so they aren't handled. }
-                 RELOC_RELATIVE :
-                   if objreloc.size=8 then
-                     reltyp:=R_X86_64_PC64
-                   else if objreloc.size=4 then
-                     reltyp:=R_X86_64_PC32
-                   else
-                     InternalError(2012061900);
-                 RELOC_ABSOLUTE :
-                   if objreloc.size=8 then
-                     reltyp:=R_X86_64_64
-                   else if objreloc.size=4 then
-                     reltyp:=R_X86_64_32
-                   else
-                     InternalError(2012061901);
-                 RELOC_ABSOLUTE32 :
-                   reltyp:=R_X86_64_32S;
-                 RELOC_GOTPCREL :
-                   reltyp:=R_X86_64_GOTPCREL;
-                 RELOC_PLT32 :
-                   reltyp:=R_X86_64_PLT32;
-{$endif x86_64}
-                 else
-                   internalerror(200602261);
-               end;
+        { create the reloc section }
+        relocsect:=TElfObjSection.create_reloc(data,s.name,false);
+        relocsect.shlink:=symtabsect.index;
+        relocsect.shinfo:=s.index;
+        { add the relocations }
+        for i:=0 to s.Objrelocations.count-1 do
+          begin
+            objreloc:=TObjRelocation(s.Objrelocations[i]);
 
-               { Symbol }
-               if assigned(objreloc.symbol) then
-                 begin
-                   if objreloc.symbol.symidx=-1 then
-                     begin
-                       writeln(objreloc.symbol.Name);
-                       internalerror(200603012);
-                     end;
-                   relsym:=objreloc.symbol.symidx;
-                 end
-               else
-                 begin
-                   if objreloc.objsection<>nil then
-                     relsym:=objreloc.objsection.secsymidx
-                   else
-                     relsym:=SHN_UNDEF;
-                 end;
-               rel.info:=ELF_R_INFO(relsym,reltyp);
-               { write reloc }
-               { ElfXX_Rel is essentially ElfXX_Rela without the addend field. }
-               MaybeSwapElfReloc(rel);
-               relocsect.write(rel,relocsect.shentsize);
-             end;
-         end;
+            { Symbol }
+            if assigned(objreloc.symbol) then
+              begin
+                if objreloc.symbol.symidx=-1 then
+                  begin
+                    writeln(objreloc.symbol.Name);
+                    internalerror(200603012);
+                  end;
+                relsym:=objreloc.symbol.symidx;
+              end
+            else
+              begin
+                if objreloc.objsection<>nil then
+                  relsym:=objreloc.objsection.secsymidx
+                else
+                  relsym:=SHN_UNDEF;
+              end;
+
+            rel.address:=objreloc.dataoffset;
+            rel.info:=ELF_R_INFO(relsym,encodereloc(objreloc));
+            rel.addend:=objreloc.orgsize;
+
+            { write reloc }
+            { ElfXX_Rel is essentially ElfXX_Rela without the addend field. }
+            MaybeSwapElfReloc(rel);
+            relocsect.write(rel,relocsect.shentsize);
+          end;
       end;
 
 
@@ -1437,82 +1316,4 @@ implementation
       end;
 
 
-{****************************************************************************
-                               TELFAssembler
-****************************************************************************}
-
-    constructor TElfAssembler.Create(smart:boolean);
-      begin
-        inherited Create(smart);
-        CObjOutput:=TElfObjectOutput;
-      end;
-
-
-{*****************************************************************************
-                                  Initialize
-*****************************************************************************}
-
-{$ifdef i386}
-     const
-       as_i386_elf32_info : tasminfo =
-          (
-            id     : as_i386_elf32;
-            idtxt  : 'ELF';
-            asmbin : '';
-            asmcmd : '';
-            supported_targets : [system_i386_linux,system_i386_beos,
-                                 system_i386_freebsd,system_i386_haiku,
-                                 system_i386_openbsd,system_i386_netbsd,
-                                 system_i386_Netware,system_i386_netwlibc,
-	                         system_i386_solaris,system_i386_embedded];
-            flags : [af_outputbinary,af_smartlink_sections,af_supports_dwarf];
-            labelprefix : '.L';
-            comment : '';
-            dollarsign: '$';
-          );
-{$endif i386}
-{$ifdef x86_64}
-     const
-       as_x86_64_elf64_info : tasminfo =
-          (
-            id     : as_x86_64_elf64;
-            idtxt  : 'ELF';
-            asmbin : '';
-            asmcmd : '';
-            supported_targets : [system_x86_64_linux,system_x86_64_freebsd,
-                                 system_x86_64_openbsd,system_x86_64_netbsd];
-            flags : [af_outputbinary,af_smartlink_sections,af_supports_dwarf];
-            labelprefix : '.L';
-            comment : '';
-            dollarsign: '$';
-          );
-{$endif x86_64}
-{$ifdef sparc}
-     const
-       as_sparc_elf32_info : tasminfo =
-          (
-            id     : as_sparc_elf32;
-            idtxt  : 'ELF';
-            asmbin : '';
-            asmcmd : '';
-            supported_targets : [];
-//            flags : [af_outputbinary,af_smartlink_sections];
-            flags : [af_outputbinary,af_supports_dwarf];
-            labelprefix : '.L';
-            comment : '';
-            dollarsign: '$';
-          );
-{$endif sparc}
-
-
-initialization
-{$ifdef i386}
-  RegisterAssembler(as_i386_elf32_info,TElfAssembler);
-{$endif i386}
-{$ifdef sparc}
-  RegisterAssembler(as_sparc_elf32_info,TElfAssembler);
-{$endif sparc}
-{$ifdef x86_64}
-  RegisterAssembler(as_x86_64_elf64_info,TElfAssembler);
-{$endif x86_64}
 end.

+ 104 - 0
compiler/sparc/cpuelf.pas

@@ -0,0 +1,104 @@
+{
+    Copyright (c) 1998-2006 by Peter Vreman
+
+    Includes ELF-related code specific to SPARC
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit cpuelf;
+
+{$i fpcdefs.inc}
+
+interface
+
+implementation
+
+  uses
+    verbose,
+    systems,ogbase,ogelf,assemble;
+
+  type
+    TElfObjOutputSparc=class(TElfObjectOutput)
+      function encodereloc(objrel:TObjRelocation):byte;override;
+    end;
+
+    TElfAssemblerSparc=class(TInternalAssembler)
+      constructor create(smart:boolean);override;
+    end;
+
+  const
+    { Relocation types }
+    R_SPARC_32 = 3;
+    R_SPARC_WDISP30 = 7;
+    R_SPARC_HI22 = 9;
+    R_SPARC_LO10 = 12;
+    R_SPARC_GNU_VTINHERIT = 250;
+    R_SPARC_GNU_VTENTRY = 251;
+
+
+{****************************************************************************
+                               TElfObjOutputSparc
+****************************************************************************}
+
+   function TElfObjOutputSparc.encodereloc(objrel:TObjRelocation):byte;
+     begin
+       case objrel.typ of
+         RELOC_ABSOLUTE :
+           result:=R_SPARC_32;
+         { TODO }
+       else
+         result:=0;
+         InternalError(2012082303);
+       end;
+     end;
+
+
+{****************************************************************************
+                               TElfAssemblerSparc
+****************************************************************************}
+
+  constructor TElfAssembleri386.create(smart:boolean);
+    begin
+      inherited Create(smart);
+      CObjOutput:=TElfObjOutputSparc;
+    end;
+
+
+{*****************************************************************************
+                                    Initialize
+*****************************************************************************}
+
+  const
+    as_sparc_elf32_info : tasminfo =
+       (
+         id     : as_sparc_elf32;
+         idtxt  : 'ELF';
+         asmbin : '';
+         asmcmd : '';
+         supported_targets : [];
+//            flags : [af_outputbinary,af_smartlink_sections];
+         flags : [af_outputbinary,af_supports_dwarf];
+         labelprefix : '.L';
+         comment : '';
+         dollarsign: '$';
+       );
+
+initialization
+  RegisterAssembler(as_sparc_elf32_info,TElfAssemblerSparc);
+
+end.
+

+ 159 - 0
compiler/x86_64/cpuelf.pas

@@ -0,0 +1,159 @@
+{
+    Copyright (c) 1998-2006 by Peter Vreman
+
+    Includes ELF-related code specific to x86_64
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit cpuelf;
+
+{$i fpcdefs.inc}
+
+interface
+
+implementation
+
+  uses
+    verbose,
+    systems,ogbase,ogelf,assemble;
+
+  type
+    TElfObjOutputx86_64=class(TElfObjectOutput)
+      function encodereloc(objrel:TObjRelocation):byte;override;
+    end;
+
+    TElfAssemblerx86_64=class(TInternalAssembler)
+      constructor create(smart:boolean);override;
+    end;
+
+  const
+    { Relocation types }
+    R_X86_64_NONE = 0;
+    R_X86_64_64 = 1;                 { Direct 64 bit   }
+    R_X86_64_PC32 = 2;               { PC relative 32 bit signed  }
+    R_X86_64_GOT32 = 3;              { 32 bit GOT entry  }
+    R_X86_64_PLT32 = 4;              { 32 bit PLT address  }
+    R_X86_64_COPY = 5;               { Copy symbol at runtime  }
+    R_X86_64_GLOB_DAT = 6;           { Create GOT entry  }
+    R_X86_64_JUMP_SLOT = 7;          { Create PLT entry  }
+    R_X86_64_RELATIVE = 8;           { Adjust by program base  }
+    R_X86_64_GOTPCREL = 9;           { 32 bit signed PC relative offset to GOT  }
+    R_X86_64_32 = 10;                { Direct 32 bit zero extended  }
+    R_X86_64_32S = 11;               { Direct 32 bit sign extended  }
+    R_X86_64_16 = 12;                { Direct 16 bit zero extended  }
+    R_X86_64_PC16 = 13;              { 16 bit sign extended PC relative  }
+    R_X86_64_8 = 14;                 { Direct 8 bit sign extended   }
+    R_X86_64_PC8 = 15;               { 8 bit sign extended PC relative  }
+    R_X86_64_DTPMOD64 = 16;          { ID of module containing symbol  }
+    R_X86_64_DTPOFF64 = 17;          { Offset in module's TLS block  }
+    R_X86_64_TPOFF64 = 18;           { Offset in initial TLS block  }
+    { 32 bit signed PC relative offset to two GOT entries for GD symbol  }
+    R_X86_64_TLSGD = 19;
+    { 32 bit signed PC relative offset to two GOT entries for LD symbol  }
+    R_X86_64_TLSLD = 20;
+    R_X86_64_DTPOFF32 = 21;          { Offset in TLS block  }
+    { 32 bit signed PC relative offset to GOT entry for IE symbol  }
+    R_X86_64_GOTTPOFF = 22;
+    R_X86_64_TPOFF32 = 23;           { Offset in initial TLS block  }
+    R_X86_64_PC64 = 24;              { PC relative 64-bit signed }
+    R_X86_64_GOTOFF64 = 25;          { 64-bit offset from GOT base }
+    R_X86_64_GOTPC32 = 26;           { PC-relative offset GOT }
+    R_X86_64_GOT64  = 27;            { 64-bit GOT entry offset }
+    R_X86_64_GOTPCREL64 = 28;        { 64-bit PC relative offset to GOT entry }
+    R_X86_64_GOTPC64 = 29;           { 64-bit PC relative offset to GOT }
+    R_X86_64_GOTPLT64 = 30;          { Like GOT64, indicates that PLT entry needed }
+    R_X86_64_PLTOFF64 = 31;          { 64-bit GOT relative offset to PLT entry }
+    R_X86_64_SIZE32 = 32;
+    R_X86_64_SIZE64 = 33;
+    R_X86_64_GOTPC32_TLSDESC = 34;
+    R_X86_64_TLSDESC_CALL = 35;
+    R_X86_64_TLSDESC = 36;
+    R_X86_64_IRELATIVE = 37;
+    R_X86_64_GNU_VTINHERIT = 250;    { GNU extension to record C++ vtable hierarchy }
+    R_X86_64_GNU_VTENTRY = 251;      { GNU extension to record C++ vtable member usage }
+
+
+{****************************************************************************
+                              TELFObjectOutputx86_64
+****************************************************************************}
+
+  function TElfObjOutputx86_64.encodereloc(objrel:TObjRelocation):byte;
+    begin
+      case objrel.typ of
+      { Note: 8 and 16-bit relocations are known to be non-conformant with
+        AMD64 ABI, so they aren't handled. }
+        RELOC_RELATIVE :
+          if objrel.size=8 then
+            result:=R_X86_64_PC64
+          else if objrel.size=4 then
+            result:=R_X86_64_PC32
+          else
+            InternalError(2012061900);
+        RELOC_ABSOLUTE :
+          if objrel.size=8 then
+            result:=R_X86_64_64
+          else if objrel.size=4 then
+            result:=R_X86_64_32
+          else
+            InternalError(2012061901);
+        RELOC_ABSOLUTE32 :
+          result:=R_X86_64_32S;
+        RELOC_GOTPCREL :
+          result:=R_X86_64_GOTPCREL;
+        RELOC_PLT32 :
+          result:=R_X86_64_PLT32;
+      else
+        result:=0;
+        InternalError(2012082302);
+      end;
+    end;
+
+{****************************************************************************
+                               TELFAssemblerx86_64
+****************************************************************************}
+
+  constructor TElfAssemblerx86_64.create(smart:boolean);
+    begin
+      inherited Create(smart);
+      CObjOutput:=TElfObjOutputx86_64;
+    end;
+
+
+{*****************************************************************************
+                                    Initialize
+*****************************************************************************}
+
+  const
+    as_x86_64_elf64_info : tasminfo =
+      (
+        id     : as_x86_64_elf64;
+        idtxt  : 'ELF';
+        asmbin : '';
+        asmcmd : '';
+        supported_targets : [system_x86_64_linux,system_x86_64_freebsd,
+                             system_x86_64_openbsd,system_x86_64_netbsd];
+        flags : [af_outputbinary,af_smartlink_sections,af_supports_dwarf];
+        labelprefix : '.L';
+        comment : '';
+        dollarsign: '$';
+      );
+
+initialization
+  RegisterAssembler(as_x86_64_elf64_info,TElfAssemblerx86_64);
+
+end.
+

+ 1 - 0
compiler/x86_64/cputarg.pas

@@ -63,6 +63,7 @@ implementation
 
       ,ogcoff
       ,ogelf
+      ,cpuelf
 
 {**************************************
         Assembler Readers