X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Felf64-hppa.c;h=3738d2bcf2c055caa010974bb3a5fd3789e3b3a3;hb=f42fb57409240f97fe271dcd4518345fb7652df5;hp=3c8e00f2b4aee30415614dfad78fda632779c5b2;hpb=f2482cb2da3165cd50cb55e3b2cf68bca1fdd88e;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c index 3c8e00f2b4..3738d2bcf2 100644 --- a/bfd/elf64-hppa.c +++ b/bfd/elf64-hppa.c @@ -1,30 +1,58 @@ /* Support for HPPA 64-bit ELF - Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. -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 3 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., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ -#include "alloca-conf.h" -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" #include "libbfd.h" #include "elf-bfd.h" #include "elf/hppa.h" #include "libhppa.h" #include "elf64-hppa.h" + +/* This is the code recommended in the autoconf documentation, almost + verbatim. */ +#ifndef __GNUC__ +# if HAVE_ALLOCA_H +# include +# else +# ifdef _AIX +/* Indented so that pre-ansi C compilers will ignore it, rather than + choke on it. Some versions of AIX require this to be the first + thing in the file. */ + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +# if !defined (__STDC__) && !defined (__hpux) +extern char *alloca (); +# else +extern void *alloca (); +# endif /* __STDC__, __hpux */ +# endif /* alloca */ +# endif /* _AIX */ +# endif /* HAVE_ALLOCA_H */ +#else +extern void *alloca (size_t); +#endif /* __GNUC__ */ + + #define ARCH_SIZE 64 #define PLT_ENTRY_SIZE 0x10 @@ -156,9 +184,6 @@ struct elf64_hppa_link_hash_table typedef struct bfd_hash_entry *(*new_hash_entry_func) PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static boolean elf64_hppa_dyn_hash_table_init - PARAMS ((struct elf64_hppa_dyn_hash_table *ht, bfd *abfd, - new_hash_entry_func new)); static struct bfd_hash_entry *elf64_hppa_new_dyn_hash_entry PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table, const char *string)); @@ -166,123 +191,116 @@ static struct bfd_link_hash_table *elf64_hppa_hash_table_create PARAMS ((bfd *abfd)); static struct elf64_hppa_dyn_hash_entry *elf64_hppa_dyn_hash_lookup PARAMS ((struct elf64_hppa_dyn_hash_table *table, const char *string, - boolean create, boolean copy)); + bfd_boolean create, bfd_boolean copy)); static void elf64_hppa_dyn_hash_traverse PARAMS ((struct elf64_hppa_dyn_hash_table *table, - boolean (*func) (struct elf64_hppa_dyn_hash_entry *, PTR), + bfd_boolean (*func) (struct elf64_hppa_dyn_hash_entry *, PTR), PTR info)); static const char *get_dyn_name - PARAMS ((asection *, struct elf_link_hash_entry *, + PARAMS ((bfd *, struct elf_link_hash_entry *, const Elf_Internal_Rela *, char **, size_t *)); /* This must follow the definitions of the various derived linker hash tables and shared functions. */ #include "elf-hppa.h" -static boolean elf64_hppa_object_p +static bfd_boolean elf64_hppa_object_p PARAMS ((bfd *)); -static boolean elf64_hppa_section_from_shdr - PARAMS ((bfd *, Elf64_Internal_Shdr *, const char *)); - static void elf64_hppa_post_process_headers PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf64_hppa_create_dynamic_sections +static bfd_boolean elf64_hppa_create_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf64_hppa_adjust_dynamic_symbol +static bfd_boolean elf64_hppa_adjust_dynamic_symbol PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); -static boolean elf64_hppa_mark_milli_and_exported_functions +static bfd_boolean elf64_hppa_mark_milli_and_exported_functions PARAMS ((struct elf_link_hash_entry *, PTR)); -static boolean elf64_hppa_size_dynamic_sections +static bfd_boolean elf64_hppa_size_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf64_hppa_link_output_symbol_hook -PARAMS ((bfd *abfd, struct bfd_link_info *, const char *, - Elf_Internal_Sym *, asection *input_sec)); +static bfd_boolean elf64_hppa_link_output_symbol_hook + PARAMS ((struct bfd_link_info *, const char *, Elf_Internal_Sym *, + asection *, struct elf_link_hash_entry *)); -static boolean elf64_hppa_finish_dynamic_symbol +static bfd_boolean elf64_hppa_finish_dynamic_symbol PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); -static int elf64_hppa_additional_program_headers PARAMS ((bfd *)); - -static boolean elf64_hppa_modify_segment_map PARAMS ((bfd *)); - static enum elf_reloc_type_class elf64_hppa_reloc_type_class PARAMS ((const Elf_Internal_Rela *)); -static boolean elf64_hppa_finish_dynamic_sections +static bfd_boolean elf64_hppa_finish_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf64_hppa_check_relocs +static bfd_boolean elf64_hppa_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); -static boolean elf64_hppa_dynamic_symbol_p +static bfd_boolean elf64_hppa_dynamic_symbol_p PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *)); -static boolean elf64_hppa_mark_exported_functions +static bfd_boolean elf64_hppa_mark_exported_functions PARAMS ((struct elf_link_hash_entry *, PTR)); -static boolean elf64_hppa_finalize_opd +static bfd_boolean elf64_hppa_finalize_opd PARAMS ((struct elf64_hppa_dyn_hash_entry *, PTR)); -static boolean elf64_hppa_finalize_dlt +static bfd_boolean elf64_hppa_finalize_dlt PARAMS ((struct elf64_hppa_dyn_hash_entry *, PTR)); -static boolean allocate_global_data_dlt +static bfd_boolean allocate_global_data_dlt PARAMS ((struct elf64_hppa_dyn_hash_entry *, PTR)); -static boolean allocate_global_data_plt +static bfd_boolean allocate_global_data_plt PARAMS ((struct elf64_hppa_dyn_hash_entry *, PTR)); -static boolean allocate_global_data_stub +static bfd_boolean allocate_global_data_stub PARAMS ((struct elf64_hppa_dyn_hash_entry *, PTR)); -static boolean allocate_global_data_opd +static bfd_boolean allocate_global_data_opd PARAMS ((struct elf64_hppa_dyn_hash_entry *, PTR)); -static boolean get_reloc_section +static bfd_boolean get_reloc_section PARAMS ((bfd *, struct elf64_hppa_link_hash_table *, asection *)); -static boolean count_dyn_reloc +static bfd_boolean count_dyn_reloc PARAMS ((bfd *, struct elf64_hppa_dyn_hash_entry *, int, asection *, int, bfd_vma, bfd_vma)); -static boolean allocate_dynrel_entries +static bfd_boolean allocate_dynrel_entries PARAMS ((struct elf64_hppa_dyn_hash_entry *, PTR)); -static boolean elf64_hppa_finalize_dynreloc +static bfd_boolean elf64_hppa_finalize_dynreloc PARAMS ((struct elf64_hppa_dyn_hash_entry *, PTR)); -static boolean get_opd +static bfd_boolean get_opd PARAMS ((bfd *, struct bfd_link_info *, struct elf64_hppa_link_hash_table *)); -static boolean get_plt +static bfd_boolean get_plt PARAMS ((bfd *, struct bfd_link_info *, struct elf64_hppa_link_hash_table *)); -static boolean get_dlt +static bfd_boolean get_dlt PARAMS ((bfd *, struct bfd_link_info *, struct elf64_hppa_link_hash_table *)); -static boolean get_stub +static bfd_boolean get_stub PARAMS ((bfd *, struct bfd_link_info *, struct elf64_hppa_link_hash_table *)); static int elf64_hppa_elf_get_symbol_type PARAMS ((Elf_Internal_Sym *, int)); -static boolean -elf64_hppa_dyn_hash_table_init (ht, abfd, new) - struct elf64_hppa_dyn_hash_table *ht; - bfd *abfd ATTRIBUTE_UNUSED; - new_hash_entry_func new; +static bfd_boolean +elf64_hppa_dyn_hash_table_init (struct elf64_hppa_dyn_hash_table *ht, + bfd *abfd ATTRIBUTE_UNUSED, + new_hash_entry_func new, + unsigned int entsize) { memset (ht, 0, sizeof (*ht)); - return bfd_hash_table_init (&ht->root, new); + return bfd_hash_table_init (&ht->root, new, entsize); } static struct bfd_hash_entry* @@ -302,14 +320,15 @@ elf64_hppa_new_dyn_hash_entry (entry, table, string) if (!ret) return 0; - /* Initialize our local data. All zeros, and definitely easier - than setting 8 bit fields. */ - memset (ret, 0, sizeof (*ret)); - /* Call the allocation method of the superclass. */ ret = ((struct elf64_hppa_dyn_hash_entry *) bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); + /* Initialize our local data. All zeros. */ + memset (&ret->dlt_offset, 0, + (sizeof (struct elf64_hppa_dyn_hash_entry) + - offsetof (struct elf64_hppa_dyn_hash_entry, dlt_offset))); + return &ret->root; } @@ -327,14 +346,16 @@ elf64_hppa_hash_table_create (abfd) if (!ret) return 0; if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, - _bfd_elf_link_hash_newfunc)) + _bfd_elf_link_hash_newfunc, + sizeof (struct elf_link_hash_entry))) { bfd_release (abfd, ret); return 0; } if (!elf64_hppa_dyn_hash_table_init (&ret->dyn_hash_table, abfd, - elf64_hppa_new_dyn_hash_entry)) + elf64_hppa_new_dyn_hash_entry, + sizeof (struct elf64_hppa_dyn_hash_entry))) return 0; return &ret->root.root; } @@ -345,7 +366,7 @@ static struct elf64_hppa_dyn_hash_entry * elf64_hppa_dyn_hash_lookup(table, string, create, copy) struct elf64_hppa_dyn_hash_table *table; const char *string; - boolean create, copy; + bfd_boolean create, copy; { return ((struct elf64_hppa_dyn_hash_entry *) bfd_hash_lookup (&table->root, string, create, copy)); @@ -356,19 +377,19 @@ elf64_hppa_dyn_hash_lookup(table, string, create, copy) static void elf64_hppa_dyn_hash_traverse (table, func, info) struct elf64_hppa_dyn_hash_table *table; - boolean (*func) PARAMS ((struct elf64_hppa_dyn_hash_entry *, PTR)); + bfd_boolean (*func) PARAMS ((struct elf64_hppa_dyn_hash_entry *, PTR)); PTR info; { (bfd_hash_traverse (&table->root, - (boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) func, + (bfd_boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) func, info)); } /* Return nonzero if ABFD represents a PA2.0 ELF64 file. Additionally we set the default architecture and machine. */ -static boolean +static bfd_boolean elf64_hppa_object_p (abfd) bfd *abfd; { @@ -378,13 +399,19 @@ elf64_hppa_object_p (abfd) i_ehdrp = elf_elfheader (abfd); if (strcmp (bfd_get_target (abfd), "elf64-hppa-linux") == 0) { - if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_LINUX) - return false; + /* GCC on hppa-linux produces binaries with OSABI=Linux, + but the kernel produces corefiles with OSABI=SysV. */ + if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_LINUX + && i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NONE) /* aka SYSV */ + return FALSE; } else { - if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_HPUX) - return false; + /* HPUX produces binaries with OSABI=HPUX, + but the kernel produces corefiles with OSABI=SysV. */ + if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_HPUX + && i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NONE) /* aka SYSV */ + return FALSE; } flags = i_ehdrp->e_flags; @@ -395,21 +422,24 @@ elf64_hppa_object_p (abfd) case EFA_PARISC_1_1: return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 11); case EFA_PARISC_2_0: - return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 20); + if (i_ehdrp->e_ident[EI_CLASS] == ELFCLASS64) + return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 25); + else + 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); } /* Don't be fussy. */ - return true; + return TRUE; } /* Given section type (hdr->sh_type), return a boolean indicating whether or not the section is an elf64-hppa specific section. */ -static boolean -elf64_hppa_section_from_shdr (abfd, hdr, name) - bfd *abfd; - Elf64_Internal_Shdr *hdr; - const char *name; +static bfd_boolean +elf64_hppa_section_from_shdr (bfd *abfd, + Elf_Internal_Shdr *hdr, + const char *name, + int shindex) { asection *newsect; @@ -417,23 +447,23 @@ elf64_hppa_section_from_shdr (abfd, hdr, name) { case SHT_PARISC_EXT: if (strcmp (name, ".PARISC.archext") != 0) - return false; + return FALSE; break; case SHT_PARISC_UNWIND: if (strcmp (name, ".PARISC.unwind") != 0) - return false; + return FALSE; break; case SHT_PARISC_DOC: case SHT_PARISC_ANNOT: default: - return false; + return FALSE; } - if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) - return false; + if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) + return FALSE; newsect = hdr->bfd_section; - return true; + return TRUE; } /* Construct a string for use in the elf64_hppa_dyn_hash_table. The @@ -441,13 +471,14 @@ elf64_hppa_section_from_shdr (abfd, hdr, name) allocate memory as necessary, possibly reusing PBUF/PLEN. */ static const char * -get_dyn_name (sec, h, rel, pbuf, plen) - asection *sec; +get_dyn_name (abfd, h, rel, pbuf, plen) + bfd *abfd; struct elf_link_hash_entry *h; const Elf_Internal_Rela *rel; char **pbuf; size_t *plen; { + asection *sec = abfd->sections; size_t nlen, tlen; char *buf; size_t len; @@ -483,7 +514,7 @@ get_dyn_name (sec, h, rel, pbuf, plen) { nlen = sprintf (buf, "%x:%lx", sec->id & 0xffffffff, - (long) ELF64_R_SYM (rel->r_info)); + (unsigned long) ELF64_R_SYM (rel->r_info)); if (rel->r_addend) { buf[nlen++] = '+'; @@ -497,7 +528,7 @@ get_dyn_name (sec, h, rel, pbuf, plen) /* SEC is a section containing relocs for an input BFD when linking; return a suitable section for holding relocs in the output BFD for a link. */ -static boolean +static bfd_boolean get_reloc_section (abfd, hppa_info, sec) bfd *abfd; struct elf64_hppa_link_hash_table *hppa_info; @@ -511,14 +542,14 @@ get_reloc_section (abfd, hppa_info, sec) (abfd, elf_elfheader(abfd)->e_shstrndx, elf_section_data(sec)->rel_hdr.sh_name)); if (srel_name == NULL) - return false; + return FALSE; - BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0 + BFD_ASSERT ((CONST_STRNEQ (srel_name, ".rela") && strcmp (bfd_get_section_name (abfd, sec), - srel_name+5) == 0) - || (strncmp (srel_name, ".rel", 4) == 0 + srel_name + 5) == 0) + || (CONST_STRNEQ (srel_name, ".rel") && strcmp (bfd_get_section_name (abfd, sec), - srel_name+4) == 0)); + srel_name + 4) == 0)); dynobj = hppa_info->root.dynobj; if (!dynobj) @@ -527,21 +558,20 @@ get_reloc_section (abfd, hppa_info, sec) srel = bfd_get_section_by_name (dynobj, srel_name); if (srel == NULL) { - srel = bfd_make_section (dynobj, srel_name); + srel = bfd_make_section_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_flags (dynobj, srel, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_LINKER_CREATED - | SEC_READONLY)) || !bfd_set_section_alignment (dynobj, srel, 3)) - return false; + return FALSE; } hppa_info->other_rel_sec = srel; - return true; + return TRUE; } /* Add a new entry to the list of dynamic relocations against DYN_H. @@ -550,7 +580,7 @@ get_reloc_section (abfd, hppa_info, sec) particular symbol so that we can create FPTR relocations in the output file. */ -static boolean +static bfd_boolean count_dyn_reloc (abfd, dyn_h, type, sec, sec_symndx, offset, addend) bfd *abfd; struct elf64_hppa_dyn_hash_entry *dyn_h; @@ -565,7 +595,7 @@ count_dyn_reloc (abfd, dyn_h, type, sec, sec_symndx, offset, addend) rent = (struct elf64_hppa_dyn_reloc_entry *) bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)); if (!rent) - return false; + return FALSE; rent->next = dyn_h->reloc_entries; rent->type = type; @@ -575,13 +605,13 @@ count_dyn_reloc (abfd, dyn_h, type, sec, sec_symndx, offset, addend) rent->addend = addend; dyn_h->reloc_entries = rent; - return true; + return TRUE; } /* Scan the RELOCS and record the type of dynamic entries that each referenced symbol needs. */ -static boolean +static bfd_boolean elf64_hppa_check_relocs (abfd, info, sec, relocs) bfd *abfd; struct bfd_link_info *info; @@ -595,17 +625,17 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs) asection *dlt, *plt, *stubs; char *buf; size_t buf_len; - int sec_symndx; + unsigned int sec_symndx; - if (info->relocateable) - return true; + if (info->relocatable) + return TRUE; /* If this is the first dynamic object found in the link, create the special sections required for dynamic linking. */ if (! elf_hash_table (info)->dynamic_sections_created) { - if (! bfd_elf64_link_create_dynamic_sections (abfd, info)) - return false; + if (! _bfd_elf_link_create_dynamic_sections (abfd, info)) + return FALSE; } hppa_info = elf64_hppa_hash_table (info); @@ -639,7 +669,7 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs) symtab_hdr->sh_info, 0, NULL, NULL, NULL); if (local_syms == NULL) - return false; + return FALSE; } /* Record the highest section index referenced by the local symbols. */ @@ -647,7 +677,8 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs) isymend = local_syms + symtab_hdr->sh_info; for (isym = local_syms; isym < isymend; isym++) { - if (isym->st_shndx > highest_shndx) + if (isym->st_shndx > highest_shndx + && isym->st_shndx < SHN_LORESERVE) highest_shndx = isym->st_shndx; } @@ -693,10 +724,13 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs) /* If we did not find a section symbol for this section, then something went terribly wrong above. */ - if (sec_symndx == -1) - return false; + if (sec_symndx == SHN_BAD) + return FALSE; - sec_symndx = hppa_info->section_syms[sec_symndx]; + if (sec_symndx < SHN_LORESERVE) + sec_symndx = hppa_info->section_syms[sec_symndx]; + else + sec_symndx = 0; } else sec_symndx = 0; @@ -708,20 +742,21 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs) relend = relocs + sec->reloc_count; for (rel = relocs; rel < relend; ++rel) { - enum { - NEED_DLT = 1, - NEED_PLT = 2, - NEED_STUB = 4, - NEED_OPD = 8, - NEED_DYNREL = 16, - }; + enum + { + NEED_DLT = 1, + NEED_PLT = 2, + NEED_STUB = 4, + NEED_OPD = 8, + NEED_DYNREL = 16, + }; struct elf_link_hash_entry *h = NULL; unsigned long r_symndx = ELF64_R_SYM (rel->r_info); struct elf64_hppa_dyn_hash_entry *dyn_h; int need_entry; const char *addr_name; - boolean maybe_dynamic; + bfd_boolean maybe_dynamic; int dynrel_type = R_PARISC_NONE; static reloc_howto_type *howto; @@ -735,19 +770,20 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs) || h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; - h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR; + h->ref_regular = 1; } /* We can only get preliminary data on whether a symbol is locally or externally defined, as not all of the input files have yet been processed. Do something with what we know, as this may help reduce memory usage and processing time later. */ - maybe_dynamic = false; + maybe_dynamic = FALSE; if (h && ((info->shared - && (!info->symbolic || info->allow_shlib_undefined) ) - || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) + && (!info->symbolic + || info->unresolved_syms_in_shared_libs == RM_IGNORE)) + || !h->def_regular || h->root.type == bfd_link_hash_defweak)) - maybe_dynamic = true; + maybe_dynamic = TRUE; howto = elf_hppa_howto_table + ELF64_R_TYPE (rel->r_info); need_entry = 0; @@ -852,11 +888,11 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs) continue; /* Collect a canonical name for this address. */ - addr_name = get_dyn_name (sec, h, rel, &buf, &buf_len); + addr_name = get_dyn_name (abfd, h, rel, &buf, &buf_len); /* Collect the canonical entry data for this address. */ dyn_h = elf64_hppa_dyn_hash_lookup (&hppa_info->dyn_hash_table, - addr_name, true, true); + addr_name, TRUE, TRUE); BFD_ASSERT (dyn_h); /* Stash away enough information to be able to find this symbol @@ -905,7 +941,7 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs) /* This could be a local function that had its address taken, in which case H will be NULL. */ if (h) - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; + h->needs_plt = 1; } /* Add a new dynamic relocation to the chain of dynamic @@ -925,20 +961,20 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs) section symbol for this section ends up in the dynamic symbol table. */ if (info->shared && dynrel_type == R_PARISC_FPTR64 - && ! (_bfd_elf64_link_record_local_dynamic_symbol + && ! (bfd_elf_link_record_local_dynamic_symbol (info, abfd, sec_symndx))) - return false; + return FALSE; } } if (buf) free (buf); - return true; + return TRUE; err_out: if (buf) free (buf); - return false; + return FALSE; } struct elf64_hppa_allocate_data @@ -949,41 +985,30 @@ struct elf64_hppa_allocate_data /* Should we do dynamic things to this symbol? */ -static boolean +static bfd_boolean elf64_hppa_dynamic_symbol_p (h, info) struct elf_link_hash_entry *h; struct bfd_link_info *info; { - if (h == NULL) - return false; - - 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; - - if (h->dynindx == -1) - return false; - - if (h->root.type == bfd_link_hash_undefweak - || h->root.type == bfd_link_hash_defweak) - return true; - - if (h->root.root.string[0] == '$' && h->root.root.string[1] == '$') - return false; - - if ((info->shared && (!info->symbolic || info->allow_shlib_undefined)) - || ((h->elf_link_hash_flags - & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)) - == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))) - return true; + /* ??? What, if anything, needs to happen wrt STV_PROTECTED symbols + and relocations that retrieve a function descriptor? Assume the + worst for now. */ + if (_bfd_elf_dynamic_symbol_p (h, info, 1)) + { + /* ??? Why is this here and not elsewhere is_local_label_name. */ + if (h->root.root.string[0] == '$' && h->root.root.string[1] == '$') + return FALSE; - return false; + return TRUE; + } + else + return FALSE; } -/* Mark all funtions exported by this file so that we can later allocate +/* Mark all functions exported by this file so that we can later allocate entries in .opd for them. */ -static boolean +static bfd_boolean elf64_hppa_mark_exported_functions (h, data) struct elf_link_hash_entry *h; PTR data; @@ -1006,26 +1031,26 @@ elf64_hppa_mark_exported_functions (h, data) /* Add this symbol to the PA64 linker hash table. */ dyn_h = elf64_hppa_dyn_hash_lookup (&hppa_info->dyn_hash_table, - h->root.root.string, true, true); + h->root.root.string, TRUE, TRUE); BFD_ASSERT (dyn_h); dyn_h->h = h; if (! hppa_info->opd_sec && ! get_opd (hppa_info->root.dynobj, info, hppa_info)) - return false; + return FALSE; dyn_h->want_opd = 1; /* Put a flag here for output_symbol_hook. */ dyn_h->st_shndx = -1; - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; + h->needs_plt = 1; } - return true; + return TRUE; } /* Allocate space for a DLT entry. */ -static boolean +static bfd_boolean allocate_global_data_dlt (dyn_h, data) struct elf64_hppa_dyn_hash_entry *dyn_h; PTR data; @@ -1047,21 +1072,21 @@ allocate_global_data_dlt (dyn_h, data) bfd *owner; owner = (h ? h->root.u.def.section->owner : dyn_h->owner); - if (! (_bfd_elf64_link_record_local_dynamic_symbol + if (! (bfd_elf_link_record_local_dynamic_symbol (x->info, owner, dyn_h->sym_indx))) - return false; + return FALSE; } } dyn_h->dlt_offset = x->ofs; x->ofs += DLT_ENTRY_SIZE; } - return true; + return TRUE; } /* Allocate space for a DLT.PLT entry. */ -static boolean +static bfd_boolean allocate_global_data_plt (dyn_h, data) struct elf64_hppa_dyn_hash_entry *dyn_h; PTR data; @@ -1082,12 +1107,12 @@ allocate_global_data_plt (dyn_h, data) else dyn_h->want_plt = 0; - return true; + return TRUE; } /* Allocate space for a STUB entry. */ -static boolean +static bfd_boolean allocate_global_data_stub (dyn_h, data) struct elf64_hppa_dyn_hash_entry *dyn_h; PTR data; @@ -1105,12 +1130,12 @@ allocate_global_data_stub (dyn_h, data) } else dyn_h->want_stub = 0; - return true; + return TRUE; } /* Allocate space for a FPTR entry. */ -static boolean +static bfd_boolean allocate_global_data_opd (dyn_h, data) struct elf64_hppa_dyn_hash_entry *dyn_h; PTR data; @@ -1129,6 +1154,7 @@ allocate_global_data_opd (dyn_h, data) /* We never need an opd entry for a symbol which is not defined by this output file. */ if (h && (h->root.type == bfd_link_hash_undefined + || h->root.type == bfd_link_hash_undefweak || h->root.u.def.section->output_section == NULL)) dyn_h->want_opd = 0; @@ -1149,11 +1175,12 @@ allocate_global_data_opd (dyn_h, data) && (h == NULL || (h->dynindx == -1))) { bfd *owner; - owner = (h ? h->root.u.def.section->owner : dyn_h->owner); + /* PR 6511: Default to using the dynamic symbol table. */ + owner = (dyn_h->owner ? dyn_h->owner: h->root.u.def.section->owner); - if (!_bfd_elf64_link_record_local_dynamic_symbol + if (!bfd_elf_link_record_local_dynamic_symbol (x->info, owner, dyn_h->sym_indx)) - return false; + return FALSE; } /* This may not be necessary or desirable anymore now that @@ -1171,14 +1198,14 @@ allocate_global_data_opd (dyn_h, data) strcpy (new_name + 1, h->root.root.string); nh = elf_link_hash_lookup (elf_hash_table (x->info), - new_name, true, true, true); + new_name, TRUE, TRUE, TRUE); nh->root.type = h->root.type; nh->root.u.def.value = h->root.u.def.value; nh->root.u.def.section = h->root.u.def.section; - if (! bfd_elf64_link_record_dynamic_symbol (x->info, nh)) - return false; + if (! bfd_elf_link_record_dynamic_symbol (x->info, nh)) + return FALSE; } dyn_h->opd_offset = x->ofs; @@ -1189,7 +1216,7 @@ allocate_global_data_opd (dyn_h, data) else dyn_h->want_opd = 0; } - return true; + return TRUE; } /* HP requires the EI_OSABI field to be filled in. The assignment to @@ -1203,24 +1230,17 @@ elf64_hppa_post_process_headers (abfd, link_info) Elf_Internal_Ehdr * i_ehdrp; i_ehdrp = elf_elfheader (abfd); - - if (strcmp (bfd_get_target (abfd), "elf64-hppa-linux") == 0) - { - i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_LINUX; - } - else - { - i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_HPUX; - i_ehdrp->e_ident[EI_ABIVERSION] = 1; - } + + i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi; + i_ehdrp->e_ident[EI_ABIVERSION] = 1; } /* Create function descriptor section (.opd). This section is called .opd - because it contains "official prodecure descriptors". The "official" + because it contains "official procedure descriptors". The "official" refers to the fact that these descriptors are used when taking the address of a procedure, thus ensuring a unique address for each procedure. */ -static boolean +static bfd_boolean get_opd (abfd, info, hppa_info) bfd *abfd; struct bfd_link_info *info ATTRIBUTE_UNUSED; @@ -1236,29 +1256,28 @@ get_opd (abfd, info, hppa_info) if (!dynobj) hppa_info->root.dynobj = dynobj = abfd; - opd = bfd_make_section (dynobj, ".opd"); + opd = bfd_make_section_with_flags (dynobj, ".opd", + (SEC_ALLOC + | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY + | SEC_LINKER_CREATED)); if (!opd - || !bfd_set_section_flags (dynobj, opd, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_LINKER_CREATED)) || !bfd_set_section_alignment (abfd, opd, 3)) { BFD_ASSERT (0); - return false; + return FALSE; } hppa_info->opd_sec = opd; } - return true; + return TRUE; } /* Create the PLT section. */ -static boolean +static bfd_boolean get_plt (abfd, info, hppa_info) bfd *abfd; struct bfd_link_info *info ATTRIBUTE_UNUSED; @@ -1274,29 +1293,28 @@ get_plt (abfd, info, hppa_info) if (!dynobj) hppa_info->root.dynobj = dynobj = abfd; - plt = bfd_make_section (dynobj, ".plt"); + plt = bfd_make_section_with_flags (dynobj, ".plt", + (SEC_ALLOC + | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY + | SEC_LINKER_CREATED)); if (!plt - || !bfd_set_section_flags (dynobj, plt, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_LINKER_CREATED)) || !bfd_set_section_alignment (abfd, plt, 3)) { BFD_ASSERT (0); - return false; + return FALSE; } hppa_info->plt_sec = plt; } - return true; + return TRUE; } /* Create the DLT section. */ -static boolean +static bfd_boolean get_dlt (abfd, info, hppa_info) bfd *abfd; struct bfd_link_info *info ATTRIBUTE_UNUSED; @@ -1312,29 +1330,28 @@ get_dlt (abfd, info, hppa_info) if (!dynobj) hppa_info->root.dynobj = dynobj = abfd; - dlt = bfd_make_section (dynobj, ".dlt"); + dlt = bfd_make_section_with_flags (dynobj, ".dlt", + (SEC_ALLOC + | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY + | SEC_LINKER_CREATED)); if (!dlt - || !bfd_set_section_flags (dynobj, dlt, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_LINKER_CREATED)) || !bfd_set_section_alignment (abfd, dlt, 3)) { BFD_ASSERT (0); - return false; + return FALSE; } hppa_info->dlt_sec = dlt; } - return true; + return TRUE; } /* Create the stubs section. */ -static boolean +static bfd_boolean get_stub (abfd, info, hppa_info) bfd *abfd; struct bfd_link_info *info ATTRIBUTE_UNUSED; @@ -1350,25 +1367,23 @@ get_stub (abfd, info, hppa_info) if (!dynobj) hppa_info->root.dynobj = dynobj = abfd; - stub = bfd_make_section (dynobj, ".stub"); + stub = bfd_make_section_with_flags (dynobj, ".stub", + (SEC_ALLOC | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY + | SEC_READONLY + | SEC_LINKER_CREATED)); if (!stub - || !bfd_set_section_flags (dynobj, stub, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY - | SEC_LINKER_CREATED)) || !bfd_set_section_alignment (abfd, stub, 3)) { BFD_ASSERT (0); - return false; + return FALSE; } hppa_info->stub_sec = stub; } - return true; + return TRUE; } /* Create sections necessary for dynamic linking. This is only a rough @@ -1409,7 +1424,7 @@ get_stub (abfd, info, hppa_info) .rela.opd: EPLT relocations for symbols exported from shared libraries. */ -static boolean +static bfd_boolean elf64_hppa_create_dynamic_sections (abfd, info) bfd *abfd; struct bfd_link_info *info; @@ -1417,68 +1432,68 @@ elf64_hppa_create_dynamic_sections (abfd, info) asection *s; if (! get_stub (abfd, info, elf64_hppa_hash_table (info))) - return false; + return FALSE; if (! get_dlt (abfd, info, elf64_hppa_hash_table (info))) - return false; + return FALSE; if (! get_plt (abfd, info, elf64_hppa_hash_table (info))) - return false; + return FALSE; if (! get_opd (abfd, info, elf64_hppa_hash_table (info))) - return false; - - s = bfd_make_section(abfd, ".rela.dlt"); + 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)); if (s == NULL - || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY - | SEC_LINKER_CREATED)) || !bfd_set_section_alignment (abfd, s, 3)) - return false; + return FALSE; elf64_hppa_hash_table (info)->dlt_rel_sec = s; - s = bfd_make_section(abfd, ".rela.plt"); + s = bfd_make_section_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_flags (abfd, s, (SEC_ALLOC | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY - | SEC_LINKER_CREATED)) || !bfd_set_section_alignment (abfd, s, 3)) - return false; + return FALSE; elf64_hppa_hash_table (info)->plt_rel_sec = s; - s = bfd_make_section(abfd, ".rela.data"); + s = bfd_make_section_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_flags (abfd, s, (SEC_ALLOC | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY - | SEC_LINKER_CREATED)) || !bfd_set_section_alignment (abfd, s, 3)) - return false; + return FALSE; elf64_hppa_hash_table (info)->other_rel_sec = s; - s = bfd_make_section(abfd, ".rela.opd"); + s = bfd_make_section_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_flags (abfd, s, (SEC_ALLOC | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY - | SEC_LINKER_CREATED)) || !bfd_set_section_alignment (abfd, s, 3)) - return false; + return FALSE; elf64_hppa_hash_table (info)->opd_rel_sec = s; - return true; + return TRUE; } /* Allocate dynamic relocations for those symbols that turned out to be dynamic. */ -static boolean +static bfd_boolean allocate_dynrel_entries (dyn_h, data) struct elf64_hppa_dyn_hash_entry *dyn_h; PTR data; @@ -1486,7 +1501,7 @@ allocate_dynrel_entries (dyn_h, data) struct elf64_hppa_allocate_data *x = (struct elf64_hppa_allocate_data *)data; struct elf64_hppa_link_hash_table *hppa_info; struct elf64_hppa_dyn_reloc_entry *rent; - boolean dynamic_symbol, shared; + bfd_boolean dynamic_symbol, shared; hppa_info = elf64_hppa_hash_table (x->info); dynamic_symbol = elf64_hppa_dynamic_symbol_p (dyn_h->h, x->info); @@ -1495,7 +1510,7 @@ allocate_dynrel_entries (dyn_h, data) /* We may need to allocate relocations for a non-dynamic symbol when creating a shared library. */ if (!dynamic_symbol && !shared) - return true; + return TRUE; /* Take care of the normal data relocations. */ @@ -1506,28 +1521,28 @@ allocate_dynrel_entries (dyn_h, data) if (!shared && rent->type == R_PARISC_FPTR64 && dyn_h->want_opd) continue; - hppa_info->other_rel_sec->_raw_size += sizeof (Elf64_External_Rela); + hppa_info->other_rel_sec->size += sizeof (Elf64_External_Rela); /* Make sure this symbol gets into the dynamic symbol table if it is not already recorded. ?!? This should not be in the loop since the symbol need only be added once. */ if (dyn_h->h == 0 || (dyn_h->h->dynindx == -1 && dyn_h->h->type != STT_PARISC_MILLI)) - if (!_bfd_elf64_link_record_local_dynamic_symbol + if (!bfd_elf_link_record_local_dynamic_symbol (x->info, rent->sec->owner, dyn_h->sym_indx)) - return false; + return FALSE; } /* Take care of the GOT and PLT relocations. */ if ((dynamic_symbol || shared) && dyn_h->want_dlt) - hppa_info->dlt_rel_sec->_raw_size += sizeof (Elf64_External_Rela); + hppa_info->dlt_rel_sec->size += sizeof (Elf64_External_Rela); /* If we are building a shared library, then every symbol that has an opd entry will need an EPLT relocation to relocate the symbol's address and __gp value based on the runtime load address. */ if (shared && dyn_h->want_opd) - hppa_info->opd_rel_sec->_raw_size += sizeof (Elf64_External_Rela); + hppa_info->opd_rel_sec->size += sizeof (Elf64_External_Rela); if (dyn_h->want_plt && dynamic_symbol) { @@ -1541,16 +1556,16 @@ allocate_dynrel_entries (dyn_h, data) else if (shared) t = 2 * sizeof (Elf64_External_Rela); - hppa_info->plt_rel_sec->_raw_size += t; + hppa_info->plt_rel_sec->size += t; } - return true; + return TRUE; } /* Adjust a symbol defined by a dynamic object and referenced by a regular object. */ -static boolean +static bfd_boolean elf64_hppa_adjust_dynamic_symbol (info, h) struct bfd_link_info *info ATTRIBUTE_UNUSED; struct elf_link_hash_entry *h; @@ -1561,13 +1576,13 @@ elf64_hppa_adjust_dynamic_symbol (info, h) /* 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 (h->weakdef != NULL) + if (h->u.weakdef != NULL) { - BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined - || h->weakdef->root.type == bfd_link_hash_defweak); - h->root.u.def.section = h->weakdef->root.u.def.section; - h->root.u.def.value = h->weakdef->root.u.def.value; - return true; + BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined + || h->u.weakdef->root.type == bfd_link_hash_defweak); + h->root.u.def.section = h->u.weakdef->root.u.def.section; + h->root.u.def.value = h->u.weakdef->root.u.def.value; + return TRUE; } /* If this is a reference to a symbol defined by a dynamic object which @@ -1577,7 +1592,7 @@ elf64_hppa_adjust_dynamic_symbol (info, h) But PA64 code is canonically PIC, so as a rule we can avoid this sort of hackery. */ - return true; + return TRUE; } /* This function is called via elf_link_hash_traverse to mark millicode @@ -1585,7 +1600,7 @@ elf64_hppa_adjust_dynamic_symbol (info, h) from the dynamic symbol table. If the symbol is not a millicode symbol, elf64_hppa_mark_exported_functions is called. */ -static boolean +static bfd_boolean elf64_hppa_mark_milli_and_exported_functions (h, data) struct elf_link_hash_entry *h; PTR data; @@ -1604,7 +1619,7 @@ elf64_hppa_mark_milli_and_exported_functions (h, data) _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr, elf->dynstr_index); } - return true; + return TRUE; } return elf64_hppa_mark_exported_functions (h, data); @@ -1613,16 +1628,16 @@ elf64_hppa_mark_milli_and_exported_functions (h, data) /* Set the final sizes of the dynamic sections and allocate memory for the contents of our special sections. */ -static boolean +static bfd_boolean elf64_hppa_size_dynamic_sections (output_bfd, info) bfd *output_bfd; struct bfd_link_info *info; { bfd *dynobj; asection *s; - boolean plt; - boolean relocs; - boolean reltext; + bfd_boolean plt; + bfd_boolean relocs; + bfd_boolean reltext; struct elf64_hppa_allocate_data data; struct elf64_hppa_link_hash_table *hppa_info; @@ -1647,11 +1662,11 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) if (elf_hash_table (info)->dynamic_sections_created) { /* Set the contents of the .interp section to the interpreter. */ - if (! info->shared) + if (info->executable) { s = bfd_get_section_by_name (dynobj, ".interp"); BFD_ASSERT (s != NULL); - s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; + s->size = sizeof ELF_DYNAMIC_INTERPRETER; s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; } } @@ -1664,7 +1679,7 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) below. */ s = bfd_get_section_by_name (dynobj, ".rela.dlt"); if (s != NULL) - s->_raw_size = 0; + s->size = 0; } /* Allocate the GOT entries. */ @@ -1675,17 +1690,17 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) data.ofs = 0x0; elf64_hppa_dyn_hash_traverse (&hppa_info->dyn_hash_table, allocate_global_data_dlt, &data); - hppa_info->dlt_sec->_raw_size = data.ofs; + hppa_info->dlt_sec->size = data.ofs; data.ofs = 0x0; elf64_hppa_dyn_hash_traverse (&hppa_info->dyn_hash_table, allocate_global_data_plt, &data); - hppa_info->plt_sec->_raw_size = data.ofs; + hppa_info->plt_sec->size = data.ofs; data.ofs = 0x0; elf64_hppa_dyn_hash_traverse (&hppa_info->dyn_hash_table, allocate_global_data_stub, &data); - hppa_info->stub_sec->_raw_size = data.ofs; + hppa_info->stub_sec->size = data.ofs; } /* Allocate space for entries in the .opd section. */ @@ -1694,7 +1709,7 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) data.ofs = 0; elf64_hppa_dyn_hash_traverse (&hppa_info->dyn_hash_table, allocate_global_data_opd, &data); - hppa_info->opd_sec->_raw_size = data.ofs; + hppa_info->opd_sec->size = data.ofs; } /* Now allocate space for dynamic relocations, if necessary. */ @@ -1703,13 +1718,12 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) allocate_dynrel_entries, &data); /* The sizes of all the sections are set. Allocate memory for them. */ - plt = false; - relocs = false; - reltext = false; + plt = FALSE; + relocs = FALSE; + reltext = FALSE; for (s = dynobj->sections; s != NULL; s = s->next) { const char *name; - boolean strip; if ((s->flags & SEC_LINKER_CREATED) == 0) continue; @@ -1718,60 +1732,21 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) of the dynobj section names depend upon the input files. */ name = bfd_get_section_name (dynobj, s); - strip = 0; - if (strcmp (name, ".plt") == 0) { - /* Strip this section if we don't need it; see the comment below. */ - if (s->_raw_size == 0) - { - strip = true; - } - else - { - /* Remember whether there is a PLT. */ - plt = true; - } - } - else if (strcmp (name, ".dlt") == 0) - { - /* Strip this section if we don't need it; see the comment below. */ - if (s->_raw_size == 0) - { - strip = true; - } + /* Remember whether there is a PLT. */ + plt = s->size != 0; } - else if (strcmp (name, ".opd") == 0) + else if (strcmp (name, ".opd") == 0 + || CONST_STRNEQ (name, ".dlt") + || strcmp (name, ".stub") == 0 + || strcmp (name, ".got") == 0) { /* Strip this section if we don't need it; see the comment below. */ - if (s->_raw_size == 0) - { - strip = true; - } } - else if (strncmp (name, ".rela", 5) == 0) + else if (CONST_STRNEQ (name, ".rela")) { - /* If we don't need this section, strip it from the output file. - This is mostly to handle .rela.bss and .rela.plt. We must - create both sections in create_dynamic_sections, because they - must be created before the linker maps input sections to output - sections. The linker does that before adjust_dynamic_symbol - is called, and it is that function which decides whether - anything needs to go into these sections. */ - if (s->_raw_size == 0) - { - /* If we don't need this section, strip it from the - output file. This is mostly to handle .rela.bss and - .rela.plt. We must create both sections in - create_dynamic_sections, because they must be created - before the linker maps input sections to output - sections. The linker does that before - adjust_dynamic_symbol is called, and it is that - function which decides whether anything needs to go - into these sections. */ - strip = true; - } - else + if (s->size != 0) { asection *target; @@ -1781,7 +1756,7 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) { const char *outname; - relocs = true; + relocs = TRUE; /* If this relocation section applies to a read only section, then we probably need a DT_TEXTREL @@ -1794,7 +1769,7 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) if (target != NULL && (target->flags & SEC_READONLY) != 0 && (target->flags & SEC_ALLOC) != 0) - reltext = true; + reltext = TRUE; } /* We use the reloc_count field as a counter if we need @@ -1802,20 +1777,30 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) s->reloc_count = 0; } } - else if (strncmp (name, ".dlt", 4) != 0 - && strcmp (name, ".stub") != 0 - && strcmp (name, ".got") != 0) + else { /* It's not one of our sections, so don't allocate space. */ continue; } - if (strip) + if (s->size == 0) { - _bfd_strip_section_from_output (info, s); + /* If we don't need this section, strip it from the + output file. This is mostly to handle .rela.bss and + .rela.plt. We must create both sections in + create_dynamic_sections, because they must be created + before the linker maps input sections to output + sections. The linker does that before + adjust_dynamic_symbol is called, and it is that + function which decides whether anything needs to go + into these sections. */ + s->flags |= SEC_EXCLUDE; continue; } + if ((s->flags & SEC_HAS_CONTENTS) == 0) + continue; + /* Allocate memory for the section contents if it has not been allocated already. We use bfd_zalloc here in case unused entries are not reclaimed before the section's @@ -1824,9 +1809,9 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) garbage. */ if (s->contents == NULL) { - s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) - return false; + s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size); + if (s->contents == NULL) + return FALSE; } } @@ -1836,11 +1821,11 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) the PLT, it is how we communicate the __gp value of a load module to the dynamic linker. */ #define add_dynamic_entry(TAG, VAL) \ - bfd_elf64_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL)) + _bfd_elf_add_dynamic_entry (info, TAG, VAL) if (!add_dynamic_entry (DT_HP_DLD_FLAGS, 0) || !add_dynamic_entry (DT_PLTGOT, 0)) - return false; + return FALSE; /* Add some entries to the .dynamic section. We fill in the values later, in elf64_hppa_finish_dynamic_sections, but we @@ -1852,20 +1837,20 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) if (!add_dynamic_entry (DT_DEBUG, 0) || !add_dynamic_entry (DT_HP_DLD_HOOK, 0) || !add_dynamic_entry (DT_HP_LOAD_MAP, 0)) - return false; + return FALSE; } /* Force DT_FLAGS to always be set. Required by HPUX 11.00 patch PHSS_26559. */ if (!add_dynamic_entry (DT_FLAGS, (info)->flags)) - return false; + return FALSE; if (plt) { 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) @@ -1873,19 +1858,19 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) if (!add_dynamic_entry (DT_RELA, 0) || !add_dynamic_entry (DT_RELASZ, 0) || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela))) - return false; + return FALSE; } if (reltext) { if (!add_dynamic_entry (DT_TEXTREL, 0)) - return false; + return FALSE; info->flags |= DF_TEXTREL; } } #undef add_dynamic_entry - return true; + return TRUE; } /* Called after we have output the symbol into the dynamic symbol @@ -1897,13 +1882,13 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) the symbols have their expected value in the normal symbol table. Ick. */ -static boolean -elf64_hppa_link_output_symbol_hook (abfd, info, name, sym, input_sec) - bfd *abfd ATTRIBUTE_UNUSED; +static bfd_boolean +elf64_hppa_link_output_symbol_hook (info, name, sym, input_sec, h) struct bfd_link_info *info; const char *name; Elf_Internal_Sym *sym; asection *input_sec ATTRIBUTE_UNUSED; + struct elf_link_hash_entry *h; { struct elf64_hppa_link_hash_table *hppa_info; struct elf64_hppa_dyn_hash_entry *dyn_h; @@ -1911,12 +1896,14 @@ elf64_hppa_link_output_symbol_hook (abfd, info, name, sym, input_sec) /* We may be called with the file symbol or section symbols. They never need munging, so it is safe to ignore them. */ if (!name) - return true; + return TRUE; /* Get the PA dyn_symbol (if any) associated with NAME. */ hppa_info = elf64_hppa_hash_table (info); dyn_h = elf64_hppa_dyn_hash_lookup (&hppa_info->dyn_hash_table, - name, false, false); + name, FALSE, FALSE); + if (!dyn_h || dyn_h->h != h) + return TRUE; /* Function symbols for which we created .opd entries *may* have been munged by finish_dynamic_symbol and have to be un-munged here. @@ -1925,20 +1912,20 @@ elf64_hppa_link_output_symbol_hook (abfd, info, name, sym, input_sec) into non-dynamic ones, so we initialize st_shndx to -1 in mark_exported_functions and check to see if it was overwritten here instead of just checking dyn_h->h->dynindx. */ - if (dyn_h && dyn_h->want_opd && dyn_h->st_shndx != -1) + if (dyn_h->want_opd && dyn_h->st_shndx != -1) { /* Restore the saved value and section index. */ sym->st_value = dyn_h->st_value; sym->st_shndx = dyn_h->st_shndx; } - return true; + return TRUE; } /* Finish up dynamic symbol handling. We set the contents of various dynamic sections here. */ -static boolean +static bfd_boolean elf64_hppa_finish_dynamic_symbol (output_bfd, info, h, sym) bfd *output_bfd; struct bfd_link_info *info; @@ -1951,7 +1938,7 @@ elf64_hppa_finish_dynamic_symbol (output_bfd, info, h, sym) hppa_info = elf64_hppa_hash_table (info); dyn_h = elf64_hppa_dyn_hash_lookup (&hppa_info->dyn_hash_table, - h->root.root.string, false, false); + h->root.root.string, FALSE, FALSE); stub = hppa_info->stub_sec; splt = hppa_info->plt_sec; @@ -1969,7 +1956,7 @@ elf64_hppa_finish_dynamic_symbol (output_bfd, info, h, sym) the original values (in elf64_hppa_link_output_symbol_hook). */ if (dyn_h && dyn_h->want_opd) { - BFD_ASSERT (sopd != NULL) + BFD_ASSERT (sopd != NULL); /* Save away the original value and section index so that we can restore them later. */ @@ -1991,8 +1978,9 @@ elf64_hppa_finish_dynamic_symbol (output_bfd, info, h, sym) { bfd_vma value; Elf_Internal_Rela rel; + bfd_byte *loc; - BFD_ASSERT (splt != NULL && spltrel != NULL) + BFD_ASSERT (splt != NULL && spltrel != NULL); /* We do not actually care about the value in the PLT entry if we are creating a shared library and the symbol is @@ -2029,11 +2017,9 @@ elf64_hppa_finish_dynamic_symbol (output_bfd, info, h, sym) rel.r_info = ELF64_R_INFO (h->dynindx, R_PARISC_IPLT); rel.r_addend = 0; - bfd_elf64_swap_reloca_out (splt->output_section->owner, &rel, - (((Elf64_External_Rela *) - spltrel->contents) - + spltrel->reloc_count)); - spltrel->reloc_count++; + loc = spltrel->contents; + loc += spltrel->reloc_count++ * sizeof (Elf64_External_Rela); + bfd_elf64_swap_reloca_out (splt->output_section->owner, &rel, loc); } /* Initialize an external call stub entry if requested. */ @@ -2044,7 +2030,7 @@ elf64_hppa_finish_dynamic_symbol (output_bfd, info, h, sym) int insn; unsigned int max_offset; - BFD_ASSERT (stub != NULL) + BFD_ASSERT (stub != NULL); /* Install the generic stub template. @@ -2085,7 +2071,7 @@ elf64_hppa_finish_dynamic_symbol (output_bfd, info, h, sym) (*_bfd_error_handler) (_("stub entry for %s cannot load .plt, dp offset = %ld"), dyn_h->root.string, (long) value); - return false; + return FALSE; } bfd_put_32 (stub->owner, (bfd_vma) insn, @@ -2108,13 +2094,13 @@ elf64_hppa_finish_dynamic_symbol (output_bfd, info, h, sym) stub->contents + dyn_h->stub_offset + 8); } - return true; + return TRUE; } /* The .opd section contains FPTRs for each function this file exports. Initialize the FPTR entries. */ -static boolean +static bfd_boolean elf64_hppa_finalize_opd (dyn_h, data) struct elf64_hppa_dyn_hash_entry *dyn_h; PTR data; @@ -2156,7 +2142,8 @@ elf64_hppa_finalize_opd (dyn_h, data) had their address taken). */ if (info->shared && dyn_h && dyn_h->want_opd) { - Elf64_Internal_Rela rel; + Elf_Internal_Rela rel; + bfd_byte *loc; int dynindx; /* We may need to do a relocation against a local symbol, in @@ -2211,30 +2198,29 @@ elf64_hppa_finalize_opd (dyn_h, data) strcpy (new_name + 1, h->root.root.string); nh = elf_link_hash_lookup (elf_hash_table (info), - new_name, false, false, false); - + new_name, TRUE, TRUE, FALSE); + /* All we really want from the new symbol is its dynamic symbol index. */ - dynindx = nh->dynindx; + if (nh) + dynindx = nh->dynindx; } rel.r_addend = 0; rel.r_info = ELF64_R_INFO (dynindx, R_PARISC_EPLT); - bfd_elf64_swap_reloca_out (sopd->output_section->owner, &rel, - (((Elf64_External_Rela *) - sopdrel->contents) - + sopdrel->reloc_count)); - sopdrel->reloc_count++; + loc = sopdrel->contents; + loc += sopdrel->reloc_count++ * sizeof (Elf64_External_Rela); + bfd_elf64_swap_reloca_out (sopd->output_section->owner, &rel, loc); } - return true; + return TRUE; } /* The .dlt section contains addresses for items referenced through the dlt. Note that we can have a DLTIND relocation for a local symbol, thus we can not depend on finish_dynamic_symbol to initialize the .dlt. */ -static boolean +static bfd_boolean elf64_hppa_finalize_dlt (dyn_h, data) struct elf64_hppa_dyn_hash_entry *dyn_h; PTR data; @@ -2269,7 +2255,9 @@ elf64_hppa_finalize_dlt (dyn_h, data) + hppa_info->opd_sec->output_offset + hppa_info->opd_sec->output_section->vma); } - else if (h->root.u.def.section) + else if ((h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + && h->root.u.def.section) { value = h->root.u.def.value + h->root.u.def.section->output_offset; if (h->root.u.def.section->output_section) @@ -2286,12 +2274,13 @@ elf64_hppa_finalize_dlt (dyn_h, data) bfd_put_64 (sdlt->owner, value, sdlt->contents + dyn_h->dlt_offset); } - /* Create a relocation for the DLT entry assocated with this symbol. + /* 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 (dyn_h->want_dlt && (elf64_hppa_dynamic_symbol_p (dyn_h->h, info) || info->shared)) { - Elf64_Internal_Rela rel; + Elf_Internal_Rela rel; + bfd_byte *loc; int dynindx; /* We may need to do a relocation against a local symbol, in @@ -2315,19 +2304,17 @@ elf64_hppa_finalize_dlt (dyn_h, data) rel.r_info = ELF64_R_INFO (dynindx, R_PARISC_DIR64); rel.r_addend = 0; - bfd_elf64_swap_reloca_out (sdlt->output_section->owner, &rel, - (((Elf64_External_Rela *) - sdltrel->contents) - + sdltrel->reloc_count)); - sdltrel->reloc_count++; + loc = sdltrel->contents; + loc += sdltrel->reloc_count++ * sizeof (Elf64_External_Rela); + bfd_elf64_swap_reloca_out (sdlt->output_section->owner, &rel, loc); } - return true; + return TRUE; } /* Finalize the dynamic relocations. Specifically the FPTR relocations for dynamic functions used to initialize static data. */ -static boolean +static bfd_boolean elf64_hppa_finalize_dynreloc (dyn_h, data) struct elf64_hppa_dyn_hash_entry *dyn_h; PTR data; @@ -2340,7 +2327,7 @@ elf64_hppa_finalize_dynreloc (dyn_h, data) dynamic_symbol = elf64_hppa_dynamic_symbol_p (dyn_h->h, info); if (!dynamic_symbol && !info->shared) - return true; + return TRUE; if (dyn_h->reloc_entries) { @@ -2362,7 +2349,8 @@ elf64_hppa_finalize_dynreloc (dyn_h, data) for (rent = dyn_h->reloc_entries; rent; rent = rent->next) { - Elf64_Internal_Rela rel; + Elf_Internal_Rela rel; + bfd_byte *loc; /* 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. */ @@ -2429,16 +2417,15 @@ elf64_hppa_finalize_dynreloc (dyn_h, data) rel.r_info = ELF64_R_INFO (dynindx, rent->type); + 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, - (((Elf64_External_Rela *) - hppa_info->other_rel_sec->contents) - + hppa_info->other_rel_sec->reloc_count)); - hppa_info->other_rel_sec->reloc_count++; + &rel, loc); } } - return true; + return TRUE; } /* Used to decide how to sort relocs in an optimal manner for the @@ -2464,7 +2451,7 @@ elf64_hppa_reloc_type_class (rela) /* Finish up the dynamic sections. */ -static boolean +static bfd_boolean elf64_hppa_finish_dynamic_sections (output_bfd, info) bfd *output_bfd; struct bfd_link_info *info; @@ -2500,7 +2487,7 @@ elf64_hppa_finish_dynamic_sections (output_bfd, info) BFD_ASSERT (sdyn != NULL); dyncon = (Elf64_External_Dyn *) sdyn->contents; - dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size); + dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size); for (; dyncon < dynconend; dyncon++) { Elf_Internal_Dyn dyn; @@ -2539,15 +2526,15 @@ elf64_hppa_finish_dynamic_sections (output_bfd, info) case DT_PLTRELSZ: s = hppa_info->plt_rel_sec; - dyn.d_un.d_val = s->_raw_size; + dyn.d_un.d_val = s->size; bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon); break; case DT_RELA: s = hppa_info->other_rel_sec; - if (! s || ! s->_raw_size) + if (! s || ! s->size) s = hppa_info->dlt_rel_sec; - if (! s || ! s->_raw_size) + if (! s || ! s->size) s = hppa_info->opd_rel_sec; dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon); @@ -2555,16 +2542,16 @@ elf64_hppa_finish_dynamic_sections (output_bfd, info) case DT_RELASZ: s = hppa_info->other_rel_sec; - dyn.d_un.d_val = s->_raw_size; + dyn.d_un.d_val = s->size; s = hppa_info->dlt_rel_sec; - dyn.d_un.d_val += s->_raw_size; + dyn.d_un.d_val += s->size; s = hppa_info->opd_rel_sec; - dyn.d_un.d_val += s->_raw_size; + dyn.d_un.d_val += s->size; /* There is some question about whether or not the size of the PLT relocs should be included here. HP's tools do it, so we'll emulate them. */ s = hppa_info->plt_rel_sec; - dyn.d_un.d_val += s->_raw_size; + dyn.d_un.d_val += s->size; bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon); break; @@ -2572,7 +2559,69 @@ elf64_hppa_finish_dynamic_sections (output_bfd, info) } } - return true; + return TRUE; +} + +/* Support for core dump NOTE sections. */ + +static bfd_boolean +elf64_hppa_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) +{ + int offset; + size_t size; + + switch (note->descsz) + { + default: + return FALSE; + + case 760: /* 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 + 32); + + /* pr_reg */ + offset = 112; + size = 640; + + break; + } + + /* Make a ".reg/999" section. */ + return _bfd_elfcore_make_pseudosection (abfd, ".reg", + size, note->descpos + offset); +} + +static bfd_boolean +elf64_hppa_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) +{ + char * command; + int n; + + switch (note->descsz) + { + default: + return FALSE; + + case 136: /* Linux/hppa elf_prpsinfo. */ + elf_tdata (abfd)->core_program + = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16); + 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; + n = strlen (command); + + if (0 < n && command[n - 1] == ' ') + command[n - 1] = '\0'; + + return TRUE; } /* Return the number of additional phdrs we will need. @@ -2588,8 +2637,8 @@ elf64_hppa_finish_dynamic_sections (output_bfd, info) existence of a .interp section. */ static int -elf64_hppa_additional_program_headers (abfd) - bfd *abfd; +elf64_hppa_additional_program_headers (bfd *abfd, + struct bfd_link_info *info ATTRIBUTE_UNUSED) { asection *s; @@ -2614,9 +2663,9 @@ elf64_hppa_additional_program_headers (abfd) to guess whether or not we are building a shared library based on the existence of a .interp section. */ -static boolean -elf64_hppa_modify_segment_map (abfd) - bfd *abfd; +static bfd_boolean +elf64_hppa_modify_segment_map (bfd *abfd, + struct bfd_link_info *info ATTRIBUTE_UNUSED) { struct elf_segment_map *m; asection *s; @@ -2632,7 +2681,7 @@ elf64_hppa_modify_segment_map (abfd) 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; @@ -2663,7 +2712,7 @@ elf64_hppa_modify_segment_map (abfd) } } - return true; + return TRUE; } /* Called when writing out an object file to decide the type of a @@ -2679,6 +2728,66 @@ elf64_hppa_elf_get_symbol_type (elf_sym, type) return type; } +/* Support HP specific sections for core files. */ +static bfd_boolean +elf64_hppa_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int 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)) + return FALSE; + + sect = bfd_make_section_anyway (abfd, ".kernel"); + if (sect == NULL) + return FALSE; + sect->size = hdr->p_filesz; + sect->filepos = hdr->p_offset; + sect->flags = SEC_HAS_CONTENTS | SEC_READONLY; + return TRUE; + } + + if (hdr->p_type == PT_HP_CORE_PROC) + { + int sig; + + if (bfd_seek (abfd, hdr->p_offset, SEEK_SET) != 0) + return FALSE; + if (bfd_bread (&sig, 4, abfd) != 4) + return FALSE; + + elf_tdata (abfd)->core_signal = sig; + + if (!_bfd_elf_make_section_from_phdr (abfd, hdr, index, typename)) + return FALSE; + + /* GDB uses the ".reg" section to read register contents. */ + return _bfd_elfcore_make_pseudosection (abfd, ".reg", hdr->p_filesz, + hdr->p_offset); + } + + if (hdr->p_type == PT_HP_CORE_LOADABLE + || hdr->p_type == PT_HP_CORE_STACK + || hdr->p_type == PT_HP_CORE_MMF) + hdr->p_type = PT_LOAD; + + return _bfd_elf_make_section_from_phdr (abfd, hdr, index, typename); +} + +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 (".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 } +}; + /* The hash bucket size is the standard one, namely 4. */ const struct elf_size_info hppa64_elf_size_info = @@ -2693,10 +2802,11 @@ const struct elf_size_info hppa64_elf_size_info = sizeof (Elf_External_Note), 4, 1, - 64, 8, + 64, 3, ELFCLASS64, EV_CURRENT, bfd_elf64_write_out_phdrs, bfd_elf64_write_shdrs_and_ehdr, + bfd_elf64_checksum_contents, bfd_elf64_write_relocs, bfd_elf64_swap_symbol_in, bfd_elf64_swap_symbol_out, @@ -2704,10 +2814,10 @@ const struct elf_size_info hppa64_elf_size_info = bfd_elf64_slurp_symbol_table, bfd_elf64_swap_dyn_in, bfd_elf64_swap_dyn_out, - NULL, - NULL, - NULL, - NULL + bfd_elf64_swap_reloc_in, + bfd_elf64_swap_reloc_out, + bfd_elf64_swap_reloca_in, + bfd_elf64_swap_reloca_out }; #define TARGET_BIG_SYM bfd_elf64_hppa_vec @@ -2717,7 +2827,10 @@ const struct elf_size_info hppa64_elf_size_info = /* This is not strictly correct. The maximum page size for PA2.0 is 64M. But everything still uses 4k. */ #define ELF_MAXPAGESIZE 0x1000 +#define ELF_OSABI ELFOSABI_HPUX + #define bfd_elf64_bfd_reloc_type_lookup elf_hppa_reloc_type_lookup +#define bfd_elf64_bfd_reloc_name_lookup elf_hppa_reloc_name_lookup #define bfd_elf64_bfd_is_local_label_name elf_hppa_is_local_label_name #define elf_info_to_howto elf_hppa_info_to_howto #define elf_info_to_howto_rel elf_hppa_info_to_howto_rel @@ -2737,6 +2850,8 @@ const struct elf_size_info hppa64_elf_size_info = elf64_hppa_create_dynamic_sections #define elf_backend_post_process_headers elf64_hppa_post_process_headers +#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 @@ -2747,7 +2862,9 @@ const struct elf_size_info hppa64_elf_size_info = elf64_hppa_finish_dynamic_symbol #define elf_backend_finish_dynamic_sections \ 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 @@ -2771,11 +2888,15 @@ const struct elf_size_info hppa64_elf_size_info = #define elf_backend_plt_readonly 0 #define elf_backend_want_plt_sym 0 #define elf_backend_got_header_size 0 -#define elf_backend_plt_header_size 0 -#define elf_backend_type_change_ok true -#define elf_backend_get_symbol_type elf64_hppa_elf_get_symbol_type -#define elf_backend_reloc_type_class elf64_hppa_reloc_type_class -#define elf_backend_rela_normal 1 +#define elf_backend_type_change_ok TRUE +#define elf_backend_get_symbol_type elf64_hppa_elf_get_symbol_type +#define elf_backend_reloc_type_class elf64_hppa_reloc_type_class +#define elf_backend_rela_normal 1 +#define elf_backend_special_sections elf64_hppa_special_sections +#define elf_backend_action_discarded elf_hppa_action_discarded +#define elf_backend_section_from_phdr elf64_hppa_section_from_phdr + +#define elf64_bed elf64_hppa_hpux_bed #include "elf64-target.h" @@ -2783,6 +2904,11 @@ const struct elf_size_info hppa64_elf_size_info = #define TARGET_BIG_SYM bfd_elf64_hppa_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 +#undef elf64_bed +#define elf64_bed elf64_hppa_linux_bed -#define INCLUDED_TARGET_FILE 1 #include "elf64-target.h"