X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felfxx-ia64.c;h=481834bb4db5db9c16001271a43421d4ff3eba7a;hb=a4bd839069db2337a6d8e219782aff38875699a7;hp=5105c4ec1615fd29cb8c0c4de2b082f20b92e092;hpb=3e932841da51a1a0858cca9a9e496e10c717e00a;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index 5105c4ec16..481834bb4d 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -1,5 +1,5 @@ /* IA-64 support for 64-bit ELF - Copyright 1998, 1999, 2000 Free Software Foundation, Inc. + Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc. Contributed by David Mosberger-Tang This file is part of BFD, the Binary File Descriptor library. @@ -157,14 +157,26 @@ static void elfNN_ia64_info_to_howto static boolean elfNN_ia64_relax_section PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info, boolean *again)); +static boolean is_unwind_section_name + PARAMS ((const char *)); static boolean elfNN_ia64_section_from_shdr PARAMS ((bfd *, ElfNN_Internal_Shdr *, char *)); static boolean elfNN_ia64_fake_sections PARAMS ((bfd *abfd, ElfNN_Internal_Shdr *hdr, asection *sec)); +static void elfNN_ia64_final_write_processing + PARAMS ((bfd *abfd, boolean linker)); static 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 boolean elfNN_ia64_aix_vec + PARAMS ((const bfd_target *vec)); +static 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 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 boolean elfNN_ia64_is_local_label_name @@ -273,7 +285,6 @@ static boolean elfNN_ia64_merge_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd)); static boolean elfNN_ia64_print_private_bfd_data PARAMS ((bfd *abfd, PTR ptr)); - /* ia64-specific relocation */ @@ -349,6 +360,8 @@ static reloc_howto_type ia64_howto_table[] = IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, false, true), IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, false, true), + IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB, "LTOFF_FPTR32MSB", 2, false, true), + IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB, "LTOFF_FPTR32LSB", 2, false, true), IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, false, true), IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, false, true), @@ -469,6 +482,8 @@ elfNN_ia64_reloc_type_lookup (abfd, bfd_code) case BFD_RELOC_IA64_LTOFF_FPTR22: rtype = R_IA64_LTOFF_FPTR22; break; case BFD_RELOC_IA64_LTOFF_FPTR64I: rtype = R_IA64_LTOFF_FPTR64I; break; + case BFD_RELOC_IA64_LTOFF_FPTR32MSB: rtype = R_IA64_LTOFF_FPTR32MSB; break; + case BFD_RELOC_IA64_LTOFF_FPTR32LSB: rtype = R_IA64_LTOFF_FPTR32LSB; break; case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break; case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break; @@ -555,6 +570,9 @@ 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) /* Select out of range branch fixup type. Note that Itanium does not support brl, and so it gets emulated by the kernel. */ @@ -901,6 +919,22 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again) return false; } +/* Return true if NAME is an unwind table section name. */ + +static inline boolean +is_unwind_section_name (name) + const char *name; +{ + size_t len1, len2, len3; + + len1 = sizeof (ELF_STRING_ia64_unwind) - 1; + len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1; + len3 = sizeof (ELF_STRING_ia64_unwind_once) - 1; + return ((strncmp (name, ELF_STRING_ia64_unwind, len1) == 0 + && strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0) + || strncmp (name, ELF_STRING_ia64_unwind_once, len3) == 0); +} + /* Handle an IA-64 specific section when reading an object file. This is called when elfcode.h finds a section with an unknown type. */ @@ -920,8 +954,6 @@ elfNN_ia64_section_from_shdr (abfd, hdr, name) switch (hdr->sh_type) { case SHT_IA_64_UNWIND: - if (strcmp (name, ELF_STRING_ia64_unwind) != 0) - return false; break; case SHT_IA_64_EXT: @@ -969,8 +1001,13 @@ elfNN_ia64_fake_sections (abfd, hdr, sec) name = bfd_get_section_name (abfd, sec); - if (strcmp (name, ELF_STRING_ia64_unwind) == 0) - hdr->sh_type = SHT_IA_64_UNWIND; + if (is_unwind_section_name (name)) + { + /* We don't have the sections numbered at this point, so sh_info + is set later, in elfNN_ia64_final_write_processing. */ + hdr->sh_type = SHT_IA_64_UNWIND; + hdr->sh_flags |= SHF_LINK_ORDER; + } else if (strcmp (name, ELF_STRING_ia64_archext) == 0) hdr->sh_type = SHT_IA_64_EXT; else if (strcmp (name, ".reloc") == 0) @@ -1000,6 +1037,70 @@ elfNN_ia64_fake_sections (abfd, hdr, sec) return true; } +/* The final processing done just before writing out an IA-64 ELF + object file. */ + +static void +elfNN_ia64_final_write_processing (abfd, linker) + bfd *abfd; + boolean linker ATTRIBUTE_UNUSED; +{ + Elf_Internal_Shdr *hdr; + const char *sname; + asection *text_sect, *s; + size_t len; + + for (s = abfd->sections; s; s = s->next) + { + hdr = &elf_section_data (s)->this_hdr; + switch (hdr->sh_type) + { + case SHT_IA_64_UNWIND: + /* See comments in gas/config/tc-ia64.c:dot_endp on why we + have to do this. */ + sname = bfd_get_section_name (abfd, s); + len = sizeof (ELF_STRING_ia64_unwind) - 1; + if (sname && strncmp (sname, ELF_STRING_ia64_unwind, len) == 0) + { + sname += len; + + if (sname[0] == '\0') + /* .IA_64.unwind -> .text */ + text_sect = bfd_get_section_by_name (abfd, ".text"); + else + /* .IA_64.unwindFOO -> FOO */ + text_sect = bfd_get_section_by_name (abfd, sname); + } + else if (sname + && (len = sizeof (ELF_STRING_ia64_unwind_once) - 1, + strncmp (sname, ELF_STRING_ia64_unwind_once, len)) == 0) + { + /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */ + size_t len2 = sizeof (".gnu.linkonce.t.") - 1; + char *once_name = alloca (len2 + strlen (sname) - len + 1); + + memcpy (once_name, ".gnu.linkonce.t.", len2); + strcpy (once_name + len2, sname + len); + text_sect = bfd_get_section_by_name (abfd, once_name); + } + else + /* last resort: fall back on .text */ + text_sect = bfd_get_section_by_name (abfd, ".text"); + + if (text_sect) + { + /* The IA-64 processor-specific ABI requires setting + sh_link to the unwind section, whereas HP-UX requires + sh_info to do so. For maximum compatibility, we'll + set both for now... */ + hdr->sh_link = elf_section_data (text_sect)->this_idx; + hdr->sh_info = elf_section_data (text_sect)->this_idx; + } + break; + } + } +} + /* Hook called by the linker routine which adds symbols from an object file. We use it to put .comm items in .sbss, and not .bss. */ @@ -1039,6 +1140,111 @@ elfNN_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) return true; } +static 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 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 = (struct elf_link_hash_entry *) bfd_link_hash_lookup (info->hash, *namep, false, false, false); + if (h == NULL) + { + struct elf_backend_data *bed; + struct elfNN_ia64_link_hash_table *ia64_info; + + 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, (struct bfd_link_hash_entry **) &h))) + return false; + + 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) + { + 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_elfheader (abfd)->e_shnum; 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); + } +} + +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_elfNN_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 @@ -1053,10 +1259,10 @@ elfNN_ia64_additional_program_headers (abfd) if (s && (s->flags & SEC_LOAD)) ++ret; - /* See if we need a PT_IA_64_UNWIND segment. */ - s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind); - if (s && (s->flags & SEC_LOAD)) - ++ret; + /* Count how many PT_IA_64_UNWIND segments we need. */ + for (s = abfd->sections; s; s = s->next) + if (is_unwind_section_name(s->name) && (s->flags & SEC_LOAD)) + ++ret; return ret; } @@ -1066,6 +1272,7 @@ elfNN_ia64_modify_segment_map (abfd) bfd *abfd; { struct elf_segment_map *m, **pm; + Elf_Internal_Shdr *hdr; asection *s; /* If we need a PT_IA_64_ARCHEXT segment, it must come before @@ -1098,29 +1305,36 @@ elfNN_ia64_modify_segment_map (abfd) } } - /* Install the PT_IA_64_UNWIND segment, if needed. */ - s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind); - if (s && (s->flags & SEC_LOAD)) + /* Install PT_IA_64_UNWIND segments, if needed. */ + for (s = abfd->sections; s; s = s->next) { - for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) - if (m->p_type == PT_IA_64_UNWIND) - break; - if (m == NULL) + hdr = &elf_section_data (s)->this_hdr; + if (hdr->sh_type != SHT_IA_64_UNWIND) + continue; + + if (s && (s->flags & SEC_LOAD)) { - m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m); + for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) + if (m->p_type == PT_IA_64_UNWIND && m->sections[0] == s) + break; + if (m == NULL) - return false; + { + m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m); + if (m == NULL) + return false; - m->p_type = PT_IA_64_UNWIND; - m->count = 1; - m->sections[0] = s; - m->next = NULL; + m->p_type = PT_IA_64_UNWIND; + m->count = 1; + m->sections[0] = s; + m->next = NULL; - /* We want to put it last. */ - pm = &elf_tdata (abfd)->segment_map; - while (*pm != NULL) - pm = &(*pm)->next; - *pm = m; + /* We want to put it last. */ + pm = &elf_tdata (abfd)->segment_map; + while (*pm != NULL) + pm = &(*pm)->next; + *pm = m; + } } } @@ -1182,6 +1396,12 @@ elfNN_ia64_dynamic_symbol_p (h, info) if (h->dynindx == -1) return false; + switch (ELF_ST_VISIBILITY (h->other)) + { + case STV_INTERNAL: + case STV_HIDDEN: + return false; + } if (h->root.type == bfd_link_hash_undefweak || h->root.type == bfd_link_hash_defweak) @@ -1320,7 +1540,8 @@ elfNN_ia64_hash_hide_symbol (info, xh) h = (struct elfNN_ia64_link_hash_entry *)xh; h->root.elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; - h->root.dynindx = -1; + if ((h->root.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0) + h->root.dynindx = -1; for (dyn_i = h->info; dyn_i; dyn_i = dyn_i->next) dyn_i->want_plt2 = 0; @@ -1775,7 +1996,8 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs) maybe_dynamic = false; if (h && ((info->shared && ! info->symbolic) || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) - || h->root.type == bfd_link_hash_defweak)) + || h->root.type == bfd_link_hash_defweak + || elfNN_ia64_aix_vec (abfd->xvec))) maybe_dynamic = true; need_entry = 0; @@ -1789,6 +2011,8 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs) case R_IA64_LTOFF_FPTR22: case R_IA64_LTOFF_FPTR64I: + case R_IA64_LTOFF_FPTR32MSB: + case R_IA64_LTOFF_FPTR32LSB: case R_IA64_LTOFF_FPTR64MSB: case R_IA64_LTOFF_FPTR64LSB: need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR; @@ -1799,7 +2023,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) + if (info->shared || h || elfNN_ia64_aix_vec (abfd->xvec)) need_entry = NEED_FPTR | NEED_DYNREL; else need_entry = NEED_FPTR; @@ -1848,7 +2072,10 @@ 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) + if (info->shared || maybe_dynamic + || (elfNN_ia64_aix_vec (abfd->xvec) + && (!h || strcmp (h->root.root.string, + "__GLOB_DATA_PTR") != 0))) need_entry = NEED_DYNREL; dynrel_type = R_IA64_DIR64LSB; break; @@ -1912,7 +2139,9 @@ 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) + if (!h && (info->shared + /* AIX also needs one */ + || elfNN_ia64_aix_vec (abfd->xvec))) { if (! (_bfd_elfNN_link_record_local_dynamic_symbol (info, abfd, r_symndx))) @@ -1968,7 +2197,10 @@ allocate_global_data_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_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)))) { dyn_i->got_offset = x->ofs; x->ofs += 8; @@ -1987,7 +2219,8 @@ 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_dynamic_symbol_p (dyn_i->h, x->info) + || elfNN_ia64_aix_vec (x->info->hash->creator))) { dyn_i->got_offset = x->ofs; x->ofs += 8; @@ -2005,7 +2238,8 @@ allocate_local_got (dyn_i, data) struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data; if (dyn_i->want_got - && ! elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)) + && ! (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info) + || elfNN_ia64_aix_vec (x->info->hash->creator))) { dyn_i->got_offset = x->ofs; x->ofs += 8; @@ -2051,7 +2285,12 @@ 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->shared) + if (x->info->shared + /* 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 (h && h->dynindx == -1) { @@ -2174,7 +2413,11 @@ allocate_dynrel_entries (dyn_i, data) boolean dynamic_symbol, shared; ia64_info = elfNN_ia64_hash_table (x->info); - dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, 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)); shared = x->info->shared; /* Take care of the normal data relocations. */ @@ -2291,8 +2534,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 *) ELF_DYNAMIC_INTERPRETER; - sec->_raw_size = strlen (ELF_DYNAMIC_INTERPRETER) + 1; + sec->contents = (bfd_byte *) DYNAMIC_INTERPRETER (output_bfd); + sec->_raw_size = strlen (DYNAMIC_INTERPRETER (output_bfd)) + 1; } /* Allocate the GOT entries. */ @@ -2577,6 +2820,7 @@ elfNN_ia64_install_value (abfd, hit_addr, val, r_type) case R_IA64_GPREL32MSB: case R_IA64_FPTR32MSB: case R_IA64_PCREL32MSB: + case R_IA64_LTOFF_FPTR32MSB: case R_IA64_SEGREL32MSB: case R_IA64_SECREL32MSB: case R_IA64_LTV32MSB: @@ -2587,6 +2831,7 @@ elfNN_ia64_install_value (abfd, hit_addr, val, r_type) case R_IA64_GPREL32LSB: case R_IA64_FPTR32LSB: case R_IA64_PCREL32LSB: + case R_IA64_LTOFF_FPTR32LSB: case R_IA64_SEGREL32LSB: case R_IA64_SECREL32LSB: case R_IA64_LTV32LSB: @@ -2798,6 +3043,7 @@ set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type) /* Install a dynamic relocation if needed. */ if (info->shared || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info) + || elfNN_ia64_aix_vec (abfd->xvec) || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB)) { if (dynindx == -1) @@ -3071,6 +3317,13 @@ elfNN_ia64_final_link (abfd, info) } _bfd_set_gp_value (abfd, gp_val); + + if (gp) + { + gp->root.type = bfd_link_hash_defined; + gp->root.u.def.value = gp_val; + gp->root.u.def.section = bfd_abs_section_ptr; + } } /* If we're producing a final executable, we need to sort the contents @@ -3280,7 +3533,11 @@ 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) + 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))) && (input_section->flags & SEC_ALLOC) != 0) { unsigned int dyn_r_type; @@ -3332,6 +3589,8 @@ 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); @@ -3427,6 +3686,8 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section, case R_IA64_LTOFF_FPTR22: case R_IA64_LTOFF_FPTR64I: + case R_IA64_LTOFF_FPTR32MSB: + case R_IA64_LTOFF_FPTR32LSB: case R_IA64_LTOFF_FPTR64MSB: case R_IA64_LTOFF_FPTR64LSB: { @@ -3471,7 +3732,8 @@ 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) + if (dynamic_symbol_p + || elfNN_ia64_aix_vec (info->hash->creator)) { BFD_ASSERT (srel != NULL); @@ -4064,6 +4326,8 @@ elfNN_ia64_print_private_bfd_data (abfd, ptr) elfNN_ia64_section_flags #define elf_backend_fake_sections \ elfNN_ia64_fake_sections +#define elf_backend_final_write_processing \ + elfNN_ia64_final_write_processing #define elf_backend_add_symbol_hook \ elfNN_ia64_add_symbol_hook #define elf_backend_additional_program_headers \ @@ -4123,3 +4387,24 @@ elfNN_ia64_print_private_bfd_data (abfd, ptr) #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol #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 + +#include "elfNN-target.h"