/* BFD back-end for HP PA-RISC ELF files.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001,
- 2002 Free Software Foundation, Inc.
+ 2002, 2003 Free Software Foundation, Inc.
Original code by
Center for Software Science
University of Utah
Largely rewritten by Alan Modra <alan@linuxcare.com.au>
-This file is part of BFD, the Binary File Descriptor library.
+ This file is part of BFD, the Binary File Descriptor library.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
#include "sysdep.h"
: ldw -24(%sp),%rp ; restore the original rp
: ldsid (%rp),%r1
: mtsp %r1,%sr0
- : be,n 0(%sr0,%rp) ; inter-space return */
+ : be,n 0(%sr0,%rp) ; inter-space return. */
#define PLT_ENTRY_SIZE 8
#define GOT_ENTRY_SIZE 4
PARAMS ((asection *, const Elf_Internal_Rela *,
struct elf32_hppa_link_hash_entry *, bfd_vma));
-static boolean hppa_build_one_stub
+static bfd_boolean hppa_build_one_stub
PARAMS ((struct bfd_hash_entry *, PTR));
-static boolean hppa_size_one_stub
+static bfd_boolean hppa_size_one_stub
PARAMS ((struct bfd_hash_entry *, PTR));
/* BFD and elf backend functions. */
-static boolean elf32_hppa_object_p PARAMS ((bfd *));
+static bfd_boolean elf32_hppa_object_p PARAMS ((bfd *));
-static boolean elf32_hppa_add_symbol_hook
+static bfd_boolean elf32_hppa_add_symbol_hook
PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
const char **, flagword *, asection **, bfd_vma *));
-static boolean elf32_hppa_create_dynamic_sections
+static bfd_boolean elf32_hppa_create_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
static void elf32_hppa_copy_indirect_symbol
- PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *));
+ PARAMS ((struct elf_backend_data *, struct elf_link_hash_entry *,
+ struct elf_link_hash_entry *));
-static boolean elf32_hppa_check_relocs
+static bfd_boolean elf32_hppa_check_relocs
PARAMS ((bfd *, struct bfd_link_info *,
asection *, const Elf_Internal_Rela *));
static asection *elf32_hppa_gc_mark_hook
- PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,
+ PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
struct elf_link_hash_entry *, Elf_Internal_Sym *));
-static boolean elf32_hppa_gc_sweep_hook
+static bfd_boolean elf32_hppa_gc_sweep_hook
PARAMS ((bfd *, struct bfd_link_info *,
asection *, const Elf_Internal_Rela *));
static void elf32_hppa_hide_symbol
- PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, boolean));
+ PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean));
-static boolean elf32_hppa_adjust_dynamic_symbol
+static bfd_boolean elf32_hppa_adjust_dynamic_symbol
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
-static boolean mark_PIC_calls
+static bfd_boolean mark_PIC_calls
PARAMS ((struct elf_link_hash_entry *, PTR));
-static boolean allocate_plt_static
+static bfd_boolean allocate_plt_static
PARAMS ((struct elf_link_hash_entry *, PTR));
-static boolean allocate_dynrelocs
+static bfd_boolean allocate_dynrelocs
PARAMS ((struct elf_link_hash_entry *, PTR));
-static boolean readonly_dynrelocs
+static bfd_boolean readonly_dynrelocs
PARAMS ((struct elf_link_hash_entry *, PTR));
-static boolean clobber_millicode_symbols
+static bfd_boolean clobber_millicode_symbols
PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *));
-static boolean elf32_hppa_size_dynamic_sections
+static bfd_boolean elf32_hppa_size_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
static void group_sections
- PARAMS ((struct elf32_hppa_link_hash_table *, bfd_size_type, boolean));
+ PARAMS ((struct elf32_hppa_link_hash_table *, bfd_size_type, bfd_boolean));
static int get_local_syms
PARAMS ((bfd *, bfd *, struct bfd_link_info *));
-static boolean elf32_hppa_final_link
+static bfd_boolean elf32_hppa_final_link
PARAMS ((bfd *, struct bfd_link_info *));
static void hppa_record_segment_addr
bfd_vma, struct elf32_hppa_link_hash_table *, asection *,
struct elf32_hppa_link_hash_entry *));
-static boolean elf32_hppa_relocate_section
+static bfd_boolean elf32_hppa_relocate_section
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *,
bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
-static boolean elf32_hppa_finish_dynamic_symbol
+static bfd_boolean elf32_hppa_finish_dynamic_symbol
PARAMS ((bfd *, struct bfd_link_info *,
struct elf_link_hash_entry *, Elf_Internal_Sym *));
static enum elf_reloc_type_class elf32_hppa_reloc_type_class
PARAMS ((const Elf_Internal_Rela *));
-static boolean elf32_hppa_finish_dynamic_sections
+static bfd_boolean elf32_hppa_finish_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
static void elf32_hppa_post_process_headers
return NULL;
stub_entry = hppa_stub_hash_lookup (&htab->stub_hash_table,
- stub_name, false, false);
+ stub_name, FALSE, FALSE);
if (hash != NULL)
hash->stub_cache = stub_entry;
stub_sec = htab->stub_group[link_sec->id].stub_sec;
if (stub_sec == NULL)
{
+ size_t namelen;
bfd_size_type len;
char *s_name;
- len = strlen (link_sec->name) + sizeof (STUB_SUFFIX);
+ namelen = strlen (link_sec->name);
+ len = namelen + sizeof (STUB_SUFFIX);
s_name = bfd_alloc (htab->stub_bfd, len);
if (s_name == NULL)
return NULL;
- strcpy (s_name, link_sec->name);
- strcpy (s_name + len - sizeof (STUB_SUFFIX), STUB_SUFFIX);
+ memcpy (s_name, link_sec->name, namelen);
+ memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
stub_sec = (*htab->add_stub_section) (s_name, link_sec);
if (stub_sec == NULL)
return NULL;
/* Enter this entry into the linker stub hash table. */
stub_entry = hppa_stub_hash_lookup (&htab->stub_hash_table, stub_name,
- true, false);
+ TRUE, FALSE);
if (stub_entry == NULL)
{
(*_bfd_error_handler) (_("%s: cannot create stub entry %s"),
#define LDW_R1_DLT LDW_R1_DP
#endif
-static boolean
+static bfd_boolean
hppa_build_one_stub (gen_entry, in_arg)
struct bfd_hash_entry *gen_entry;
PTR in_arg;
(long) stub_entry->stub_offset,
stub_entry->root.string);
bfd_set_error (bfd_error_bad_value);
- return false;
+ return FALSE;
}
val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_fsel) >> 2;
default:
BFD_FAIL ();
- return false;
+ return FALSE;
}
stub_sec->_raw_size += size;
- return true;
+ return TRUE;
}
#undef LDIL_R1
/* As above, but don't actually build the stub. Just bump offset so
we know stub section sizes. */
-static boolean
+static bfd_boolean
hppa_size_one_stub (gen_entry, in_arg)
struct bfd_hash_entry *gen_entry;
PTR in_arg;
}
stub_entry->stub_sec->_raw_size += size;
- return true;
+ return TRUE;
}
/* Return nonzero if ABFD represents an HPPA ELF32 file.
Additionally we set the default architecture and machine. */
-static boolean
+static bfd_boolean
elf32_hppa_object_p (abfd)
bfd *abfd;
{
if (strcmp (bfd_get_target (abfd), "elf32-hppa-linux") == 0)
{
if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_LINUX)
- return false;
+ return FALSE;
}
else
{
if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_HPUX)
- return false;
+ return FALSE;
}
flags = i_ehdrp->e_flags;
case EFA_PARISC_2_0 | EF_PARISC_WIDE:
return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 25);
}
- return true;
+ return TRUE;
}
/* Undo the generic ELF code's subtraction of section->vma from the
value of each external symbol. */
-static boolean
+static bfd_boolean
elf32_hppa_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
bfd *abfd ATTRIBUTE_UNUSED;
struct bfd_link_info *info ATTRIBUTE_UNUSED;
bfd_vma *valp;
{
*valp += (*secp)->vma;
- return true;
+ return TRUE;
}
/* Create the .plt and .got sections, and set up our hash table
short-cuts to various dynamic sections. */
-static boolean
+static bfd_boolean
elf32_hppa_create_dynamic_sections (abfd, info)
bfd *abfd;
struct bfd_link_info *info;
/* Don't try to create the .plt and .got twice. */
htab = hppa_link_hash_table (info);
if (htab->splt != NULL)
- return true;
+ return TRUE;
/* Call the generic code to do most of the work. */
if (! _bfd_elf_create_dynamic_sections (abfd, info))
- return false;
+ return FALSE;
htab->splt = bfd_get_section_by_name (abfd, ".plt");
htab->srelplt = bfd_get_section_by_name (abfd, ".rela.plt");
| SEC_LINKER_CREATED
| SEC_READONLY))
|| ! bfd_set_section_alignment (abfd, htab->srelgot, 2))
- return false;
+ return FALSE;
htab->sdynbss = bfd_get_section_by_name (abfd, ".dynbss");
htab->srelbss = bfd_get_section_by_name (abfd, ".rela.bss");
- return true;
+ return TRUE;
}
/* Copy the extra info we tack onto an elf_link_hash_entry. */
static void
-elf32_hppa_copy_indirect_symbol (dir, ind)
+elf32_hppa_copy_indirect_symbol (bed, dir, ind)
+ struct elf_backend_data *bed;
struct elf_link_hash_entry *dir, *ind;
{
struct elf32_hppa_link_hash_entry *edir, *eind;
eind->dyn_relocs = NULL;
}
- _bfd_elf_link_hash_copy_indirect (dir, ind);
+ _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
}
/* Look through the relocs for a section during the first phase, and
table, and dynamic reloc sections. At this point we haven't
necessarily read all the input files. */
-static boolean
+static bfd_boolean
elf32_hppa_check_relocs (abfd, info, sec, relocs)
bfd *abfd;
struct bfd_link_info *info;
asection *stubreloc;
if (info->relocateable)
- return true;
+ return TRUE;
htab = hppa_link_hash_table (info);
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
bfd_archive_filename (abfd),
elf_hppa_howto_table[r_type].name);
bfd_set_error (bfd_error_bad_value);
- return false;
+ return FALSE;
}
/* Fall through. */
case R_PARISC_GNU_VTINHERIT:
if (!_bfd_elf32_gc_record_vtinherit (abfd, sec,
&h->elf, rel->r_offset))
- return false;
+ return FALSE;
continue;
/* This relocation describes which C++ vtable entries are actually
case R_PARISC_GNU_VTENTRY:
if (!_bfd_elf32_gc_record_vtentry (abfd, sec,
&h->elf, rel->r_addend))
- return false;
+ return FALSE;
continue;
default:
if (htab->elf.dynobj == NULL)
htab->elf.dynobj = abfd;
if (!elf32_hppa_create_dynamic_sections (htab->elf.dynobj, info))
- return false;
+ return FALSE;
}
if (h != NULL)
local_got_refcounts = ((bfd_signed_vma *)
bfd_zalloc (abfd, size));
if (local_got_refcounts == NULL)
- return false;
+ return FALSE;
elf_local_got_refcounts (abfd) = local_got_refcounts;
}
local_got_refcounts[r_symndx] += 1;
local_got_refcounts = ((bfd_signed_vma *)
bfd_zalloc (abfd, size));
if (local_got_refcounts == NULL)
- return false;
+ return FALSE;
elf_local_got_refcounts (abfd) = local_got_refcounts;
}
local_plt_refcounts = (local_got_refcounts
(_("Could not find relocation section for %s"),
sec->name);
bfd_set_error (bfd_error_bad_value);
- return false;
+ return FALSE;
}
if (htab->elf.dynobj == NULL)
if (sreloc == NULL
|| !bfd_set_section_flags (dynobj, sreloc, flags)
|| !bfd_set_section_alignment (dynobj, sreloc, 2))
- return false;
+ return FALSE;
}
elf_section_data (sec)->sreloc = sreloc;
s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
sec, r_symndx);
if (s == NULL)
- return false;
+ return FALSE;
head = ((struct elf32_hppa_dyn_reloc_entry **)
&elf_section_data (s)->local_dynrel);
bfd_alloc (htab->elf.dynobj,
(bfd_size_type) sizeof *p));
if (p == NULL)
- return false;
+ return FALSE;
p->next = *head;
*head = p;
p->sec = sec;
}
}
- return true;
+ return TRUE;
}
/* Return the section that should be marked against garbage collection
for a given relocation. */
static asection *
-elf32_hppa_gc_mark_hook (abfd, info, rel, h, sym)
- bfd *abfd;
+elf32_hppa_gc_mark_hook (sec, info, rel, h, sym)
+ asection *sec;
struct bfd_link_info *info ATTRIBUTE_UNUSED;
Elf_Internal_Rela *rel;
struct elf_link_hash_entry *h;
}
}
else
- {
- return bfd_section_from_elf_index (abfd, sym->st_shndx);
- }
+ return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
return NULL;
}
/* Update the got and plt entry reference counts for the section being
removed. */
-static boolean
+static bfd_boolean
elf32_hppa_gc_sweep_hook (abfd, info, sec, relocs)
bfd *abfd;
struct bfd_link_info *info ATTRIBUTE_UNUSED;
bfd_signed_vma *local_got_refcounts;
bfd_signed_vma *local_plt_refcounts;
const Elf_Internal_Rela *rel, *relend;
- unsigned long r_symndx;
- struct elf_link_hash_entry *h;
- struct elf32_hppa_link_hash_table *htab;
- bfd *dynobj;
elf_section_data (sec)->local_dynrel = NULL;
local_plt_refcounts = local_got_refcounts;
if (local_plt_refcounts != NULL)
local_plt_refcounts += symtab_hdr->sh_info;
- htab = hppa_link_hash_table (info);
- dynobj = htab->elf.dynobj;
- if (dynobj == NULL)
- return true;
relend = relocs + sec->reloc_count;
for (rel = relocs; rel < relend; rel++)
- switch ((unsigned int) ELF32_R_TYPE (rel->r_info))
- {
- case R_PARISC_DLTIND14F:
- case R_PARISC_DLTIND14R:
- case R_PARISC_DLTIND21L:
- r_symndx = ELF32_R_SYM (rel->r_info);
- if (r_symndx >= symtab_hdr->sh_info)
- {
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
- if (h->got.refcount > 0)
- h->got.refcount -= 1;
- }
- else if (local_got_refcounts != NULL)
- {
- if (local_got_refcounts[r_symndx] > 0)
- local_got_refcounts[r_symndx] -= 1;
- }
- break;
-
- case R_PARISC_PCREL12F:
- case R_PARISC_PCREL17C:
- case R_PARISC_PCREL17F:
- case R_PARISC_PCREL22F:
- r_symndx = ELF32_R_SYM (rel->r_info);
- if (r_symndx >= symtab_hdr->sh_info)
- {
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
- if (h->plt.refcount > 0)
- h->plt.refcount -= 1;
- }
- break;
-
- case R_PARISC_PLABEL14R:
- case R_PARISC_PLABEL21L:
- case R_PARISC_PLABEL32:
- r_symndx = ELF32_R_SYM (rel->r_info);
- if (r_symndx >= symtab_hdr->sh_info)
- {
- struct elf32_hppa_link_hash_entry *eh;
- struct elf32_hppa_dyn_reloc_entry **pp;
- struct elf32_hppa_dyn_reloc_entry *p;
-
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-
- if (h->plt.refcount > 0)
- h->plt.refcount -= 1;
+ {
+ unsigned long r_symndx;
+ unsigned int r_type;
+ struct elf_link_hash_entry *h = NULL;
- eh = (struct elf32_hppa_link_hash_entry *) h;
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ struct elf32_hppa_link_hash_entry *eh;
+ struct elf32_hppa_dyn_reloc_entry **pp;
+ struct elf32_hppa_dyn_reloc_entry *p;
- for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
- if (p->sec == sec)
- {
-#if RELATIVE_DYNRELOCS
- if (!IS_ABSOLUTE_RELOC (rtype))
- p->relative_count -= 1;
-#endif
- p->count -= 1;
- if (p->count == 0)
- *pp = p->next;
- break;
- }
- }
- else if (local_plt_refcounts != NULL)
- {
- if (local_plt_refcounts[r_symndx] > 0)
- local_plt_refcounts[r_symndx] -= 1;
- }
- break;
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ eh = (struct elf32_hppa_link_hash_entry *) h;
- case R_PARISC_DIR32:
- r_symndx = ELF32_R_SYM (rel->r_info);
- if (r_symndx >= symtab_hdr->sh_info)
- {
- struct elf32_hppa_link_hash_entry *eh;
- struct elf32_hppa_dyn_reloc_entry **pp;
- struct elf32_hppa_dyn_reloc_entry *p;
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+ if (p->sec == sec)
+ {
+ /* Everything must go for SEC. */
+ *pp = p->next;
+ break;
+ }
+ }
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ r_type = ELF32_R_TYPE (rel->r_info);
+ switch (r_type)
+ {
+ case R_PARISC_DLTIND14F:
+ case R_PARISC_DLTIND14R:
+ case R_PARISC_DLTIND21L:
+ if (h != NULL)
+ {
+ if (h->got.refcount > 0)
+ h->got.refcount -= 1;
+ }
+ else if (local_got_refcounts != NULL)
+ {
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx] -= 1;
+ }
+ break;
- eh = (struct elf32_hppa_link_hash_entry *) h;
+ case R_PARISC_PCREL12F:
+ case R_PARISC_PCREL17C:
+ case R_PARISC_PCREL17F:
+ case R_PARISC_PCREL22F:
+ if (h != NULL)
+ {
+ if (h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+ }
+ break;
- for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
- if (p->sec == sec)
- {
-#if RELATIVE_DYNRELOCS
- if (!IS_ABSOLUTE_RELOC (R_PARISC_DIR32))
- p->relative_count -= 1;
-#endif
- p->count -= 1;
- if (p->count == 0)
- *pp = p->next;
- break;
- }
- }
- break;
+ case R_PARISC_PLABEL14R:
+ case R_PARISC_PLABEL21L:
+ case R_PARISC_PLABEL32:
+ if (h != NULL)
+ {
+ if (h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+ }
+ else if (local_plt_refcounts != NULL)
+ {
+ if (local_plt_refcounts[r_symndx] > 0)
+ local_plt_refcounts[r_symndx] -= 1;
+ }
+ break;
- default:
- break;
- }
+ default:
+ break;
+ }
+ }
- return true;
+ return TRUE;
}
/* Our own version of hide_symbol, so that we can keep plt entries for
elf32_hppa_hide_symbol (info, h, force_local)
struct bfd_link_info *info;
struct elf_link_hash_entry *h;
- boolean force_local;
+ bfd_boolean force_local;
{
if (force_local)
{
change the definition to something the rest of the link can
understand. */
-static boolean
+static bfd_boolean
elf32_hppa_adjust_dynamic_symbol (info, h)
struct bfd_link_info *info;
struct elf_link_hash_entry *h;
}
}
- return true;
+ return TRUE;
}
else
h->plt.offset = (bfd_vma) -1;
abort ();
h->root.u.def.section = h->weakdef->root.u.def.section;
h->root.u.def.value = h->weakdef->root.u.def.value;
- return true;
+ return TRUE;
}
/* This is a reference to a symbol defined by a dynamic object which
For such cases we need not do anything here; the relocations will
be handled correctly by relocate_section. */
if (info->shared)
- return true;
+ return TRUE;
/* If there are no references to this symbol that do not use the
GOT, we don't need to generate a copy reloc. */
if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0)
- return true;
+ return TRUE;
eh = (struct elf32_hppa_link_hash_entry *) h;
for (p = eh->dyn_relocs; p != NULL; p = p->next)
if (p == NULL)
{
h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF;
- return true;
+ return TRUE;
}
/* We must allocate the symbol in our .dynbss section, which will
if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
{
if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two))
- return false;
+ return FALSE;
}
/* Define the symbol as being at this point in the section. */
/* Increment the section size to make room for the symbol. */
s->_raw_size += h->size;
- return true;
+ return TRUE;
}
/* Called via elf_link_hash_traverse to create .plt entries for an
application that uses statically linked PIC functions. Similar to
the first part of elf32_hppa_adjust_dynamic_symbol. */
-static boolean
+static bfd_boolean
mark_PIC_calls (h, inf)
struct elf_link_hash_entry *h;
PTR inf ATTRIBUTE_UNUSED;
{
h->plt.offset = (bfd_vma) -1;
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
- return true;
+ return TRUE;
}
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
((struct elf32_hppa_link_hash_entry *) h)->pic_call = 1;
- return true;
+ return TRUE;
}
/* Allocate space in the .plt for entries that won't have relocations.
ie. pic_call and plabel entries. */
-static boolean
+static bfd_boolean
allocate_plt_static (h, inf)
struct elf_link_hash_entry *h;
PTR inf;
asection *s;
if (h->root.type == bfd_link_hash_indirect)
- return true;
+ return TRUE;
if (h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
&& h->type != STT_PARISC_MILLI)
{
if (! bfd_elf32_link_record_dynamic_symbol (info, h))
- return false;
+ return FALSE;
}
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h))
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
}
- return true;
+ return TRUE;
}
/* Allocate space in .plt, .got and associated reloc sections for
global syms. */
-static boolean
+static bfd_boolean
allocate_dynrelocs (h, inf)
struct elf_link_hash_entry *h;
PTR inf;
struct elf32_hppa_dyn_reloc_entry *p;
if (h->root.type == bfd_link_hash_indirect)
- return true;
+ return TRUE;
if (h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
&& h->type != STT_PARISC_MILLI)
{
if (! bfd_elf32_link_record_dynamic_symbol (info, h))
- return false;
+ return FALSE;
}
s = htab->sgot;
eh = (struct elf32_hppa_link_hash_entry *) h;
if (eh->dyn_relocs == NULL)
- return true;
+ return TRUE;
/* If this is a -Bsymbolic shared link, then we need to discard all
space allocated for dynamic pc-relative relocs against symbols
&& h->type != STT_PARISC_MILLI)
{
if (! bfd_elf32_link_record_dynamic_symbol (info, h))
- return false;
+ return FALSE;
}
/* If that succeeded, we know we'll be keeping all the
}
eh->dyn_relocs = NULL;
- return true;
+ return TRUE;
keep: ;
}
sreloc->_raw_size += p->count * sizeof (Elf32_External_Rela);
}
- return true;
+ return TRUE;
}
/* This function is called via elf_link_hash_traverse to force
for all dynamic symbols. Arguably, this is a bug in
elf_adjust_dynamic_symbol. */
-static boolean
+static bfd_boolean
clobber_millicode_symbols (h, info)
struct elf_link_hash_entry *h;
struct bfd_link_info *info;
if (h->type == STT_PARISC_MILLI
&& (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
{
- elf32_hppa_hide_symbol (info, h, true);
+ elf32_hppa_hide_symbol (info, h, TRUE);
}
- return true;
+ return TRUE;
}
/* Find any dynamic relocs that apply to read-only sections. */
-static boolean
+static bfd_boolean
readonly_dynrelocs (h, inf)
struct elf_link_hash_entry *h;
PTR inf;
info->flags |= DF_TEXTREL;
/* Not an error, just cut short the traversal. */
- return false;
+ return FALSE;
}
}
- return true;
+ return TRUE;
}
/* Set the sizes of the dynamic sections. */
-static boolean
+static bfd_boolean
elf32_hppa_size_dynamic_sections (output_bfd, info)
bfd *output_bfd ATTRIBUTE_UNUSED;
struct bfd_link_info *info;
bfd *dynobj;
bfd *ibfd;
asection *s;
- boolean relocs;
+ bfd_boolean relocs;
htab = hppa_link_hash_table (info);
dynobj = htab->elf.dynobj;
/* The check_relocs and adjust_dynamic_symbol entry points have
determined the sizes of the various dynamic sections. Allocate
memory for them. */
- relocs = false;
+ relocs = FALSE;
for (s = dynobj->sections; s != NULL; s = s->next)
{
if ((s->flags & SEC_LINKER_CREATED) == 0)
/* Remember whether there are any reloc sections other
than .rela.plt. */
if (s != htab->srelplt)
- relocs = true;
+ relocs = TRUE;
/* We use the reloc_count field as a counter if we need
to copy relocs into the output file. */
we may not fill in all the reloc sections. */
s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
if (s->contents == NULL && s->_raw_size != 0)
- return false;
+ return FALSE;
}
if (htab->elf.dynamic_sections_created)
bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
if (!add_dynamic_entry (DT_PLTGOT, 0))
- return false;
+ return FALSE;
/* Add some entries to the .dynamic section. We fill in the
values later, in elf32_hppa_finish_dynamic_sections, but we
if (!info->shared)
{
if (!add_dynamic_entry (DT_DEBUG, 0))
- return false;
+ return FALSE;
}
if (htab->srelplt->_raw_size != 0)
if (!add_dynamic_entry (DT_PLTRELSZ, 0)
|| !add_dynamic_entry (DT_PLTREL, DT_RELA)
|| !add_dynamic_entry (DT_JMPREL, 0))
- return false;
+ return FALSE;
}
if (relocs)
if (!add_dynamic_entry (DT_RELA, 0)
|| !add_dynamic_entry (DT_RELASZ, 0)
|| !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
- return false;
+ return FALSE;
/* If any dynamic relocs apply to a read-only section,
then we need a DT_TEXTREL entry. */
if ((info->flags & DF_TEXTREL) != 0)
{
if (!add_dynamic_entry (DT_TEXTREL, 0))
- return false;
+ return FALSE;
}
}
}
#undef add_dynamic_entry
- return true;
+ return TRUE;
}
/* External entry points for sizing and building linker stubs. */
/* Set up various things so that we can make a list of input sections
for each output section included in the link. Returns -1 on error,
- 0 when no stubs will be needed, and 1 on success. */
+ 0 when no stubs will be needed, and 1 on success. */
int
elf32_hppa_setup_section_lists (output_bfd, info)
group_sections (htab, stub_group_size, stubs_always_before_branch)
struct elf32_hppa_link_hash_table *htab;
bfd_size_type stub_group_size;
- boolean stubs_always_before_branch;
+ bfd_boolean stubs_always_before_branch;
{
asection **list = htab->input_list + htab->top_index;
do
asection *curr;
asection *prev;
bfd_size_type total;
+ bfd_boolean big_sec;
curr = tail;
if (tail->_cooked_size)
total = tail->_cooked_size;
else
total = tail->_raw_size;
+ big_sec = total >= stub_group_size;
+
while ((prev = PREV_SEC (curr)) != NULL
&& ((total += curr->output_offset - prev->output_offset)
< stub_group_size))
while (tail != curr && (tail = prev) != NULL);
/* But wait, there's more! Input sections up to 240000
- bytes before the stub section can be handled by it too. */
- if (!stubs_always_before_branch)
+ bytes before the stub section can be handled by it too.
+ Don't do this if we have a really large section after the
+ stubs, as adding more stubs increases the chance that
+ branches may not reach into the stub section. */
+ if (!stubs_always_before_branch && !big_sec)
{
total = 0;
while (prev != NULL
input_bfd = input_bfd->link_next, bfd_indx++)
{
Elf_Internal_Shdr *symtab_hdr;
- Elf_Internal_Shdr *shndx_hdr;
- Elf_Internal_Sym *isym;
- Elf32_External_Sym *ext_syms, *esym, *end_sy;
- Elf_External_Sym_Shndx *shndx_buf, *shndx;
- bfd_size_type sec_size;
/* We'll need the symbol table in a second. */
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
if (symtab_hdr->sh_info == 0)
continue;
- /* We need an array of the local symbols attached to the input bfd.
- Unfortunately, we're going to have to read & swap them in. */
- sec_size = symtab_hdr->sh_info;
- sec_size *= sizeof (Elf_Internal_Sym);
- local_syms = (Elf_Internal_Sym *) bfd_malloc (sec_size);
+ /* We need an array of the local symbols attached to the input bfd. */
+ local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
if (local_syms == NULL)
- return -1;
-
- all_local_syms[bfd_indx] = local_syms;
- sec_size = symtab_hdr->sh_info;
- sec_size *= sizeof (Elf32_External_Sym);
- ext_syms = (Elf32_External_Sym *) bfd_malloc (sec_size);
- if (ext_syms == NULL)
- return -1;
-
- if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread ((PTR) ext_syms, sec_size, input_bfd) != sec_size)
{
- error_ret_free_ext_syms:
- free (ext_syms);
- return -1;
- }
-
- shndx_buf = NULL;
- shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_hdr;
- if (shndx_hdr->sh_size != 0)
- {
- sec_size = symtab_hdr->sh_info;
- sec_size *= sizeof (Elf_External_Sym_Shndx);
- shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (sec_size);
- if (shndx_buf == NULL)
- goto error_ret_free_ext_syms;
-
- if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread ((PTR) shndx_buf, sec_size, input_bfd) != sec_size)
- {
- free (shndx_buf);
- goto error_ret_free_ext_syms;
- }
+ local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ /* Cache them for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) local_syms;
}
+ if (local_syms == NULL)
+ return -1;
- /* Swap the local symbols in. */
- for (esym = ext_syms, end_sy = esym + symtab_hdr->sh_info,
- isym = local_syms, shndx = shndx_buf;
- esym < end_sy;
- esym++, isym++, shndx = (shndx ? shndx + 1 : NULL))
- bfd_elf32_swap_symbol_in (input_bfd, esym, shndx, isym);
-
- /* Now we can free the external symbols. */
- free (shndx_buf);
- free (ext_syms);
+ all_local_syms[bfd_indx] = local_syms;
if (info->shared && htab->multi_subspace)
{
stub_name = hash->elf.root.root.string;
stub_entry = hppa_stub_hash_lookup (&htab->stub_hash_table,
stub_name,
- false, false);
+ FALSE, FALSE);
if (stub_entry == NULL)
{
stub_entry = hppa_add_stub (stub_name, sec, htab);
PC-relative calls to a target that is unreachable with a "bl"
instruction. */
-boolean
+bfd_boolean
elf32_hppa_size_stubs (output_bfd, stub_bfd, info, multi_subspace, group_size,
add_stub_section, layout_sections_again)
bfd *output_bfd;
bfd *stub_bfd;
struct bfd_link_info *info;
- boolean multi_subspace;
+ bfd_boolean multi_subspace;
bfd_signed_vma group_size;
asection * (*add_stub_section) PARAMS ((const char *, asection *));
void (*layout_sections_again) PARAMS ((void));
{
bfd_size_type stub_group_size;
- boolean stubs_always_before_branch;
- boolean stub_changed;
- boolean ret = 0;
+ bfd_boolean stubs_always_before_branch;
+ bfd_boolean stub_changed;
struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info);
/* Stash our params away. */
if (stub_group_size == 1)
{
/* Default values. */
- stub_group_size = 7680000;
- if (htab->has_17bit_branch || htab->multi_subspace)
- stub_group_size = 240000;
- if (htab->has_12bit_branch)
- stub_group_size = 7500;
+ if (stubs_always_before_branch)
+ {
+ stub_group_size = 7680000;
+ if (htab->has_17bit_branch || htab->multi_subspace)
+ stub_group_size = 240000;
+ if (htab->has_12bit_branch)
+ stub_group_size = 7500;
+ }
+ else
+ {
+ stub_group_size = 6971392;
+ if (htab->has_17bit_branch || htab->multi_subspace)
+ stub_group_size = 217856;
+ if (htab->has_12bit_branch)
+ stub_group_size = 6808;
+ }
}
group_sections (htab, stub_group_size, stubs_always_before_branch);
default:
if (htab->all_local_syms)
goto error_ret_free_local;
- return false;
+ return FALSE;
case 0:
- stub_changed = false;
+ stub_changed = FALSE;
break;
case 1:
- stub_changed = true;
+ stub_changed = TRUE;
break;
}
section != NULL;
section = section->next)
{
- Elf_Internal_Shdr *input_rel_hdr;
- Elf32_External_Rela *external_relocs, *erelaend, *erela;
Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
- bfd_size_type amt;
/* If there aren't any relocs, then there's nothing more
to do. */
|| section->output_section->owner != output_bfd)
continue;
- /* Allocate space for the external relocations. */
- amt = section->reloc_count;
- amt *= sizeof (Elf32_External_Rela);
- external_relocs = (Elf32_External_Rela *) bfd_malloc (amt);
- if (external_relocs == NULL)
- {
- goto error_ret_free_local;
- }
-
- /* Likewise for the internal relocations. */
- amt = section->reloc_count;
- amt *= sizeof (Elf_Internal_Rela);
- internal_relocs = (Elf_Internal_Rela *) bfd_malloc (amt);
+ /* Get the relocs. */
+ internal_relocs
+ = _bfd_elf32_link_read_relocs (input_bfd, section, NULL,
+ (Elf_Internal_Rela *) NULL,
+ info->keep_memory);
if (internal_relocs == NULL)
- {
- free (external_relocs);
- goto error_ret_free_local;
- }
-
- /* Read in the external relocs. */
- input_rel_hdr = &elf_section_data (section)->rel_hdr;
- if (bfd_seek (input_bfd, input_rel_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread ((PTR) external_relocs,
- input_rel_hdr->sh_size,
- input_bfd) != input_rel_hdr->sh_size)
- {
- free (external_relocs);
- error_ret_free_internal:
- free (internal_relocs);
- goto error_ret_free_local;
- }
-
- /* Swap in the relocs. */
- erela = external_relocs;
- erelaend = erela + section->reloc_count;
- irela = internal_relocs;
- for (; erela < erelaend; erela++, irela++)
- bfd_elf32_swap_reloca_in (input_bfd, erela, irela);
-
- /* We're done with the external relocs, free them. */
- free (external_relocs);
+ goto error_ret_free_local;
/* Now examine each relocation. */
irela = internal_relocs;
if (r_type >= (unsigned int) R_PARISC_UNIMPLEMENTED)
{
bfd_set_error (bfd_error_bad_value);
- goto error_ret_free_internal;
+ error_ret_free_internal:
+ if (elf_section_data (section)->relocs == NULL)
+ free (internal_relocs);
+ goto error_ret_free_local;
}
/* Only look for stubs on call instructions. */
stub_entry = hppa_stub_hash_lookup (&htab->stub_hash_table,
stub_name,
- false, false);
+ FALSE, FALSE);
if (stub_entry != NULL)
{
/* The proper stub has already been created. */
if (stub_entry == NULL)
{
free (stub_name);
- goto error_ret_free_local;
+ goto error_ret_free_internal;
}
stub_entry->target_value = sym_value;
stub_entry->stub_type = hppa_stub_long_branch_shared;
}
stub_entry->h = hash;
- stub_changed = true;
+ stub_changed = TRUE;
}
/* We're done with the internal relocs, free them. */
- free (internal_relocs);
+ if (elf_section_data (section)->relocs == NULL)
+ free (internal_relocs);
}
}
/* Ask the linker to do its stuff. */
(*htab->layout_sections_again) ();
- stub_changed = false;
+ stub_changed = FALSE;
}
- ret = true;
+ free (htab->all_local_syms);
+ return TRUE;
error_ret_free_local:
- while (htab->bfd_count-- > 0)
- if (htab->all_local_syms[htab->bfd_count])
- free (htab->all_local_syms[htab->bfd_count]);
free (htab->all_local_syms);
-
- return ret;
+ return FALSE;
}
/* For a final link, this function is called after we have sized the
stubs to provide a value for __gp. */
-boolean
+bfd_boolean
elf32_hppa_set_gp (abfd, info)
bfd *abfd;
struct bfd_link_info *info;
struct elf32_hppa_link_hash_table *htab;
htab = hppa_link_hash_table (info);
- h = bfd_link_hash_lookup (&htab->elf.root, "$global$", false, false, false);
+ h = bfd_link_hash_lookup (&htab->elf.root, "$global$", FALSE, FALSE, FALSE);
if (h != NULL
&& (h->type == bfd_link_hash_defined
gp_val += sec->output_section->vma + sec->output_offset;
elf_gp (abfd) = gp_val;
- return true;
+ return TRUE;
}
/* Build all the stubs associated with the current output file. The
functions here. This function is called via hppaelf_finish in the
linker. */
-boolean
+bfd_boolean
elf32_hppa_build_stubs (info)
struct bfd_link_info *info;
{
size = stub_sec->_raw_size;
stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, size);
if (stub_sec->contents == NULL && size != 0)
- return false;
+ return FALSE;
stub_sec->_raw_size = 0;
}
table = &htab->stub_hash_table;
bfd_hash_traverse (table, hppa_build_one_stub, info);
- return true;
+ return TRUE;
}
/* Perform a final link. */
-static boolean
+static bfd_boolean
elf32_hppa_final_link (abfd, info)
bfd *abfd;
struct bfd_link_info *info;
{
/* Invoke the regular ELF linker to do all the work. */
if (!bfd_elf32_bfd_final_link (abfd, info))
- return false;
+ return FALSE;
/* If we're producing a final executable, sort the contents of the
unwind section. */
case R_PARISC_DPREL14R:
case R_PARISC_DPREL14F:
/* For all the DP relative relocations, we need to examine the symbol's
- section. If it's a code section, then "data pointer relative" makes
- no sense. In that case we don't adjust the "value", and for 21 bit
- addil instructions, we change the source addend register from %dp to
- %r0. This situation commonly arises when a variable's "constness"
+ section. If it has no section or if it's a code section, then
+ "data pointer relative" makes no sense. In that case we don't
+ adjust the "value", and for 21 bit addil instructions, we change the
+ source addend register from %dp to %r0. This situation commonly
+ arises for undefined weak symbols and when a variable's "constness"
is declared differently from the way the variable is defined. For
instance: "extern int foo" with foo defined as "const int foo". */
- if (sym_sec == NULL)
- break;
- if ((sym_sec->flags & SEC_CODE) != 0)
+ if (sym_sec == NULL || (sym_sec->flags & SEC_CODE) != 0)
{
if ((insn & ((0x3f << 26) | (0x1f << 21)))
== (((int) OP_ADDIL << 26) | (27 << 21)))
/* Relocate an HPPA ELF section. */
-static boolean
+static bfd_boolean
elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
contents, relocs, local_syms, local_sections)
bfd *output_bfd;
Elf_Internal_Rela *rel;
Elf_Internal_Rela *relend;
+ if (info->relocateable)
+ return TRUE;
+
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
htab = hppa_link_hash_table (info);
bfd_vma relocation;
bfd_reloc_status_type r;
const char *sym_name;
- boolean plabel;
- boolean warned_undef;
+ bfd_boolean plabel;
+ bfd_boolean warned_undef;
r_type = ELF32_R_TYPE (rel->r_info);
if (r_type >= (unsigned int) R_PARISC_UNIMPLEMENTED)
{
bfd_set_error (bfd_error_bad_value);
- return false;
+ return FALSE;
}
if (r_type == (unsigned int) R_PARISC_GNU_VTENTRY
|| r_type == (unsigned int) R_PARISC_GNU_VTINHERIT)
continue;
- r_symndx = ELF32_R_SYM (rel->r_info);
-
- if (info->relocateable)
- {
- /* This is a relocatable link. We don't have to change
- anything, unless the reloc is against a section symbol,
- in which case we have to adjust according to where the
- section symbol winds up in the output section. */
- if (r_symndx < symtab_hdr->sh_info)
- {
- sym = local_syms + r_symndx;
- if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
- {
- sym_sec = local_sections[r_symndx];
- rel->r_addend += sym_sec->output_offset;
- }
- }
- continue;
- }
-
/* This is a final link. */
+ r_symndx = ELF32_R_SYM (rel->r_info);
h = NULL;
sym = NULL;
sym_sec = NULL;
- warned_undef = false;
+ warned_undef = FALSE;
if (r_symndx < symtab_hdr->sh_info)
{
/* This is a local symbol, h defaults to NULL. */
&& ELF_ST_VISIBILITY (h->elf.other) == STV_DEFAULT
&& h->elf.type != STT_PARISC_MILLI)
{
- if (info->symbolic && !info->allow_shlib_undefined)
- {
- if (!((*info->callbacks->undefined_symbol)
- (info, h->elf.root.root.string, input_bfd,
- input_section, rel->r_offset, false)))
- return false;
- warned_undef = true;
- }
+ if (!((*info->callbacks->undefined_symbol)
+ (info, h->elf.root.root.string, input_bfd,
+ input_section, rel->r_offset, FALSE)))
+ return FALSE;
+ warned_undef = TRUE;
}
else
{
if (!((*info->callbacks->undefined_symbol)
(info, h->elf.root.root.string, input_bfd,
- input_section, rel->r_offset, true)))
- return false;
- warned_undef = true;
+ input_section, rel->r_offset, TRUE)))
+ return FALSE;
+ warned_undef = TRUE;
}
}
case R_PARISC_DLTIND21L:
{
bfd_vma off;
- boolean do_got = 0;
+ bfd_boolean do_got = 0;
/* Relocation is to the entry for this symbol in the
global offset table. */
if (h != NULL)
{
- boolean dyn;
+ bfd_boolean dyn;
off = h->elf.got.offset;
dyn = htab->elf.dynamic_sections_created;
In this case it is relative to the base of the
object because the symbol index is zero. */
Elf_Internal_Rela outrel;
- asection *srelgot = htab->srelgot;
- Elf32_External_Rela *loc;
+ bfd_byte *loc;
+ asection *s = htab->srelgot;
outrel.r_offset = (off
+ htab->sgot->output_offset
+ htab->sgot->output_section->vma);
outrel.r_info = ELF32_R_INFO (0, R_PARISC_DIR32);
outrel.r_addend = relocation;
- loc = (Elf32_External_Rela *) srelgot->contents;
- loc += srelgot->reloc_count++;
+ loc = s->contents;
+ loc += s->reloc_count++ * sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
}
else
if (htab->elf.dynamic_sections_created)
{
bfd_vma off;
- boolean do_plt = 0;
+ bfd_boolean do_plt = 0;
/* If we have a global symbol with a PLT slot, then
redirect this relocation to it. */
/* Output a dynamic IPLT relocation for this
PLT entry. */
Elf_Internal_Rela outrel;
- asection *srelplt = htab->srelplt;
- Elf32_External_Rela *loc;
+ bfd_byte *loc;
+ asection *s = htab->srelplt;
outrel.r_offset = (off
+ htab->splt->output_offset
+ htab->splt->output_section->vma);
outrel.r_info = ELF32_R_INFO (0, R_PARISC_IPLT);
outrel.r_addend = relocation;
- loc = (Elf32_External_Rela *) srelplt->contents;
- loc += srelplt->reloc_count++;
+ loc = s->contents;
+ loc += s->reloc_count++ * sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
}
else
|| h->elf.root.type == bfd_link_hash_undefined)))
{
Elf_Internal_Rela outrel;
- boolean skip;
+ bfd_boolean skip;
asection *sreloc;
- Elf32_External_Rela *loc;
+ bfd_byte *loc;
/* When generating a shared object, these relocations
are copied into the output file to be resolved at run
if (sreloc == NULL)
abort ();
- loc = (Elf32_External_Rela *) sreloc->contents;
- loc += sreloc->reloc_count++;
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
}
break;
symtab_hdr->sh_link,
sym->st_name);
if (sym_name == NULL)
- return false;
+ return FALSE;
if (*sym_name == '\0')
sym_name = bfd_section_name (input_bfd, sym_sec);
}
howto->name,
sym_name);
bfd_set_error (bfd_error_bad_value);
- return false;
+ return FALSE;
}
}
else
if (!((*info->callbacks->reloc_overflow)
(info, sym_name, howto->name, (bfd_vma) 0,
input_bfd, input_section, rel->r_offset)))
- return false;
+ return FALSE;
}
}
- return true;
+ return TRUE;
}
/* Finish up dynamic symbol handling. We set the contents of various
dynamic sections here. */
-static boolean
+static bfd_boolean
elf32_hppa_finish_dynamic_symbol (output_bfd, info, h, sym)
bfd *output_bfd;
struct bfd_link_info *info;
if (! ((struct elf32_hppa_link_hash_entry *) h)->pic_call)
{
Elf_Internal_Rela rel;
- Elf32_External_Rela *loc;
+ bfd_byte *loc;
/* Create a dynamic IPLT relocation for this entry. */
rel.r_offset = (h->plt.offset
rel.r_addend = value;
}
- loc = (Elf32_External_Rela *) htab->srelplt->contents;
- loc += htab->srelplt->reloc_count++;
+ loc = htab->srelplt->contents;
+ loc += htab->srelplt->reloc_count++ * sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloca_out (htab->splt->output_section->owner,
&rel, loc);
}
if (h->got.offset != (bfd_vma) -1)
{
Elf_Internal_Rela rel;
- Elf32_External_Rela *loc;
+ bfd_byte *loc;
/* This symbol has an entry in the global offset table. Set it
up. */
rel.r_addend = 0;
}
- loc = (Elf32_External_Rela *) htab->srelgot->contents;
- loc += htab->srelgot->reloc_count++;
+ loc = htab->srelgot->contents;
+ loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
}
{
asection *s;
Elf_Internal_Rela rel;
- Elf32_External_Rela *loc;
+ bfd_byte *loc;
/* This symbol needs a copy reloc. Set it up. */
+ h->root.u.def.section->output_section->vma);
rel.r_addend = 0;
rel.r_info = ELF32_R_INFO (h->dynindx, R_PARISC_COPY);
- loc = (Elf32_External_Rela *) s->contents + s->reloc_count++;
+ loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
}
sym->st_shndx = SHN_ABS;
}
- return true;
+ return TRUE;
}
/* Used to decide how to sort relocs in an optimal manner for the
/* Finish up the dynamic sections. */
-static boolean
+static bfd_boolean
elf32_hppa_finish_dynamic_sections (output_bfd, info)
bfd *output_bfd;
struct bfd_link_info *info;
case DT_PLTRELSZ:
s = htab->srelplt;
- if (s->_cooked_size != 0)
- dyn.d_un.d_val = s->_cooked_size;
- else
- dyn.d_un.d_val = s->_raw_size;
+ dyn.d_un.d_val = s->_raw_size;
break;
case DT_RELASZ:
/* Don't count procedure linkage table relocs in the
overall reloc count. */
- if (htab->srelplt != NULL)
- {
- s = htab->srelplt->output_section;
- if (s->_cooked_size != 0)
- dyn.d_un.d_val -= s->_cooked_size;
- else
- dyn.d_un.d_val -= s->_raw_size;
- }
+ s = htab->srelplt;
+ if (s == NULL)
+ continue;
+ dyn.d_un.d_val -= s->_raw_size;
+ break;
+
+ case DT_RELA:
+ /* We may not be using the standard ELF linker script.
+ If .rela.plt is the first .rela section, we adjust
+ DT_RELA to not include it. */
+ s = htab->srelplt;
+ if (s == NULL)
+ continue;
+ if (dyn.d_un.d_ptr != s->output_section->vma + s->output_offset)
+ continue;
+ dyn.d_un.d_ptr += s->_raw_size;
break;
}
{
(*_bfd_error_handler)
(_(".got section not immediately after .plt section"));
- return false;
+ return FALSE;
}
}
}
- return true;
+ return TRUE;
}
/* Tweak the OSABI field of the elf header. */
#define elf_backend_plt_readonly 0
#define elf_backend_want_plt_sym 0
#define elf_backend_got_header_size 8
+#define elf_backend_rela_normal 1
#define TARGET_BIG_SYM bfd_elf32_hppa_vec
#define TARGET_BIG_NAME "elf32-hppa"