This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[patch] x86-64 merger part1 - elf64-x86-64 support


Hi
I've implemented support for AMD x86-64 architecture (see
http://www.x86-64.org) to binutils and in the following weeks I would like to
merge it to the mainline.  Currently the code is stable enought to pass
gcc/binutils testsuite on x86-64 runtime and build almost booting kernel (it
don't boot because of kernel bugs).  Only very few known bugs remain and of
course I will fix them before merging relevant parts.

Code is not functionally complette - the missing bits are PIC support and SSE-2.
I would like to avoid these from the first wave of merger anyway, since they
add unnecesary complications to the code and would make it harder to review.

Since the merger is quite large, especially on the gas side, where x86-64 code
is implemented inside existing i386 backend, please let me know what way
would be most convenient for you.

As first experiment, I've prepared patch to bfd that adds basics support for
the elf64-x86-64 format.  Hope that it is easy to review and in the shape ready
for inclusion.

Honza

Mon Nov 27 16:23:49 MET 2000  Jan Hubicka  <jh@suse.cz>
	* Makefile.am (BFD64_BACKENDS): Add elf64-x86-64.lo
	BFD64_BACKENDS_CFILES): Add elf64-x86-64.c
	(elf64-x86-64.lo): Add dependencies.
	* archures.c (DESCRIPTION): Add bfd_mach_x86_64,
	bfd_mach_x86_64_intel_syntax.
	* elf.c (prep_headers): Use EM_x86_64 for 64bit output.
	* config.bfd (x86_64): Add.
	* configure.in: Add support for bfd_elf64_x86_64_vec.
	* cpu-i386.c (bfd_x86_64_arch_intel_syntax, bfd_x86_64_arch): Add.
	(bfd_i386_arch, i8086_ar): Link in.
	* elf64-x86-64.c: New file.
	* reloc.c (ENUMDOC): Add BFD_RELOC_X86_64*.
	* targets.c (bfd_elf64_x86_64_vec): Add.
	(bfd_target_vect): Add bfd_elf64_x86_64_vec.

Mon Nov 27 16:28:06 MET 2000  Jan Hubicka  <jh@suse.cz>
	* common.h (EM_X86_64): New macro.
	* x86-64.h: New file.
diff -Nrc3p bu/binutils-001127/bfd/Makefile.am binutils/bfd/Makefile.am
*** bu/binutils-001127/bfd/Makefile.am	Tue Nov  7 01:43:24 2000
--- binutils/bfd/Makefile.am	Mon Nov 27 14:10:48 2000
*************** BFD64_BACKENDS = \
*** 411,416 ****
--- 411,417 ----
  	coff64-rs6000.lo \
  	demo64.lo \
  	efi-app-ia64.lo \
+ 	elf64-x86-64.lo \
  	elf64-alpha.lo \
  	elf64-hppa.lo \
  	elf64-ia64.lo \
*************** BFD64_BACKENDS_CFILES = \
*** 427,432 ****
--- 428,434 ----
  	coff64-rs6000.c \
  	demo64.c \
  	efi-app-ia64.c \
+ 	elf64-x86-64.c \
  	elf64-alpha.c \
  	elf64-hppa.c \
  	elf64-ia64.c \
*************** elf64-hppa.lo: elf64-hppa.c $(INCDIR)/fi
*** 1253,1258 ****
--- 1255,1264 ----
  elf64-ia64.lo: elf64-ia64.c $(INCDIR)/filenames.h elf-bfd.h \
    $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
    $(INCDIR)/bfdlink.h $(INCDIR)/opcode/ia64.h $(INCDIR)/elf/ia64.h \
+   $(INCDIR)/elf/reloc-macros.h elf64-target.h
+ elf64-x86-64.lo: elf64-x86-64.c $(INCDIR)/filenames.h elf-bfd.h \
+   $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+   $(INCDIR)/bfdlink.h $(INCDIR)/opcode/i386.h $(INCDIR)/elf/x86-64.h \
    $(INCDIR)/elf/reloc-macros.h elf64-target.h
  elf64-gen.lo: elf64-gen.c $(INCDIR)/filenames.h elf-bfd.h \
    $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
