/* BFD back-end for HP PA-RISC ELF files.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Original code by
/* Various hash macros and functions. */
#define hppa_link_hash_table(p) \
- ((struct elf32_hppa_link_hash_table *) ((p)->hash))
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == HPPA32_ELF_DATA ? ((struct elf32_hppa_link_hash_table *) ((p)->hash)) : NULL)
#define hppa_elf_hash_entry(ent) \
((struct elf32_hppa_link_hash_entry *)(ent))
elf32_hppa_mkobject (bfd *abfd)
{
return bfd_elf_allocate_object (abfd, sizeof (struct elf_obj_tdata),
- HPPA_ELF_TDATA);
+ HPPA32_ELF_DATA);
}
/* Assorted hash table functions. */
return NULL;
if (!_bfd_elf_link_hash_table_init (&htab->etab, abfd, hppa_link_hash_newfunc,
- sizeof (struct elf32_hppa_link_hash_entry)))
+ sizeof (struct elf32_hppa_link_hash_entry),
+ HPPA32_ELF_DATA))
{
free (htab);
return NULL;
info = (struct bfd_link_info *)in_arg;
htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
stub_sec = hsh->stub_sec;
/* Make a note of the offset within the stubs for this entry. */
/* Don't try to create the .plt and .got twice. */
htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
if (htab->splt != NULL)
return TRUE;
const Elf_Internal_Rela *rela_end;
struct elf32_hppa_link_hash_table *htab;
asection *sreloc;
- asection *stubreloc;
int tls_type = GOT_UNKNOWN, old_tls_type = GOT_UNKNOWN;
if (info->relocatable)
return TRUE;
htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
eh_syms = elf_sym_hashes (abfd);
sreloc = NULL;
- stubreloc = NULL;
rela_end = relocs + sec->reloc_count;
for (rela = relocs; rela < rela_end; rela++)
if (r_type == R_PARISC_TLS_LDM21L
|| r_type == R_PARISC_TLS_LDM14R)
- hppa_link_hash_table (info)->tls_ldm_got.refcount += 1;
+ htab->tls_ldm_got.refcount += 1;
else
{
if (hh != NULL)
bfd_signed_vma *local_got_refcounts;
bfd_signed_vma *local_plt_refcounts;
const Elf_Internal_Rela *rela, *relend;
+ struct elf32_hppa_link_hash_table *htab;
if (info->relocatable)
return TRUE;
+ htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
elf_section_data (sec)->local_dynrel = NULL;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
case R_PARISC_TLS_LDM21L:
case R_PARISC_TLS_LDM14R:
- hppa_link_hash_table (info)->tls_ldm_got.refcount -= 1;
+ htab->tls_ldm_got.refcount -= 1;
break;
case R_PARISC_PCREL12F:
same memory location for the variable. */
htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
/* We must generate a 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;
hh = hppa_elf_hash_entry (eh);
htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
if (htab->etab.dynamic_sections_created
&& eh->plt.refcount > 0)
{
info = inf;
htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
hh = hppa_elf_hash_entry (eh);
if (htab->etab.dynamic_sections_created
bfd_boolean relocs;
htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
dynobj = htab->etab.dynobj;
if (dynobj == NULL)
abort ();
bfd_size_type amt;
struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return -1;
+
/* Count the number of input BFDs and find the top input section id. */
for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
input_bfd != NULL;
{
struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return;
+
if (isec->output_section->index <= htab->top_index)
{
asection **list = htab->input_list + isec->output_section->index;
int stub_changed = 0;
struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return -1;
+
/* We want to read in symbol extension records only once. To do this
we need to read in the local symbols in parallel and save them for
later use; so hold pointers to the local symbols in an array. */
bfd_boolean stub_changed;
struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
/* Stash our params away. */
htab->stub_bfd = stub_bfd;
htab->multi_subspace = multi_subspace;
struct elf32_hppa_link_hash_table *htab;
htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
h = bfd_link_hash_lookup (&htab->etab.root, "$global$", FALSE, FALSE, FALSE);
if (h != NULL
struct elf32_hppa_link_hash_table *htab;
htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
for (stub_sec = htab->stub_bfd->sections;
stub_sec != NULL;
struct elf32_hppa_link_hash_table *htab;
htab = (struct elf32_hppa_link_hash_table*) data;
+ if (htab == NULL)
+ return;
if ((section->flags & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
{
case R_PARISC_DPREL21L:
case R_PARISC_DPREL14R:
case R_PARISC_DPREL14F:
+ case R_PARISC_TLS_GD21L:
+ case R_PARISC_TLS_LDM21L:
+ case R_PARISC_TLS_IE21L:
/* Convert instructions that use the linkage table pointer (r19) to
instructions that use the global data pointer (dp). This is the
most efficient way of using PIC code in an incomplete executable,
but the user must follow the standard runtime conventions for
accessing data for this to work. */
- if (orig_r_type == R_PARISC_DLTIND21L)
+ if (orig_r_type == R_PARISC_DLTIND21L
+ || (!info->shared
+ && (r_type == R_PARISC_TLS_GD21L
+ || r_type == R_PARISC_TLS_LDM21L
+ || r_type == R_PARISC_TLS_IE21L)))
{
/* Convert addil instructions if the original reloc was a
DLTIND21L. GCC sometimes uses a register other than r19 for
case R_PARISC_DLTIND21L:
case R_PARISC_DLTIND14R:
case R_PARISC_DLTIND14F:
- case R_PARISC_TLS_GD21L:
case R_PARISC_TLS_GD14R:
- case R_PARISC_TLS_LDM21L:
case R_PARISC_TLS_LDM14R:
- case R_PARISC_TLS_IE21L:
case R_PARISC_TLS_IE14R:
value -= elf_gp (input_section->output_section->owner);
break;
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
local_got_offsets = elf_local_got_offsets (input_bfd);
rela = relocs;
bfd_byte *loc;
htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
if (eh->plt.offset != (bfd_vma) -1)
{
asection *sdyn;
htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
dynobj = htab->etab.dynobj;
sdyn = bfd_get_section_by_name (dynobj, ".dynamic");