X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf64-ppc.c;h=8e1935dfb9d1a941dcd3d97c18bfd54e9c66b7d1;hb=86fb1dece37497b267579ed4f062d280cd5760cd;hp=339d7f9dcc136bdfeac106a75b48b2a01fa04253;hpb=805fc79928c2c14c9223a18e8e1e0b94ccb58f16;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 339d7f9dcc..8e1935dfb9 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -55,20 +55,16 @@ static bfd_reloc_status_type ppc64_elf_toc64_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); static bfd_reloc_status_type ppc64_elf_unhandled_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static void ppc64_elf_get_symbol_info + PARAMS ((bfd *, asymbol *, symbol_info *)); static boolean ppc64_elf_set_private_flags PARAMS ((bfd *, flagword)); static boolean ppc64_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *)); static boolean ppc64_elf_section_from_shdr - PARAMS ((bfd *, Elf64_Internal_Shdr *, char *)); + PARAMS ((bfd *, Elf64_Internal_Shdr *, const char *)); -/* Mask to set RA in memory instructions. */ -#define RA_REGISTER_MASK 0x001f0000 - -/* Value to shift register by to insert RA. */ -#define RA_REGISTER_SHIFT 16 - /* The name of the dynamic interpreter. This is put in the .interp section. */ #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" @@ -112,7 +108,7 @@ static boolean ppc64_elf_section_from_shdr #define CROR_151515 0x4def7b82 #define CROR_313131 0x4ffffb82 -/* .glink entries for the first 32k functions are two instructions. */ +/* .glink entries for the first 32k functions are two instructions. */ #define LI_R0_0 0x38000000 /* li %r0,0 */ #define B_DOT 0x48000000 /* b . */ @@ -482,7 +478,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { 0, /* rightshift */ 4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */ 64, /* bitsize */ - true, /* pc_relative */ + false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ @@ -490,7 +486,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* partial_inplace */ 0, /* src_mask */ 0xffffffffffffffff, /* dst_mask */ - true), /* pcrel_offset */ + false), /* pcrel_offset */ /* Like R_PPC64_ADDR32, but may be unaligned. */ HOWTO (R_PPC64_UADDR32, /* type */ @@ -529,7 +525,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { 32, /* bitsize */ true, /* pc_relative */ 0, /* bitpos */ - /* FIXME: Verify. Was complain_overflow_bitfield. */ + /* FIXME: Verify. Was complain_overflow_bitfield. */ complain_overflow_signed, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_PPC64_REL32", /* name */ @@ -617,11 +613,11 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { 0xffff, /* dst_mask */ false), /* pcrel_offset */ - /* 32-bit section relative relocation. */ + /* 16-bit section relative relocation. */ HOWTO (R_PPC64_SECTOFF, /* type */ 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ @@ -629,10 +625,10 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { "R_PPC64_SECTOFF", /* name */ false, /* partial_inplace */ 0, /* src_mask */ - 0xffffffff, /* dst_mask */ + 0xffff, /* dst_mask */ false), /* pcrel_offset */ - /* 16-bit lower half section relative relocation. */ + /* Like R_PPC64_SECTOFF, but no overflow warning. */ HOWTO (R_PPC64_SECTOFF_LO, /* type */ 0, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ @@ -802,7 +798,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { 0xffffffffffffffff, /* dst_mask */ true), /* pcrel_offset */ - /* 64-bit relocation to the symbol's procedure linkage table. */ + /* 64-bit relocation to the symbol's procedure linkage table. */ HOWTO (R_PPC64_PLT64, /* type */ 0, /* rightshift */ 4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */ @@ -1072,8 +1068,8 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { /* Like R_PPC64_SECTOFF, but for instructions with a DS field. */ HOWTO (R_PPC64_SECTOFF_DS, /* type */ 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ @@ -1081,7 +1077,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { "R_PPC64_SECTOFF_DS", /* name */ false, /* partial_inplace */ 0, /* src_mask */ - 0xfffffffc, /* dst_mask */ + 0xfffc, /* dst_mask */ false), /* pcrel_offset */ /* Like R_PPC64_SECTOFF_LO, but for instructions with a DS field. */ @@ -1280,7 +1276,7 @@ ppc64_elf_reloc_type_lookup (abfd, code) break; case BFD_RELOC_HI16_S_PLTOFF: ppc_reloc = R_PPC64_PLT16_HA; break; - case BFD_RELOC_32_BASEREL: ppc_reloc = R_PPC64_SECTOFF; + case BFD_RELOC_16_BASEREL: ppc_reloc = R_PPC64_SECTOFF; break; case BFD_RELOC_LO16_BASEREL: ppc_reloc = R_PPC64_SECTOFF_LO; break; @@ -1365,8 +1361,8 @@ ppc64_elf_info_to_howto (abfd, cache_ptr, dst) { unsigned int type; + /* Initialize howto table if needed. */ if (!ppc64_elf_howto_table[R_PPC64_ADDR32]) - /* Initialize howto table if needed. */ ppc_howto_init (); type = ELF64_R_TYPE (dst->r_info); @@ -1392,7 +1388,7 @@ ppc64_elf_ha_reloc (abfd, reloc_entry, symbol, data, call the generic function. Any adjustment will be done at final link time. */ if (output_bfd != NULL) - return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message); /* Adjust the addend for sign extension of the low 16 bits. @@ -1423,7 +1419,7 @@ ppc64_elf_brtaken_reloc (abfd, reloc_entry, symbol, data, call the generic function. Any adjustment will be done at final link time. */ if (output_bfd != NULL) - return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message); octets = reloc_entry->address * bfd_octets_per_byte (abfd); @@ -1432,7 +1428,7 @@ ppc64_elf_brtaken_reloc (abfd, reloc_entry, symbol, data, r_type = (enum elf_ppc_reloc_type) reloc_entry->howto->type; if (r_type == R_PPC64_ADDR14_BRTAKEN || r_type == R_PPC64_REL14_BRTAKEN) - insn |= 0x01 << 21; /* 'y' or 't' bit, lowest bit of BO field. */ + insn |= 0x01 << 21; /* 'y' or 't' bit, lowest bit of BO field. */ if (is_power4) { @@ -1484,7 +1480,7 @@ ppc64_elf_sectoff_reloc (abfd, reloc_entry, symbol, data, call the generic function. Any adjustment will be done at final link time. */ if (output_bfd != NULL) - return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message); /* Subtract the symbol section base address. */ @@ -1507,7 +1503,7 @@ ppc64_elf_sectoff_ha_reloc (abfd, reloc_entry, symbol, data, call the generic function. Any adjustment will be done at final link time. */ if (output_bfd != NULL) - return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message); /* Subtract the symbol section base address. */ @@ -1535,7 +1531,7 @@ ppc64_elf_toc_reloc (abfd, reloc_entry, symbol, data, call the generic function. Any adjustment will be done at final link time. */ if (output_bfd != NULL) - return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message); TOCstart = _bfd_get_gp_value (input_section->output_section->owner); @@ -1564,7 +1560,7 @@ ppc64_elf_toc_ha_reloc (abfd, reloc_entry, symbol, data, call the generic function. Any adjustment will be done at final link time. */ if (output_bfd != NULL) - return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message); TOCstart = _bfd_get_gp_value (input_section->output_section->owner); @@ -1597,7 +1593,7 @@ ppc64_elf_toc64_reloc (abfd, reloc_entry, symbol, data, call the generic function. Any adjustment will be done at final link time. */ if (output_bfd != NULL) - return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message); TOCstart = _bfd_get_gp_value (input_section->output_section->owner); @@ -1624,7 +1620,7 @@ ppc64_elf_unhandled_reloc (abfd, reloc_entry, symbol, data, call the generic function. Any adjustment will be done at final link time. */ if (output_bfd != NULL) - return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message); if (error_message != NULL) @@ -1637,6 +1633,22 @@ ppc64_elf_unhandled_reloc (abfd, reloc_entry, symbol, data, return bfd_reloc_dangerous; } +/* Return symbol info as per usual for ELF targets, except that + symbols in .opd are given 'd' or 'D' for type. */ + +static void +ppc64_elf_get_symbol_info (abfd, symbol, ret) + bfd *abfd; + asymbol *symbol; + symbol_info *ret; +{ + _bfd_elf_get_symbol_info (abfd, symbol, ret); + if (ret->type == '?' + && (symbol->flags & (BSF_GLOBAL | BSF_LOCAL)) != 0 + && strcmp (symbol->section->name, ".opd") == 0) + ret->type = (symbol->flags & BSF_GLOBAL) != 0 ? 'D' : 'd'; +} + /* Function to set whether a module needs the -mrelocatable bit set. */ static boolean @@ -1763,7 +1775,7 @@ static boolean ppc64_elf_section_from_shdr (abfd, hdr, name) bfd *abfd; Elf64_Internal_Shdr *hdr; - char *name; + const char *name; { asection *newsect; flagword flags; @@ -2775,11 +2787,6 @@ ppc64_elf_check_relocs (abfd, info, sec, relocs) false, false, false); if (fdh != NULL) { - /* Ensure the function descriptor symbol string is - part of the code symbol string. We aren't - changing the name here, just allowing some tricks - in ppc64_elf_hide_symbol. */ - fdh->root.root.string = h->root.root.string + 1; ((struct ppc_link_hash_entry *) fdh)->is_func_descriptor = 1; ((struct ppc_link_hash_entry *) fdh)->oh = h; ((struct ppc_link_hash_entry *) h)->is_func = 1; @@ -3231,7 +3238,6 @@ func_desc_adjust (h, inf) } ((struct ppc_link_hash_entry *) fdh)->is_func_descriptor = 1; ((struct ppc_link_hash_entry *) fdh)->oh = h; - fdh->root.root.string = h->root.root.string + 1; ((struct ppc_link_hash_entry *) h)->oh = fdh; } @@ -3242,8 +3248,14 @@ func_desc_adjust (h, inf) been imported from another library. Function code syms that are really in the library we must leave global to prevent the linker dragging in a definition from a static library. */ - force_local = ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 - && info->shared); + force_local = (info->shared + && ((h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0 + || fdh == NULL + || (fdh->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0 + || (fdh->elf_link_hash_flags + & ELF_LINK_FORCED_LOCAL) != 0)); _bfd_elf_link_hash_hide_symbol (info, h, force_local); } @@ -3508,14 +3520,48 @@ ppc64_elf_hide_symbol (info, h, force_local) if (((struct ppc_link_hash_entry *) h)->is_func_descriptor) { - const char *name; struct elf_link_hash_entry *fh = ((struct ppc_link_hash_entry *) h)->oh; - struct ppc_link_hash_table *htab; - name = h->root.root.string - 1; - htab = ppc_hash_table (info); if (fh == NULL) - fh = elf_link_hash_lookup (&htab->elf, name, false, false, false); + { + const char *p, *q; + struct ppc_link_hash_table *htab; + char save; + + /* We aren't supposed to use alloca in BFD because on + systems which do not have alloca the version in libiberty + calls xmalloc, which might cause the program to crash + when it runs out of memory. This function doesn't have a + return status, so there's no way to gracefully return an + error. So cheat. We know that string[-1] can be safely + dereferenced; It's either a string in an ELF string + table, or allocated in an objalloc structure. */ + + p = h->root.root.string - 1; + save = *p; + *(char *) p = '.'; + htab = ppc_hash_table (info); + fh = elf_link_hash_lookup (&htab->elf, p, false, false, false); + *(char *) p = save; + + /* Unfortunately, if it so happens that the string we were + looking for was allocated immediately before this string, + then we overwrote the string terminator. That's the only + reason the lookup should fail. */ + if (fh == NULL) + { + q = h->root.root.string + strlen (h->root.root.string); + while (q >= h->root.root.string && *q == *p) + --q, --p; + if (q < h->root.root.string && *p == '.') + fh = elf_link_hash_lookup (&htab->elf, p, false, false, false); + } + if (fh != NULL) + { + ((struct ppc_link_hash_entry *) h)->oh = fh; + ((struct ppc_link_hash_entry *) fh)->oh = h; + } + } if (fh != NULL) _bfd_elf_link_hash_hide_symbol (info, fh, force_local); } @@ -3877,6 +3923,10 @@ ppc64_elf_size_dynamic_sections (output_bfd, info) continue; } + /* .plt is in the bss section. We don't initialise it. */ + if ((s->flags & SEC_LOAD) == 0) + continue; + /* Allocate memory for the section contents. We use bfd_zalloc here in case unused entries are not reclaimed before the section's contents are written out. This should not happen, @@ -3903,7 +3953,7 @@ ppc64_elf_size_dynamic_sections (output_bfd, info) return false; } - if (htab->splt->_raw_size != 0) + if (htab->splt != NULL && htab->splt->_raw_size != 0) { if (!add_dynamic_entry (DT_PLTGOT, 0) || !add_dynamic_entry (DT_PLTRELSZ, 0) @@ -4159,6 +4209,20 @@ ppc_build_one_stub (gen_entry, in_arg) htab->sglink->_cooked_size = p - htab->sglink->contents; htab->sglink->reloc_count += 1; + /* Do the best we can for shared libraries built without + exporting ".foo" for each "foo". This can happen when symbol + versioning scripts strip all bar a subset of symbols. */ + if (stub_entry->h->oh->root.type != bfd_link_hash_defined + && stub_entry->h->oh->root.type != bfd_link_hash_defweak) + { + /* Point the symbol at the stub. There may be multiple stubs, + we don't really care; The main thing is to make this sym + defined somewhere. */ + stub_entry->h->oh->root.type = bfd_link_hash_defined; + stub_entry->h->oh->root.u.def.section = stub_entry->stub_sec; + stub_entry->h->oh->root.u.def.value = stub_entry->stub_offset; + } + /* Now build the stub. */ off = stub_entry->h->elf.plt.offset; if (off >= (bfd_vma) -2) @@ -4268,7 +4332,7 @@ ppc_size_one_stub (gen_entry, in_arg) /* Set up various things so that we can make a list of input sections for each output section included in the link. Returns -1 on error, - 0 when no stubs will be needed, and 1 on success. */ + 0 when no stubs will be needed, and 1 on success. */ int ppc64_elf_setup_section_lists (output_bfd, info) @@ -4826,12 +4890,10 @@ ppc64_elf_size_stubs (output_bfd, stub_bfd, info, group_size, (*htab->layout_sections_again) (); } - if (htab->sbrlt->_raw_size == 0) - { - _bfd_strip_section_from_output (info, htab->sbrlt); - if (htab->srelbrlt != NULL) - _bfd_strip_section_from_output (info, htab->srelbrlt); - } + /* It would be nice to strip .branch_lt from the output if the + section is empty, but it's too late. If we strip sections here, + the dynamic symbol table is corrupted since the section symbol + for the stripped section isn't written. */ ret = true; @@ -5051,6 +5113,9 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, /* Disabled until we sort out how ld should choose 'y' vs 'at'. */ boolean is_power4 = false; + if (info->relocateable) + return true; + /* Initialize howto table if needed. */ if (!ppc64_elf_howto_table[R_PPC64_ADDR32]) ppc_howto_init (); @@ -5078,6 +5143,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, unsigned long r_symndx; bfd_vma relocation; boolean unresolved_reloc; + boolean warned; long insn; struct ppc_stub_hash_entry *stub_entry; bfd_vma max_br_offset; @@ -5085,27 +5151,6 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, r_type = (enum elf_ppc_reloc_type) ELF64_R_TYPE (rel->r_info); r_symndx = ELF64_R_SYM (rel->r_info); - - if (info->relocateable) - { - /* This is a relocatable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if ((unsigned) ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - sec = local_sections[r_symndx]; - rel->r_addend += sec->output_offset + sym->st_value; - } - } - continue; - } - - /* This is a final link. */ - offset = rel->r_offset; addend = rel->r_addend; r = bfd_reloc_other; @@ -5114,6 +5159,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, h = (struct elf_link_hash_entry *) 0; sym_name = (const char *) 0; unresolved_reloc = false; + warned = false; if (r_type == R_PPC64_TOC) { @@ -5128,6 +5174,8 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, sym_name = ""; relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); + /* rel may have changed, update our copy of addend. */ + addend = rel->r_addend; } else { @@ -5168,6 +5216,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, || info->no_undefined || ELF_ST_VISIBILITY (h->other))))) return false; + warned = true; } } @@ -5181,8 +5230,8 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, /* Branch taken prediction relocations. */ case R_PPC64_ADDR14_BRTAKEN: case R_PPC64_REL14_BRTAKEN: - insn = 0x01 << 21; /* 'y' or 't' bit, lowest bit of BO field. */ - /* Fall thru. */ + insn = 0x01 << 21; /* 'y' or 't' bit, lowest bit of BO field. */ + /* Fall thru. */ /* Branch not taken prediction relocations. */ case R_PPC64_ADDR14_BRNTAKEN: @@ -5564,6 +5613,16 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, relocate = true; if (r_type == R_PPC64_ADDR64 || r_type == R_PPC64_TOC) { + if (is_opd && h != NULL && info->shared) + { + /* Lie about opd entries. This case occurs + when building shared libraries and we + reference a function in another shared + lib. In that case we won't use the opd + entry in this lib; We ought to edit the + opd section to remove unused entries. */ + unresolved_reloc = false; + } outrel.r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE); } else @@ -5721,12 +5780,15 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, && !(info->shared && (input_section->flags & SEC_DEBUGGING) != 0 && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0)) - (*_bfd_error_handler) - (_("%s(%s+0x%lx): unresolvable relocation against symbol `%s'"), - bfd_archive_filename (input_bfd), - bfd_get_section_name (input_bfd, input_section), - (long) rel->r_offset, - h->root.root.string); + { + (*_bfd_error_handler) + (_("%s(%s+0x%lx): unresolvable relocation against symbol `%s'"), + bfd_archive_filename (input_bfd), + bfd_get_section_name (input_bfd, input_section), + (long) rel->r_offset, + h->root.root.string); + ret = false; + } r = _bfd_final_link_relocate (ppc64_elf_howto_table[(int) r_type], input_bfd, @@ -5736,9 +5798,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, relocation, addend); - if (r == bfd_reloc_ok) - ; - else if (r == bfd_reloc_overflow) + if (r != bfd_reloc_ok) { const char *name; @@ -5769,13 +5829,25 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, name = bfd_section_name (input_bfd, sec); } - if (! ((*info->callbacks->reloc_overflow) - (info, name, ppc64_elf_howto_table[(int) r_type]->name, - (bfd_vma) 0, input_bfd, input_section, offset))) - return false; + if (r == bfd_reloc_overflow) + { + if (warned) + continue; + if (!((*info->callbacks->reloc_overflow) + (info, name, ppc64_elf_howto_table[(int) r_type]->name, + rel->r_addend, input_bfd, input_section, offset))) + return false; + } + else + { + (*_bfd_error_handler) + (_("%s(%s+0x%lx): reloc against `%s': error %d"), + bfd_archive_filename (input_bfd), + bfd_get_section_name (input_bfd, input_section), + (long) rel->r_offset, name, (int) r); + ret = false; + } } - else - ret = false; } return ret; @@ -6051,12 +6123,14 @@ ppc64_elf_finish_dynamic_sections (output_bfd, info) #define elf_backend_plt_header_size PLT_INITIAL_ENTRY_SIZE #define elf_backend_can_gc_sections 1 #define elf_backend_can_refcount 1 +#define elf_backend_rela_normal 1 #define bfd_elf64_bfd_reloc_type_lookup ppc64_elf_reloc_type_lookup #define bfd_elf64_bfd_set_private_flags ppc64_elf_set_private_flags #define bfd_elf64_bfd_merge_private_bfd_data ppc64_elf_merge_private_bfd_data #define bfd_elf64_bfd_link_hash_table_create ppc64_elf_link_hash_table_create #define bfd_elf64_bfd_link_hash_table_free ppc64_elf_link_hash_table_free +#define bfd_elf64_get_symbol_info ppc64_elf_get_symbol_info #define elf_backend_section_from_shdr ppc64_elf_section_from_shdr #define elf_backend_create_dynamic_sections ppc64_elf_create_dynamic_sections