X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felfxx-ia64.c;h=ed626bfae3960316c7a73e48ca89570348cf1445;hb=3f7deb8a34ed3d6ad3e4b5194a9c0b697452ec6b;hp=c78abe7b13c6ba3f12eaf8dc9cdfade403be2e88;hpb=eff26f7814f8020f59ea8819f2cb836c4dba2f84;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index c78abe7b13..ed626bfae3 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -193,14 +193,6 @@ static bfd_boolean elfNN_ia64_add_symbol_hook PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym, const char **namep, flagword *flagsp, asection **secp, bfd_vma *valp)); -static bfd_boolean elfNN_ia64_aix_vec - PARAMS ((const bfd_target *vec)); -static bfd_boolean elfNN_ia64_aix_add_symbol_hook - PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym, - const char **namep, flagword *flagsp, asection **secp, - bfd_vma *valp)); -static bfd_boolean elfNN_ia64_aix_link_add_symbols - PARAMS ((bfd *abfd, struct bfd_link_info *info)); static int elfNN_ia64_additional_program_headers PARAMS ((bfd *abfd)); static bfd_boolean elfNN_ia64_modify_segment_map @@ -208,7 +200,7 @@ static bfd_boolean elfNN_ia64_modify_segment_map static bfd_boolean elfNN_ia64_is_local_label_name PARAMS ((bfd *abfd, const char *name)); static bfd_boolean elfNN_ia64_dynamic_symbol_p - PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info)); + PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info, int)); static bfd_boolean elfNN_ia64_local_hash_table_init PARAMS ((struct elfNN_ia64_local_hash_table *ht, bfd *abfd, new_hash_entry_func new)); @@ -219,7 +211,7 @@ static struct bfd_hash_entry *elfNN_ia64_new_elf_hash_entry PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table, const char *string)); static void elfNN_ia64_hash_copy_indirect - PARAMS ((struct elf_backend_data *, struct elf_link_hash_entry *, + PARAMS ((const struct elf_backend_data *, struct elf_link_hash_entry *, struct elf_link_hash_entry *)); static void elfNN_ia64_hash_hide_symbol PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean)); @@ -454,21 +446,21 @@ static reloc_howto_type ia64_howto_table[] = IA64_HOWTO (R_IA64_TPREL14, "TPREL14", 0, FALSE, FALSE), IA64_HOWTO (R_IA64_TPREL22, "TPREL22", 0, FALSE, FALSE), IA64_HOWTO (R_IA64_TPREL64I, "TPREL64I", 0, FALSE, FALSE), - IA64_HOWTO (R_IA64_TPREL64MSB, "TPREL64MSB", 8, FALSE, FALSE), - IA64_HOWTO (R_IA64_TPREL64LSB, "TPREL64LSB", 8, FALSE, FALSE), + IA64_HOWTO (R_IA64_TPREL64MSB, "TPREL64MSB", 4, FALSE, FALSE), + IA64_HOWTO (R_IA64_TPREL64LSB, "TPREL64LSB", 4, FALSE, FALSE), IA64_HOWTO (R_IA64_LTOFF_TPREL22, "LTOFF_TPREL22", 0, FALSE, FALSE), - IA64_HOWTO (R_IA64_DTPMOD64MSB, "TPREL64MSB", 8, FALSE, FALSE), - IA64_HOWTO (R_IA64_DTPMOD64LSB, "TPREL64LSB", 8, FALSE, FALSE), + IA64_HOWTO (R_IA64_DTPMOD64MSB, "TPREL64MSB", 4, FALSE, FALSE), + IA64_HOWTO (R_IA64_DTPMOD64LSB, "TPREL64LSB", 4, FALSE, FALSE), IA64_HOWTO (R_IA64_LTOFF_DTPMOD22, "LTOFF_DTPMOD22", 0, FALSE, FALSE), IA64_HOWTO (R_IA64_DTPREL14, "DTPREL14", 0, FALSE, FALSE), IA64_HOWTO (R_IA64_DTPREL22, "DTPREL22", 0, FALSE, FALSE), IA64_HOWTO (R_IA64_DTPREL64I, "DTPREL64I", 0, FALSE, FALSE), - IA64_HOWTO (R_IA64_DTPREL32MSB, "DTPREL32MSB", 4, FALSE, FALSE), - IA64_HOWTO (R_IA64_DTPREL32LSB, "DTPREL32LSB", 4, FALSE, FALSE), - IA64_HOWTO (R_IA64_DTPREL64MSB, "DTPREL64MSB", 8, FALSE, FALSE), - IA64_HOWTO (R_IA64_DTPREL64LSB, "DTPREL64LSB", 8, FALSE, FALSE), + IA64_HOWTO (R_IA64_DTPREL32MSB, "DTPREL32MSB", 2, FALSE, FALSE), + IA64_HOWTO (R_IA64_DTPREL32LSB, "DTPREL32LSB", 2, FALSE, FALSE), + IA64_HOWTO (R_IA64_DTPREL64MSB, "DTPREL64MSB", 4, FALSE, FALSE), + IA64_HOWTO (R_IA64_DTPREL64LSB, "DTPREL64LSB", 4, FALSE, FALSE), IA64_HOWTO (R_IA64_LTOFF_DTPREL22, "LTOFF_DTPREL22", 0, FALSE, FALSE), }; @@ -657,9 +649,6 @@ static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] = }; #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" -#define AIX_DYNAMIC_INTERPRETER "/usr/lib/ia64l64/libc.so.1" -#define DYNAMIC_INTERPRETER(abfd) \ - (elfNN_ia64_aix_vec (abfd->xvec) ? AIX_DYNAMIC_INTERPRETER : ELF_DYNAMIC_INTERPRETER) static const bfd_byte oor_brl[16] = { @@ -667,6 +656,28 @@ static const bfd_byte oor_brl[16] = 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */ 0x00, 0x00, 0x00, 0xc0 }; + +static const bfd_byte oor_ip[48] = +{ + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */ + 0x01, 0x00, 0x00, 0x60, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */ + 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */ + 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */ + 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */ + 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */ + 0x60, 0x00, 0x80, 0x00 /* br b6;; */ +}; + +static size_t oor_branch_size = sizeof (oor_brl); + +void +bfd_elfNN_ia64_after_parse (int itanium) +{ + oor_branch_size = itanium ? sizeof (oor_ip) : sizeof (oor_brl); +} + /* These functions do relaxation for IA-64 ELF. */ @@ -842,7 +853,7 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again) } /* Can't do anything else with dynamic symbols. */ - else if (elfNN_ia64_dynamic_symbol_p (h, link_info)) + else if (elfNN_ia64_dynamic_symbol_p (h, link_info, r_type)) continue; else @@ -902,9 +913,7 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again) if (tsec == ia64_info->plt_sec) size = sizeof (plt_full_entry); else - { - size = sizeof (oor_brl); - } + size = oor_branch_size; /* Resize the current section to make room for the new branch. */ trampoff = (sec->_cooked_size + 15) & (bfd_vma) -16; @@ -925,10 +934,22 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again) } else { - memcpy (contents + trampoff, oor_brl, size); - irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info), - R_IA64_PCREL60B); - irel->r_offset = trampoff + 2; + if (size == sizeof (oor_ip)) + { + memcpy (contents + trampoff, oor_ip, size); + irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info), + R_IA64_PCREL64I); + irel->r_addend -= 16; + irel->r_offset = trampoff + 2; + } + else + { + memcpy (contents + trampoff, oor_brl, size); + irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info), + R_IA64_PCREL60B); + irel->r_offset = trampoff + 2; + } + } /* Record the fixup so we don't do it again this section. */ @@ -1367,114 +1388,6 @@ elfNN_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) return TRUE; } -static bfd_boolean -elfNN_ia64_aix_vec (const bfd_target *vec) -{ - extern const bfd_target bfd_elfNN_ia64_aix_little_vec; - extern const bfd_target bfd_elfNN_ia64_aix_big_vec; - - return (/**/vec == & bfd_elfNN_ia64_aix_little_vec - || vec == & bfd_elfNN_ia64_aix_big_vec); -} - -/* Hook called by the linker routine which adds symbols from an object - file. We use it to handle OS-specific symbols. */ - -static bfd_boolean -elfNN_ia64_aix_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) - bfd *abfd; - struct bfd_link_info *info; - const Elf_Internal_Sym *sym; - const char **namep; - flagword *flagsp; - asection **secp; - bfd_vma *valp; -{ - if (strcmp (*namep, "__GLOB_DATA_PTR") == 0) - { - /* Define __GLOB_DATA_PTR when it is encountered. This is expected to - be a linker-defined symbol by the Aix C runtime startup code. IBM sez - no one else should use it b/c it is undocumented. */ - struct elf_link_hash_entry *h; - - h = elf_link_hash_lookup (elf_hash_table (info), *namep, - FALSE, FALSE, FALSE); - if (h == NULL) - { - struct elf_backend_data *bed; - struct elfNN_ia64_link_hash_table *ia64_info; - struct bfd_link_hash_entry *bh = NULL; - - bed = get_elf_backend_data (abfd); - ia64_info = elfNN_ia64_hash_table (info); - - if (!(_bfd_generic_link_add_one_symbol - (info, abfd, *namep, BSF_GLOBAL, - bfd_get_section_by_name (abfd, ".bss"), - bed->got_symbol_offset, (const char *) NULL, FALSE, - bed->collect, &bh))) - return FALSE; - - h = (struct elf_link_hash_entry *) bh; - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - h->type = STT_OBJECT; - - if (! _bfd_elf_link_record_dynamic_symbol (info, h)) - return FALSE; - } - - return TRUE; - } - else if (sym->st_shndx == SHN_LOOS) - { - unsigned int i; - - /* SHN_AIX_SYSCALL: Treat this as any other symbol. The special symbol - is only relevant when compiling code for extended system calls. - Replace the "special" section with .text, if possible. - Note that these symbols are always assumed to be in .text. */ - for (i = 1; i < elf_numsections (abfd); i++) - { - asection * sec = bfd_section_from_elf_index (abfd, i); - - if (sec && strcmp (sec->name, ".text") == 0) - { - *secp = sec; - break; - } - } - - if (*secp == NULL) - *secp = bfd_abs_section_ptr; - - *valp = sym->st_size; - - return TRUE; - } - else - { - return elfNN_ia64_add_symbol_hook (abfd, info, sym, - namep, flagsp, secp, valp); - } -} - -bfd_boolean -elfNN_ia64_aix_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - /* Make sure dynamic sections are always created. */ - if (! elf_hash_table (info)->dynamic_sections_created - && abfd->xvec == info->hash->creator) - { - if (! _bfd_elf_link_create_dynamic_sections (abfd, info)) - return FALSE; - } - - /* Now do the standard call. */ - return bfd_elfNN_bfd_link_add_symbols (abfd, info); -} - /* Return the number of additional phdrs we will need. */ static int @@ -1627,39 +1540,16 @@ elfNN_ia64_is_local_label_name (abfd, name) /* Should we do dynamic things to this symbol? */ static bfd_boolean -elfNN_ia64_dynamic_symbol_p (h, info) +elfNN_ia64_dynamic_symbol_p (h, info, r_type) struct elf_link_hash_entry *h; struct bfd_link_info *info; + int r_type; { - 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; - switch (ELF_ST_VISIBILITY (h->other)) - { - case STV_INTERNAL: - case STV_HIDDEN: - return FALSE; - default: - break; - } + bfd_boolean ignore_protected + = ((r_type & 0xf8) == 0x40 /* FPTR relocs */ + || (r_type & 0xf8) == 0x50); /* LTOFF_FPTR relocs */ - if (h->root.type == bfd_link_hash_undefweak - || h->root.type == bfd_link_hash_defweak) - return TRUE; - - if ((!info->executable && (!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; + return _bfd_elf_dynamic_symbol_p (h, info, ignore_protected); } static bfd_boolean @@ -1731,7 +1621,7 @@ elfNN_ia64_new_elf_hash_entry (entry, table, string) static void elfNN_ia64_hash_copy_indirect (bed, xdir, xind) - struct elf_backend_data *bed ATTRIBUTE_UNUSED; + const struct elf_backend_data *bed ATTRIBUTE_UNUSED; struct elf_link_hash_entry *xdir, *xind; { struct elfNN_ia64_link_hash_entry *dir, *ind; @@ -1923,6 +1813,8 @@ elfNN_ia64_create_dynamic_sections (abfd, info) { flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec); bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags); + /* The .got section is always aligned at 8 bytes. */ + bfd_set_section_alignment (abfd, ia64_info->got_sec, 3); } if (!get_pltoff (abfd, info, ia64_info)) @@ -2049,6 +1941,10 @@ get_got (abfd, info, ia64_info) BFD_ASSERT (got); ia64_info->got_sec = got; + /* The .got section is always aligned at 8 bytes. */ + if (!bfd_set_section_alignment (abfd, got, 3)) + return 0; + flags = bfd_get_section_flags (abfd, got); bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags); } @@ -2300,10 +2196,9 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs) this may help reduce memory usage and processing time later. */ maybe_dynamic = FALSE; if (h && ((!info->executable - && (!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 - || elfNN_ia64_aix_vec (abfd->xvec))) + || h->root.type == bfd_link_hash_defweak)) maybe_dynamic = TRUE; need_entry = 0; @@ -2360,7 +2255,7 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs) case R_IA64_FPTR32LSB: case R_IA64_FPTR64MSB: case R_IA64_FPTR64LSB: - if (info->shared || h || elfNN_ia64_aix_vec (abfd->xvec)) + if (info->shared || h) need_entry = NEED_FPTR | NEED_DYNREL; else need_entry = NEED_FPTR; @@ -2412,10 +2307,7 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs) case R_IA64_DIR64MSB: case R_IA64_DIR64LSB: /* Shared objects will always need at least a REL relocation. */ - if (info->shared || maybe_dynamic - || (elfNN_ia64_aix_vec (abfd->xvec) - && (!h || strcmp (h->root.root.string, - "__GLOB_DATA_PTR") != 0))) + if (info->shared || maybe_dynamic) need_entry = NEED_DYNREL; dynrel_type = R_IA64_DIR64LSB; break; @@ -2489,9 +2381,7 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs) /* FPTRs for shared libraries are allocated by the dynamic linker. Make sure this local symbol will appear in the dynamic symbol table. */ - if (!h && (info->shared - /* AIX also needs one */ - || elfNN_ia64_aix_vec (abfd->xvec))) + if (!h && info->shared) { if (! (_bfd_elfNN_link_record_local_dynamic_symbol (info, abfd, (long) r_symndx))) @@ -2541,10 +2431,7 @@ allocate_global_data_got (dyn_i, data) if ((dyn_i->want_got || dyn_i->want_gotx) && ! dyn_i->want_fptr - && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info) - || (elfNN_ia64_aix_vec (x->info->hash->creator) - && (!dyn_i->h || strcmp (dyn_i->h->root.root.string, - "__GLOB_DATA_PTR") != 0)))) + && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0)) { dyn_i->got_offset = x->ofs; x->ofs += 8; @@ -2556,7 +2443,7 @@ allocate_global_data_got (dyn_i, data) } if (dyn_i->want_dtpmod) { - if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)) + if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0)) { dyn_i->dtpmod_offset = x->ofs; x->ofs += 8; @@ -2593,8 +2480,7 @@ allocate_global_fptr_got (dyn_i, data) if (dyn_i->want_got && dyn_i->want_fptr - && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info) - || elfNN_ia64_aix_vec (x->info->hash->creator))) + && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, R_IA64_FPTR64LSB)) { dyn_i->got_offset = x->ofs; x->ofs += 8; @@ -2612,8 +2498,7 @@ allocate_local_got (dyn_i, data) struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data; if ((dyn_i->want_got || dyn_i->want_gotx) - && ! (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info) - || elfNN_ia64_aix_vec (x->info->hash->creator))) + && !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0)) { dyn_i->got_offset = x->ofs; x->ofs += 8; @@ -2659,15 +2544,10 @@ allocate_fptr (dyn_i, data) || h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; - if ((!x->info->executable - && (!h - || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT - || h->root.type != bfd_link_hash_undefweak)) - /* AIX needs an FPTR in this case. */ - || (elfNN_ia64_aix_vec (x->info->hash->creator) - && (!h - || h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak))) + if (!x->info->executable + && (!h + || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + || h->root.type != bfd_link_hash_undefweak)) { if (h && h->dynindx == -1) { @@ -2712,7 +2592,7 @@ allocate_plt_entries (dyn_i, data) h = (struct elf_link_hash_entry *) h->root.u.i.link; /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */ - if (elfNN_ia64_dynamic_symbol_p (h, x->info)) + if (elfNN_ia64_dynamic_symbol_p (h, x->info, 0)) { bfd_size_type offset = x->ofs; if (offset == 0) @@ -2790,11 +2670,10 @@ allocate_dynrel_entries (dyn_i, data) bfd_boolean dynamic_symbol, shared, resolved_zero; ia64_info = elfNN_ia64_hash_table (x->info); - dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info) - || (elfNN_ia64_aix_vec (x->info->hash->creator) - /* Don't allocate an entry for __GLOB_DATA_PTR */ - && (!dyn_i->h || strcmp (dyn_i->h->root.root.string, - "__GLOB_DATA_PTR") != 0)); + + /* Note that this can't be used in relation to FPTR relocs below. */ + dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0); + shared = x->info->shared; resolved_zero = (dyn_i->h && ELF_ST_VISIBILITY (dyn_i->h->other) @@ -2919,7 +2798,7 @@ elfNN_ia64_adjust_dynamic_symbol (info, h) static bfd_boolean elfNN_ia64_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; + bfd *output_bfd ATTRIBUTE_UNUSED; struct bfd_link_info *info; { struct elfNN_ia64_allocate_data data; @@ -2940,8 +2819,8 @@ elfNN_ia64_size_dynamic_sections (output_bfd, info) { sec = bfd_get_section_by_name (dynobj, ".interp"); BFD_ASSERT (sec != NULL); - sec->contents = (bfd_byte *) DYNAMIC_INTERPRETER (output_bfd); - sec->_raw_size = strlen (DYNAMIC_INTERPRETER (output_bfd)) + 1; + sec->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER; + sec->_raw_size = strlen (ELF_DYNAMIC_INTERPRETER) + 1; } /* Allocate the GOT entries. */ @@ -3482,8 +3361,7 @@ set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type) || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT || dyn_i->h->root.type != bfd_link_hash_undefweak) && dyn_r_type != R_IA64_DTPREL64LSB) - || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info) - || elfNN_ia64_aix_vec (abfd->xvec) + || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info, dyn_r_type) || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB)) && (!dyn_i->want_ltoff_fptr || !info->pie @@ -3948,7 +3826,6 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section, asection *sym_sec; bfd_byte *hit_addr; bfd_boolean dynamic_symbol_p; - bfd_boolean local_symbol_p; bfd_boolean undef_weak_ref; r_type = ELFNN_R_TYPE (rel->r_info); @@ -4009,62 +3886,24 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section, } else { - long indx; + bfd_boolean unresolved_reloc; + bfd_boolean warned; - /* Reloc against global symbol. */ - indx = r_symndx - symtab_hdr->sh_info; - h = elf_sym_hashes (input_bfd)[indx]; - 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; + RELOC_FOR_GLOBAL_SYMBOL (h, elf_sym_hashes (input_bfd), + r_symndx, + symtab_hdr, value, sym_sec, + unresolved_reloc, info, + warned); - value = 0; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sym_sec = h->root.u.def.section; - - /* Detect the cases that sym_sec->output_section is - expected to be NULL -- all cases in which the symbol - is defined in another shared module. This includes - PLT relocs for which we've created a PLT entry and - other relocs for which we're prepared to create - dynamic relocations. */ - /* ??? Just accept it NULL and continue. */ - - if (sym_sec->output_section != NULL) - { - value = (h->root.u.def.value - + sym_sec->output_section->vma - + sym_sec->output_offset); - } - } - else if (h->root.type == bfd_link_hash_undefweak) + if (h->root.type == bfd_link_hash_undefweak) undef_weak_ref = TRUE; - else if (! info->executable - && !info->no_undefined - && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - ; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, - (!info->shared || info->no_undefined - || ELF_ST_VISIBILITY (h->other))))) - return FALSE; - continue; - } + else if (warned) + continue; } hit_addr = contents + rel->r_offset; value += rel->r_addend; - dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info); - /* Is this symbol locally defined? A protected symbol is locallly - defined. But its function descriptor may not. Use it with - caution. */ - local_symbol_p = (! dynamic_symbol_p - || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT); + dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type); switch (r_type) { @@ -4080,11 +3919,7 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section, case R_IA64_DIR64MSB: case R_IA64_DIR64LSB: /* Install a dynamic relocation for this reloc. */ - if ((dynamic_symbol_p || info->shared - || (elfNN_ia64_aix_vec (info->hash->creator) - /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */ - && (!h || strcmp (h->root.root.string, - "__GLOB_DATA_PTR") != 0))) + if ((dynamic_symbol_p || info->shared) && r_symndx != 0 && (input_section->flags & SEC_ALLOC) != 0) { @@ -4097,7 +3932,7 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section, /* If we don't need dynamic symbol lookup, find a matching RELATIVE relocation. */ dyn_r_type = r_type; - if (! local_symbol_p) + if (dynamic_symbol_p) { dynindx = h->dynindx; addend = rel->r_addend; @@ -4137,8 +3972,6 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section, addend = value; } - if (elfNN_ia64_aix_vec (info->hash->creator)) - rel->r_addend = value; elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section, srel, rel->r_offset, dyn_r_type, dynindx, addend); @@ -4303,9 +4136,7 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section, case R_IA64_PCREL64MSB: case R_IA64_PCREL64LSB: /* Install a dynamic relocation for this reloc. */ - if ((dynamic_symbol_p - || elfNN_ia64_aix_vec (info->hash->creator)) - && r_symndx != 0) + if (dynamic_symbol_p && r_symndx != 0) { BFD_ASSERT (srel != NULL); @@ -4449,7 +4280,7 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section, /* If we don't need dynamic symbol lookup, install two RELATIVE relocations. */ - if (local_symbol_p) + if (!dynamic_symbol_p) { unsigned int dyn_r_type; @@ -4697,7 +4528,7 @@ elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym) loc = ia64_info->rel_pltoff_sec->contents; loc += ((ia64_info->rel_pltoff_sec->reloc_count + index) - * sizeof (Elf64_External_Rela)); + * sizeof (ElfNN_External_Rela)); bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc); } @@ -4947,6 +4778,13 @@ elfNN_ia64_reloc_type_class (rela) } } +static struct bfd_elf_special_section const elfNN_ia64_special_sections[]= +{ + { ".sbss", 5, -1, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT }, + { ".sdata", 6, -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT }, + { NULL, 0, 0, 0, 0 } +}; + static bfd_boolean elfNN_ia64_hpux_vec (const bfd_target *vec) { @@ -4978,6 +4816,23 @@ elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval) } return FALSE; } + +static void +elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, + asymbol *asym) +{ + elf_symbol_type *elfsym = (elf_symbol_type *) asym;; + + switch (elfsym->internal_elf_sym.st_shndx) + { + case SHN_IA_64_ANSI_COMMON: + asym->section = bfd_com_section_ptr; + asym->value = elfsym->internal_elf_sym.st_size; + asym->flags &= ~BSF_GLOBAL; + break; + } +} + #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec #define TARGET_LITTLE_NAME "elfNN-ia64-little" @@ -5054,27 +4909,7 @@ elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval) #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class #define elf_backend_rela_normal 1 - -#include "elfNN-target.h" - -/* AIX-specific vectors. */ - -#undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec -#undef TARGET_LITTLE_NAME -#define TARGET_LITTLE_NAME "elfNN-ia64-aix-little" -#undef TARGET_BIG_SYM -#define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec -#undef TARGET_BIG_NAME -#define TARGET_BIG_NAME "elfNN-ia64-aix-big" - -#undef elf_backend_add_symbol_hook -#define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook - -#undef bfd_elfNN_bfd_link_add_symbols -#define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols - -#define elfNN_bed elfNN_ia64_aix_bed +#define elf_backend_special_sections elfNN_ia64_special_sections #include "elfNN-target.h" @@ -5087,14 +4922,6 @@ elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval) #undef TARGET_BIG_NAME #define TARGET_BIG_NAME "elfNN-ia64-hpux-big" -/* We need to undo the AIX specific functions. */ - -#undef elf_backend_add_symbol_hook -#define elf_backend_add_symbol_hook elfNN_ia64_add_symbol_hook - -#undef bfd_elfNN_bfd_link_add_symbols -#define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols - /* These are HP-UX specific functions. */ #undef elf_backend_post_process_headers @@ -5103,6 +4930,9 @@ elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval) #undef elf_backend_section_from_bfd_section #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section +#undef elf_backend_symbol_processing +#define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing + #undef elf_backend_want_p_paddr_set_to_zero #define elf_backend_want_p_paddr_set_to_zero 1