summaryrefslogtreecommitdiff
path: root/bfd/elf32-i386.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/elf32-i386.c')
-rw-r--r--bfd/elf32-i386.c114
1 files changed, 86 insertions, 28 deletions
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index b71d78eb073..e26ee798afb 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -2617,36 +2617,40 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
BFD_ASSERT (rel->r_offset >= 1);
val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
BFD_ASSERT (rel->r_offset + 4 <= input_section->_raw_size);
- if (val != 0xa1)
- {
- BFD_ASSERT (rel->r_offset >= 2);
- type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
- }
if (val == 0xa1)
{
/* movl foo, %eax. */
- bfd_put_8 (output_bfd, 0xb8, contents + rel->r_offset - 2);
- }
- else if (type == 0x8b)
- {
- /* movl */
- BFD_ASSERT ((val & 0xc7) == 0x05);
- bfd_put_8 (output_bfd, 0xc7,
- contents + rel->r_offset - 2);
- bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
- contents + rel->r_offset - 1);
+ bfd_put_8 (output_bfd, 0xb8, contents + rel->r_offset - 1);
}
- else if (type == 0x03)
+ else
{
- /* addl */
- BFD_ASSERT ((val & 0xc7) == 0x05);
- bfd_put_8 (output_bfd, 0x81,
- contents + rel->r_offset - 2);
- bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
- contents + rel->r_offset - 1);
+ BFD_ASSERT (rel->r_offset >= 2);
+ type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
+ switch (type)
+ {
+ case 0x8b:
+ /* movl */
+ BFD_ASSERT ((val & 0xc7) == 0x05);
+ bfd_put_8 (output_bfd, 0xc7,
+ contents + rel->r_offset - 2);
+ bfd_put_8 (output_bfd,
+ 0xc0 | ((val >> 3) & 7),
+ contents + rel->r_offset - 1);
+ break;
+ case 0x03:
+ /* addl */
+ BFD_ASSERT ((val & 0xc7) == 0x05);
+ bfd_put_8 (output_bfd, 0x81,
+ contents + rel->r_offset - 2);
+ bfd_put_8 (output_bfd,
+ 0xc0 | ((val >> 3) & 7),
+ contents + rel->r_offset - 1);
+ break;
+ default:
+ BFD_FAIL ();
+ break;
+ }
}
- else
- BFD_FAIL ();
bfd_put_32 (output_bfd, -tpoff (info, relocation),
contents + rel->r_offset);
continue;
@@ -2926,7 +2930,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
break;
case R_386_TLS_LDO_32:
- if (info->shared)
+ if (info->shared || (input_section->flags & SEC_CODE) == 0)
relocation -= dtpoff_base (info);
else
/* When converting LDO to LE, we must negate. */
@@ -3344,13 +3348,11 @@ elf_i386_finish_dynamic_sections (output_bfd, info)
return true;
}
-#ifndef ELF_ARCH
#define TARGET_LITTLE_SYM bfd_elf32_i386_vec
#define TARGET_LITTLE_NAME "elf32-i386"
#define ELF_ARCH bfd_arch_i386
#define ELF_MACHINE_CODE EM_386
#define ELF_MAXPAGESIZE 0x1000
-#endif /* ELF_ARCH */
#define elf_backend_can_gc_sections 1
#define elf_backend_can_refcount 1
@@ -3385,6 +3387,62 @@ elf_i386_finish_dynamic_sections (output_bfd, info)
#define elf_backend_relocate_section elf_i386_relocate_section
#define elf_backend_size_dynamic_sections elf_i386_size_dynamic_sections
-#ifndef ELF32_I386_C_INCLUDED
#include "elf32-target.h"
+
+/* FreeBSD support. */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM bfd_elf32_i386_freebsd_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-i386-freebsd"
+
+/* The kernel recognizes executables as valid only if they carry a
+ "FreeBSD" label in the ELF header. So we put this label on all
+ executables and (for simplicity) also all other object files. */
+
+static void elf_i386_post_process_headers
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+static void
+elf_i386_post_process_headers (abfd, link_info)
+ bfd *abfd;
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED;
+{
+ Elf_Internal_Ehdr *i_ehdrp;
+
+ i_ehdrp = elf_elfheader (abfd);
+
+ /* Put an ABI label supported by FreeBSD >= 4.1. */
+ i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
+#ifdef OLD_FREEBSD_ABI_LABEL
+ /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard. */
+ memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);
#endif
+}
+
+#undef elf_backend_post_process_headers
+#define elf_backend_post_process_headers elf_i386_post_process_headers
+
+#define elf32_bed elf32_i386_fbsd_bed
+
+#include "elf32-target.h"
+
+#undef elf_backend_post_process_headers
+#undef elf32_bed
+
+/* QNX support. */
+#include "elf32-qnx.h"
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM bfd_elf32_i386qnx_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-i386-nto"
+
+#define elf32_bed elf32_i386_qnx_bed
+
+#include "elf32-target.h"
+
+#undef elf_backend_set_nonloadable_filepos
+#undef elf_backend_is_contained_by_filepos
+#undef elf_backend_copy_private_bfd_data_p
+#undef elf32_bed