diff -Nrc3p bu/binutils-001127/bfd/archures.c binutils/bfd/archures.c
*** bu/binutils-001127/bfd/archures.c	Sat Nov 25 01:21:34 2000
--- binutils/bfd/archures.c	Mon Nov 27 14:10:51 2000
*************** DESCRIPTION
*** 136,141 ****
--- 136,143 ----
  .#define bfd_mach_i386_i386 0
  .#define bfd_mach_i386_i8086 1
  .#define bfd_mach_i386_i386_intel_syntax 2
+ .#define bfd_mach_x86_64 3
+ .#define bfd_mach_x86_64_intel_syntax 4
  .  bfd_arch_we32k,     {* AT&T WE32xxx *}
  .  bfd_arch_tahoe,     {* CCI/Harris Tahoe *}
  .  bfd_arch_i860,      {* Intel 860 *}
*** bu/binutils-001127/bfd/elf.c	Wed Oct 11 09:05:01 2000
--- binutils/bfd/elf.c	Mon Nov 27 14:11:03 2000
*************** prep_headers (abfd)
*** 3306,3312 ****
        i_ehdrp->e_machine = EM_S370;
        break;
      case bfd_arch_i386:
!       i_ehdrp->e_machine = EM_386;
        break;
      case bfd_arch_ia64:
        i_ehdrp->e_machine = EM_IA_64;
--- 3306,3315 ----
        i_ehdrp->e_machine = EM_S370;
        break;
      case bfd_arch_i386:
!       if (bfd_get_arch_size (abfd) == 64)
! 	i_ehdrp->e_machine = EM_X86_64;
!       else
! 	i_ehdrp->e_machine = EM_386;
        break;
      case bfd_arch_ia64:
        i_ehdrp->e_machine = EM_IA_64;
diff -Nrc3p bu/binutils-001127/bfd/config.bfd binutils/bfd/config.bfd
*** bu/binutils-001127/bfd/config.bfd	Sat Nov 25 01:21:34 2000
--- binutils/bfd/config.bfd	Mon Nov 27 14:10:58 2000
*************** alpha*) targ_archs=bfd_alpha_arch ;;
*** 32,40 ****
  arm*)	targ_archs=bfd_arm_arch ;;
  strongarm*) targ_archs=bfd_arm_arch ;;
  thumb*)	targ_archs=bfd_arm_arch ;;
  c30*)	targ_archs=bfd_tic30_arch ;;
  c54x*)	targ_archs=bfd_tic54x_arch ;;
  hppa*)	targ_archs=bfd_hppa_arch ;;
  i[3456]86) targ_archs=bfd_i386_arch ;;
  i370)   targ_archs=bfd_i370_arch ;;
  m6811*|m68hc11*) targ_archs="bfd_m68hc11_arch bfd_m68hc12_arch" ;;
--- 32,41 ----
  arm*)	targ_archs=bfd_arm_arch ;;
  strongarm*) targ_archs=bfd_arm_arch ;;
  thumb*)	targ_archs=bfd_arm_arch ;;
  c30*)	targ_archs=bfd_tic30_arch ;;
  c54x*)	targ_archs=bfd_tic54x_arch ;;
  hppa*)	targ_archs=bfd_hppa_arch ;;
+ x86_64) targ_archs=bfd_i386_arch ;;
  i[3456]86) targ_archs=bfd_i386_arch ;;
  i370)   targ_archs=bfd_i370_arch ;;
  m6811*|m68hc11*) targ_archs="bfd_m68hc11_arch bfd_m68hc12_arch" ;;
*************** case "${targ}" in
*** 350,355 ****
--- 341,350 ----
    i[3456]86-*-linux-gnu*)
      targ_defvec=bfd_elf32_i386_vec
      targ_selvecs="i386linux_vec bfd_efi_app_ia32_vec"
+     ;;
+   x86_64-*-linux-gnu*)
+     targ_defvec=bfd_elf64_x86_64_vec
+     targ_selvecs="bfd_elf32_i386_vec i386linux_vec bfd_efi_app_ia32_vec"
      ;;
    i[3456]86-*-lynxos*)
      targ_defvec=i386lynx_coff_vec
