/* Support for HPPA 64-bit ELF
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 1999-2020 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
-#include "alloca-conf.h"
#include "sysdep.h"
+#include "alloca-conf.h"
#include "bfd.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/hppa.h"
#include "libhppa.h"
#include "elf64-hppa.h"
-
+#include "libiberty.h"
#define ARCH_SIZE 64
};
#define hppa_link_hash_table(p) \
- ((struct elf64_hppa_link_hash_table *) ((p)->hash))
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == HPPA64_ELF_DATA ? ((struct elf64_hppa_link_hash_table *) ((p)->hash)) : NULL)
#define hppa_elf_hash_entry(ent) \
((struct elf64_hppa_link_hash_entry *)(ent))
static bfd_boolean elf64_hppa_object_p
(bfd *);
-static void elf64_hppa_post_process_headers
- (bfd *, struct bfd_link_info *);
-
static bfd_boolean elf64_hppa_create_dynamic_sections
(bfd *, struct bfd_link_info *);
(bfd *, struct bfd_link_info *,
struct elf_link_hash_entry *, Elf_Internal_Sym *);
-static enum elf_reloc_type_class elf64_hppa_reloc_type_class
- (const Elf_Internal_Rela *);
-
static bfd_boolean elf64_hppa_finish_dynamic_sections
(bfd *, struct bfd_link_info *);
entry = bfd_hash_allocate (table,
sizeof (struct elf64_hppa_link_hash_entry));
if (entry == NULL)
- return entry;
+ return entry;
}
/* Call the allocation method of the superclass. */
elf64_hppa_hash_table_create (bfd *abfd)
{
struct elf64_hppa_link_hash_table *htab;
- bfd_size_type amt = sizeof (*htab);
+ size_t amt = sizeof (*htab);
- htab = bfd_zalloc (abfd, amt);
+ htab = bfd_zmalloc (amt);
if (htab == NULL)
return NULL;
if (!_bfd_elf_link_hash_table_init (&htab->root, abfd,
hppa64_link_hash_newfunc,
- sizeof (struct elf64_hppa_link_hash_entry)))
+ sizeof (struct elf64_hppa_link_hash_entry),
+ HPPA64_ELF_DATA))
{
- bfd_release (abfd, htab);
+ free (htab);
return NULL;
}
i_ehdrp = elf_elfheader (abfd);
if (strcmp (bfd_get_target (abfd), "elf64-hppa-linux") == 0)
{
- /* GCC on hppa-linux produces binaries with OSABI=Linux,
+ /* GCC on hppa-linux produces binaries with OSABI=GNU,
but the kernel produces corefiles with OSABI=SysV. */
- if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_LINUX
+ if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_GNU
&& i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NONE) /* aka SYSV */
return FALSE;
}
return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 11);
case EFA_PARISC_2_0:
if (i_ehdrp->e_ident[EI_CLASS] == ELFCLASS64)
- return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 25);
+ return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 25);
else
- return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 20);
+ return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 20);
case EFA_PARISC_2_0 | EF_PARISC_WIDE:
return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 25);
}
const char *name,
int shindex)
{
- asection *newsect;
-
switch (hdr->sh_type)
{
case SHT_PARISC_EXT:
if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
return FALSE;
- newsect = hdr->bfd_section;
- return TRUE;
+ return ((hdr->sh_flags & SHF_PARISC_SHORT) == 0
+ || bfd_set_section_flags (hdr->bfd_section,
+ hdr->bfd_section->flags | SEC_SMALL_DATA));
}
/* SEC is a section containing relocs for an input BFD when linking; return
srel_name = (bfd_elf_string_from_elf_section
(abfd, elf_elfheader(abfd)->e_shstrndx,
- elf_section_data(sec)->rel_hdr.sh_name));
+ _bfd_elf_single_rel_hdr(sec)->sh_name));
if (srel_name == NULL)
return FALSE;
- BFD_ASSERT ((CONST_STRNEQ (srel_name, ".rela")
- && strcmp (bfd_get_section_name (abfd, sec),
- srel_name + 5) == 0)
- || (CONST_STRNEQ (srel_name, ".rel")
- && strcmp (bfd_get_section_name (abfd, sec),
- srel_name + 4) == 0));
-
dynobj = hppa_info->root.dynobj;
if (!dynobj)
hppa_info->root.dynobj = dynobj = abfd;
- srel = bfd_get_section_by_name (dynobj, srel_name);
+ srel = bfd_get_linker_section (dynobj, srel_name);
if (srel == NULL)
{
- srel = bfd_make_section_with_flags (dynobj, srel_name,
- (SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED
- | SEC_READONLY));
+ srel = bfd_make_section_anyway_with_flags (dynobj, srel_name,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
if (srel == NULL
- || !bfd_set_section_alignment (dynobj, srel, 3))
+ || !bfd_set_section_alignment (srel, 3))
return FALSE;
}
struct elf64_hppa_link_hash_entry *hh,
int type,
asection *sec,
- int sec_symndx,
- bfd_vma offset,
+ int sec_symndx,
+ bfd_vma offset,
bfd_vma addend)
{
struct elf64_hppa_dyn_reloc_entry *rent;
{
Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
bfd_signed_vma *local_refcounts;
-
+
local_refcounts = elf_local_got_refcounts (abfd);
if (local_refcounts == NULL)
{
const Elf_Internal_Rela *relend;
Elf_Internal_Shdr *symtab_hdr;
const Elf_Internal_Rela *rel;
- asection *dlt, *plt, *stubs;
- char *buf;
- size_t buf_len;
unsigned int sec_symndx;
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
return TRUE;
/* If this is the first dynamic object found in the link, create
}
hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
/* If necessary, build a new table holding section symbols indices
for this BFD. */
- if (info->shared && hppa_info->section_syms_bfd != abfd)
+ if (bfd_link_pic (info) && hppa_info->section_syms_bfd != abfd)
{
unsigned long i;
unsigned int highest_shndx;
relocations when building shared libraries. When not building shared
libraries this value is never really used, but assign it to zero to
prevent out of bounds memory accesses in other routines. */
- if (info->shared)
+ if (bfd_link_pic (info))
{
sec_symndx = _bfd_elf_section_from_bfd_section (abfd, sec);
else
sec_symndx = 0;
- dlt = plt = stubs = NULL;
- buf = NULL;
- buf_len = 0;
-
relend = relocs + sec->reloc_count;
for (rel = relocs; rel < relend; ++rel)
{
|| hh->eh.root.type == bfd_link_hash_warning)
hh = hppa_elf_hash_entry (hh->eh.root.u.i.link);
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
hh->eh.ref_regular = 1;
}
else
have yet been processed. Do something with what we know, as
this may help reduce memory usage and processing time later. */
maybe_dynamic = FALSE;
- if (hh && ((info->shared
+ if (hh && ((bfd_link_pic (info)
&& (!info->symbolic
|| info->unresolved_syms_in_shared_libs == RM_IGNORE))
|| !hh->eh.def_regular
break;
case R_PARISC_DIR64:
- if (info->shared || maybe_dynamic)
+ if (bfd_link_pic (info) || maybe_dynamic)
need_entry = (NEED_DYNREL);
dynrel_type = R_PARISC_DIR64;
break;
case R_PARISC_LTOFF_FPTR16F:
case R_PARISC_LTOFF_FPTR16WF:
case R_PARISC_LTOFF_FPTR16DF:
- if (info->shared || maybe_dynamic)
+ if (bfd_link_pic (info) || maybe_dynamic)
need_entry = (NEED_DLT | NEED_OPD | NEED_PLT);
else
need_entry = (NEED_DLT | NEED_OPD | NEED_PLT);
/* This is a simple OPD entry. */
case R_PARISC_FPTR64:
- if (info->shared || maybe_dynamic)
+ if (bfd_link_pic (info) || maybe_dynamic)
need_entry = (NEED_OPD | NEED_PLT | NEED_DYNREL);
else
need_entry = (NEED_OPD | NEED_PLT);
else
{
bfd_signed_vma *local_dlt_refcounts;
-
+
/* This is a DLT entry for a local symbol. */
local_dlt_refcounts = hppa64_elf_local_refcounts (abfd);
if (local_dlt_refcounts == NULL)
{
bfd_signed_vma *local_dlt_refcounts;
bfd_signed_vma *local_plt_refcounts;
-
+
/* This is a PLT entry for a local symbol. */
local_dlt_refcounts = hppa64_elf_local_refcounts (abfd);
if (local_dlt_refcounts == NULL)
{
bfd_signed_vma *local_dlt_refcounts;
bfd_signed_vma *local_opd_refcounts;
-
+
/* This is a OPD for a local symbol. */
local_dlt_refcounts = hppa64_elf_local_refcounts (abfd);
if (local_dlt_refcounts == NULL)
a dynamic R_PARISC_FPTR64 relocation, then make sure the
section symbol for this section ends up in the dynamic
symbol table. */
- if (info->shared && dynrel_type == R_PARISC_FPTR64
+ if (bfd_link_pic (info) && dynrel_type == R_PARISC_FPTR64
&& ! (bfd_elf_link_record_local_dynamic_symbol
(info, abfd, sec_symndx)))
return FALSE;
}
}
- if (buf)
- free (buf);
return TRUE;
err_out:
- if (buf)
- free (buf);
return FALSE;
}
struct elf64_hppa_link_hash_table *hppa_info;
hppa_info = hppa_link_hash_table (info);
-
- if (eh->root.type == bfd_link_hash_warning)
- eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
+ if (hppa_info == NULL)
+ return FALSE;
if (eh
&& (eh->root.type == bfd_link_hash_defined
if (hh->want_dlt)
{
- if (x->info->shared)
+ if (bfd_link_pic (x->info))
{
/* Possibly add the symbol to the local dynamic symbol
table since we might need to create a dynamic relocation
allocate_global_data_plt (struct elf_link_hash_entry *eh, void *data)
{
struct elf64_hppa_link_hash_entry *hh = hppa_elf_hash_entry (eh);
- struct elf64_hppa_allocate_data *x = (struct elf64_hppa_allocate_data *)data;
+ struct elf64_hppa_allocate_data *x = (struct elf64_hppa_allocate_data *) data;
if (hh->want_plt
&& elf64_hppa_dynamic_symbol_p (eh, x->info)
hh->plt_offset = x->ofs;
x->ofs += PLT_ENTRY_SIZE;
if (hh->plt_offset < 0x2000)
- hppa_link_hash_table (x->info)->gp_offset = hh->plt_offset;
+ {
+ struct elf64_hppa_link_hash_table *hppa_info;
+
+ hppa_info = hppa_link_hash_table (x->info);
+ if (hppa_info == NULL)
+ return FALSE;
+
+ hppa_info->gp_offset = hh->plt_offset;
+ }
}
else
hh->want_plt = 0;
if (hh && hh->want_opd)
{
- while (hh->eh.root.type == bfd_link_hash_indirect
- || hh->eh.root.type == bfd_link_hash_warning)
- hh = hppa_elf_hash_entry (hh->eh.root.u.i.link);
-
/* We never need an opd entry for a symbol which is not
defined by this output file. */
if (hh && (hh->eh.root.type == bfd_link_hash_undefined
/* If we are creating a shared library, took the address of a local
function or might export this function from this object file, then
we have to create an opd descriptor. */
- else if (x->info->shared
+ else if (bfd_link_pic (x->info)
|| hh == NULL
|| (hh->eh.dynindx == -1 && hh->eh.type != STT_PARISC_MILLI)
|| (hh->eh.root.type == bfd_link_hash_defined
create a runtime relocation for the symbol to properly
initialize the .opd entry. Make sure the symbol gets
added to the dynamic symbol table. */
- if (x->info->shared
+ if (bfd_link_pic (x->info)
&& (hh == NULL || (hh->eh.dynindx == -1)))
{
bfd *owner;
in dynamic relocs. But name munging does make the result
much easier to debug. ie, the EPLT reloc will reference
a symbol like .foobar, instead of .text + offset. */
- if (x->info->shared && eh)
+ if (bfd_link_pic (x->info) && eh)
{
char *new_name;
struct elf_link_hash_entry *nh;
- new_name = alloca (strlen (eh->root.root.string) + 2);
- new_name[0] = '.';
- strcpy (new_name + 1, eh->root.root.string);
+ new_name = concat (".", eh->root.root.string, NULL);
nh = elf_link_hash_lookup (elf_hash_table (x->info),
new_name, TRUE, TRUE, TRUE);
+ free (new_name);
nh->root.type = eh->root.type;
nh->root.u.def.value = eh->root.u.def.value;
nh->root.u.def.section = eh->root.u.def.section;
if (! bfd_elf_link_record_dynamic_symbol (x->info, nh))
return FALSE;
-
}
hh->opd_offset = x->ofs;
x->ofs += OPD_ENTRY_SIZE;
/* HP requires the EI_OSABI field to be filled in. The assignment to
EI_ABIVERSION may not be strictly necessary. */
-static void
-elf64_hppa_post_process_headers (bfd *abfd,
- struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
+static bfd_boolean
+elf64_hppa_init_file_header (bfd *abfd, struct bfd_link_info *info)
{
- Elf_Internal_Ehdr * i_ehdrp;
+ Elf_Internal_Ehdr *i_ehdrp;
+
+ if (!_bfd_elf_init_file_header (abfd, info))
+ return FALSE;
i_ehdrp = elf_elfheader (abfd);
-
i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
i_ehdrp->e_ident[EI_ABIVERSION] = 1;
+ return TRUE;
}
/* Create function descriptor section (.opd). This section is called .opd
if (!dynobj)
hppa_info->root.dynobj = dynobj = abfd;
- opd = bfd_make_section_with_flags (dynobj, ".opd",
- (SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED));
+ opd = bfd_make_section_anyway_with_flags (dynobj, ".opd",
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED));
if (!opd
- || !bfd_set_section_alignment (abfd, opd, 3))
+ || !bfd_set_section_alignment (opd, 3))
{
BFD_ASSERT (0);
return FALSE;
if (!dynobj)
hppa_info->root.dynobj = dynobj = abfd;
- plt = bfd_make_section_with_flags (dynobj, ".plt",
- (SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED));
+ plt = bfd_make_section_anyway_with_flags (dynobj, ".plt",
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED));
if (!plt
- || !bfd_set_section_alignment (abfd, plt, 3))
+ || !bfd_set_section_alignment (plt, 3))
{
BFD_ASSERT (0);
return FALSE;
if (!dynobj)
hppa_info->root.dynobj = dynobj = abfd;
- dlt = bfd_make_section_with_flags (dynobj, ".dlt",
- (SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED));
+ dlt = bfd_make_section_anyway_with_flags (dynobj, ".dlt",
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED));
if (!dlt
- || !bfd_set_section_alignment (abfd, dlt, 3))
+ || !bfd_set_section_alignment (dlt, 3))
{
BFD_ASSERT (0);
return FALSE;
if (!dynobj)
hppa_info->root.dynobj = dynobj = abfd;
- stub = bfd_make_section_with_flags (dynobj, ".stub",
- (SEC_ALLOC | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_READONLY
- | SEC_LINKER_CREATED));
+ stub = bfd_make_section_anyway_with_flags (dynobj, ".stub",
+ (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_READONLY
+ | SEC_LINKER_CREATED));
if (!stub
- || !bfd_set_section_alignment (abfd, stub, 3))
+ || !bfd_set_section_alignment (stub, 3))
{
BFD_ASSERT (0);
return FALSE;
struct bfd_link_info *info)
{
asection *s;
+ struct elf64_hppa_link_hash_table *hppa_info;
- if (! get_stub (abfd, info, hppa_link_hash_table (info)))
+ hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
+
+ if (! get_stub (abfd, info, hppa_info))
return FALSE;
- if (! get_dlt (abfd, info, hppa_link_hash_table (info)))
+ if (! get_dlt (abfd, info, hppa_info))
return FALSE;
- if (! get_plt (abfd, info, hppa_link_hash_table (info)))
+ if (! get_plt (abfd, info, hppa_info))
return FALSE;
- if (! get_opd (abfd, info, hppa_link_hash_table (info)))
+ if (! get_opd (abfd, info, hppa_info))
return FALSE;
- s = bfd_make_section_with_flags (abfd, ".rela.dlt",
- (SEC_ALLOC | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_READONLY
- | SEC_LINKER_CREATED));
+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.dlt",
+ (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_READONLY
+ | SEC_LINKER_CREATED));
if (s == NULL
- || !bfd_set_section_alignment (abfd, s, 3))
+ || !bfd_set_section_alignment (s, 3))
return FALSE;
- hppa_link_hash_table (info)->dlt_rel_sec = s;
-
- s = bfd_make_section_with_flags (abfd, ".rela.plt",
- (SEC_ALLOC | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_READONLY
- | SEC_LINKER_CREATED));
+ hppa_info->dlt_rel_sec = s;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.plt",
+ (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_READONLY
+ | SEC_LINKER_CREATED));
if (s == NULL
- || !bfd_set_section_alignment (abfd, s, 3))
+ || !bfd_set_section_alignment (s, 3))
return FALSE;
- hppa_link_hash_table (info)->plt_rel_sec = s;
-
- s = bfd_make_section_with_flags (abfd, ".rela.data",
- (SEC_ALLOC | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_READONLY
- | SEC_LINKER_CREATED));
+ hppa_info->plt_rel_sec = s;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.data",
+ (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_READONLY
+ | SEC_LINKER_CREATED));
if (s == NULL
- || !bfd_set_section_alignment (abfd, s, 3))
+ || !bfd_set_section_alignment (s, 3))
return FALSE;
- hppa_link_hash_table (info)->other_rel_sec = s;
-
- s = bfd_make_section_with_flags (abfd, ".rela.opd",
- (SEC_ALLOC | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_READONLY
- | SEC_LINKER_CREATED));
+ hppa_info->other_rel_sec = s;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.opd",
+ (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_READONLY
+ | SEC_LINKER_CREATED));
if (s == NULL
- || !bfd_set_section_alignment (abfd, s, 3))
+ || !bfd_set_section_alignment (s, 3))
return FALSE;
- hppa_link_hash_table (info)->opd_rel_sec = s;
+ hppa_info->opd_rel_sec = s;
return TRUE;
}
bfd_boolean dynamic_symbol, shared;
hppa_info = hppa_link_hash_table (x->info);
+ if (hppa_info == NULL)
+ return FALSE;
+
dynamic_symbol = elf64_hppa_dynamic_symbol_p (eh, x->info);
- shared = x->info->shared;
+ shared = bfd_link_pic (x->info);
/* We may need to allocate relocations for a non-dynamic symbol
when creating a shared library. */
/* If this is a weak symbol, and there is a real definition, the
processor independent code will have arranged for us to see the
real definition first, and we can just use the same value. */
- if (eh->u.weakdef != NULL)
+ if (eh->is_weakalias)
{
- BFD_ASSERT (eh->u.weakdef->root.type == bfd_link_hash_defined
- || eh->u.weakdef->root.type == bfd_link_hash_defweak);
- eh->root.u.def.section = eh->u.weakdef->root.u.def.section;
- eh->root.u.def.value = eh->u.weakdef->root.u.def.value;
+ struct elf_link_hash_entry *def = weakdef (eh);
+ BFD_ASSERT (def->root.type == bfd_link_hash_defined);
+ eh->root.u.def.section = def->root.u.def.section;
+ eh->root.u.def.value = def->root.u.def.value;
return TRUE;
}
elf64_hppa_mark_milli_and_exported_functions (struct elf_link_hash_entry *eh,
void *data)
{
- struct elf_link_hash_entry *elf = eh;
- struct bfd_link_info *info = (struct bfd_link_info *)data;
+ struct bfd_link_info *info = (struct bfd_link_info *) data;
- if (elf->root.type == bfd_link_hash_warning)
- elf = (struct elf_link_hash_entry *) elf->root.u.i.link;
-
- if (elf->type == STT_PARISC_MILLI)
+ if (eh->type == STT_PARISC_MILLI)
{
- if (elf->dynindx != -1)
+ if (eh->dynindx != -1)
{
- elf->dynindx = -1;
+ eh->dynindx = -1;
_bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
- elf->dynstr_index);
+ eh->dynstr_index);
}
return TRUE;
}
bfd_boolean reltext;
hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
- dynobj = elf_hash_table (info)->dynobj;
+ dynobj = hppa_info->root.dynobj;
BFD_ASSERT (dynobj != NULL);
/* Mark each function this program exports so that we will allocate
We have to traverse the main linker hash table since we have to
find functions which may not have been mentioned in any relocs. */
- elf_link_hash_traverse (elf_hash_table (info),
- (elf_hash_table (info)->dynamic_sections_created
+ elf_link_hash_traverse (&hppa_info->root,
+ (hppa_info->root.dynamic_sections_created
? elf64_hppa_mark_milli_and_exported_functions
: elf64_hppa_mark_exported_functions),
info);
- if (elf_hash_table (info)->dynamic_sections_created)
+ if (hppa_info->root.dynamic_sections_created)
{
/* Set the contents of the .interp section to the interpreter. */
- if (info->executable)
+ if (bfd_link_executable (info) && !info->nointerp)
{
- sec = bfd_get_section_by_name (dynobj, ".interp");
+ sec = bfd_get_linker_section (dynobj, ".interp");
BFD_ASSERT (sec != NULL);
sec->size = sizeof ELF_DYNAMIC_INTERPRETER;
sec->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
not actually use these entries. Reset the size of .rela.dlt,
which will cause it to get stripped from the output file
below. */
- sec = bfd_get_section_by_name (dynobj, ".rela.dlt");
+ sec = hppa_info->dlt_rel_sec;
if (sec != NULL)
sec->size = 0;
}
/* Set up DLT, PLT and OPD offsets for local syms, and space for local
dynamic relocs. */
- for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
{
bfd_signed_vma *local_dlt;
bfd_signed_vma *end_local_dlt;
{
*local_dlt = sec->size;
sec->size += DLT_ENTRY_SIZE;
- if (info->shared)
- {
+ if (bfd_link_pic (info))
+ {
srel->size += sizeof (Elf64_External_Rela);
- }
+ }
}
else
*local_dlt = (bfd_vma) -1;
{
*local_plt = sec->size;
sec->size += PLT_ENTRY_SIZE;
- if (info->shared)
+ if (bfd_link_pic (info))
srel->size += sizeof (Elf64_External_Rela);
}
else
{
*local_opd = sec->size;
sec->size += OPD_ENTRY_SIZE;
- if (info->shared)
+ if (bfd_link_pic (info))
srel->size += sizeof (Elf64_External_Rela);
}
else
if (hppa_info->dlt_sec)
{
data.ofs = hppa_info->dlt_sec->size;
- elf_link_hash_traverse (elf_hash_table (info),
+ elf_link_hash_traverse (&hppa_info->root,
allocate_global_data_dlt, &data);
hppa_info->dlt_sec->size = data.ofs;
}
if (hppa_info->plt_sec)
{
data.ofs = hppa_info->plt_sec->size;
- elf_link_hash_traverse (elf_hash_table (info),
- allocate_global_data_plt, &data);
+ elf_link_hash_traverse (&hppa_info->root,
+ allocate_global_data_plt, &data);
hppa_info->plt_sec->size = data.ofs;
}
if (hppa_info->stub_sec)
{
data.ofs = 0x0;
- elf_link_hash_traverse (elf_hash_table (info),
+ elf_link_hash_traverse (&hppa_info->root,
allocate_global_data_stub, &data);
hppa_info->stub_sec->size = data.ofs;
}
if (hppa_info->opd_sec)
{
data.ofs = hppa_info->opd_sec->size;
- elf_link_hash_traverse (elf_hash_table (info),
+ elf_link_hash_traverse (&hppa_info->root,
allocate_global_data_opd, &data);
hppa_info->opd_sec->size = data.ofs;
}
/* Now allocate space for dynamic relocations, if necessary. */
if (hppa_info->root.dynamic_sections_created)
- elf_link_hash_traverse (elf_hash_table (info),
+ elf_link_hash_traverse (&hppa_info->root,
allocate_dynrel_entries, &data);
/* The sizes of all the sections are set. Allocate memory for them. */
/* It's OK to base decisions on the section name, because none
of the dynobj section names depend upon the input files. */
- name = bfd_get_section_name (dynobj, sec);
+ name = bfd_section_name (sec);
if (strcmp (name, ".plt") == 0)
{
entry. The entries in the .rela.plt section
really apply to the .got section, which we
created ourselves and so know is not readonly. */
- outname = bfd_get_section_name (output_bfd,
- sec->output_section);
+ outname = bfd_section_name (sec->output_section);
target = bfd_get_section_by_name (output_bfd, outname + 4);
if (target != NULL
&& (target->flags & SEC_READONLY) != 0
}
}
- if (elf_hash_table (info)->dynamic_sections_created)
+ if (hppa_info->root.dynamic_sections_created)
{
/* Always create a DT_PLTGOT. It actually has nothing to do with
the PLT, it is how we communicate the __gp value of a load
must add the entries now so that we get the correct size for
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
- if (! info->shared)
+ if (! bfd_link_pic (info))
{
if (!add_dynamic_entry (DT_DEBUG, 0)
|| !add_dynamic_entry (DT_HP_DLD_HOOK, 0)
Elf_Internal_Sym *sym)
{
struct elf64_hppa_link_hash_entry *hh = hppa_elf_hash_entry (eh);
- asection *stub, *splt, *sdlt, *sopd, *spltrel, *sdltrel;
+ asection *stub, *splt, *sopd, *spltrel;
struct elf64_hppa_link_hash_table *hppa_info;
hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
stub = hppa_info->stub_sec;
splt = hppa_info->plt_sec;
- sdlt = hppa_info->dlt_sec;
sopd = hppa_info->opd_sec;
spltrel = hppa_info->plt_rel_sec;
- sdltrel = hppa_info->dlt_rel_sec;
/* Incredible. It is actually necessary to NOT use the symbol's real
value when building the dynamic symbol table for a shared library.
if we are creating a shared library and the symbol is
still undefined, we create a dynamic relocation to fill
in the correct value. */
- if (info->shared && eh->root.type == bfd_link_hash_undefined)
+ if (bfd_link_pic (info) && eh->root.type == bfd_link_hash_undefined)
value = 0;
else
value = (eh->root.u.def.value + eh->root.u.def.section->vma);
in the output_offset of the PLT section. */
bfd_put_64 (splt->owner, value, splt->contents + hh->plt_offset);
- value = _bfd_get_gp_value (splt->output_section->owner);
+ value = _bfd_get_gp_value (info->output_bfd);
bfd_put_64 (splt->owner, value, splt->contents + hh->plt_offset + 0x8);
/* Create a dynamic IPLT relocation for this entry.
loc = spltrel->contents;
loc += spltrel->reloc_count++ * sizeof (Elf64_External_Rela);
- bfd_elf64_swap_reloca_out (splt->output_section->owner, &rel, loc);
+ bfd_elf64_swap_reloca_out (info->output_bfd, &rel, loc);
}
/* Initialize an external call stub entry if requested. */
if ((value & 7) || value + max_offset >= 2*max_offset - 8)
{
- (*_bfd_error_handler) (_("stub entry for %s cannot load .plt, dp offset = %ld"),
- hh->eh.root.root.string,
- (long) value);
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("stub entry for %s cannot load .plt, dp offset = %" PRId64),
+ hh->eh.root.root.string, (int64_t) value);
return FALSE;
}
asection *sopdrel;
hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
+
sopd = hppa_info->opd_sec;
sopdrel = hppa_info->opd_rel_sec;
bfd_put_64 (sopd->owner, value, sopd->contents + hh->opd_offset + 16);
/* The last word is our local __gp value. */
- value = _bfd_get_gp_value (sopd->output_section->owner);
+ value = _bfd_get_gp_value (info->output_bfd);
bfd_put_64 (sopd->owner, value, sopd->contents + hh->opd_offset + 24);
}
/* If we are generating a shared library, we must generate EPLT relocations
for each entry in the .opd, even for static functions (they may have
had their address taken). */
- if (info->shared && hh->want_opd)
+ if (bfd_link_pic (info) && hh->want_opd)
{
Elf_Internal_Rela rel;
bfd_byte *loc;
char *new_name;
struct elf_link_hash_entry *nh;
- new_name = alloca (strlen (eh->root.root.string) + 2);
- new_name[0] = '.';
- strcpy (new_name + 1, eh->root.root.string);
+ new_name = concat (".", eh->root.root.string, NULL);
nh = elf_link_hash_lookup (elf_hash_table (info),
new_name, TRUE, TRUE, FALSE);
-
+
/* All we really want from the new symbol is its dynamic
symbol index. */
if (nh)
dynindx = nh->dynindx;
+ free (new_name);
}
rel.r_addend = 0;
loc = sopdrel->contents;
loc += sopdrel->reloc_count++ * sizeof (Elf64_External_Rela);
- bfd_elf64_swap_reloca_out (sopd->output_section->owner, &rel, loc);
+ bfd_elf64_swap_reloca_out (info->output_bfd, &rel, loc);
}
return TRUE;
}
asection *sdlt, *sdltrel;
hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
sdlt = hppa_info->dlt_sec;
sdltrel = hppa_info->dlt_rel_sec;
address, so there is no need to create a relocation. Just install
the proper value into the DLT, note this shortcut can not be
skipped when building a shared library. */
- if (! info->shared && hh && hh->want_dlt)
+ if (! bfd_link_pic (info) && hh && hh->want_dlt)
{
bfd_vma value;
/* Create a relocation for the DLT entry associated with this symbol.
When building a shared library the symbol does not have to be dynamic. */
if (hh->want_dlt
- && (elf64_hppa_dynamic_symbol_p (eh, info) || info->shared))
+ && (elf64_hppa_dynamic_symbol_p (eh, info) || bfd_link_pic (info)))
{
Elf_Internal_Rela rel;
bfd_byte *loc;
loc = sdltrel->contents;
loc += sdltrel->reloc_count++ * sizeof (Elf64_External_Rela);
- bfd_elf64_swap_reloca_out (sdlt->output_section->owner, &rel, loc);
+ bfd_elf64_swap_reloca_out (info->output_bfd, &rel, loc);
}
return TRUE;
}
dynamic_symbol = elf64_hppa_dynamic_symbol_p (eh, info);
- if (!dynamic_symbol && !info->shared)
+ if (!dynamic_symbol && !bfd_link_pic (info))
return TRUE;
if (hh->reloc_entries)
int dynindx;
hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
/* We may need to do a relocation against a local symbol, in
which case we have to look up it's dynamic symbol index off
/* Allocate one iff we are building a shared library, the relocation
isn't a R_PARISC_FPTR64, or we don't want an opd entry. */
- if (!info->shared && rent->type == R_PARISC_FPTR64 && hh->want_opd)
+ if (!bfd_link_pic (info)
+ && rent->type == R_PARISC_FPTR64 && hh->want_opd)
continue;
/* Create a dynamic relocation for this entry.
We use a section symbol recorded by check_relocs as the
base symbol for the relocation. The addend is the difference
between the section symbol and the address of the .opd entry. */
- if (info->shared && rent->type == R_PARISC_FPTR64 && hh->want_opd)
+ if (bfd_link_pic (info)
+ && rent->type == R_PARISC_FPTR64 && hh->want_opd)
{
bfd_vma value, value2;
loc = hppa_info->other_rel_sec->contents;
loc += (hppa_info->other_rel_sec->reloc_count++
* sizeof (Elf64_External_Rela));
- bfd_elf64_swap_reloca_out (hppa_info->other_rel_sec->output_section->owner,
- &rel, loc);
+ bfd_elf64_swap_reloca_out (info->output_bfd, &rel, loc);
}
}
dynamic linker, before writing them out. */
static enum elf_reloc_type_class
-elf64_hppa_reloc_type_class (const Elf_Internal_Rela *rela)
+elf64_hppa_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
- if (ELF64_R_SYM (rela->r_info) == 0)
+ if (ELF64_R_SYM (rela->r_info) == STN_UNDEF)
return reloc_class_relative;
switch ((int) ELF64_R_TYPE (rela->r_info))
struct elf64_hppa_link_hash_table *hppa_info;
hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
/* Finalize the contents of the .opd section. */
elf_link_hash_traverse (elf_hash_table (info),
elf64_hppa_finalize_dlt,
info);
- sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
if (elf_hash_table (info)->dynamic_sections_created)
{
area at the start of the .data section. So all we have to
to is find the start of the .data section. */
s = bfd_get_section_by_name (output_bfd, ".data");
+ if (!s)
+ return FALSE;
dyn.d_un.d_ptr = s->vma;
bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
break;
case 760: /* Linux/hppa */
/* pr_cursig */
- elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
/* pr_pid */
- elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 32);
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 32);
/* pr_reg */
offset = 112;
return FALSE;
case 136: /* Linux/hppa elf_prpsinfo. */
- elf_tdata (abfd)->core_program
+ elf_tdata (abfd)->core->program
= _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
- elf_tdata (abfd)->core_command
+ elf_tdata (abfd)->core->command
= _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
}
/* Note that for some reason, a spurious space is tacked
onto the end of the args in some (at least one anyway)
implementations, so strip it off if it exists. */
- command = elf_tdata (abfd)->core_command;
+ command = elf_tdata (abfd)->core->command;
n = strlen (command);
if (0 < n && command[n - 1] == ' ')
return 0;
}
+static bfd_boolean
+elf64_hppa_allow_non_load_phdr (bfd *abfd ATTRIBUTE_UNUSED,
+ const Elf_Internal_Phdr *phdr ATTRIBUTE_UNUSED,
+ unsigned int count ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
/* Allocate and initialize any program headers required by this
specific backend.
existence of a .interp section. */
static bfd_boolean
-elf64_hppa_modify_segment_map (bfd *abfd,
- struct bfd_link_info *info ATTRIBUTE_UNUSED)
+elf64_hppa_modify_segment_map (bfd *abfd, struct bfd_link_info *info)
{
struct elf_segment_map *m;
- asection *s;
- s = bfd_get_section_by_name (abfd, ".interp");
- if (! s)
+ m = elf_seg_map (abfd);
+ if (info != NULL && !info->user_phdrs && m != NULL && m->p_type != PT_PHDR)
{
- for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
- if (m->p_type == PT_PHDR)
- break;
+ m = ((struct elf_segment_map *)
+ bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
if (m == NULL)
- {
- m = ((struct elf_segment_map *)
- bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
- if (m == NULL)
- return FALSE;
+ return FALSE;
- m->p_type = PT_PHDR;
- m->p_flags = PF_R | PF_X;
- m->p_flags_valid = 1;
- m->p_paddr_valid = 1;
- m->includes_phdrs = 1;
+ m->p_type = PT_PHDR;
+ m->p_flags = PF_R | PF_X;
+ m->p_flags_valid = 1;
+ m->p_paddr_valid = 1;
+ m->includes_phdrs = 1;
- m->next = elf_tdata (abfd)->segment_map;
- elf_tdata (abfd)->segment_map = m;
- }
+ m->next = elf_seg_map (abfd);
+ elf_seg_map (abfd) = m;
}
- for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
+ for (m = elf_seg_map (abfd) ; m != NULL; m = m->next)
if (m->p_type == PT_LOAD)
{
unsigned int i;
}
/* Support HP specific sections for core files. */
+
static bfd_boolean
-elf64_hppa_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int index,
+elf64_hppa_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int sec_index,
const char *typename)
{
if (hdr->p_type == PT_HP_CORE_KERNEL)
{
asection *sect;
- if (!_bfd_elf_make_section_from_phdr (abfd, hdr, index, typename))
+ if (!_bfd_elf_make_section_from_phdr (abfd, hdr, sec_index, typename))
return FALSE;
sect = bfd_make_section_anyway (abfd, ".kernel");
if (bfd_bread (&sig, 4, abfd) != 4)
return FALSE;
- elf_tdata (abfd)->core_signal = sig;
+ elf_tdata (abfd)->core->signal = sig;
- if (!_bfd_elf_make_section_from_phdr (abfd, hdr, index, typename))
+ if (!_bfd_elf_make_section_from_phdr (abfd, hdr, sec_index, typename))
return FALSE;
/* GDB uses the ".reg" section to read register contents. */
|| hdr->p_type == PT_HP_CORE_MMF)
hdr->p_type = PT_LOAD;
- return _bfd_elf_make_section_from_phdr (abfd, hdr, index, typename);
+ return _bfd_elf_make_section_from_phdr (abfd, hdr, sec_index, typename);
}
/* Hook called by the linker routine which adds symbols from an object
asection **secp,
bfd_vma *valp)
{
- unsigned int index = sym->st_shndx;
+ unsigned int sec_index = sym->st_shndx;
- switch (index)
+ switch (sec_index)
{
case SHN_PARISC_ANSI_COMMON:
*secp = bfd_make_section_old_way (abfd, ".PARISC.ansi.common");
{
struct bfd_link_info *info = data;
- if (h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
/* If we are not creating a shared library, and this symbol is
referenced by a shared library but is not defined anywhere, then
the generic code will warn that it is undefined.
Ultimately we should have better controls over the generic ELF BFD
linker code. */
- if (! info->relocatable
+ if (! bfd_link_relocatable (info)
&& info->unresolved_syms_in_shared_libs != RM_IGNORE
&& h->root.type == bfd_link_hash_undefined
&& h->ref_dynamic
{
struct bfd_link_info *info = data;
- if (h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
/* If we are not creating a shared library, and this symbol is
referenced by a shared library but is not defined anywhere, then
the generic code will warn that it is undefined.
Ultimately we should have better controls over the generic ELF BFD
linker code. */
- if (! info->relocatable
+ if (! bfd_link_relocatable (info)
&& info->unresolved_syms_in_shared_libs != RM_IGNORE
&& h->root.type == bfd_link_hash_undefined
&& !h->ref_dynamic
static bfd_boolean
elf_hppa_final_link (bfd *abfd, struct bfd_link_info *info)
{
- bfd_boolean retval;
+ struct stat buf;
struct elf64_hppa_link_hash_table *hppa_info = hppa_link_hash_table (info);
- if (! info->relocatable)
+ if (hppa_info == NULL)
+ return FALSE;
+
+ if (! bfd_link_relocatable (info))
{
struct elf_link_hash_entry *gp;
bfd_vma gp_val;
info);
/* Invoke the regular ELF backend linker to do all the work. */
- retval = bfd_elf_final_link (abfd, info);
+ if (!bfd_elf_final_link (abfd, info))
+ return FALSE;
elf_link_hash_traverse (elf_hash_table (info),
elf_hppa_remark_useless_dynamic_symbols,
/* If we're producing a final executable, sort the contents of the
unwind section. */
- if (retval && !info->relocatable)
- retval = elf_hppa_sort_unwind (abfd);
+ if (bfd_link_relocatable (info))
+ return TRUE;
+
+ /* Do not attempt to sort non-regular files. This is here
+ especially for configure scripts and kernel builds which run
+ tests with "ld [...] -o /dev/null". */
+ if (stat (abfd->filename, &buf) != 0
+ || !S_ISREG(buf.st_mode))
+ return TRUE;
- return retval;
+ return elf_hppa_sort_unwind (abfd);
}
/* Relocate the given INSN. VALUE should be the actual value we want
unsigned int r_type = howto->type;
bfd_byte *hit_data = contents + offset;
+ if (hppa_info == NULL)
+ return bfd_reloc_notsupported;
+
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
local_offsets = elf_local_got_offsets (input_bfd);
insn = bfd_get_32 (input_bfd, hit_data);
if (max_branch_offset != 0
&& value + addend + max_branch_offset >= 2*max_branch_offset)
{
- (*_bfd_error_handler)
- (_("%B(%A+0x%lx): cannot reach %s"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB(%pA+%#" PRIx64 "): cannot reach %s"),
input_bfd,
input_section,
- offset,
- eh->root.root.string);
+ (uint64_t) offset,
+ eh ? eh->root.root.string : "unknown");
bfd_set_error (bfd_error_bad_value);
- return bfd_reloc_notsupported;
+ return bfd_reloc_overflow;
}
/* Adjust for any field selectors. */
{
bfd_vma *local_opd_offsets, *local_dlt_offsets;
- if (local_offsets == NULL)
- abort ();
+ if (local_offsets == NULL)
+ abort ();
/* Now do .opd creation if needed. */
if (r_type == R_PARISC_LTOFF_FPTR14R
(hppa_info->opd_sec->contents + off + 16));
/* The last word is our local __gp value. */
- value = _bfd_get_gp_value
- (hppa_info->opd_sec->output_section->owner);
+ value = _bfd_get_gp_value (info->output_bfd);
bfd_put_64 (hppa_info->opd_sec->owner, value,
(hppa_info->opd_sec->contents + off + 24));
}
case R_PARISC_LTOFF_FPTR32:
{
- /* We may still need to create the FPTR itself if it was for
- a local symbol. */
- if (hh == NULL)
- {
- /* The first two words of an .opd entry are zero. */
- memset (hppa_info->opd_sec->contents + hh->opd_offset, 0, 16);
-
- /* The next word is the address of the function. */
- bfd_put_64 (hppa_info->opd_sec->owner, value + addend,
- (hppa_info->opd_sec->contents
- + hh->opd_offset + 16));
-
- /* The last word is our local __gp value. */
- value = _bfd_get_gp_value
- (hppa_info->opd_sec->output_section->owner);
- bfd_put_64 (hppa_info->opd_sec->owner, value,
- hppa_info->opd_sec->contents + hh->opd_offset + 24);
-
- /* The DLT value is the address of the .opd entry. */
- value = (hh->opd_offset
- + hppa_info->opd_sec->output_offset
- + hppa_info->opd_sec->output_section->vma);
-
- bfd_put_64 (hppa_info->dlt_sec->owner,
- value,
- hppa_info->dlt_sec->contents + hh->dlt_offset);
- }
+ /* FIXME: There used to be code here to create the FPTR itself if
+ the relocation was against a local symbol. But the code could
+ never have worked. If the assert below is ever triggered then
+ the code will need to be reinstated and fixed so that it does
+ what is needed. */
+ BFD_ASSERT (hh != NULL);
/* We want the value of the DLT offset for this symbol, not
the symbol's actual address. Note that __gp may not point
+ hh->opd_offset + 16));
/* The last word is our local __gp value. */
- value = _bfd_get_gp_value
- (hppa_info->opd_sec->output_section->owner);
+ value = _bfd_get_gp_value (info->output_bfd);
bfd_put_64 (hppa_info->opd_sec->owner, value,
hppa_info->opd_sec->contents + hh->opd_offset + 24);
{
bfd_vma *local_opd_offsets;
- if (local_offsets == NULL)
- abort ();
+ if (local_offsets == NULL)
+ abort ();
local_opd_offsets = local_offsets + 2 * symtab_hdr->sh_info;
off = local_opd_offsets[r_symndx];
if ((off & 1) != 0)
{
BFD_ASSERT (off != (bfd_vma) -1);
- off &= ~1;
+ off &= ~1;
}
else
{
(hppa_info->opd_sec->contents + off + 16));
/* The last word is our local __gp value. */
- value = _bfd_get_gp_value
- (hppa_info->opd_sec->output_section->owner);
+ value = _bfd_get_gp_value (info->output_bfd);
bfd_put_64 (hppa_info->opd_sec->owner, value,
hppa_info->opd_sec->contents + off + 24);
}
struct elf64_hppa_link_hash_table *hppa_info;
hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
+
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
rel = relocs;
asection *sym_sec;
bfd_vma relocation;
bfd_reloc_status_type r;
- bfd_boolean warned_undef;
r_type = ELF_R_TYPE (rel->r_info);
if (r_type < 0 || r_type >= (int) R_PARISC_UNIMPLEMENTED)
eh = NULL;
sym = NULL;
sym_sec = NULL;
- warned_undef = FALSE;
if (r_symndx < symtab_hdr->sh_info)
{
/* This is a local symbol, hh defaults to NULL. */
else
{
/* This is not a local symbol. */
- bfd_boolean unresolved_reloc;
struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
- /* It seems this can happen with erroneous or unsupported
+ /* It seems this can happen with erroneous or unsupported
input (mixing a.out and elf in an archive, for example.) */
if (sym_hashes == NULL)
return FALSE;
eh = sym_hashes[r_symndx - symtab_hdr->sh_info];
- while (eh->root.type == bfd_link_hash_indirect
+ if (info->wrap_hash != NULL
+ && (input_section->flags & SEC_DEBUGGING) != 0)
+ eh = ((struct elf_link_hash_entry *)
+ unwrap_hash_lookup (info, input_bfd, &eh->root));
+
+ while (eh->root.type == bfd_link_hash_indirect
|| eh->root.type == bfd_link_hash_warning)
eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
- warned_undef = FALSE;
- unresolved_reloc = FALSE;
relocation = 0;
if (eh->root.type == bfd_link_hash_defined
|| eh->root.type == bfd_link_hash_defweak)
{
sym_sec = eh->root.u.def.section;
- if (sym_sec == NULL
- || sym_sec->output_section == NULL)
- /* Set a flag that will be cleared later if we find a
- relocation value for this symbol. output_section
- is typically NULL for symbols satisfied by a shared
- library. */
- unresolved_reloc = TRUE;
- else
+ if (sym_sec != NULL
+ && sym_sec->output_section != NULL)
relocation = (eh->root.u.def.value
+ sym_sec->output_section->vma
+ sym_sec->output_offset);
else if (info->unresolved_syms_in_objects == RM_IGNORE
&& ELF_ST_VISIBILITY (eh->other) == STV_DEFAULT)
;
- else if (!info->relocatable
+ else if (!bfd_link_relocatable (info)
&& elf_hppa_is_dynamic_loader_symbol (eh->root.root.string))
continue;
- else if (!info->relocatable)
+ else if (!bfd_link_relocatable (info))
{
bfd_boolean err;
err = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
|| ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT);
- if (!info->callbacks->undefined_symbol (info,
- eh->root.root.string,
- input_bfd,
- input_section,
- rel->r_offset, err))
- return FALSE;
- warned_undef = TRUE;
+ (*info->callbacks->undefined_symbol) (info,
+ eh->root.root.string,
+ input_bfd,
+ input_section,
+ rel->r_offset, err);
}
- if (!info->relocatable
- && relocation == 0
- && eh->root.type != bfd_link_hash_defined
- && eh->root.type != bfd_link_hash_defweak
- && eh->root.type != bfd_link_hash_undefweak)
- {
- if (info->unresolved_syms_in_objects == RM_IGNORE
- && ELF_ST_VISIBILITY (eh->other) == STV_DEFAULT
- && eh->type == STT_PARISC_MILLI)
- {
- if (! info->callbacks->undefined_symbol
- (info, eh_name (eh), input_bfd,
- input_section, rel->r_offset, FALSE))
- return FALSE;
- warned_undef = TRUE;
- }
- }
+ if (!bfd_link_relocatable (info)
+ && relocation == 0
+ && eh->root.type != bfd_link_hash_defined
+ && eh->root.type != bfd_link_hash_defweak
+ && eh->root.type != bfd_link_hash_undefweak)
+ {
+ if (info->unresolved_syms_in_objects == RM_IGNORE
+ && ELF_ST_VISIBILITY (eh->other) == STV_DEFAULT
+ && eh->type == STT_PARISC_MILLI)
+ (*info->callbacks->undefined_symbol)
+ (info, eh_name (eh), input_bfd,
+ input_section, rel->r_offset, FALSE);
+ }
}
- if (sym_sec != NULL && elf_discarded_section (sym_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;
- }
+ if (sym_sec != NULL && discarded_section (sym_sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
continue;
r = elf_hppa_final_link_relocate (rel, input_bfd, output_bfd,
if (sym_name == NULL)
return FALSE;
if (*sym_name == '\0')
- sym_name = bfd_section_name (input_bfd, sym_sec);
+ sym_name = bfd_section_name (sym_sec);
}
- if (!((*info->callbacks->reloc_overflow)
- (info, (eh ? &eh->root : NULL), sym_name,
- howto->name, (bfd_vma) 0, input_bfd,
- input_section, rel->r_offset)))
- return FALSE;
+ (*info->callbacks->reloc_overflow)
+ (info, (eh ? &eh->root : NULL), sym_name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
}
break;
}
static const struct bfd_elf_special_section elf64_hppa_special_sections[] =
{
- { STRING_COMMA_LEN (".fini"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
- { STRING_COMMA_LEN (".init"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
- { STRING_COMMA_LEN (".plt"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
- { STRING_COMMA_LEN (".dlt"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
+ { STRING_COMMA_LEN (".tbss"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_HP_TLS },
+ { STRING_COMMA_LEN (".fini"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".init"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".plt"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
+ { STRING_COMMA_LEN (".dlt"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
{ STRING_COMMA_LEN (".sdata"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
- { STRING_COMMA_LEN (".sbss"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
- { STRING_COMMA_LEN (".tbss"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_HP_TLS },
- { NULL, 0, 0, 0, 0 }
+ { STRING_COMMA_LEN (".sbss"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
+ { NULL, 0, 0, 0, 0 }
};
/* The hash bucket size is the standard one, namely 4. */
bfd_elf64_swap_reloca_out
};
-#define TARGET_BIG_SYM bfd_elf64_hppa_vec
+#define TARGET_BIG_SYM hppa_elf64_vec
#define TARGET_BIG_NAME "elf64-hppa"
#define ELF_ARCH bfd_arch_hppa
+#define ELF_TARGET_ID HPPA64_ELF_DATA
#define ELF_MACHINE_CODE EM_PARISC
/* This is not strictly correct. The maximum page size for PA2.0 is
64M. But everything still uses 4k. */
#define elf_backend_create_dynamic_sections \
elf64_hppa_create_dynamic_sections
-#define elf_backend_post_process_headers elf64_hppa_post_process_headers
+#define elf_backend_init_file_header elf64_hppa_init_file_header
+
+#define elf_backend_omit_section_dynsym _bfd_elf_omit_section_dynsym_all
-#define elf_backend_omit_section_dynsym \
- ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
#define elf_backend_adjust_dynamic_symbol \
elf64_hppa_adjust_dynamic_symbol
elf64_hppa_finish_dynamic_sections
#define elf_backend_grok_prstatus elf64_hppa_grok_prstatus
#define elf_backend_grok_psinfo elf64_hppa_grok_psinfo
-
+
/* Stuff for the BFD linker: */
#define bfd_elf64_bfd_link_hash_table_create \
elf64_hppa_hash_table_create
#define elf_backend_modify_segment_map \
elf64_hppa_modify_segment_map
+#define elf_backend_allow_non_load_phdr \
+ elf64_hppa_allow_non_load_phdr
+
#define elf_backend_link_output_symbol_hook \
elf64_hppa_link_output_symbol_hook
#include "elf64-target.h"
#undef TARGET_BIG_SYM
-#define TARGET_BIG_SYM bfd_elf64_hppa_linux_vec
+#define TARGET_BIG_SYM hppa_elf64_linux_vec
#undef TARGET_BIG_NAME
#define TARGET_BIG_NAME "elf64-hppa-linux"
#undef ELF_OSABI
-#define ELF_OSABI ELFOSABI_LINUX
-#undef elf_backend_post_process_headers
-#define elf_backend_post_process_headers _bfd_elf_set_osabi
+#define ELF_OSABI ELFOSABI_GNU
#undef elf64_bed
#define elf64_bed elf64_hppa_linux_bed
+#undef elf_backend_special_sections
+#define elf_backend_special_sections (elf64_hppa_special_sections + 1)
#include "elf64-target.h"