/* X86-64 specific support for 64-bit ELF
- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
- Free Software Foundation, Inc.
+ Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+ 2010 Free Software Foundation, Inc.
Contributed by Jan Hubicka <jh@suse.cz>.
This file is part of BFD, the Binary File Descriptor library.
= bfd_get_16 (abfd, note->descdata + 12);
/* pr_pid */
- elf_tdata (abfd)->core_pid
+ elf_tdata (abfd)->core_lwpid
= bfd_get_32 (abfd, note->descdata + 32);
/* pr_reg */
return FALSE;
case 136: /* sizeof(struct elf_prpsinfo) on Linux/x86_64 */
+ elf_tdata (abfd)->core_pid
+ = bfd_get_32 (abfd, note->descdata + 24);
elf_tdata (abfd)->core_program
= _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
elf_tdata (abfd)->core_command
#define is_x86_64_elf(bfd) \
(bfd_get_flavour (bfd) == bfd_target_elf_flavour \
&& elf_tdata (bfd) != NULL \
- && elf_object_id (bfd) == X86_64_ELF_TDATA)
+ && elf_object_id (bfd) == X86_64_ELF_DATA)
static bfd_boolean
elf64_x86_64_mkobject (bfd *abfd)
{
return bfd_elf_allocate_object (abfd, sizeof (struct elf64_x86_64_obj_tdata),
- X86_64_ELF_TDATA);
+ X86_64_ELF_DATA);
}
/* x86-64 ELF linker hash table. */
asection *sdynbss;
asection *srelbss;
- /* The offset into splt of the PLT entry for the TLS descriptor
- resolver. Special values are 0, if not necessary (or not found
- to be necessary yet), and -1 if needed but not determined
- yet. */
- bfd_vma tlsdesc_plt;
- /* The offset into sgot of the GOT entry used by the PLT entry
- above. */
- bfd_vma tlsdesc_got;
-
- union {
+ union
+ {
bfd_signed_vma refcount;
bfd_vma offset;
} tls_ld_got;
/* Used by local STT_GNU_IFUNC symbols. */
htab_t loc_hash_table;
- void *loc_hash_memory;
+ void * loc_hash_memory;
+
+ /* The offset into splt of the PLT entry for the TLS descriptor
+ resolver. Special values are 0, if not necessary (or not found
+ to be necessary yet), and -1 if needed but not determined
+ yet. */
+ bfd_vma tlsdesc_plt;
+ /* The offset into sgot of the GOT entry used by the PLT entry
+ above. */
+ bfd_vma tlsdesc_got;
};
/* Get the x86-64 ELF linker hash table from a link_info structure. */
#define elf64_x86_64_hash_table(p) \
- ((struct elf64_x86_64_link_hash_table *) ((p)->hash))
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == X86_64_ELF_DATA ? ((struct elf64_x86_64_link_hash_table *) ((p)->hash)) : NULL)
#define elf64_x86_64_compute_jump_table_size(htab) \
((htab)->elf.srelplt->reloc_count * GOT_ENTRY_SIZE)
subclass. */
if (entry == NULL)
{
- entry = bfd_hash_allocate (table,
- sizeof (struct elf64_x86_64_link_hash_entry));
+ entry = (struct bfd_hash_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct elf64_x86_64_link_hash_entry));
if (entry == NULL)
return entry;
}
ret->elf.indx = sec->id;
ret->elf.dynstr_index = ELF64_R_SYM (rel->r_info);
ret->elf.dynindx = -1;
- ret->elf.plt.offset = (bfd_vma) -1;
- ret->elf.got.offset = (bfd_vma) -1;
*slot = ret;
}
return &ret->elf;
if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
elf64_x86_64_link_hash_newfunc,
- sizeof (struct elf64_x86_64_link_hash_entry)))
+ sizeof (struct elf64_x86_64_link_hash_entry),
+ X86_64_ELF_DATA))
{
free (ret);
return NULL;
return FALSE;
htab = elf64_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
if (!info->shared)
htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss");
unsigned int to_type = from_type;
bfd_boolean check = TRUE;
+ /* Skip TLS transition for functions. */
+ if (h != NULL
+ && (h->type == STT_FUNC
+ || h->type == STT_GNU_IFUNC))
+ return TRUE;
+
switch (from_type)
{
case R_X86_64_TLSGD:
case R_X86_64_GOTPC32_TLSDESC:
case R_X86_64_TLSDESC_CALL:
case R_X86_64_GOTTPOFF:
- if (!info->shared)
+ if (info->executable)
{
if (h == NULL)
to_type = R_X86_64_TPOFF32;
{
unsigned int new_to_type = to_type;
- if (!info->shared
+ if (info->executable
&& h != NULL
&& h->dynindx == -1
&& tls_type == GOT_TLS_IE)
break;
case R_X86_64_TLSLD:
- if (!info->shared)
+ if (info->executable)
to_type = R_X86_64_TPOFF32;
break;
name = h->root.root.string;
else
{
- Elf_Internal_Sym *isym;
struct elf64_x86_64_link_hash_table *htab;
+
htab = elf64_x86_64_hash_table (info);
- isym = bfd_sym_from_r_symndx (&htab->sym_cache,
- abfd, r_symndx);
- name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
+ if (htab == NULL)
+ name = "*unknown*";
+ else
+ {
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
+ }
}
(*_bfd_error_handler)
BFD_ASSERT (is_x86_64_elf (abfd));
htab = elf64_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
symtab_hdr = &elf_symtab_hdr (abfd);
sym_hashes = elf_sym_hashes (abfd);
TRUE);
if (h == NULL)
return FALSE;
-
+
/* Fake a STT_GNU_IFUNC symbol. */
h->type = STT_GNU_IFUNC;
h->def_regular = 1;
{
/* It is referenced by a non-shared object. */
h->ref_regular = 1;
-
+ h->needs_plt = 1;
+
/* STT_GNU_IFUNC symbol must go through PLT. */
h->plt.refcount += 1;
goto create_got;
case R_X86_64_TPOFF32:
- if (info->shared)
+ if (!info->executable)
{
- if (h->root.root.string)
+ if (h)
name = h->root.root.string;
else
name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
break;
case R_X86_64_GOTTPOFF:
- if (info->shared)
+ if (!info->executable)
info->flags |= DF_STATIC_TLS;
/* Fall through */
tls_type |= old_tls_type;
else
{
- if (h->root.root.string)
+ if (h)
name = h->root.root.string;
else
name = bfd_elf_sym_name (abfd, symtab_hdr,
&& (sec->flags & SEC_ALLOC) != 0
&& (sec->flags & SEC_READONLY) != 0)
{
- if (h->root.root.string)
+ if (h)
name = h->root.root.string;
else
name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
easily. Oh well. */
asection *s;
void **vpp;
- Elf_Internal_Sym *isym;
isym = bfd_sym_from_r_symndx (&htab->sym_cache,
abfd, r_symndx);
asection *sec,
const Elf_Internal_Rela *relocs)
{
+ struct elf64_x86_64_link_hash_table *htab;
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes;
bfd_signed_vma *local_got_refcounts;
if (info->relocatable)
return TRUE;
+ htab = elf64_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
elf_section_data (sec)->local_dynrel = NULL;
symtab_hdr = &elf_symtab_hdr (abfd);
break;
}
}
+ else
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+
+ /* Check relocation against local STT_GNU_IFUNC symbol. */
+ if (isym != NULL
+ && ELF64_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ {
+ h = elf64_x86_64_get_local_sym_hash (htab, abfd, rel,
+ FALSE);
+ if (h == NULL)
+ abort ();
+ }
+ }
r_type = ELF64_R_TYPE (rel->r_info);
if (! elf64_x86_64_tls_transition (info, abfd, sec, NULL,
switch (r_type)
{
case R_X86_64_TLSLD:
- if (elf64_x86_64_hash_table (info)->tls_ld_got.refcount > 0)
- elf64_x86_64_hash_table (info)->tls_ld_got.refcount -= 1;
+ if (htab->tls_ld_got.refcount > 0)
+ htab->tls_ld_got.refcount -= 1;
break;
case R_X86_64_TLSGD:
h->plt.refcount -= 1;
if (h->got.refcount > 0)
h->got.refcount -= 1;
+ if (h->type == STT_GNU_IFUNC)
+ {
+ if (h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+ }
}
else if (local_got_refcounts != NULL)
{
same memory location for the variable. */
htab = elf64_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
/* We must generate a R_X86_64_COPY reloc to tell the dynamic linker
to copy the initial value out of the dynamic object and into the
info = (struct bfd_link_info *) inf;
htab = elf64_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
/* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
here if it is defined and referenced in a non-shared object. */
/* If R_X86_64_GOTTPOFF symbol is now local to the binary,
make it a R_X86_64_TPOFF32 requiring no GOT entry. */
if (h->got.refcount > 0
- && !info->shared
+ && info->executable
&& h->dynindx == -1
&& elf64_x86_64_hash_entry (h)->tls_type == GOT_TLS_IE)
{
bfd *ibfd;
htab = elf64_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
dynobj = htab->elf.dynobj;
if (dynobj == NULL)
abort ();
}
}
+ if (htab->elf.sgotplt)
+ {
+ /* Don't allocate .got.plt section if there are no GOT nor PLT
+ entries. */
+ if ((htab->elf.sgotplt->size
+ == get_elf_backend_data (output_bfd)->got_header_size)
+ && (htab->elf.splt == NULL
+ || htab->elf.splt->size == 0)
+ && (htab->elf.sgot == NULL
+ || htab->elf.sgot->size == 0)
+ && (htab->elf.iplt == NULL
+ || htab->elf.iplt->size == 0)
+ && (htab->elf.igotplt == NULL
+ || htab->elf.igotplt->size == 0))
+ htab->elf.sgotplt->size = 0;
+ }
+
/* We now have determined the sizes of the various dynamic sections.
Allocate memory for them. */
relocs = FALSE;
if (tlsbase && tlsbase->type == STT_TLS)
{
+ struct elf64_x86_64_link_hash_table *htab;
struct bfd_link_hash_entry *bh = NULL;
const struct elf_backend_data *bed
= get_elf_backend_data (output_bfd);
+ htab = elf64_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
if (!(_bfd_generic_link_add_one_symbol
(info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
tls_sec, 0, NULL, FALSE,
bed->collect, &bh)))
return FALSE;
- elf64_x86_64_hash_table (info)->tls_module_base = bh;
+ htab->tls_module_base = bh;
tlsbase = (struct elf_link_hash_entry *)bh;
tlsbase->def_regular = 1;
static void
elf64_x86_64_set_tls_module_base (struct bfd_link_info *info)
{
+ struct elf64_x86_64_link_hash_table *htab;
struct bfd_link_hash_entry *base;
if (!info->executable)
return;
- base = elf64_x86_64_hash_table (info)->tls_module_base;
+ htab = elf64_x86_64_hash_table (info);
+ if (htab == NULL)
+ return;
- if (!base)
+ base = htab->tls_module_base;
+ if (base == NULL)
return;
- base->u.def.value = elf_hash_table (info)->tls_size;
+ base->u.def.value = htab->elf.tls_size;
}
/* Return the base VMA address which should be subtracted from real addresses
&& (contents [offset - 1] & 0xf0) == 0x80));
}
+static void
+elf64_x86_64_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
+{
+ bfd_byte *loc = s->contents;
+ loc += s->reloc_count++ * sizeof (Elf64_External_Rela);
+ BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
+ <= s->contents + s->size);
+ bfd_elf64_swap_reloca_out (abfd, rel, loc);
+}
+
/* Relocate an x86_64 ELF section. */
static bfd_boolean
BFD_ASSERT (is_x86_64_elf (input_bfd));
htab = elf64_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
symtab_hdr = &elf_symtab_hdr (input_bfd);
sym_hashes = elf_sym_hashes (input_bfd);
local_got_offsets = elf_local_got_offsets (input_bfd);
&sec, rel);
/* Relocate against local STT_GNU_IFUNC symbol. */
- if (ELF64_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ if (!info->relocatable
+ && ELF64_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
{
h = elf64_x86_64_get_local_sym_hash (htab, input_bfd,
rel, FALSE);
}
else
{
- bfd_boolean warned;
+ bfd_boolean warned ATTRIBUTE_UNUSED;
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
r_symndx, symtab_hdr, sym_hashes,
}
if (sec != NULL && elf_discarded_section (sec))
- {
- /* For relocs against symbols from removed linkonce sections,
- or sections discarded by a linker script, we just want the
- section contents zeroed. Avoid any special processing. */
- _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
- rel->r_info = 0;
- rel->r_addend = 0;
- continue;
- }
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, relend, howto, contents);
if (info->relocatable)
continue;
if (info->shared && h->non_got_ref)
{
Elf_Internal_Rela outrel;
- bfd_byte *loc;
asection *sreloc;
/* Need a dynamic relocation to get the real function
}
sreloc = htab->elf.irelifunc;
- loc = sreloc->contents;
- loc += (sreloc->reloc_count++
- * sizeof (Elf64_External_Rela));
- bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+ elf64_x86_64_append_rela (output_bfd, sreloc, &outrel);
/* If this reloc is against an external symbol, we
do not want to fiddle with the addend. Otherwise,
{
asection *s;
Elf_Internal_Rela outrel;
- bfd_byte *loc;
/* We need to generate a R_X86_64_RELATIVE reloc
for the dynamic linker. */
+ off);
outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
outrel.r_addend = relocation;
- loc = s->contents;
- loc += s->reloc_count++ * sizeof (Elf64_External_Rela);
- bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+ elf64_x86_64_append_rela (output_bfd, s, &outrel);
}
local_got_offsets[r_symndx] |= 1;
|| h->root.type == bfd_link_hash_undefined)))
{
Elf_Internal_Rela outrel;
- bfd_byte *loc;
bfd_boolean skip, relocate;
asection *sreloc;
BFD_ASSERT (sreloc != NULL && sreloc->contents != NULL);
- loc = sreloc->contents;
- loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
- bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+ elf64_x86_64_append_rela (output_bfd, sreloc, &outrel);
/* If this reloc is against an external symbol, we do
not want to fiddle with the addend. Otherwise, we
leaq x@tlsdesc(%rip), %rax
Change it to:
- movl $x@tpoff, %rax
- */
+ movl $x@tpoff, %rax. */
- unsigned int val, type, type2;
+ unsigned int val, type;
type = bfd_get_8 (input_bfd, contents + roff - 3);
- type2 = bfd_get_8 (input_bfd, contents + roff - 2);
val = bfd_get_8 (input_bfd, contents + roff - 1);
bfd_put_8 (output_bfd, 0x48 | ((type >> 2) & 1),
contents + roff - 3);
else
{
Elf_Internal_Rela outrel;
- bfd_byte *loc;
int dr_type, indx;
asection *sreloc;
+ offplt
+ htab->sgotplt_jump_table_size);
sreloc = htab->elf.srelplt;
- loc = sreloc->contents;
- loc += sreloc->reloc_count++
- * sizeof (Elf64_External_Rela);
- BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
- <= sreloc->contents + sreloc->size);
if (indx == 0)
outrel.r_addend = relocation - elf64_x86_64_dtpoff_base (info);
else
outrel.r_addend = 0;
- bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+ elf64_x86_64_append_rela (output_bfd, sreloc, &outrel);
}
sreloc = htab->elf.srelgot;
outrel.r_addend = relocation - elf64_x86_64_dtpoff_base (info);
outrel.r_info = ELF64_R_INFO (indx, dr_type);
- loc = sreloc->contents;
- loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
- BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
- <= sreloc->contents + sreloc->size);
- bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+ elf64_x86_64_append_rela (output_bfd, sreloc, &outrel);
if (GOT_TLS_GD_P (tls_type))
{
outrel.r_info = ELF64_R_INFO (indx,
R_X86_64_DTPOFF64);
outrel.r_offset += GOT_ENTRY_SIZE;
- sreloc->reloc_count++;
- loc += sizeof (Elf64_External_Rela);
- BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
- <= sreloc->contents + sreloc->size);
- bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+ elf64_x86_64_append_rela (output_bfd, sreloc,
+ &outrel);
}
}
leaq x@tlsdesc(%rip), %rax
Change it to:
- movq x@gottpoff(%rip), %rax # before xchg %ax,%ax
- */
-
- unsigned int val, type, type2;
-
- type = bfd_get_8 (input_bfd, contents + roff - 3);
- type2 = bfd_get_8 (input_bfd, contents + roff - 2);
- val = bfd_get_8 (input_bfd, contents + roff - 1);
+ movq x@gottpoff(%rip), %rax # before xchg %ax,%ax. */
/* Now modify the instruction as appropriate. To
turn a leaq into a movq in the form we use it, it
call *(%rax)
Change it to:
- xchg %ax,%ax. */
-
- unsigned int val, type;
+ xchg %ax, %ax. */
- type = bfd_get_8 (input_bfd, contents + roff);
- val = bfd_get_8 (input_bfd, contents + roff + 1);
bfd_put_8 (output_bfd, 0x66, contents + roff);
bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
continue;
else
{
Elf_Internal_Rela outrel;
- bfd_byte *loc;
if (htab->elf.srelgot == NULL)
abort ();
htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
outrel.r_info = ELF64_R_INFO (0, R_X86_64_DTPMOD64);
outrel.r_addend = 0;
- loc = htab->elf.srelgot->contents;
- loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf64_External_Rela);
- bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+ elf64_x86_64_append_rela (output_bfd, htab->elf.srelgot,
+ &outrel);
htab->tls_ld_got.offset |= 1;
}
relocation = htab->elf.sgot->output_section->vma
break;
case R_X86_64_DTPOFF32:
- if (info->shared || (input_section->flags & SEC_CODE) == 0)
+ if (!info->executable|| (input_section->flags & SEC_CODE) == 0)
relocation -= elf64_x86_64_dtpoff_base (info);
else
relocation = elf64_x86_64_tpoff (info, relocation);
break;
case R_X86_64_TPOFF32:
- BFD_ASSERT (! info->shared);
+ BFD_ASSERT (info->executable);
relocation = elf64_x86_64_tpoff (info, relocation);
break;
struct elf64_x86_64_link_hash_table *htab;
htab = elf64_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
if (h->plt.offset != (bfd_vma) -1)
{
corresponds to this symbol. This is the index of this symbol
in all the symbols for which we are making plt entries. The
first entry in the procedure linkage table is reserved.
-
+
Get the offset into the .got table of the entry that
corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
bytes. The first three are reserved for the dynamic linker.
&& elf64_x86_64_hash_entry (h)->tls_type != GOT_TLS_IE)
{
Elf_Internal_Rela rela;
- bfd_byte *loc;
/* This symbol has an entry in the global offset table. Set it
up. */
}
else
{
+ asection *plt;
+
if (!h->pointer_equality_needed)
abort ();
/* For non-shared object, we can't use .got.plt, which
contains the real function addres if we need pointer
equality. We load the GOT entry with the PLT entry. */
- asection *plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
+ plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
bfd_put_64 (output_bfd, (plt->output_section->vma
+ plt->output_offset
+ h->plt.offset),
rela.r_addend = 0;
}
- loc = htab->elf.srelgot->contents;
- loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf64_External_Rela);
- bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
+ elf64_x86_64_append_rela (output_bfd, htab->elf.srelgot, &rela);
}
if (h->needs_copy)
{
Elf_Internal_Rela rela;
- bfd_byte *loc;
/* This symbol needs a copy reloc. Set it up. */
+ h->root.u.def.section->output_offset);
rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_COPY);
rela.r_addend = 0;
- loc = htab->srelbss->contents;
- loc += htab->srelbss->reloc_count++ * sizeof (Elf64_External_Rela);
- bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
+ elf64_x86_64_append_rela (output_bfd, htab->srelbss, &rela);
}
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may
asection *sdyn;
htab = elf64_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
dynobj = htab->elf.dynobj;
sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
if (htab->elf.sgotplt)
{
+ if (bfd_is_abs_section (htab->elf.sgotplt->output_section))
+ {
+ (*_bfd_error_handler)
+ (_("discarded output section: `%A'"), htab->elf.sgotplt);
+ return FALSE;
+ }
+
/* Fill in the first three entries in the global offset table. */
if (htab->elf.sgotplt->size > 0)
{
}
*secp = lcomm;
*valp = sym->st_size;
- break;
+ return TRUE;
}
- if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ if ((abfd->flags & DYNAMIC) == 0
+ && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
return TRUE;
static bfd_boolean
elf64_x86_64_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
- asection *sec, int *index)
+ asection *sec, int *index_return)
{
if (sec == &_bfd_elf_large_com_section)
{
- *index = SHN_X86_64_LCOMMON;
+ *index_return = SHN_X86_64_LCOMMON;
return TRUE;
}
return FALSE;
#define TARGET_LITTLE_SYM bfd_elf64_x86_64_vec
#define TARGET_LITTLE_NAME "elf64-x86-64"
#define ELF_ARCH bfd_arch_i386
+#define ELF_TARGET_ID X86_64_ELF_DATA
#define ELF_MACHINE_CODE EM_X86_64
#define ELF_MAXPAGESIZE 0x200000
#define ELF_MINPAGESIZE 0x1000
#define elf64_bed elf64_x86_64_fbsd_bed
#include "elf64-target.h"
+
+/* Solaris 2 support. */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM bfd_elf64_x86_64_sol2_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf64-x86-64-sol2"
+
+/* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE
+ objects won't be recognized. */
+#undef ELF_OSABI
+
+#undef elf64_bed
+#define elf64_bed elf64_x86_64_sol2_bed
+
+/* The Solaris 2 ABI requires a plt symbol on all platforms.
+
+ Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output
+ File, p.63. */
+#undef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym 1
+
+#include "elf64-target.h"
+
+/* Intel L1OM support. */
+
+static bfd_boolean
+elf64_l1om_elf_object_p (bfd *abfd)
+{
+ /* Set the right machine number for an L1OM elf64 file. */
+ bfd_default_set_arch_mach (abfd, bfd_arch_l1om, bfd_mach_l1om);
+ return TRUE;
+}
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM bfd_elf64_l1om_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf64-l1om"
+#undef ELF_ARCH
+#define ELF_ARCH bfd_arch_l1om
+
+#undef ELF_MACHINE_CODE
+#define ELF_MACHINE_CODE EM_L1OM
+
+#undef ELF_OSABI
+
+#undef elf64_bed
+#define elf64_bed elf64_l1om_bed
+
+#undef elf_backend_object_p
+#define elf_backend_object_p elf64_l1om_elf_object_p
+
+#undef elf_backend_post_process_headers
+
+#include "elf64-target.h"
+
+/* FreeBSD L1OM support. */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM bfd_elf64_l1om_freebsd_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf64-l1om-freebsd"
+
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_FREEBSD
+
+#undef elf64_bed
+#define elf64_bed elf64_l1om_fbsd_bed
+
+#undef elf_backend_post_process_headers
+#define elf_backend_post_process_headers _bfd_elf_set_osabi
+
+#include "elf64-target.h"