*** bu/binutils-001127/bfd/configure.in	Mon Nov 27 14:38:30 2000
--- binutils/bfd/configure.in	Mon Nov 27 14:10:59 2000
*************** do
*** 507,512 ****
--- 507,513 ----
      bfd_elf32_hppa_vec)		tb="$tb elf32-hppa.lo elf32.lo $elf" ;;
      bfd_elf32_i370_vec)		tb="$tb elf32-i370.lo elf32.lo $elf" ;;
      bfd_elf32_i386_vec)		tb="$tb elf32-i386.lo elf32.lo $elf" ;;
+     bfd_elf64_x86_64_vec)	tb="$tb elf64-x86-64.lo elf64.lo $elf" ;;
      bfd_elf32_i860_vec)		tb="$tb elf32-i860.lo elf32.lo $elf" ;;
      bfd_elf32_i860_little_vec)	tb="$tb elf32-i860.lo elf32.lo $elf" ;;
      bfd_elf32_i960_vec)		tb="$tb elf32-i960.lo elf32.lo $elf" ;;
diff -Nrc3p bu/binutils-001127/bfd/cpu-i386.c binutils/bfd/cpu-i386.c
*** bu/binutils-001127/bfd/cpu-i386.c	Thu Nov 16 21:48:09 2000
--- binutils/bfd/cpu-i386.c	Mon Nov 27 14:10:59 2000
*************** const bfd_arch_info_type bfd_i386_arch_i
*** 36,41 ****
--- 36,56 ----
    bfd_default_scan ,
    0,
  };
+ const bfd_arch_info_type bfd_x86_64_arch_intel_syntax =
+ {
+   64,	/* 64 bits in a word */
+   64,	/* 64 bits in an address */
+   8,	/* 8 bits in a byte */
+   bfd_arch_i386,
+   bfd_mach_x86_64_intel_syntax,
+   "x86_64:intel",
+   "x86_64:intel",
+   3,
+   true,
+   bfd_default_compatible, 
+   bfd_default_scan ,
+   &bfd_i386_arch_intel_syntax,
+ };
  static const bfd_arch_info_type i8086_arch =
  {
    32,	/* 32 bits in a word */
*************** static const bfd_arch_info_type i8086_ar
*** 49,55 ****
    false,
    bfd_default_compatible,
    bfd_default_scan ,
!   &bfd_i386_arch_intel_syntax,
  };
  
  const bfd_arch_info_type bfd_i386_arch =
--- 64,86 ----
    false,
    bfd_default_compatible,
    bfd_default_scan ,
!   &bfd_x86_64_arch_intel_syntax,
! };
! 
! const bfd_arch_info_type bfd_x86_64_arch =
! {
!   64,	/* 32 bits in a word */
!   64,	/* 32 bits in an address */
!   8,	/* 8 bits in a byte */
!   bfd_arch_i386,
!   bfd_mach_x86_64,
!   "x86_64",
!   "x86_64",
!   3,
!   true,
!   bfd_default_compatible, 
!   bfd_default_scan ,
!   &i8086_arch,
  };
  
  const bfd_arch_info_type bfd_i386_arch =
*************** const bfd_arch_info_type bfd_i386_arch =
*** 65,70 ****
    true,
    bfd_default_compatible,
    bfd_default_scan ,
!   &i8086_arch,
  };
  
--- 96,101 ----
    true,
    bfd_default_compatible,
    bfd_default_scan ,
!   &bfd_x86_64_arch 
  };
  
