diff options
Diffstat (limited to 'bfd/elf64-alpha.c')
-rw-r--r-- | bfd/elf64-alpha.c | 127 |
1 files changed, 73 insertions, 54 deletions
diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index 2c380d6..94b4ebe 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -324,14 +324,14 @@ elf64_alpha_bfd_link_hash_table_create (abfd) struct alpha_elf_link_hash_table *ret; bfd_size_type amt = sizeof (struct alpha_elf_link_hash_table); - ret = (struct alpha_elf_link_hash_table *) bfd_zalloc (abfd, amt); + ret = (struct alpha_elf_link_hash_table *) bfd_zmalloc (amt); if (ret == (struct alpha_elf_link_hash_table *) NULL) return NULL; if (! _bfd_elf_link_hash_table_init (&ret->root, abfd, elf64_alpha_link_hash_newfunc)) { - bfd_release (abfd, ret); + free (ret); return NULL; } @@ -2120,18 +2120,21 @@ elf64_alpha_output_extsym (h, data) boolean strip; asection *sec, *output_section; + if (h->root.root.type == bfd_link_hash_warning) + h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link; + if (h->root.indx == -2) strip = false; else if (((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - || (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0) - && (h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 - && (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) + || (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0) + && (h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 + && (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) strip = true; else if (einfo->info->strip == strip_all - || (einfo->info->strip == strip_some - && bfd_hash_lookup (einfo->info->keep_hash, - h->root.root.root.string, - false, false) == NULL)) + || (einfo->info->strip == strip_some + && bfd_hash_lookup (einfo->info->keep_hash, + h->root.root.root.string, + false, false) == NULL)) strip = true; else strip = false; @@ -2150,44 +2153,44 @@ elf64_alpha_output_extsym (h, data) h->esym.asym.st = stGlobal; if (h->root.root.type != bfd_link_hash_defined - && h->root.root.type != bfd_link_hash_defweak) - h->esym.asym.sc = scAbs; + && h->root.root.type != bfd_link_hash_defweak) + h->esym.asym.sc = scAbs; else - { - const char *name; - - sec = h->root.root.u.def.section; - output_section = sec->output_section; - - /* When making a shared library and symbol h is the one from - the another shared library, OUTPUT_SECTION may be null. */ - if (output_section == NULL) - h->esym.asym.sc = scUndefined; - else - { - name = bfd_section_name (output_section->owner, output_section); - - if (strcmp (name, ".text") == 0) - h->esym.asym.sc = scText; - else if (strcmp (name, ".data") == 0) - h->esym.asym.sc = scData; - else if (strcmp (name, ".sdata") == 0) - h->esym.asym.sc = scSData; - else if (strcmp (name, ".rodata") == 0 - || strcmp (name, ".rdata") == 0) - h->esym.asym.sc = scRData; - else if (strcmp (name, ".bss") == 0) - h->esym.asym.sc = scBss; - else if (strcmp (name, ".sbss") == 0) - h->esym.asym.sc = scSBss; - else if (strcmp (name, ".init") == 0) - h->esym.asym.sc = scInit; - else if (strcmp (name, ".fini") == 0) - h->esym.asym.sc = scFini; - else - h->esym.asym.sc = scAbs; - } - } + { + const char *name; + + sec = h->root.root.u.def.section; + output_section = sec->output_section; + + /* When making a shared library and symbol h is the one from + the another shared library, OUTPUT_SECTION may be null. */ + if (output_section == NULL) + h->esym.asym.sc = scUndefined; + else + { + name = bfd_section_name (output_section->owner, output_section); + + if (strcmp (name, ".text") == 0) + h->esym.asym.sc = scText; + else if (strcmp (name, ".data") == 0) + h->esym.asym.sc = scData; + else if (strcmp (name, ".sdata") == 0) + h->esym.asym.sc = scSData; + else if (strcmp (name, ".rodata") == 0 + || strcmp (name, ".rdata") == 0) + h->esym.asym.sc = scRData; + else if (strcmp (name, ".bss") == 0) + h->esym.asym.sc = scBss; + else if (strcmp (name, ".sbss") == 0) + h->esym.asym.sc = scSBss; + else if (strcmp (name, ".init") == 0) + h->esym.asym.sc = scInit; + else if (strcmp (name, ".fini") == 0) + h->esym.asym.sc = scFini; + else + h->esym.asym.sc = scAbs; + } + } h->esym.asym.reserved = 0; h->esym.asym.index = indexNil; @@ -2199,18 +2202,18 @@ elf64_alpha_output_extsym (h, data) || h->root.root.type == bfd_link_hash_defweak) { if (h->esym.asym.sc == scCommon) - h->esym.asym.sc = scBss; + h->esym.asym.sc = scBss; else if (h->esym.asym.sc == scSCommon) - h->esym.asym.sc = scSBss; + h->esym.asym.sc = scSBss; sec = h->root.root.u.def.section; output_section = sec->output_section; if (output_section != NULL) - h->esym.asym.value = (h->root.root.u.def.value - + sec->output_offset - + output_section->vma); + h->esym.asym.value = (h->root.root.u.def.value + + sec->output_offset + + output_section->vma); else - h->esym.asym.value = 0; + h->esym.asym.value = 0; } else if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) { @@ -2232,8 +2235,8 @@ elf64_alpha_output_extsym (h, data) } if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap, - h->root.root.root.string, - &h->esym)) + h->root.root.root.string, + &h->esym)) { einfo->failed = true; return false; @@ -2861,6 +2864,9 @@ elf64_alpha_calc_got_offsets_for_symbol (h, arg) { struct alpha_elf_got_entry *gotent; + if (h->root.root.type == bfd_link_hash_warning) + h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link; + for (gotent = h->got_entries; gotent; gotent = gotent->next) if (gotent->use_count > 0) { @@ -3038,6 +3044,9 @@ elf64_alpha_calc_dynrel_sizes (h, info) struct alpha_elf_link_hash_entry *h; struct bfd_link_info *info; { + if (h->root.root.type == bfd_link_hash_warning) + h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link; + /* If the symbol was defined as a common symbol in a regular object file, and there was no definition in any dynamic object, then the linker will have allocated space for the symbol in a common @@ -3686,6 +3695,16 @@ elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section, } goto default_reloc; + case R_ALPHA_SREL32: + case R_ALPHA_SREL64: + /* ??? .eh_frame references to discarded sections will be smashed + to relocations against SHN_UNDEF. The .eh_frame format allows + NULL to be encoded as 0 in any format, so this works here. */ + if (r_symndx == 0) + howto = (elf64_alpha_howto_table + + (r_type - R_ALPHA_SREL32 + R_ALPHA_REFLONG)); + goto default_reloc; + default: default_reloc: r = _bfd_final_link_relocate (howto, input_bfd, input_section, |