{
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. */
+ 0x0f, 0x1f, 0x40, 0x00 /* nopl 0(%rax) */
};
/* Subsequent entries in a procedure linkage table look like this. */
static bfd_boolean
elf64_x86_64_mkobject (bfd *abfd)
{
- bfd_size_type amt = sizeof (struct elf64_x86_64_obj_tdata);
- abfd->tdata.any = bfd_zalloc (abfd, amt);
if (abfd->tdata.any == NULL)
- return FALSE;
- return TRUE;
+ {
+ bfd_size_type amt = sizeof (struct elf64_x86_64_obj_tdata);
+ abfd->tdata.any = bfd_zalloc (abfd, amt);
+ if (abfd->tdata.any == NULL)
+ return FALSE;
+ }
+ return bfd_elf_mkobject (abfd);
}
static bfd_boolean
&& (r_type != R_X86_64_PC32)
&& (r_type != R_X86_64_PC64))
|| (h != NULL
- && (! info->symbolic
+ && (! SYMBOLIC_BIND (info, h)
|| h->root.type == bfd_link_hash_defweak
|| !h->def_regular))))
|| (ELIMINATE_COPY_RELOCS
if (name == NULL)
return FALSE;
- if (strncmp (name, ".rela", 5) != 0
+ if (! CONST_STRNEQ (name, ".rela")
|| strcmp (bfd_get_section_name (abfd, sec),
name + 5) != 0)
{
/* Strip this section if we don't need it; see the
comment below. */
}
- else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0)
+ else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
{
if (s->size != 0 && s != htab->srelplt)
relocs = TRUE;
|| r_type == R_X86_64_PC32
|| r_type == R_X86_64_PC64
|| !info->shared
- || !info->symbolic
+ || !SYMBOLIC_BIND (info, h)
|| !h->def_regular))
{
outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
val = bfd_get_8 (input_bfd, contents + roff + 1);
BFD_ASSERT (val == 0x10);
- /* Now modify the instruction as appropriate. */
- bfd_put_8 (output_bfd, 0x90, contents + roff);
+ /* Now modify the instruction as appropriate. Use
+ xchg %ax,%ax instead of 2 nops. */
+ bfd_put_8 (output_bfd, 0x66, contents + roff);
bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
continue;
}
val = bfd_get_8 (input_bfd, contents + roff + 1);
BFD_ASSERT (val == 0x10);
- /* Now modify the instruction as appropriate. */
- bfd_put_8 (output_bfd, 0x90, contents + roff);
+ /* Now modify the instruction as appropriate. Use
+ xchg %ax,%ax instead of 2 nops. */
+ bfd_put_8 (output_bfd, 0x66, contents + roff);
bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
continue;
}
static int
-elf64_x86_64_additional_program_headers (bfd *abfd)
+elf64_x86_64_additional_program_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
asection *s;
int count = 0;
return count;
}
+/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
+
+static bfd_boolean
+elf64_x86_64_hash_symbol (struct elf_link_hash_entry *h)
+{
+ if (h->plt.offset != (bfd_vma) -1
+ && !h->def_regular
+ && !h->pointer_equality_needed)
+ return FALSE;
+
+ return _bfd_elf_hash_symbol (h);
+}
+
static const struct bfd_elf_special_section
elf64_x86_64_special_sections[]=
{
- { ".gnu.linkonce.lb", 16, -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
- { ".gnu.linkonce.lr", 16, -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE},
- { ".gnu.linkonce.lt", 16, -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR + SHF_X86_64_LARGE},
- { ".lbss", 5, -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
- { ".ldata", 6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
- { ".lrodata", 8, -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE},
- { NULL, 0, 0, 0, 0 }
+ { STRING_COMMA_LEN (".gnu.linkonce.lb"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
+ { STRING_COMMA_LEN (".gnu.linkonce.lr"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE},
+ { STRING_COMMA_LEN (".gnu.linkonce.lt"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR + SHF_X86_64_LARGE},
+ { STRING_COMMA_LEN (".lbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
+ { STRING_COMMA_LEN (".ldata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
+ { STRING_COMMA_LEN (".lrodata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE},
+ { NULL, 0, 0, 0, 0 }
};
#define TARGET_LITTLE_SYM bfd_elf64_x86_64_vec
elf64_x86_64_special_sections
#define elf_backend_additional_program_headers \
elf64_x86_64_additional_program_headers
+#define elf_backend_hash_symbol \
+ elf64_x86_64_hash_symbol
+
+#include "elf64-target.h"
+
+/* FreeBSD support. */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM bfd_elf64_x86_64_freebsd_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf64-x86-64-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
+elf64_x86_64_fbsd_post_process_headers (bfd * abfd,
+ struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
+{
+ Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form. */
+
+ i_ehdrp = elf_elfheader (abfd);
+
+ /* Put an ABI label supported by FreeBSD >= 4.1. */
+ i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
+}
+
+#undef elf_backend_post_process_headers
+#define elf_backend_post_process_headers elf64_x86_64_fbsd_post_process_headers
+
+#undef elf64_bed
+#define elf64_bed elf64_x86_64_fbsd_bed
#include "elf64-target.h"