diff -Nrc3p bu/binutils-001127/bfd/elf64-x86-64.c binutils/bfd/elf64-x86-64.c
*** bu/binutils-001127/bfd/elf64-x86-64.c	Thu Jan  1 01:00:00 1970
--- binutils/bfd/elf64-x86-64.c	Mon Nov 27 15:41:28 2000
***************
*** 0 ****
--- 1,353 ----
+ /* X86-64 specific support for 64-bit ELF
+    Copyright 2000 Free Software Foundation, Inc.
+    Contributed by Jan Hubicka <jh@suse.cz>.
+ 
+ This file is part of BFD, the Binary File Descriptor library.
+ 
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+ 
+ #include "bfd.h"
+ #include "sysdep.h"
+ #include "libbfd.h"
+ #include "elf-bfd.h"
+ 
+ #include "elf/x86-64.h"
+ 
+ /* We use only the RELA entries.  */
+ #define USE_RELA
+ 
+ /* In case we're on a 32-bit machine, construct a 64-bit "-1" value.  */
+ #define MINUS_ONE (~ (bfd_vma) 0)
+ 
+ /* The relocation "howto" table.  Order of fields:
+    type, size, bitsize, pc_relative, complain_on_overflow, special_function,
+    name, partial_inplace, src_mask, dst_pack, pcrel_offset  */
+ static reloc_howto_type x86_64_elf_howto_table[] =
+ {
+   HOWTO(R_X86_64_NONE,	  0,0, 0,false,0,complain_overflow_dont,    0, "R_X86_64_NONE",   false,0x00000000,0x00000000,false),
+   HOWTO(R_X86_64_64,	  0,4,64,false,0,complain_overflow_bitfield,0, "R_X86_64_64",     false,MINUS_ONE ,MINUS_ONE ,false),
+   HOWTO(R_X86_64_PC32,	  0,4,32,true ,0,complain_overflow_signed  ,0, "R_X86_64_PC32",   false,0xffffffff,0xffffffff,true),
+   HOWTO(R_X86_64_GOT32,	  0,4,32,false,0,complain_overflow_signed  ,0, "R_X86_64_GOT32",  false,0xffffffff,0xffffffff,false),
+   HOWTO(R_X86_64_PLT32,	  0,4,32,true ,0,complain_overflow_signed  ,0, "R_X86_64_PLT32",  false,0xffffffff,0xffffffff,true),
+   HOWTO(R_X86_64_COPY,     0,4,32,false,0,complain_overflow_bitfield,0, "R_X86_64_COPY",   false,0xffffffff,0xffffffff,false),
+   HOWTO(R_X86_64_GLOB_DAT, 0,4,64,false,0,complain_overflow_bitfield,0,"R_X86_64_GLOB_DAT",false,MINUS_ONE ,MINUS_ONE ,false),
+   HOWTO(R_X86_64_RELATIVE ,0,4,64,false,0,complain_overflow_bitfield,0,"R_X86_64_RELATIVE",false,MINUS_ONE ,MINUS_ONE ,false),
+   HOWTO(R_X86_64_JUMP_SLOT,0,4,64,false,0,complain_overflow_bitfield,0,"R_X86_64_JUMP_SLOT",false,MINUS_ONE,MINUS_ONE ,false),
+   HOWTO(R_X86_64_GOTPCREL, 0,4,32,true, 0,complain_overflow_signed  ,0, "R_X86_64_PCREL",  false,0xffffffff,0xffffffff,true),
+   HOWTO(R_X86_64_32,	  0,4,32,false,0,complain_overflow_unsigned,0, "R_X86_64_32",     false,0xffffffff,0xffffffff,false),
+   HOWTO(R_X86_64_32S,	  0,4,32,false,0,complain_overflow_signed,  0, "R_X86_64_32S",    false,0xffffffff,0xffffffff,false),
+   HOWTO(R_X86_64_16,	  0,1,16,false,0,complain_overflow_bitfield,0, "R_X86_64_16",     false,0xffff    ,0xffff,    false),
+   HOWTO(R_X86_64_PC16,	  0,1,16,true ,0,complain_overflow_bitfield,0, "R_X86_64_PC16",   false,0xffff    ,0xffff,    true),
+   HOWTO(R_X86_64_8,	  0,0, 8,false,0,complain_overflow_signed  ,0, "R_X86_64_8",      false,0xff      ,0xff,      false),
+   HOWTO(R_X86_64_PC8,	  0,0, 8,true ,0,complain_overflow_signed  ,0, "R_X86_64_PC8",    false,0xff      ,0xff,      true),
+ };
+ 
+ /* Map BFD relocs to the x86_64 elf relocs.  */
+ struct elf_reloc_map {
+   bfd_reloc_code_real_type bfd_reloc_val;
+   unsigned char elf_reloc_val;
+ };
+ 
+ static CONST struct elf_reloc_map x86_64_reloc_map[] =
+ {
+   { BFD_RELOC_NONE,		R_X86_64_NONE, },
+   { BFD_RELOC_64, 		R_X86_64_64,   },
+   { BFD_RELOC_32_PCREL,		R_X86_64_PC32, },
+   { BFD_RELOC_X86_64_GOT32,	R_X86_64_GOT32,},
+   { BFD_RELOC_X86_64_PLT32,	R_X86_64_PLT32,},
+   { BFD_RELOC_X86_64_COPY,	R_X86_64_COPY, },
+   { BFD_RELOC_X86_64_GLOB_DAT,	R_X86_64_GLOB_DAT, },
+   { BFD_RELOC_X86_64_JUMP_SLOT,	R_X86_64_JUMP_SLOT, },
+   { BFD_RELOC_X86_64_RELATIVE,	R_X86_64_RELATIVE, },
+   { BFD_RELOC_X86_64_GOTPCREL,	R_X86_64_GOTPCREL, },
+   { BFD_RELOC_32,		R_X86_64_32, },
+   { BFD_RELOC_X86_64_32S,	R_X86_64_32S, },
+   { BFD_RELOC_16,		R_X86_64_16, },
+   { BFD_RELOC_16_PCREL,		R_X86_64_PC16, },
+   { BFD_RELOC_8,		R_X86_64_8, },
+   { BFD_RELOC_8_PCREL,		R_X86_64_PC8, },
+ };
+ 
+ 
+ static reloc_howto_type *elf64_x86_64_reloc_type_lookup
+   PARAMS ((bfd *, bfd_reloc_code_real_type));
+ static void elf64_x86_64_info_to_howto
+   PARAMS ((bfd *, arelent *, Elf64_Internal_Rela *));
+ static struct bfd_link_hash_table *elf64_x86_64_link_hash_table_create
+   PARAMS ((bfd *));
+ static boolean elf64_x86_64_relocate_section
+   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ 	   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+ 
+ /* Given a BFD reloc type, return a HOWTO structure.  */
+ static reloc_howto_type *
+ elf64_x86_64_reloc_type_lookup (abfd, code)
+      bfd *abfd ATTRIBUTE_UNUSED;
+      bfd_reloc_code_real_type code;
+ {
+   unsigned int i;
+   for (i = 0; i < sizeof (x86_64_reloc_map) / sizeof (struct elf_reloc_map);
+        i++)
+     {
+       if (x86_64_reloc_map[i].bfd_reloc_val == code)
+ 	return &x86_64_elf_howto_table[(int)
+ 				       x86_64_reloc_map[i].elf_reloc_val];
+     }
+   return 0;
+ }
+ 
+ 
+ /* Given an x86_64 ELF reloc type, fill in an arelent structure.  */
+ static void
+ elf64_x86_64_info_to_howto (abfd, cache_ptr, dst)
+      bfd *abfd ATTRIBUTE_UNUSED;
+      arelent *cache_ptr;
+      Elf64_Internal_Rela *dst;
+ {
+   unsigned r_type;
+ 
+   r_type = ELF64_R_TYPE (dst->r_info);
+   BFD_ASSERT (r_type < (unsigned int) R_X86_64_max);
+   cache_ptr->howto = &x86_64_elf_howto_table[r_type];
+   BFD_ASSERT (r_type == cache_ptr->howto->type);
+ }
+ 
+ /* Hash table functions - these will be used by dynamic linking code and
+    right now they are needed to keep ld happy.  */
+ 
+ /* x86_64  ELF linker hash table.  */
+ 
+ struct elf64_x86_64_link_hash_table
+ {
+   struct elf_link_hash_table root;
+ };
+ 
+ 
+ /* Get the X86-64 ELF linker hash table from a link_info structure.  */
+ 
+ #define elf64_x86_64_hash_table(p) \
+   ((struct elf64_x86_64_link_hash_table *) ((p)->hash))
+ 
+ /* Create an X86-64 ELF linker hash table.  */
+ 
+ static struct bfd_link_hash_table *
+ elf64_x86_64_link_hash_table_create (abfd)
+      bfd *abfd;
+ {
+   struct elf64_x86_64_link_hash_table *ret;
+ 
+   ret = ((struct elf64_x86_64_link_hash_table *)
+ 	 bfd_alloc (abfd, sizeof (struct elf64_x86_64_link_hash_table)));
+   if (ret == (struct elf64_x86_64_link_hash_table *) NULL)
+     return NULL;
+ 
+   if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
+ 				       _bfd_elf_link_hash_newfunc))
+     {
+       bfd_release (abfd, ret);
+       return NULL;
+     }
+ 
+   return &ret->root.root;
+ }
+ 
+ boolean
+ elf64_x86_64_elf_object_p (abfd)
+      bfd *abfd;
+ {
+   /* Set the right machine number for an x86-64 elf64 file.  */
+   bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64);
+   return true;
+ }
+ 
+ /* Relocate an x86_64 ELF section.  */
+ 
+ static boolean
+ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
+ 			       contents, relocs, local_syms, local_sections)
+      bfd *output_bfd;
+      struct bfd_link_info *info;
+      bfd *input_bfd;
+      asection *input_section;
+      bfd_byte *contents;
+      Elf_Internal_Rela *relocs;
+      Elf_Internal_Sym *local_syms;
+      asection **local_sections;
+ {
+   bfd *dynobj;
+   Elf_Internal_Shdr *symtab_hdr;
+   struct elf_link_hash_entry **sym_hashes;
+   bfd_vma *local_got_offsets;
+   asection *sreloc;
+   Elf_Internal_Rela *rel;
+   Elf_Internal_Rela *relend;
+ 
+   dynobj = elf_hash_table (info)->dynobj;
+   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+   sym_hashes = elf_sym_hashes (input_bfd);
+   local_got_offsets = elf_local_got_offsets (input_bfd);
+ 
+   sreloc = NULL;
+   if (dynobj != NULL)
+     abort ();
+ 
+   rel = relocs;
+   relend = relocs + input_section->reloc_count;
+   for (; rel < relend; rel++)
+     {
+       int r_type;
+       reloc_howto_type *howto;
+       unsigned long r_symndx;
+       struct elf_link_hash_entry *h;
+       Elf_Internal_Sym *sym;
+       asection *sec;
+       bfd_vma relocation;
+       bfd_reloc_status_type r;
+       unsigned int indx;
+ 
+       r_type = ELF64_R_TYPE (rel->r_info);
+ 
+       if ((indx = (unsigned) r_type) >= R_X86_64_max)
+ 	{
+ 	  bfd_set_error (bfd_error_bad_value);
+ 	  return false;
+ 	}
+       howto = x86_64_elf_howto_table + indx;
+ 
+       r_symndx = ELF64_R_SYM (rel->r_info);
+ 
+       if (info->relocateable)
+ 	{
+ 	  /* This is a relocateable link.  We don't have to change
+ 	     anything, unless the reloc is against a section symbol,
+ 	     in which case we have to adjust according to where the
+ 	     section symbol winds up in the output section.  */
+ 	  if (r_symndx < symtab_hdr->sh_info)
+ 	    {
+ 	      sym = local_syms + r_symndx;
+ 	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ 		{
+ 		  sec = local_sections[r_symndx];
+ 		  rel->r_addend += sec->output_offset + sym->st_value;
+ 		}
+ 	    }
+ 
+ 	  continue;
+ 	}
+ 
+       /* This is a final link.  */
+       h = NULL;
+       sym = NULL;
+       sec = NULL;
+       if (r_symndx < symtab_hdr->sh_info)
+ 	{
+ 	  sym = local_syms + r_symndx;
+ 	  sec = local_sections[r_symndx];
+ 	  relocation = (sec->output_section->vma
+ 			+ sec->output_offset
+ 			+ sym->st_value);
+ 	}
+       else
+ 	{
+ 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ 	  while (h->root.type == bfd_link_hash_indirect
+ 		 || h->root.type == bfd_link_hash_warning)
+ 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ 	  if (h->root.type == bfd_link_hash_defined
+ 	      || h->root.type == bfd_link_hash_defweak)
+ 	    {
+ 	      sec = h->root.u.def.section;
+ 	      if (sec->output_section == NULL)
+ 		{
+ 		  (*_bfd_error_handler)
+ 		    (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
+ 		     bfd_get_filename (input_bfd), h->root.root.string,
+ 		     bfd_get_section_name (input_bfd, input_section));
+ 		  relocation = 0;
+ 		}
+ 	      else
+ 		relocation = (h->root.u.def.value
+ 			      + sec->output_section->vma
+ 			      + sec->output_offset);
+ 	    }
+ 	  else if (h->root.type == bfd_link_hash_undefweak)
+ 	    relocation = 0;
+ 	  else
+ 	    {
+ 	      if (! ((*info->callbacks->undefined_symbol)
+ 		     (info, h->root.root.string, input_bfd,
+ 		      input_section, rel->r_offset,
+ 		      (!info->shared || info->no_undefined
+ 		       || ELF_ST_VISIBILITY (h->other)))))
+ 		return false;
+ 	      relocation = 0;
+ 	    }
+ 	}
+       /* This function should support shared objects, but don't.  */
+       if (info->shared)
+ 	abort();
+ 
+       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ 				    contents, rel->r_offset,
+ 				    relocation, rel->r_addend);
+ 
+       if (r != bfd_reloc_ok)
+ 	{
+ 	  switch (r)
+ 	    {
+ 	    default:
+ 	    case bfd_reloc_outofrange:
+ 	      abort ();
+ 	    case bfd_reloc_overflow:
+ 	      {
+ 		const char *name;
+ 
+ 		if (h != NULL)
+ 		  name = h->root.root.string;
+ 		else
+ 		  {
+ 		    name = bfd_elf_string_from_elf_section (input_bfd,
+ 							    symtab_hdr->sh_link,
+ 							    sym->st_name);
+ 		    if (name == NULL)
+ 		      return false;
+ 		    if (*name == '\0')
+ 		      name = bfd_section_name (input_bfd, sec);
+ 		  }
+ 		if (! ((*info->callbacks->reloc_overflow)
+ 		       (info, name, howto->name, (bfd_vma) 0,
+ 			input_bfd, input_section, rel->r_offset)))
+ 		  return false;
+ 	      }
+ 	      break;
+ 	    }
+ 	}
+     }
+   return true;
+ }
+ 
+ 
+ #define TARGET_LITTLE_SYM		bfd_elf64_x86_64_vec
+ #define TARGET_LITTLE_NAME		"elf64-x86-64"
+ #define ELF_ARCH			bfd_arch_i386
+ #define ELF_MACHINE_CODE		EM_X86_64
+ #define ELF_MAXPAGESIZE			0x100000
+ #define elf_info_to_howto		elf64_x86_64_info_to_howto
+ #define bfd_elf64_bfd_reloc_type_lookup	elf64_x86_64_reloc_type_lookup
+ #define elf_backend_object_p            elf64_x86_64_elf_object_p
+ #define elf_backend_relocate_section	elf64_x86_64_relocate_section
+ #define bfd_elf64_bfd_link_hash_table_create elf64_x86_64_link_hash_table_create
+ 
+ #include "elf64-target.h"
diff -Nrc3p bu/binutils-001127/bfd/reloc.c binutils/bfd/reloc.c
*** bu/binutils-001127/bfd/reloc.c	Thu Nov 16 23:44:07 2000
--- binutils/bfd/reloc.c	Mon Nov 27 15:43:14 2000
*************** ENUMDOC
*** 2078,2083 ****
--- 2078,2102 ----
    i386/elf relocations
  
  ENUM
