From: Andreas Jaeger Date: Wed, 14 Feb 2001 10:57:47 +0000 (+0000) Subject: 2001-02-14 Bo Thorsen X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=407443a31c6523427f8c252378d95dcd04c68678;p=binutils-gdb.git 2001-02-14 Bo Thorsen * elf64-x86-64.c: Small formatting fixes and rearrangements of code. (elf64_86_64_size_info): Struct added to fix a problem with the hashtable string entries. (elf64_x86_64_adjust_dynamic_symbol): Add generation of .got.plt. (elf64_x86_64_size_dynamic_sections): A FIXME removed. (elf64_x86_64_size_dynamic_sections): Fix a dynamic entry and remove the FIXME for this. (elf64_x86_64_adjust_dynamic_symbol): Fix check for unneeded .plt section. Also removed the FIXME for it. (x86_64_elf_howto_table): Use bfd_elf_generic_reloc. (ELF_DYNAMIC_INTERPRETER): Fix the name of the dynamic linker. (elf64_x86_64_finish_dynamic_sections): Enable .got.plt writing. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ae04d073982..9a0da2a172a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2001-02-14 Bo Thorsen + + * elf64-x86-64.c: Small formatting fixes and rearrangements of code. + (elf64_86_64_size_info): Struct added to fix a problem + with the hashtable string entries. + (elf64_x86_64_adjust_dynamic_symbol): Add generation of .got.plt. + (elf64_x86_64_size_dynamic_sections): A FIXME removed. + (elf64_x86_64_size_dynamic_sections): Fix a dynamic entry and + remove the FIXME for this. + (elf64_x86_64_adjust_dynamic_symbol): Fix check for unneeded .plt + section. Also removed the FIXME for it. + (x86_64_elf_howto_table): Use bfd_elf_generic_reloc. + (ELF_DYNAMIC_INTERPRETER): Fix the name of the dynamic linker. + (elf64_x86_64_finish_dynamic_sections): Enable .got.plt writing. + 2001-02-13 Richard Henderson * elfxx-ia64.c (elfNN_ia64_final_link): Set __gp if required diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 288377c734e..9e10c917f0d 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -32,26 +32,42 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #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 */ + 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_GOTPCREL",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), + HOWTO(R_X86_64_NONE, 0, 0, 0, false, 0, complain_overflow_dont, + bfd_elf_generic_reloc, "R_X86_64_NONE", false, 0x00000000, 0x00000000, false), + HOWTO(R_X86_64_64, 0, 4, 64, false, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_X86_64_64", false, MINUS_ONE, MINUS_ONE, false), + HOWTO(R_X86_64_PC32, 0, 4, 32, true, 0, complain_overflow_signed, + bfd_elf_generic_reloc, "R_X86_64_PC32", false, 0xffffffff, 0xffffffff, true), + HOWTO(R_X86_64_GOT32, 0, 4, 32, false, 0, complain_overflow_signed, + bfd_elf_generic_reloc, "R_X86_64_GOT32", false, 0xffffffff, 0xffffffff, false), + HOWTO(R_X86_64_PLT32, 0, 4, 32, true, 0, complain_overflow_signed, + bfd_elf_generic_reloc, "R_X86_64_PLT32", false, 0xffffffff, 0xffffffff, true), + HOWTO(R_X86_64_COPY, 0, 4, 32, false, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_X86_64_COPY", false, 0xffffffff, 0xffffffff, false), + HOWTO(R_X86_64_GLOB_DAT, 0, 4, 64, false, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_X86_64_GLOB_DAT", false, MINUS_ONE, MINUS_ONE, false), + HOWTO(R_X86_64_RELATIVE, 0, 4, 64, false, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_X86_64_RELATIVE", false, MINUS_ONE, MINUS_ONE, false), + HOWTO(R_X86_64_JUMP_SLOT, 0, 4, 64, false, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_X86_64_JUMP_SLOT", false, MINUS_ONE, MINUS_ONE, false), + HOWTO(R_X86_64_GOTPCREL, 0, 4, 32, true,0 , complain_overflow_signed, + bfd_elf_generic_reloc, "R_X86_64_GOTPCREL", false, 0xffffffff, 0xffffffff, true), + HOWTO(R_X86_64_32, 0, 4, 32, false, 0, complain_overflow_unsigned, + bfd_elf_generic_reloc, "R_X86_64_32", false, 0xffffffff, 0xffffffff, false), + HOWTO(R_X86_64_32S, 0, 4, 32, false, 0, complain_overflow_signed, + bfd_elf_generic_reloc, "R_X86_64_32S", false, 0xffffffff, 0xffffffff, false), + HOWTO(R_X86_64_16, 0, 1, 16, false, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_X86_64_16", false, 0xffff, 0xffff, false), + HOWTO(R_X86_64_PC16,0, 1, 16, true, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_X86_64_PC16", false, 0xffff, 0xffff, true), + HOWTO(R_X86_64_8, 0, 0, 8, false, 0, complain_overflow_signed, + bfd_elf_generic_reloc, "R_X86_64_8", false, 0xff, 0xff, false), + HOWTO(R_X86_64_PC8, 0, 0, 8, true, 0, complain_overflow_signed, + bfd_elf_generic_reloc, "R_X86_64_PC8", false, 0xff, 0xff, true) }; /* Map BFD relocs to the x86_64 elf relocs. */ @@ -97,7 +113,7 @@ static boolean elf64_x86_64_size_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); static boolean elf64_x86_64_relocate_section PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); + Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); static boolean elf64_x86_64_finish_dynamic_symbol PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, Elf_Internal_Sym *sym)); @@ -137,12 +153,12 @@ elf64_x86_64_info_to_howto (abfd, cache_ptr, dst) BFD_ASSERT (r_type == cache_ptr->howto->type); } -/* Functions for the x86-64 ELF linker. */ +/* Functions for the x86-64 ELF linker. */ -/* The name of the dynamic interpreter. This is put in the .interp +/* The name of the dynamic interpreter. This is put in the .interp section. */ -#define ELF_DYNAMIC_INTERPRETER "/lib/libd64.so.1" +#define ELF_DYNAMIC_INTERPRETER "/lib/ld64.so.1" /* The size in bytes of an entry in the global offset table. */ @@ -159,7 +175,7 @@ static const bfd_byte elf64_x86_64_plt0_entry[PLT_ENTRY_SIZE] = { 0xff, 0xb3, 8, 0, 0, 0, /* pushq GOT+8(%rip) */ 0xff, 0xa3, 16, 0, 0, 0, /* jmp GOT+16(%rip) */ - 0, 0, 0, 0 /* pad out to 16 bytes. */ + 0, 0, 0, 0 /* pad out to 16 bytes. */ }; /* Subsequent entries in a procedure linkage table look like this. */ @@ -167,7 +183,7 @@ static const bfd_byte elf64_x86_64_plt0_entry[PLT_ENTRY_SIZE] = static const bfd_byte elf64_x86_64_plt_entry[PLT_ENTRY_SIZE] = { 0xff, 0xa3, /* jmp *name@GOTPC(%rip) */ - 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */ + 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */ 0x68, /* pushq immediate */ 0, 0, 0, 0, /* replaced with index into relocation table. */ 0xe9, /* jmp relative */ @@ -175,10 +191,10 @@ static const bfd_byte elf64_x86_64_plt_entry[PLT_ENTRY_SIZE] = }; /* The x86-64 linker needs to keep track of the number of relocs that - it decides to copy in check_relocs for each symbol. This is so + it decides to copy in check_relocs for each symbol. This is so that it can discard PC relative relocs if it doesn't need them when linking with -Bsymbolic. We store the information in a field - extending the regular ELF linker hash table. */ + extending the regular ELF linker hash table. */ /* This structure keeps track of the number of PC relative relocs we have copied for a given symbol. */ @@ -205,7 +221,8 @@ struct elf64_x86_64_link_hash_entry /* x86-64 ELF linker hash table. */ -struct elf64_x86_64_link_hash_table { +struct elf64_x86_64_link_hash_table +{ struct elf_link_hash_table root; }; @@ -227,7 +244,7 @@ static boolean elf64_x86_64_discard_copies #define elf64_x86_64_hash_table(p) \ ((struct elf64_x86_64_link_hash_table *) ((p)->hash)) -/* Create an entry in an x86-64 ELF linker hash table. */ +/* Create an entry in an x86-64 ELF linker hash table. */ static struct bfd_hash_entry * elf64_x86_64_link_hash_newfunc (entry, table, string) @@ -239,7 +256,7 @@ elf64_x86_64_link_hash_newfunc (entry, table, string) (struct elf64_x86_64_link_hash_entry *) entry; /* Allocate the structure if it has not already been allocated by a - subclass. */ + subclass. */ if (ret == (struct elf64_x86_64_link_hash_entry *) NULL) ret = ((struct elf64_x86_64_link_hash_entry *) bfd_hash_allocate (table, @@ -351,7 +368,7 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs) { case R_X86_64_GOTPCREL: case R_X86_64_GOT32: - /* This symbol requires a global offset table entry. */ + /* This symbol requires a global offset table entry. */ if (sgot == NULL) { @@ -432,14 +449,14 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs) case R_X86_64_PLT32: /* This symbol requires a procedure linkage table entry. We - actually build the entry in adjust_dynamic_symbol, - because this might be a case of linking PIC code which is - never referenced by a dynamic object, in which case we - don't need to generate a procedure linkage table entry - after all. */ + actually build the entry in adjust_dynamic_symbol, + because this might be a case of linking PIC code which is + never referenced by a dynamic object, in which case we + don't need to generate a procedure linkage table entry + after all. */ /* If this is a local symbol, we resolve it directly without - creating a procedure linkage table entry. */ + creating a procedure linkage table entry. */ if (h == NULL) continue; @@ -464,7 +481,7 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs) into the shared library. However, if we are linking with -Bsymbolic, we do not need to copy a reloc against a global symbol which is defined in an object we are - including in the link (i.e., DEF_REGULAR is set). At + including in the link (i.e., DEF_REGULAR is set). At this point we have not seen all the input files, so it is possible that DEF_REGULAR is not set now but will be set later (it is never cleared). We account for that @@ -558,7 +575,7 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs) } /* Return the section that should be marked against GC for a given - relocation. */ + relocation. */ static asection * elf64_x86_64_gc_mark_hook (abfd, info, rel, h, sym) @@ -597,7 +614,7 @@ elf64_x86_64_gc_mark_hook (abfd, info, rel, h, sym) return NULL; } -/* Update the got entry reference counts for the section being removed. */ +/* Update the got entry reference counts for the section being removed. */ static boolean elf64_x86_64_gc_sweep_hook (abfd, info, sec, relocs) @@ -683,7 +700,7 @@ elf64_x86_64_gc_sweep_hook (abfd, info, sec, relocs) regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to change the definition to something the rest of the link can - understand. */ + understand. */ static boolean elf64_x86_64_adjust_dynamic_symbol (info, h) @@ -713,21 +730,16 @@ elf64_x86_64_adjust_dynamic_symbol (info, h) if (h->type == STT_FUNC || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) { - if (! elf_hash_table (info)->dynamic_sections_created) + if ((! info->shared + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 + && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0) + || (info->shared && h->plt.refcount <= 0)) { - /* FIXME: These are the sparc64 comment and then the i386 comment. - How we need to deal with this and why remains to be seen. */ - /* This case can occur if we saw a WPLT30 reloc in an input - file, but none of the input files were dynamic objects. - In such a case, we don't actually need to build a - procedure linkage table, and we can just do a WDISP30 - reloc instead. */ /* This case can occur if we saw a PLT32 reloc in an input file, but the symbol was never referred to by a dynamic object, or if all references were garbage collected. In such a case, we don't actually need to build a procedure linkage table, and we can just do a PC32 reloc instead. */ - /* i386 code: */ h->plt.offset = (bfd_vma) -1; h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; return true; @@ -750,7 +762,7 @@ elf64_x86_64_adjust_dynamic_symbol (info, h) /* If this symbol is not defined in a regular file, and we are not generating a shared library, then set the symbol to this - location in the .plt. This is required to make function + location in the .plt. This is required to make function pointers compare as equal between the normal executable and the shared library. */ if (! info->shared @@ -765,6 +777,12 @@ elf64_x86_64_adjust_dynamic_symbol (info, h) /* Make room for this entry. */ s->_raw_size += PLT_ENTRY_SIZE; + /* We also need to make an entry in the .got.plt section, which + will be placed in the .got section by the linker script. */ + s = bfd_get_section_by_name (dynobj, ".got.plt"); + BFD_ASSERT (s != NULL); + s->_raw_size += GOT_ENTRY_SIZE; + /* We also need to make an entry in the .rela.plt section. */ s = bfd_get_section_by_name (dynobj, ".rela.plt"); BFD_ASSERT (s != NULL); @@ -775,7 +793,7 @@ elf64_x86_64_adjust_dynamic_symbol (info, h) /* If this is a weak symbol, and there is a real definition, the processor independent code will have arranged for us to see the - real definition first, and we can just use the same value. */ + real definition first, and we can just use the same value. */ if (h->weakdef != NULL) { BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined @@ -786,12 +804,12 @@ elf64_x86_64_adjust_dynamic_symbol (info, h) } /* This is a reference to a symbol defined by a dynamic object which - is not a function. */ + is not a function. */ /* If we are creating a shared library, we must presume that the only references to the symbol are via the global offset table. For such cases we need not do anything here; the relocations will - be handled correctly by relocate_section. */ + be handled correctly by relocate_section. */ if (info->shared) return true; @@ -801,7 +819,7 @@ elf64_x86_64_adjust_dynamic_symbol (info, h) return true; /* We must allocate the symbol in our .dynbss section, which will - become part of the .bss section of the executable. There will be + become part of the .bss section of the executable. There will be an entry for this symbol in the .dynsym section. The dynamic object will contain position independent code, so all references from the dynamic object to this symbol will go through the global @@ -828,7 +846,7 @@ elf64_x86_64_adjust_dynamic_symbol (info, h) } /* We need to figure out the alignment required for this symbol. I - have no idea how ELF linkers handle this. 16-bytes is the size + have no idea how ELF linkers handle this. 16-bytes is the size of the largest type that requires hard alignment -- long double. */ /* FIXME: This is VERY ugly. Should be fixed for all architectures using this construct. */ @@ -884,10 +902,10 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info) else { /* We may have created entries in the .rela.got section. - However, if we are not creating the dynamic sections, we will - not actually use these entries. Reset the size of .rela.got, - which will cause it to get stripped from the output file - below. */ + However, if we are not creating the dynamic sections, we will + not actually use these entries. Reset the size of .rela.got, + which will cause it to get stripped from the output file + below. */ s = bfd_get_section_by_name (dynobj, ".rela.got"); if (s != NULL) s->_raw_size = 0; @@ -924,7 +942,7 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info) if (s->_raw_size == 0) { /* Strip this section if we don't need it; see the - comment below. */ + comment below. */ strip = true; } else @@ -953,7 +971,7 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info) asection *target; /* Remember whether there are any reloc sections other - than .rela.plt. */ + than .rela.plt. */ if (strcmp (name, ".rela.plt") != 0) { const char *outname; @@ -1006,7 +1024,7 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info) /* Add some entries to the .dynamic section. We fill in the values later, in elf64_x86_64_finish_dynamic_sections, but we must add the entries now so that we get the correct size for - the .dynamic section. The DT_DEBUG entry is filled in by the + the .dynamic section. The DT_DEBUG entry is filled in by the dynamic linker and used by the debugger. */ if (! info->shared) { @@ -1016,10 +1034,9 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info) if (plt) { - /* FIXME: Are all these needed? */ if (! bfd_elf64_add_dynamic_entry (info, DT_PLTGOT, 0) || ! bfd_elf64_add_dynamic_entry (info, DT_PLTRELSZ, 0) - || ! bfd_elf64_add_dynamic_entry (info, DT_PLTREL, DT_REL) + || ! bfd_elf64_add_dynamic_entry (info, DT_PLTREL, DT_RELA) || ! bfd_elf64_add_dynamic_entry (info, DT_JMPREL, 0)) return false; } @@ -1079,7 +1096,7 @@ elf64_x86_64_discard_copies (h, inf) static boolean elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) + contents, relocs, local_syms, local_sections) bfd *output_bfd; struct bfd_link_info *info; bfd *input_bfd; @@ -1155,7 +1172,7 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, continue; } - /* This is a final link. */ + /* This is a final link. */ h = NULL; sym = NULL; sec = NULL; @@ -1228,15 +1245,15 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, { /* This is actually a static link, or it is a -Bsymbolic link and the symbol is defined locally, or the symbol - was forced to be local because of a version file. We + was forced to be local because of a version file. We must initialize this entry in the global offset table. Since the offset must always be a multiple of 8, we use the least significant bit to record whether we have initialized it already. When doing a dynamic link, we create a .rela.got - relocation entry to initialize the value. This is - done in the finish_dynamic_symbol routine. */ + relocation entry to initialize the value. This is + done in the finish_dynamic_symbol routine. */ if ((off & 1) != 0) off &= ~1; else @@ -1258,8 +1275,8 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, off = local_got_offsets[r_symndx]; /* The offset must always be a multiple of 8. We use - the least significant bit to record whether we have - already generated the necessary reloc. */ + the least significant bit to record whether we have + already generated the necessary reloc. */ if ((off & 1) != 0) off &= ~1; else @@ -1312,15 +1329,15 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, { /* This is actually a static link, or it is a -Bsymbolic link and the symbol is defined locally, or the symbol - was forced to be local because of a version file. We + was forced to be local because of a version file. We must initialize this entry in the global offset table. Since the offset must always be a multiple of 8, we use the least significant bit to record whether we have initialized it already. When doing a dynamic link, we create a .rela.got - relocation entry to initialize the value. This is - done in the finish_dynamic_symbol routine. */ + relocation entry to initialize the value. This is + done in the finish_dynamic_symbol routine. */ if ((off & 1) != 0) off &= ~1; else @@ -1342,8 +1359,8 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, off = local_got_offsets[r_symndx]; /* The offset must always be a multiple of 8. We use - the least significant bit to record whether we have - already generated the necessary reloc. */ + the least significant bit to record whether we have + already generated the necessary reloc. */ if ((off & 1) != 0) off &= ~1; else @@ -1384,15 +1401,15 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, procedure linkage table. */ /* Resolve a PLT32 reloc against a local symbol directly, - without using the procedure linkage table. */ + without using the procedure linkage table. */ if (h == NULL) break; if (h->plt.offset == (bfd_vma) -1 || splt == NULL) { /* We didn't make a PLT entry for this symbol. This - happens when statically linking PIC code, or when - using -Bsymbolic. */ + happens when statically linking PIC code, or when + using -Bsymbolic. */ break; } @@ -1408,7 +1425,7 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, case R_X86_64_PC16: case R_X86_64_PC32: /* FIXME: The abi says the linker should make sure the value is - the same when it's zeroextended to 64 bit. */ + the same when it's zeroextended to 64 bit. */ if (info->shared && (input_section->flags & SEC_ALLOC) != 0 && ((r_type != R_X86_64_PC8 && r_type != R_X86_64_PC16 @@ -1424,7 +1441,7 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, /* When generating a shared object, these relocations are copied into the output file to be resolved at run - time. */ + time. */ if (sreloc == NULL) { @@ -1483,7 +1500,7 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, else { /* h->dynindx may be -1 if this symbol was marked to - become local. */ + become local. */ if (h == NULL || ((info->symbolic || h->dynindx == -1) && (h->elf_link_hash_flags @@ -1586,7 +1603,7 @@ elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym) Elf_Internal_Rela rela; /* This symbol has an entry in the procedure linkage table. Set - it up. */ + it up. */ BFD_ASSERT (h->dynindx != -1); @@ -1602,7 +1619,7 @@ elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym) plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; /* Get the offset into the .got table of the entry that - corresponds to this function. Each .got entry is GOT_ENTRY_SIZE + corresponds to this function. Each .got entry is GOT_ENTRY_SIZE bytes. The first three are reserved. */ got_offset = (plt_index + 3) * GOT_ENTRY_SIZE; @@ -1619,7 +1636,7 @@ elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym) bfd_put_64 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE), splt->contents + h->plt.offset + 12); - /* Fill in the entry in the global offset table. */ + /* Fill in the entry in the global offset table. */ bfd_put_64 (output_bfd, (splt->output_section->vma + splt->output_offset + h->plt.offset + 6), sgot->contents + got_offset); @@ -1637,7 +1654,7 @@ elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym) if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) { /* Mark the symbol as undefined, rather than as defined in - the .plt section. Leave the value alone. */ + the .plt section. Leave the value alone. */ sym->st_shndx = SHN_UNDEF; } } @@ -1696,8 +1713,7 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info) asection *splt; Elf64_External_Dyn *dyncon, *dynconend; - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL && sdyn != NULL); + BFD_ASSERT (sdyn != NULL); dyncon = (Elf64_External_Dyn *) sdyn->contents; dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size); @@ -1730,14 +1746,14 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info) case DT_RELASZ: /* FIXME: This comment and code is from elf64-alpha.c: */ /* My interpretation of the TIS v1.1 ELF document indicates - that RELASZ should not include JMPREL. This is not what + that RELASZ should not include JMPREL. This is not what the rest of the BFD does. It is, however, what the glibc ld.so wants. Do this fixup here until we found out who is right. */ s = bfd_get_section_by_name (output_bfd, ".rela.plt"); if (s) { - /* Subtract JMPREL size from RELASZ. */ + /* Subtract JMPREL size from RELASZ. */ dyn.d_un.d_val -= (s->_cooked_size ? s->_cooked_size : s->_raw_size); } @@ -1755,9 +1771,11 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info) } /* Initialize the contents of the .plt section. */ + splt = bfd_get_section_by_name (dynobj, ".plt"); + BFD_ASSERT (splt != NULL); if (splt->_raw_size > 0) { - memcpy (splt->contents, elf64_x86_64_plt0_entry, PLT_ENTRY_SIZE); + memcpy (splt->contents, elf64_x86_64_plt0_entry, PLT_ENTRY_SIZE); } elf_section_data (splt->output_section)->this_hdr.sh_entsize = @@ -1766,7 +1784,7 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info) /* Set the first entry in the global offset table to the address of the dynamic section. */ - sgot = bfd_get_section_by_name (dynobj, ".got"); + sgot = bfd_get_section_by_name (dynobj, ".got.plt"); BFD_ASSERT (sgot != NULL); if (sgot->_raw_size > 0) { @@ -1787,12 +1805,49 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info) return true; } +/* + * Why was the hash table entry size definition changed from + * ARCH_SIZE/8 to 4? This breaks the 64 bit dynamic linker and + * this is the only reason for the elf64_x86_64_size_info structure. + */ + +const struct elf_size_info elf64_86_64_size_info = +{ + sizeof (Elf64_External_Ehdr), + sizeof (Elf64_External_Phdr), + sizeof (Elf64_External_Shdr), + sizeof (Elf64_External_Rel), + sizeof (Elf64_External_Rela), + sizeof (Elf64_External_Sym), + sizeof (Elf64_External_Dyn), + sizeof (Elf_External_Note), + 8, /* hash-table entry size */ + 1, /* internal relocations per external relocations */ + 64, /* arch_size */ + 8, /* file_align */ + ELFCLASS64, EV_CURRENT, + bfd_elf64_write_out_phdrs, + bfd_elf64_write_shdrs_and_ehdr, + bfd_elf64_write_relocs, + bfd_elf64_swap_symbol_out, + bfd_elf64_slurp_reloc_table, + bfd_elf64_slurp_symbol_table, + bfd_elf64_swap_dyn_in, + bfd_elf64_swap_dyn_out, + NULL, + NULL, + NULL, + NULL +}; + #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_backend_size_info elf64_86_64_size_info + #define elf_backend_can_gc_sections 1 #define elf_backend_want_got_plt 1 #define elf_backend_plt_readonly 1 @@ -1801,13 +1856,11 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info) #define elf_backend_plt_header_size PLT_ENTRY_SIZE #define elf_info_to_howto elf64_x86_64_info_to_howto -#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_final_link _bfd_elf64_gc_common_final_link #define bfd_elf64_bfd_link_hash_table_create \ elf64_x86_64_link_hash_table_create -#define bfd_elf64_bfd_reloc_type_lookup elf64_x86_64_reloc_type_lookup +#define bfd_elf64_bfd_reloc_type_lookup elf64_x86_64_reloc_type_lookup #define elf_backend_adjust_dynamic_symbol elf64_x86_64_adjust_dynamic_symbol #define elf_backend_check_relocs elf64_x86_64_check_relocs @@ -1819,5 +1872,6 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info) #define elf_backend_gc_sweep_hook elf64_x86_64_gc_sweep_hook #define elf_backend_relocate_section elf64_x86_64_relocate_section #define elf_backend_size_dynamic_sections elf64_x86_64_size_dynamic_sections +#define elf_backend_object_p elf64_x86_64_elf_object_p #include "elf64-target.h"