diff options
author | Andreas Jaeger <aj@suse.de> | 2001-04-19 09:39:28 +0000 |
---|---|---|
committer | Andreas Jaeger <aj@suse.de> | 2001-04-19 09:39:28 +0000 |
commit | fbd347082a35a9c1a4ce15c2248fc252f5b28716 (patch) | |
tree | d3add91eb34914dd496ab6763b510dcf9937d397 | |
parent | 7a52a367235aca6bbf8ce3c77fc12135d9204f71 (diff) | |
download | binutils-redhat-fbd347082a35a9c1a4ce15c2248fc252f5b28716.tar.gz |
2001-04-19 Andreas Jaeger <aj@suse.de>
* elf64-x86-64.c (elf64_x86_64_plt0_entry): Fix instructions.
(elf64_x86_64_plt_entry): Likewise.
(elf64_x86_64_finish_dynamic_sections): Fix PLT0 generation.
(elf64_x86_64_finish_dynamic_symbol): Fix PLT generation.
-rw-r--r-- | bfd/ChangeLog | 13 | ||||
-rw-r--r-- | bfd/elf64-x86-64.c | 59 |
2 files changed, 57 insertions, 15 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5aa3634834..0bdbf4c38a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2001-04-19 Andreas Jaeger <aj@suse.de> + + * elf64-x86-64.c (elf64_x86_64_plt0_entry): Fix instructions. + (elf64_x86_64_plt_entry): Likewise. + (elf64_x86_64_finish_dynamic_sections): Fix PLT0 generation. + (elf64_x86_64_finish_dynamic_symbol): Fix PLT generation. + 2001-04-17 Hans-Peter Nilsson <hp@axis.com> * elf32-cris.c: Tweak comments related to dynamic linking. @@ -12,7 +19,7 @@ (elf_cris_size_dynamic_sections): Iterate over elf_cris_discard_excess_program_dynamics when not creating shared library. - (elf_cris_discard_excess_dso_dynamics): Renamed from + (elf_cris_discard_excess_dso_dynamics): Renamed from elf_cris_discard_copies. Correct typo, s/Rel/Rela/. (elf_cris_discard_excess_program_dynamics): New. @@ -83,7 +90,7 @@ * configure.in (bfd_elf64_tradbigmips_vec): New. Traditional 64bit big endian MIPS ELF target. - (bfd_elf64_tradlittlemips_vec): New. Traditional 64bit little + (bfd_elf64_tradlittlemips_vec): New. Traditional 64bit little endian MIPS ELF target. * configure: Regenerated. @@ -272,7 +279,7 @@ * Most files: Update copyright notices using Perl script created by Kevin Buettner <kevinb@redhat.com>. - + 2001-03-07 Nick Clifton <nickc@redhat.com> * elf32-arm.h (elf32_arm_final_link_relocate): Conditionalise diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index d797165c3d..6c7e98bd71 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -173,18 +173,18 @@ elf64_x86_64_info_to_howto (abfd, cache_ptr, dst) 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. */ + 0xff, 0x35, 8, 0, 0, 0, /* pushq GOT+8(%rip) */ + 0xff, 0x25, 16, 0, 0, 0, /* jmpq *GOT+16(%rip) */ + 0x90, 0x90, 0x90, 0x90 /* pad out to 16 bytes with nops. */ }; /* Subsequent entries in a procedure linkage table look like this. */ static const bfd_byte elf64_x86_64_plt_entry[PLT_ENTRY_SIZE] = { - 0xff, 0xa3, /* jmp *name@GOTPC(%rip) */ + 0xff, 0x25, /* jmpq *name@GOTPC(%rip) */ 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */ - 0x68, /* pushq immediate */ + 0x68, /* pushq immediate */ 0, 0, 0, 0, /* replaced with index into relocation table. */ 0xe9, /* jmp relative */ 0, 0, 0, 0 /* replaced with offset to start of .plt0. */ @@ -1664,13 +1664,26 @@ elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym) /* Insert the relocation positions of the plt section. The magic numbers at the end of the statements are the positions of the relocations in the plt section. */ - bfd_put_64 (output_bfd, got_offset, splt->contents + h->plt.offset + 2); - bfd_put_64 (output_bfd, plt_index * sizeof (Elf64_External_Rela), + /* Put offset for jmp *name@GOTPCREL(%rip), since the + instruction uses 6 bytes, subtract this value. */ + bfd_put_32 (output_bfd, + (sgot->output_section->vma + + sgot->output_offset + + got_offset + - splt->output_section->vma + - splt->output_offset + - h->plt.offset + - 6), + splt->contents + h->plt.offset + 2); + /* Put relocation index. */ + bfd_put_32 (output_bfd, plt_index, splt->contents + h->plt.offset + 7); - bfd_put_64 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE), + /* Put offset for jmp .PLT0. */ + bfd_put_32 (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, initially this + points to the pushq instruction in the PLT which is at offset 6. */ bfd_put_64 (output_bfd, (splt->output_section->vma + splt->output_offset + h->plt.offset + 6), sgot->contents + got_offset); @@ -1747,6 +1760,8 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info) dynobj = elf_hash_table (info)->dynobj; + sgot = bfd_get_section_by_name (dynobj, ".got.plt"); + BFD_ASSERT (sgot != NULL); sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); if (elf_hash_table (info)->dynamic_sections_created) @@ -1816,7 +1831,29 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info) BFD_ASSERT (splt != NULL); if (splt->_raw_size > 0) { + /* Fill in the first entry in the procedure linkage table. */ memcpy (splt->contents, elf64_x86_64_plt0_entry, PLT_ENTRY_SIZE); + /* Add offset for pushq GOT+8(%rip), since the instruction + uses 6 bytes subtract this value. */ + bfd_put_32 (output_bfd, + (sgot->output_section->vma + + sgot->output_offset + + 8 + - splt->output_section->vma + - splt->output_offset + - 6), + splt->contents + 2); + /* Add offset for jmp *GOT+16(%rip). The 12 is the offset to + the end of the instruction. */ + bfd_put_32 (output_bfd, + (sgot->output_section->vma + + sgot->output_offset + + 16 + - splt->output_section->vma + - splt->output_offset + - 12), + splt->contents + 8); + } elf_section_data (splt->output_section)->this_hdr.sh_entsize = @@ -1825,8 +1862,6 @@ 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.plt"); - BFD_ASSERT (sgot != NULL); if (sgot->_raw_size > 0) { if (sdyn == NULL) @@ -1835,7 +1870,7 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info) bfd_put_64 (output_bfd, sdyn->output_section->vma + sdyn->output_offset, sgot->contents); - /* Write GOT[1] and GOT[2], needed for the linker. */ + /* Write GOT[1] and GOT[2], needed for the dynamic linker. */ bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + GOT_ENTRY_SIZE); bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + GOT_ENTRY_SIZE*2); } |