+   BFD_RELOC_X86_64_GOT32
+ ENUMX
+   BFD_RELOC_X86_64_PLT32
+ ENUMX
+   BFD_RELOC_X86_64_COPY
+ ENUMX
+   BFD_RELOC_X86_64_GLOB_DAT
+ ENUMX
+   BFD_RELOC_X86_64_JUMP_SLOT
+ ENUMX
+   BFD_RELOC_X86_64_RELATIVE
+ ENUMX
+   BFD_RELOC_X86_64_GOTPCREL
+ ENUMX
+   BFD_RELOC_X86_64_32S
+ ENUMDOC
+   x86-64/elf relocations
+ 
+ ENUM
    BFD_RELOC_NS32K_IMM_8
  ENUMX
    BFD_RELOC_NS32K_IMM_16
diff -Nrc3p bu/binutils-001127/bfd/targets.c binutils/bfd/targets.c
*** bu/binutils-001127/bfd/targets.c	Tue Nov  7 01:43:26 2000
--- binutils/bfd/targets.c	Mon Nov 27 14:11:21 2000
*************** extern const bfd_target bfd_elf32_shl_ve
*** 552,557 ****
--- 552,558 ----
  extern const bfd_target bfd_elf32_shlin_vec;
  extern const bfd_target bfd_elf32_shblin_vec;
  extern const bfd_target bfd_elf32_sparc_vec;
