summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2019-07-26 16:11:50 -0700
committerH. Peter Anvin <hpa@zytor.com>2019-07-26 16:11:50 -0700
commitf273765a6737c98e7da7d4ceb6e054c9cb41202b (patch)
tree2c20882fea6b36f351c8045e0e867d1da91d89cd
parentca31717da1f9d73035cb2635110577b250e2b339 (diff)
downloadbinutils-f273765a6737c98e7da7d4ceb6e054c9cb41202b.tar.gz
binutils-f273765a6737c98e7da7d4ceb6e054c9cb41202b.tar.xz
binutils-f273765a6737c98e7da7d4ceb6e054c9cb41202b.zip
i386: add R_386_SEGRELATIVE
R_386_SEGRELATIVE is to R_386_SEG16 what R_386_RELATIVE is to R_386_32. This makes it very easy to get the necessary relocation information for both pure 16-bit and mixed 16/32-bit code without having to have a postprocessor redoing a bunch of the linker's job. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--bfd/bfd-in2.h1
-rw-r--r--bfd/elf32-i386.c21
-rw-r--r--bfd/libbfd.h1
-rw-r--r--bfd/reloc.c8
-rw-r--r--include/elf/i386.h1
5 files changed, 25 insertions, 7 deletions
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index af19a65f07..0a4d891fc8 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -3357,6 +3357,7 @@ instruction. */
BFD_RELOC_386_SEG16,
BFD_RELOC_386_SUB16,
BFD_RELOC_386_SUB32,
+ BFD_RELOC_386_SEGRELATIVE,
/* x86-64/elf relocations */
BFD_RELOC_X86_64_GOT32,
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index c04fb735f3..cd12cc8bfd 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -157,9 +157,12 @@ static reloc_howto_type elf_howto_table[]=
HOWTO(R_386_SUB32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_386_SUB32",
TRUE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(R_386_SEGRELATIVE, 4, 1, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_386_SEGRELATIVE",
+ TRUE, 0xffff, 0xffff, FALSE),
/* Another gap. */
-#define R_386_ext3 (R_386_SUB32 + 1 - R_386_seg16_offset)
+#define R_386_ext3 (R_386_SEGRELATIVE + 1 - R_386_seg16_offset)
#define R_386_vt_offset (R_386_GNU_VTINHERIT - R_386_ext3)
/* GNU extension to record C++ vtable hierarchy. */
@@ -363,6 +366,10 @@ elf_i386_reloc_type_lookup (bfd *abfd,
TRACE ("BFD_RELOC_386_SUB32");
return &elf_howto_table[R_386_SUB32 - R_386_seg16_offset];
+ case BFD_RELOC_386_SEGRELATIVE:
+ TRACE ("BFD_RELOC_386_SEGRELATIVE");
+ return &elf_howto_table[R_386_SEGRELATIVE];
+
case BFD_RELOC_VTABLE_INHERIT:
TRACE ("BFD_RELOC_VTABLE_INHERIT");
return &elf_howto_table[R_386_GNU_VTINHERIT - R_386_vt_offset];
@@ -1795,6 +1802,7 @@ create_got:
case R_386_32:
case R_386_PC32:
+ case R_386_SEG16:
if (eh != NULL && (sec->flags & SEC_CODE) != 0)
eh->zero_undefweak |= 0x2;
do_relocation:
@@ -1917,7 +1925,7 @@ do_size:
p->count += 1;
/* Count size relocation as PC-relative relocation. */
- if (r_type == R_386_PC32 || size_reloc)
+ if (r_type == R_386_PC32 || r_type == R_386_SEG16 || size_reloc)
p->pc_count += 1;
}
break;
@@ -1936,7 +1944,6 @@ do_size:
goto error_return;
break;
- case R_386_SEG16:
case R_386_SUB16:
case R_386_SUB32:
if (bfd_link_dll (info))
@@ -2767,6 +2774,7 @@ disallow_got32:
case R_386_32:
case R_386_PC32:
+ case R_386_SEG16:
if ((input_section->flags & SEC_ALLOC) == 0
|| is_vxworks_tls)
break;
@@ -2803,8 +2811,10 @@ disallow_got32:
else
{
/* This symbol is local, or marked to become local. */
+ r_type = (r_type == R_386_SEG16)
+ ? R_386_SEGRELATIVE : R_386_RELATIVE;
relocate = TRUE;
- outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
+ outrel.r_info = ELF32_R_INFO (0, r_type);
}
sreloc = elf_section_data (input_section)->sreloc;
@@ -3456,9 +3466,6 @@ disallow_got32:
automatically since i386 uses REL, not RELA relocation.
The previous relocation result becomes the addend for the
current relocation. */
- case R_386_SEG16:
- break;
-
case R_386_SUB16:
case R_386_SUB32:
relocation = -relocation;
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 65fe647da0..fc92aae689 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -1345,6 +1345,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_386_SEG16",
"BFD_RELOC_386_SUB16",
"BFD_RELOC_386_SUB32",
+ "BFD_RELOC_386_SEGRELATIVE",
"BFD_RELOC_X86_64_GOT32",
"BFD_RELOC_X86_64_PLT32",
"BFD_RELOC_X86_64_COPY",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 9ca68ca61d..55e26465a9 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -2595,6 +2595,14 @@ ENUMX
BFD_RELOC_386_IRELATIVE
ENUMX
BFD_RELOC_386_GOT32X
+ENUMX
+ BFD_RELOC_386_SEG16
+ENUMX
+ BFD_RELOC_386_SUB16
+ENUMX
+ BFD_RELOC_386_SUB32
+ENUMX
+ BFD_RELOC_386_SEGRELATIVE
ENUMDOC
i386/elf relocations
diff --git a/include/elf/i386.h b/include/elf/i386.h
index 5b4cae5003..cc45f57ade 100644
--- a/include/elf/i386.h
+++ b/include/elf/i386.h
@@ -74,6 +74,7 @@ START_RELOC_NUMBERS (elf_i386_reloc_type)
RELOC_NUMBER (R_386_SEG16, 45)
RELOC_NUMBER (R_386_SUB16, 46)
RELOC_NUMBER (R_386_SUB32, 47)
+ RELOC_NUMBER (R_386_SEGRELATIVE, 48)
/* Used by Intel. */
RELOC_NUMBER (R_386_USED_BY_INTEL_200, 200)