/* BFD back-end for HP PA-RISC ELF files.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001
- Free Software Foundation, Inc.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001,
+ 2002 Free Software Foundation, Inc.
Original code by
Center for Software Science
#include "libhppa.h"
#include "elf32-hppa.h"
#define ARCH_SIZE 32
-#include "elf-hppa.h"
#include "elf32-hppa.h"
+#include "elf-hppa.h"
/* In order to gain some understanding of code in this file without
knowing all the intricate details of the linker, note the
asection *, const Elf_Internal_Rela *));
static void elf32_hppa_hide_symbol
- PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
+ PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, boolean));
static boolean elf32_hppa_adjust_dynamic_symbol
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
plabels. */
static void
-elf32_hppa_hide_symbol (info, h)
- struct bfd_link_info *info ATTRIBUTE_UNUSED;
+elf32_hppa_hide_symbol (info, h, force_local)
+ struct bfd_link_info *info;
struct elf_link_hash_entry *h;
+ boolean force_local;
{
- if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
- h->dynindx = -1;
+ if (force_local)
+ {
+ h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
+ if (h->dynindx != -1)
+ {
+ h->dynindx = -1;
+ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+ h->dynstr_index);
+ }
+ }
+
if (! ((struct elf32_hppa_link_hash_entry *) h)->plabel)
{
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
if (h->type == STT_PARISC_MILLI
&& (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
{
- struct elf32_hppa_link_hash_table *htab;
-
- h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
- elf32_hppa_hide_symbol (info, h);
- htab = hppa_link_hash_table (info);
- _bfd_elf_strtab_delref (htab->elf.dynstr, h->dynstr_index);
-
- /* ?!? We only want to remove these from the dynamic symbol table.
- Therefore we do not leave ELF_LINK_FORCED_LOCAL set. */
- h->elf_link_hash_flags &= ~ELF_LINK_FORCED_LOCAL;
+ elf32_hppa_hide_symbol (info, h, true);
}
return true;
}
linker script /DISCARD/, so we'll be discarding
the relocs too. */
}
- else
+ else if (p->count != 0)
{
srel = elf_section_data (p->sec)->sreloc;
srel->_raw_size += p->count * sizeof (Elf32_External_Rela);
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
}
}
}
/* If any dynamic relocs apply to a read-only section,
then we need a DT_TEXTREL entry. */
- elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, (PTR) info);
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (&htab->elf, readonly_dynrelocs,
+ (PTR) info);
if ((info->flags & DF_TEXTREL) != 0)
{
r_field = e_fsel;
break;
- case R_PARISC_DIR21L:
+ case R_PARISC_DLTIND21L:
case R_PARISC_PCREL21L:
- case R_PARISC_DPREL21L:
case R_PARISC_PLABEL21L:
- case R_PARISC_DLTIND21L:
+ r_field = e_lsel;
+ break;
+
+ case R_PARISC_DIR21L:
+ case R_PARISC_DPREL21L:
r_field = e_lrsel;
break;
- case R_PARISC_DIR17R:
case R_PARISC_PCREL17R:
- case R_PARISC_DIR14R:
case R_PARISC_PCREL14R:
- case R_PARISC_DPREL14R:
case R_PARISC_PLABEL14R:
case R_PARISC_DLTIND14R:
+ r_field = e_rsel;
+ break;
+
+ case R_PARISC_DIR17R:
+ case R_PARISC_DIR14R:
+ case R_PARISC_DPREL14R:
r_field = e_rrsel;
break;
outrel.r_offset =
_bfd_elf_section_offset (output_bfd, info, input_section,
rel->r_offset);
- skip = (outrel.r_offset == (bfd_vma) -1);
+ skip = (outrel.r_offset == (bfd_vma) -1
+ || outrel.r_offset == (bfd_vma) -2);
outrel.r_offset += (input_section->output_offset
+ input_section->output_section->vma);