+ extern const bfd_target bfd_elf64_x86_64_vec;
  extern const bfd_target bfd_elf32_tradbigmips_vec;
  extern const bfd_target bfd_elf32_tradlittlemips_vec;
  extern const bfd_target bfd_elf32_v850_vec;
*************** const bfd_target * const bfd_target_vect
*** 738,743 ****
--- 739,747 ----
  	&bfd_elf32_hppa_vec,
  	&bfd_elf32_i370_vec,
  	&bfd_elf32_i386_vec,
+ #ifdef BFD64
+ 	&bfd_elf64_x86_64_vec,
+ #endif
  	&bfd_elf32_i860_vec,
  	&bfd_elf32_i860_little_vec,
  	&bfd_elf32_i960_vec,
diff -Nrc3p bu/binutils-001127/include/elf/common.h binutils/include/elf/common.h
*** bu/binutils-001127/include/elf/common.h	Thu Nov 23 00:19:15 2000
--- binutils/include/elf/common.h	Mon Oct  9 22:46:25 2000
*************** Foundation, Inc., 59 Temple Place - Suit
*** 140,145 ****
--- 140,146 ----
  #define EM_ME16	       59	/* Toyota ME16 processor */
  #define EM_ST100       60	/* STMicroelectronics ST100 processor */
  #define EM_TINYJ       61	/* Advanced Logic Corp. TinyJ embedded processor */
