/* BFD back-end for HP PA-RISC ELF files.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001,
- 2002, 2003, 2004 Free Software Foundation, Inc.
+ 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Original code by
Center for Software Science
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. */
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
#include "bfd.h"
#include "sysdep.h"
elf32_hppa_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
{
struct elf32_hppa_link_hash_table *htab;
+ struct elf_link_hash_entry *h;
/* Don't try to create the .plt and .got twice. */
htab = hppa_link_hash_table (info);
htab->srelplt = bfd_get_section_by_name (abfd, ".rela.plt");
htab->sgot = bfd_get_section_by_name (abfd, ".got");
- htab->srelgot = bfd_make_section (abfd, ".rela.got");
+ htab->srelgot = bfd_make_section_with_flags (abfd, ".rela.got",
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
if (htab->srelgot == NULL
- || ! bfd_set_section_flags (abfd, htab->srelgot,
- (SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED
- | SEC_READONLY))
|| ! bfd_set_section_alignment (abfd, htab->srelgot, 2))
return FALSE;
htab->sdynbss = bfd_get_section_by_name (abfd, ".dynbss");
htab->srelbss = bfd_get_section_by_name (abfd, ".rela.bss");
- return TRUE;
+ /* hppa-linux needs _GLOBAL_OFFSET_TABLE_ to be visible from the main
+ application, because __canonicalize_funcptr_for_compare needs it. */
+ h = elf_hash_table (info)->hgot;
+ h->forced_local = 0;
+ h->other = STV_DEFAULT;
+ return bfd_elf_link_record_dynamic_symbol (info, h);
}
/* Copy the extra info we tack onto an elf_link_hash_entry. */
case R_PARISC_DIR14F: /* Used for load/store from absolute locn. */
case R_PARISC_DIR14R:
case R_PARISC_DIR21L: /* As above, and for ext branches too. */
-#if 0
- /* Help debug shared library creation. Any of the above
- relocs can be used in shared libs, but they may cause
- pages to become unshared. */
- if (info->shared)
- {
- (*_bfd_error_handler)
- (_("%B: relocation %s should not be used when making a shared object; recompile with -fPIC"),
- abfd,
- elf_hppa_howto_table[r_type].name);
- }
- /* Fall through. */
-#endif
-
case R_PARISC_DIR32: /* .word relocs. */
/* We may want to output a dynamic relocation later. */
need_entry = NEED_DYNREL;
{
flagword flags;
- sreloc = bfd_make_section (dynobj, name);
flags = (SEC_HAS_CONTENTS | SEC_READONLY
| SEC_IN_MEMORY | SEC_LINKER_CREATED);
if ((sec->flags & SEC_ALLOC) != 0)
flags |= SEC_ALLOC | SEC_LOAD;
+ sreloc = bfd_make_section_with_flags (dynobj,
+ name,
+ flags);
if (sreloc == NULL
- || !bfd_set_section_flags (dynobj, sreloc, flags)
|| !bfd_set_section_alignment (dynobj, sreloc, 2))
return FALSE;
}
struct elf32_hppa_dyn_reloc_entry *p;
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
eh = (struct elf32_hppa_link_hash_entry *) h;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
return TRUE;
}
+/* Support for core dump NOTE sections. */
+
+static bfd_boolean
+elf32_hppa_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ size_t size;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 396: /* Linux/hppa */
+ /* pr_cursig */
+ 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 + 24);
+
+ /* pr_reg */
+ offset = 72;
+ size = 320;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+static bfd_boolean
+elf32_hppa_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 124: /* Linux/hppa elf_prpsinfo. */
+ elf_tdata (abfd)->core_program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
+ elf_tdata (abfd)->core_command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 44, 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. */
+ {
+ char *command = elf_tdata (abfd)->core_command;
+ int n = strlen (command);
+
+ if (0 < n && command[n - 1] == ' ')
+ command[n - 1] = '\0';
+ }
+
+ return TRUE;
+}
+
/* Our own version of hide_symbol, so that we can keep plt entries for
plabels. */
info = inf;
htab = hppa_link_hash_table (info);
if (htab->elf.dynamic_sections_created
- && h->plt.refcount > 0)
+ && h->plt.refcount > 0)
{
/* Make sure this symbol is output as a dynamic symbol.
Undefined weak syms won't yet be marked as dynamic. */
adjust_dynamic_symbol is called, and it is that
function which decides whether anything needs to go
into these sections. */
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
/* We can't use output_bfd->section_count here to find the top output
section index as some sections may have been removed, and
- _bfd_strip_section_from_output doesn't renumber the indices. */
+ strip_excluded_output_sections doesn't renumber the indices. */
for (section = output_bfd->sections, top_index = 0;
section != NULL;
section = section->next)
== (((int) OP_ADDIL << 26) | (27 << 21)))
{
insn &= ~ (0x1f << 21);
-#if 0 /* debug them. */
- (*_bfd_error_handler)
- (_("%B(%A+0x%lx): fixing %s"),
- input_bfd,
- input_section,
- (long) rel->r_offset,
- howto->name);
-#endif
}
/* Now try to make things easy for the dynamic linker. */
outrel.r_info = ELF32_R_INFO (indx, r_type);
}
-#if 0
- /* EH info can cause unaligned DIR32 relocs.
- Tweak the reloc type for the dynamic linker. */
- if (r_type == R_PARISC_DIR32 && (outrel.r_offset & 3) != 0)
- outrel.r_info = ELF32_R_INFO (ELF32_R_SYM (outrel.r_info),
- R_PARISC_DIR32U);
-#endif
sreloc = elf_section_data (input_section)->sreloc;
if (sreloc == NULL)
abort ();
else
{
if (!((*info->callbacks->reloc_overflow)
- (info, sym_name, howto->name, 0, input_bfd, input_section,
- rel->r_offset)))
+ (info, (h ? &h->elf.root : NULL), sym_name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))
return FALSE;
}
}
#define elf_backend_size_dynamic_sections elf32_hppa_size_dynamic_sections
#define elf_backend_gc_mark_hook elf32_hppa_gc_mark_hook
#define elf_backend_gc_sweep_hook elf32_hppa_gc_sweep_hook
+#define elf_backend_grok_prstatus elf32_hppa_grok_prstatus
+#define elf_backend_grok_psinfo elf32_hppa_grok_psinfo
#define elf_backend_object_p elf32_hppa_object_p
#define elf_backend_final_write_processing elf_hppa_final_write_processing
#define elf_backend_post_process_headers elf32_hppa_post_process_headers