X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=bfd%2Felf64-hppa.c;h=76dcc18b24362eaca542704ce26147386a6975fc;hb=72adc230457cc2885fe394ab4647dceab2d9d0aa;hp=4c88a543a37560a41fa3da8d545d7724e1210e1f;hpb=1049f94e8e1a9eae86a694d2dca94a6194f763b1;p=binutils-gdb.git diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c index 4c88a543a37..76dcc18b243 100644 --- a/bfd/elf64-hppa.c +++ b/bfd/elf64-hppa.c @@ -1,5 +1,6 @@ /* Support for HPPA 64-bit ELF - Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright 1999, 2000, 2001, 2002, 2003, 2004 + Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -173,7 +174,7 @@ static void elf64_hppa_dyn_hash_traverse 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 @@ -202,8 +203,8 @@ static bfd_boolean elf64_hppa_size_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); static bfd_boolean elf64_hppa_link_output_symbol_hook - PARAMS ((bfd *abfd, struct bfd_link_info *, const char *, - Elf_Internal_Sym *, asection *input_sec)); + PARAMS ((struct bfd_link_info *, const char *, Elf_Internal_Sym *, + asection *, struct elf_link_hash_entry *)); static bfd_boolean elf64_hppa_finish_dynamic_symbol PARAMS ((bfd *, struct bfd_link_info *, @@ -213,7 +214,7 @@ static int elf64_hppa_additional_program_headers PARAMS ((bfd *)); static bfd_boolean elf64_hppa_modify_segment_map - PARAMS ((bfd *)); + PARAMS ((bfd *, struct bfd_link_info *)); static enum elf_reloc_type_class elf64_hppa_reloc_type_class PARAMS ((const Elf_Internal_Rela *)); @@ -380,7 +381,10 @@ 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) + /* 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 @@ -443,13 +447,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; @@ -710,13 +715,14 @@ 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); @@ -746,7 +752,7 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs) this may help reduce memory usage and processing time later. */ maybe_dynamic = FALSE; if (h && ((info->shared - && (!info->symbolic || info->allow_shlib_undefined) ) + && (!info->symbolic || info->unresolved_syms_in_shared_libs == RM_IGNORE)) || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) || h->root.type == bfd_link_hash_defweak)) maybe_dynamic = TRUE; @@ -854,7 +860,7 @@ 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, @@ -927,7 +933,7 @@ 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; } @@ -956,33 +962,22 @@ 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; + /* ??? 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; - if (h->root.root.string[0] == '$' && h->root.root.string[1] == '$') + return TRUE; + } + else 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; - - 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 bfd_boolean @@ -1049,7 +1044,7 @@ 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; } @@ -1153,7 +1148,7 @@ allocate_global_data_opd (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; } @@ -1179,7 +1174,7 @@ allocate_global_data_opd (dyn_h, data) 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)) + if (! bfd_elf_link_record_dynamic_symbol (x->info, nh)) return FALSE; } @@ -1218,7 +1213,7 @@ elf64_hppa_post_process_headers (abfd, link_info) } /* 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. */ @@ -1515,7 +1510,7 @@ allocate_dynrel_entries (dyn_h, data) 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; } @@ -1649,7 +1644,7 @@ 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); @@ -1838,7 +1833,7 @@ 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)) @@ -1900,12 +1895,12 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) table. Ick. */ static bfd_boolean -elf64_hppa_link_output_symbol_hook (abfd, info, name, sym, input_sec) - bfd *abfd ATTRIBUTE_UNUSED; +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; @@ -1919,6 +1914,8 @@ elf64_hppa_link_output_symbol_hook (abfd, info, name, sym, input_sec) hppa_info = elf64_hppa_hash_table (info); dyn_h = elf64_hppa_dyn_hash_lookup (&hppa_info->dyn_hash_table, 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. @@ -1927,7 +1924,7 @@ 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; @@ -2269,7 +2266,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,7 +2285,7 @@ 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)) @@ -2614,8 +2613,9 @@ elf64_hppa_additional_program_headers (abfd) existence of a .interp section. */ static bfd_boolean -elf64_hppa_modify_segment_map (abfd) +elf64_hppa_modify_segment_map (abfd, info) bfd *abfd; + struct bfd_link_info *info ATTRIBUTE_UNUSED; { struct elf_segment_map *m; asection *s; @@ -2678,6 +2678,13 @@ elf64_hppa_elf_get_symbol_type (elf_sym, type) return type; } +static struct bfd_elf_special_section const elf64_hppa_special_sections[]= +{ + { ".fini", 5, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, + { ".init", 5, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, + { NULL, 0, 0, 0, 0 } +}; + /* The hash bucket size is the standard one, namely 4. */ const struct elf_size_info hppa64_elf_size_info = @@ -2770,11 +2777,11 @@ 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_special_sections elf64_hppa_special_sections #include "elf64-target.h" @@ -2783,5 +2790,7 @@ const struct elf_size_info hppa64_elf_size_info = #undef TARGET_BIG_NAME #define TARGET_BIG_NAME "elf64-hppa-linux" +#undef elf_backend_special_sections + #define INCLUDED_TARGET_FILE 1 #include "elf64-target.h"