+ #define EM_X86_64      62	/* Advanced Micro Devices X86-64 processor */
  
  #define EM_FX66	       66	/* Siemens FX66 microcontroller */
  #define EM_ST9PLUS     67	/* STMicroelectronics ST9+ 8/16 bit microcontroller */
diff -Nrc3p bu/binutils-001127/include/elf/x86-64.h binutils/include/elf/x86-64.h
*** bu/binutils-001127/include/elf/x86-64.h	Thu Jan  1 01:00:00 1970
--- binutils/include/elf/x86-64.h	Mon Nov 27 15:40:05 2000
***************
*** 0 ****
--- 1,46 ----
+ /* x86_64 ELF support for BFD.
+    Copyright (C) 2000 Free Software Foundation, Inc.
+    Contributed by Jan Hubicka <jh@suse.cz>
+ 
+    This file is part of BFD, the Binary File Descriptor library.
+ 
+    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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+ 
+ #ifndef _ELF_X86_64_H
+ #define _ELF_X86_64_H
+ 
+ #include "elf/reloc-macros.h"
+ 
+ START_RELOC_NUMBERS (elf_x86_64_reloc_type)
+      RELOC_NUMBER (R_X86_64_NONE,	0)	/* No reloc */
+      RELOC_NUMBER (R_X86_64_64,		1)	/* Direct 64 bit  */
+      RELOC_NUMBER (R_X86_64_PC32,	2)	/* PC relative 32 bit signed */
+      RELOC_NUMBER (R_X86_64_GOT32,	3)	/* 32 bit GOT entry */
+      RELOC_NUMBER (R_X86_64_PLT32,	4)	/* 32 bit PLT address */
+      RELOC_NUMBER (R_X86_64_COPY,	5)	/* Copy symbol at runtime */
+      RELOC_NUMBER (R_X86_64_GLOB_DAT,	6)	/* Create GOT entry */
+      RELOC_NUMBER (R_X86_64_JUMP_SLOT,	7)	/* Create PLT entry */
+      RELOC_NUMBER (R_X86_64_RELATIVE,	8)	/* Adjust by program base */
+      RELOC_NUMBER (R_X86_64_GOTPCREL,	9)	/* 32 bit signed pc relative
+ 						   offset to GOT */
+      RELOC_NUMBER (R_X86_64_32,		10)	/* Direct 32 bit zero extended */
+      RELOC_NUMBER (R_X86_64_32S,		11)	/* Direct 32 bit sign extended */
+      RELOC_NUMBER (R_X86_64_16,		12)	/* Direct 16 bit zero extended */
+      RELOC_NUMBER (R_X86_64_PC16,	13)	/* 16 bit sign extended pc relative*/
+      RELOC_NUMBER (R_X86_64_8,		14)	/* Direct 8 bit sign extended */
+      RELOC_NUMBER (R_X86_64_PC8,		15)	/* 8 bit sign extended pc relative*/
+ END_RELOC_NUMBERS (R_X86_64_max)
+ 
+ #endif

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]