summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2018-12-20 08:31:17 -0800
committerH.J. Lu <hjl.tools@gmail.com>2018-12-20 10:21:49 -0800
commit3705cabd71de7577b7e379a3dd483414f39619f5 (patch)
tree4f287741980ea63289e710a231d8287abebfa023
parent388c71de6716902ba39fadba3d41b5f3cdb59dca (diff)
downloadbinutils-gdb-3705cabd71de7577b7e379a3dd483414f39619f5.tar.gz
Initial support for R_386_SEG16/R_386_SUB16/R_386_SUB32
-rw-r--r--bfd/bfd-in2.h3
-rw-r--r--bfd/elf32-i386.c96
-rw-r--r--bfd/libbfd.h3
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",