diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2018-12-20 08:31:17 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2018-12-20 10:21:49 -0800 |
commit | 3705cabd71de7577b7e379a3dd483414f39619f5 (patch) | |
tree | 4f287741980ea63289e710a231d8287abebfa023 | |
parent | 388c71de6716902ba39fadba3d41b5f3cdb59dca (diff) | |
download | binutils-gdb-3705cabd71de7577b7e379a3dd483414f39619f5.tar.gz |
Initial support for R_386_SEG16/R_386_SUB16/R_386_SUB32
-rw-r--r-- | bfd/bfd-in2.h | 3 | ||||
-rw-r--r-- | bfd/elf32-i386.c | 96 | ||||
-rw-r--r-- | bfd/libbfd.h | 3 |
3 files changed, 96 insertions, 6 deletions
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index ab71c350f7d..d5e9fb124b5 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -3306,6 +3306,9 @@ instruction. */ BFD_RELOC_386_TLS_DESC, BFD_RELOC_386_IRELATIVE, BFD_RELOC_386_GOT32X, + BFD_RELOC_386_SEG16, + BFD_RELOC_386_SUB16, + BFD_RELOC_386_SUB32, /* x86-64/elf relocations */ BFD_RELOC_X86_64_GOT32, diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 7fe6afb8cfc..bd4f18e0cae 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -146,7 +146,21 @@ static reloc_howto_type elf_howto_table[]= /* Another gap. */ #define R_386_ext2 (R_386_GOT32X + 1 - R_386_tls_offset) -#define R_386_vt_offset (R_386_GNU_VTINHERIT - R_386_ext2) +#define R_386_seg16_offset (R_386_SEG16 - R_386_ext2) + + HOWTO(R_386_SEG16, 0, 1, 16, TRUE, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_386_SEG16", + TRUE, 0xffff, 0xffff, FALSE), + HOWTO(R_386_SUB16, 0, 1, 16, TRUE, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_386_SUB16", + TRUE, 0xffff, 0xffff, FALSE), + HOWTO(R_386_SUB32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_386_SUB32", + TRUE, 0xffffffff, 0xffffffff, FALSE), + + /* Another gap. */ +#define R_386_ext3 (R_386_SUB32 + 1 - R_386_seg16_offset) +#define R_386_vt_offset (R_386_GNU_VTINHERIT - R_386_ext3) /* GNU extension to record C++ vtable hierarchy. */ HOWTO (R_386_GNU_VTINHERIT, /* type */ @@ -337,6 +351,18 @@ elf_i386_reloc_type_lookup (bfd *abfd, TRACE ("BFD_RELOC_386_GOT32X"); return &elf_howto_table[R_386_GOT32X - R_386_tls_offset]; + case BFD_RELOC_386_SEG16: + TRACE ("BFD_RELOC_386_SEG16"); + return &elf_howto_table[R_386_SEG16 - R_386_seg16_offset]; + + case BFD_RELOC_386_SUB16: + TRACE ("BFD_RELOC_386_SUB16"); + return &elf_howto_table[R_386_SUB16 - R_386_seg16_offset]; + + case BFD_RELOC_386_SUB32: + TRACE ("BFD_RELOC_386_SUB32"); + return &elf_howto_table[R_386_SUB32 - R_386_seg16_offset]; + case BFD_RELOC_VTABLE_INHERIT: TRACE ("BFD_RELOC_VTABLE_INHERIT"); return &elf_howto_table[R_386_GNU_VTINHERIT - R_386_vt_offset]; @@ -379,8 +405,10 @@ elf_i386_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, unsigned r_type) >= R_386_ext - R_386_standard) && ((indx = r_type - R_386_tls_offset) - R_386_ext >= R_386_ext2 - R_386_ext) - && ((indx = r_type - R_386_vt_offset) - R_386_ext2 - >= R_386_vt - R_386_ext2)) + && ((indx = r_type - R_386_seg16_offset ) - R_386_ext2 + >= R_386_ext3 - R_386_ext2) + && ((indx = r_type - R_386_vt_offset) - R_386_ext3 + >= R_386_vt - R_386_ext3)) return NULL; /* PR 17512: file: 0f67f69d. */ if (elf_howto_table [indx].type != r_type) @@ -1914,6 +1942,36 @@ do_size: goto error_return; break; + case R_386_SEG16: + case R_386_SUB16: + case R_386_SUB32: + if (!bfd_link_executable (info)) + { + reloc_howto_type *howto; + unsigned int indx; + if ((indx = r_type) >= R_386_standard + && ((indx = r_type - R_386_ext_offset) - R_386_standard + >= R_386_ext - R_386_standard) + && ((indx = r_type - R_386_seg16_offset) - R_386_ext + >= R_386_ext2 - R_386_ext) + && ((indx = r_type - R_386_tls_offset) - R_386_ext2 + >= R_386_ext3 - R_386_ext2)) + return _bfd_unrecognized_reloc (abfd, sec, r_type); + howto = elf_howto_table + indx; + if (h) + name = h->root.root.string; + else + name = bfd_elf_sym_name (abfd, symtab_hdr, isym, + NULL); + info->callbacks->einfo + (_("%F%P: %pB: unsupported relocation %s against symbol " + "`%s' for non-executable\n"), + abfd, howto->name, name); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + break; + default: break; } @@ -2070,6 +2128,8 @@ elf_i386_relocate_section (bfd *output_bfd, asection *resolved_plt; bfd_boolean resolved_to_zero; bfd_boolean relative_reloc; + bfd_vma addend; + bfd_byte *where; r_type = ELF32_R_TYPE (rel->r_info); if (r_type == R_386_GNU_VTINHERIT @@ -2084,7 +2144,11 @@ elf_i386_relocate_section (bfd *output_bfd, && ((indx = r_type - R_386_ext_offset) - R_386_standard >= R_386_ext - R_386_standard) && ((indx = r_type - R_386_tls_offset) - R_386_ext - >= R_386_ext2 - R_386_ext)) + >= R_386_ext2 - R_386_ext) + && ((indx = r_type - R_386_seg16_offset ) - R_386_ext2 + >= R_386_ext3 - R_386_ext2) + && ((indx = r_type - R_386_vt_offset) - R_386_ext3 + >= R_386_vt - R_386_ext3)) return _bfd_unrecognized_reloc (input_bfd, input_section, r_type); howto = elf_howto_table + indx; @@ -2108,8 +2172,7 @@ elf_i386_relocate_section (bfd *output_bfd, || (bfd_link_relocatable (info) && sec->output_offset != 0))) { - bfd_vma addend; - bfd_byte *where = contents + rel->r_offset; + where = contents + rel->r_offset; switch (howto->size) { @@ -3396,6 +3459,27 @@ disallow_got32: relocation = -elf_i386_tpoff (info, relocation); break; + case R_386_SEG16: + where = contents + rel->r_offset; + addend = bfd_get_16 (input_bfd, where); + relocation = addend + (relocation >> 4); + bfd_put_16 (input_bfd, 0, where); + break; + + case R_386_SUB16: + where = contents + rel->r_offset; + addend = bfd_get_16 (input_bfd, where); + relocation = addend - relocation; + bfd_put_16 (input_bfd, 0, where); + break; + + case R_386_SUB32: + where = contents + rel->r_offset; + addend = bfd_get_32 (input_bfd, where); + relocation = addend - relocation; + bfd_put_32 (input_bfd, 0, where); + break; + default: break; } diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 1189e633584..5de7ccfe049 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1342,6 +1342,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_386_TLS_DESC", "BFD_RELOC_386_IRELATIVE", "BFD_RELOC_386_GOT32X", + "BFD_RELOC_386_SEG16", + "BFD_RELOC_386_SUB16", + "BFD_RELOC_386_SUB32", "BFD_RELOC_X86_64_GOT32", "BFD_RELOC_X86_64_PLT32", "BFD_RELOC_X86_64_COPY", |