* elf-bfd.h (struct elf_backend_data): Add
elf_backend_archive_symbol_lookup. (_bfd_elf_archive_symbol_lookup): Declare. * elflink.c (_bfd_elf_archive_symbol_lookup): New function.. (elf_link_add_archive_symbols): ..extracted from here. Call the backend version. * elfxx-target.h (elf_backend_archive_symbol_lookup): Provide default. (elfNN_bed): Init new field. * elf64-ppc.c (elf_backend_check_directives): Define. (elf_backend_archive_symbol_lookup): Define. (struct ppc_link_hash_table): Add tls_get_add_fd. Make tls_get_add a ppc_link_hash_entry pointer. (get_fdh): Move. (ppc64_elf_archive_symbol_lookup, opd_entry_value): New functions. (add_symbol_adjust, ppc64_elf_check_directives): New functions. (ppc64_elf_check_relocs, ppc64_elf_gc_mark_hook, func_desc_adjust, ppc64_elf_adjust_dynamic_symbol, ppc64_elf_tls_setup, ppc64_elf_tls_optimize, allocate_dynrelocs, ppc_type_of_stub, ppc_build_one_stub, ppc64_elf_size_stubs, ppc64_elf_relocate_section, ppc64_elf_finish_dynamic_symbol): Handle branch relocs to function descriptor symbols.
This commit is contained in:
parent
fed7ba43e0
commit
8387904def
5 changed files with 498 additions and 153 deletions
|
@ -1,3 +1,27 @@
|
|||
2004-08-09 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf-bfd.h (struct elf_backend_data): Add
|
||||
elf_backend_archive_symbol_lookup.
|
||||
(_bfd_elf_archive_symbol_lookup): Declare.
|
||||
* elflink.c (_bfd_elf_archive_symbol_lookup): New function..
|
||||
(elf_link_add_archive_symbols): ..extracted from here. Call the
|
||||
backend version.
|
||||
* elfxx-target.h (elf_backend_archive_symbol_lookup): Provide default.
|
||||
(elfNN_bed): Init new field.
|
||||
* elf64-ppc.c (elf_backend_check_directives): Define.
|
||||
(elf_backend_archive_symbol_lookup): Define.
|
||||
(struct ppc_link_hash_table): Add tls_get_add_fd. Make tls_get_add
|
||||
a ppc_link_hash_entry pointer.
|
||||
(get_fdh): Move.
|
||||
(ppc64_elf_archive_symbol_lookup, opd_entry_value): New functions.
|
||||
(add_symbol_adjust, ppc64_elf_check_directives): New functions.
|
||||
(ppc64_elf_check_relocs, ppc64_elf_gc_mark_hook, func_desc_adjust,
|
||||
ppc64_elf_adjust_dynamic_symbol, ppc64_elf_tls_setup,
|
||||
ppc64_elf_tls_optimize, allocate_dynrelocs, ppc_type_of_stub,
|
||||
ppc_build_one_stub, ppc64_elf_size_stubs, ppc64_elf_relocate_section,
|
||||
ppc64_elf_finish_dynamic_symbol): Handle branch relocs to function
|
||||
descriptor symbols.
|
||||
|
||||
2004-08-09 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf64-ppc.c (struct ppc_link_hash_entry): Expand adjust_done comment.
|
||||
|
@ -21,7 +45,6 @@
|
|||
(ppc64_elf_mark_entry_syms): Delete.
|
||||
(ppc64_elf_gc_mark_hook): Mark entry syms here. Also mark opd
|
||||
sections. Use get_opd_info.
|
||||
|
||||
* elf64-ppc.h (ppc64_elf_mark_entry_syms): Delete.
|
||||
|
||||
2004-08-09 Alan Modra <amodra@bigpond.net.au>
|
||||
|
|
|
@ -579,11 +579,16 @@ struct elf_backend_data
|
|||
bfd_boolean (*elf_backend_symbol_table_processing)
|
||||
(bfd *, elf_symbol_type *, unsigned int);
|
||||
|
||||
/* A function to set the type of the info field. Processor-specific
|
||||
/* A function to set the type of the info field. Processor-specific
|
||||
types should be handled here. */
|
||||
int (*elf_backend_get_symbol_type)
|
||||
(Elf_Internal_Sym *, int);
|
||||
|
||||
/* A function to return the linker hash table entry of a symbol that
|
||||
might be satisfied by an archive symbol. */
|
||||
struct elf_link_hash_entry * (*elf_backend_archive_symbol_lookup)
|
||||
(bfd *, struct bfd_link_info *, const char *);
|
||||
|
||||
/* Return true if local section symbols should have a non-null st_name.
|
||||
NULL implies false. */
|
||||
bfd_boolean (*elf_backend_name_local_section_symbols)
|
||||
|
@ -1681,6 +1686,8 @@ extern void bfd_elf64_write_relocs
|
|||
extern bfd_boolean bfd_elf64_slurp_reloc_table
|
||||
(bfd *, asection *, asymbol **, bfd_boolean);
|
||||
|
||||
extern struct elf_link_hash_entry *_bfd_elf_archive_symbol_lookup
|
||||
(bfd *, struct bfd_link_info *, const char *);
|
||||
extern bfd_boolean bfd_elf_link_add_symbols
|
||||
(bfd *, struct bfd_link_info *);
|
||||
extern bfd_boolean _bfd_elf_add_dynamic_entry
|
||||
|
|
514
bfd/elf64-ppc.c
514
bfd/elf64-ppc.c
|
@ -83,6 +83,8 @@ static bfd_reloc_status_type ppc64_elf_unhandled_reloc
|
|||
#define elf_backend_create_dynamic_sections ppc64_elf_create_dynamic_sections
|
||||
#define elf_backend_copy_indirect_symbol ppc64_elf_copy_indirect_symbol
|
||||
#define elf_backend_add_symbol_hook ppc64_elf_add_symbol_hook
|
||||
#define elf_backend_check_directives ppc64_elf_check_directives
|
||||
#define elf_backend_archive_symbol_lookup ppc64_elf_archive_symbol_lookup
|
||||
#define elf_backend_check_relocs ppc64_elf_check_relocs
|
||||
#define elf_backend_gc_mark_hook ppc64_elf_gc_mark_hook
|
||||
#define elf_backend_gc_sweep_hook ppc64_elf_gc_sweep_hook
|
||||
|
@ -2569,7 +2571,11 @@ get_opd_info (asection * sec)
|
|||
creating a shared library containing foo, we need to have both symbols
|
||||
dynamic so that references to .foo are satisfied during the early
|
||||
stages of linking. Otherwise the linker might decide to pull in a
|
||||
definition from some other object, eg. a static library. */
|
||||
definition from some other object, eg. a static library.
|
||||
|
||||
Update: As of August 2004, we support a new convention. Function
|
||||
calls may use the function descriptor symbol, ie. "bl foo". This
|
||||
behaves exactly as "bl .foo". */
|
||||
|
||||
/* The linker needs to keep track of the number of relocs that it
|
||||
decides to copy as dynamic relocs in check_relocs for each symbol.
|
||||
|
@ -2857,8 +2863,9 @@ struct ppc_link_hash_table
|
|||
asection *brlt;
|
||||
asection *relbrlt;
|
||||
|
||||
/* Shortcut to .__tls_get_addr. */
|
||||
struct elf_link_hash_entry *tls_get_addr;
|
||||
/* Shortcut to .__tls_get_addr and __tls_get_addr. */
|
||||
struct ppc_link_hash_entry *tls_get_addr;
|
||||
struct ppc_link_hash_entry *tls_get_addr_fd;
|
||||
|
||||
/* Statistics. */
|
||||
unsigned long stub_count[ppc_stub_plt_call];
|
||||
|
@ -3463,7 +3470,49 @@ ppc64_elf_copy_indirect_symbol
|
|||
BFD_ASSERT (eind->elf.dynindx == -1);
|
||||
}
|
||||
|
||||
/* Hack symbols defined in .opd sections to be function type. */
|
||||
/* Find the function descriptor hash entry from the given function code
|
||||
hash entry FH. Link the entries via their OH fields. */
|
||||
|
||||
static struct ppc_link_hash_entry *
|
||||
get_fdh (struct ppc_link_hash_entry *fh, struct ppc_link_hash_table *htab)
|
||||
{
|
||||
struct ppc_link_hash_entry *fdh = fh->oh;
|
||||
|
||||
if (fdh == NULL)
|
||||
{
|
||||
const char *fd_name = fh->elf.root.root.string + 1;
|
||||
|
||||
fdh = (struct ppc_link_hash_entry *)
|
||||
elf_link_hash_lookup (&htab->elf, fd_name, FALSE, FALSE, FALSE);
|
||||
if (fdh != NULL)
|
||||
{
|
||||
fdh->is_func_descriptor = 1;
|
||||
fdh->oh = fh;
|
||||
fh->is_func = 1;
|
||||
fh->oh = fdh;
|
||||
}
|
||||
}
|
||||
|
||||
return fdh;
|
||||
}
|
||||
|
||||
/* Hacks to support old ABI code.
|
||||
When making function calls, old ABI code references function entry
|
||||
points (dot symbols), while new ABI code references the function
|
||||
descriptor symbol. We need to make any combination of reference and
|
||||
definition work together, without breaking archive linking.
|
||||
|
||||
For a defined function "foo" and an undefined call to "bar":
|
||||
An old object defines "foo" and ".foo", references ".bar" (possibly
|
||||
"bar" too).
|
||||
A new object defines "foo" and references "bar".
|
||||
|
||||
A new object thus has no problem with its undefined symbols being
|
||||
satisfied by definitions in an old object. On the other hand, the
|
||||
old object won't have ".bar" satisfied by a new object. */
|
||||
|
||||
/* Fix function descriptor symbols defined in .opd sections to be
|
||||
function type. */
|
||||
|
||||
static bfd_boolean
|
||||
ppc64_elf_add_symbol_hook (bfd *ibfd ATTRIBUTE_UNUSED,
|
||||
|
@ -3480,6 +3529,80 @@ ppc64_elf_add_symbol_hook (bfd *ibfd ATTRIBUTE_UNUSED,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* This function makes an old ABI object reference to ".bar" cause the
|
||||
inclusion of a new ABI object archive that defines "bar". */
|
||||
|
||||
static struct elf_link_hash_entry *
|
||||
ppc64_elf_archive_symbol_lookup (bfd *abfd,
|
||||
struct bfd_link_info *info,
|
||||
const char *name)
|
||||
{
|
||||
struct elf_link_hash_entry *h;
|
||||
char *dot_name;
|
||||
size_t len;
|
||||
|
||||
h = _bfd_elf_archive_symbol_lookup (abfd, info, name);
|
||||
if (h != NULL)
|
||||
return h;
|
||||
|
||||
if (name[0] == '.')
|
||||
return h;
|
||||
|
||||
len = strlen (name);
|
||||
dot_name = bfd_alloc (abfd, len + 2);
|
||||
if (dot_name == NULL)
|
||||
return (struct elf_link_hash_entry *) 0 - 1;
|
||||
dot_name[0] = '.';
|
||||
memcpy (dot_name + 1, name, len + 1);
|
||||
h = _bfd_elf_archive_symbol_lookup (abfd, info, dot_name);
|
||||
bfd_release (abfd, dot_name);
|
||||
return h;
|
||||
}
|
||||
|
||||
/* This function satisfies all old ABI object references to ".bar" if a
|
||||
new ABI object defines "bar". This stops later archive searches from
|
||||
including an object if we already have a function descriptor
|
||||
definition. It also prevents the linker complaining about undefined
|
||||
symbols. */
|
||||
|
||||
static bfd_boolean
|
||||
add_symbol_adjust (struct elf_link_hash_entry *h, void *inf)
|
||||
{
|
||||
struct bfd_link_info *info;
|
||||
struct ppc_link_hash_table *htab;
|
||||
struct ppc_link_hash_entry *fdh;
|
||||
|
||||
if (h->root.type == bfd_link_hash_indirect)
|
||||
return TRUE;
|
||||
|
||||
if (h->root.type == bfd_link_hash_warning)
|
||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||
|
||||
if (h->root.type != bfd_link_hash_undefined
|
||||
|| h->root.root.string[0] != '.')
|
||||
return TRUE;
|
||||
|
||||
info = inf;
|
||||
htab = ppc_hash_table (info);
|
||||
fdh = get_fdh ((struct ppc_link_hash_entry *) h, htab);
|
||||
if (fdh != NULL)
|
||||
{
|
||||
h->root.type = bfd_link_hash_defweak;
|
||||
h->root.u.def.section = &bfd_und_section;
|
||||
h->root.u.def.value = 0;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bfd_boolean
|
||||
ppc64_elf_check_directives (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
struct bfd_link_info *info)
|
||||
{
|
||||
struct ppc_link_hash_table *htab = ppc_hash_table (info);
|
||||
elf_link_hash_traverse (&htab->elf, add_symbol_adjust, info);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bfd_boolean
|
||||
update_local_sym_info (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
|
||||
unsigned long r_symndx, bfd_vma r_addend, int tls_type)
|
||||
|
@ -3553,31 +3676,6 @@ update_plt_info (bfd *abfd, struct ppc_link_hash_entry *eh, bfd_vma addend)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Find the function descriptor hash entry from the given function code
|
||||
hash entry FH. Link the entries via their OH fields. */
|
||||
static struct ppc_link_hash_entry *
|
||||
get_fdh (struct ppc_link_hash_entry *fh, struct ppc_link_hash_table *htab)
|
||||
{
|
||||
struct ppc_link_hash_entry *fdh = fh->oh;
|
||||
|
||||
if (fdh == NULL)
|
||||
{
|
||||
const char *fd_name = fh->elf.root.root.string + 1;
|
||||
|
||||
fdh = (struct ppc_link_hash_entry *)
|
||||
elf_link_hash_lookup (&htab->elf, fd_name, FALSE, FALSE, FALSE);
|
||||
if (fdh != NULL)
|
||||
{
|
||||
fdh->is_func_descriptor = 1;
|
||||
fdh->oh = fh;
|
||||
fh->is_func = 1;
|
||||
fh->oh = fdh;
|
||||
}
|
||||
}
|
||||
|
||||
return fdh;
|
||||
}
|
||||
|
||||
/* Look through the relocs for a section during the first phase, and
|
||||
calculate needed space in the global offset table, procedure
|
||||
linkage table, and dynamic reloc sections. */
|
||||
|
@ -3815,23 +3913,30 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||
/* Fall through. */
|
||||
|
||||
case R_PPC64_REL24:
|
||||
if (h != NULL
|
||||
&& h->root.root.string[0] == '.'
|
||||
&& h->root.root.string[1] != 0)
|
||||
if (h != NULL)
|
||||
{
|
||||
/* We may need a .plt entry if the function this reloc
|
||||
refers to is in a shared lib. */
|
||||
if (!update_plt_info (abfd, (struct ppc_link_hash_entry *) h,
|
||||
rel->r_addend))
|
||||
return FALSE;
|
||||
if (h == htab->tls_get_addr)
|
||||
if (h == &htab->tls_get_addr->elf
|
||||
|| h == &htab->tls_get_addr_fd->elf)
|
||||
sec->has_tls_reloc = 1;
|
||||
else if ((strncmp (h->root.root.string, ".__tls_get_addr", 15)
|
||||
== 0)
|
||||
else if (htab->tls_get_addr == NULL
|
||||
&& !strncmp (h->root.root.string, ".__tls_get_addr", 15)
|
||||
&& (h->root.root.string[15] == 0
|
||||
|| h->root.root.string[15] == '@'))
|
||||
{
|
||||
htab->tls_get_addr = h;
|
||||
htab->tls_get_addr = (struct ppc_link_hash_entry *) h;
|
||||
sec->has_tls_reloc = 1;
|
||||
}
|
||||
else if (htab->tls_get_addr_fd == NULL
|
||||
&& !strncmp (h->root.root.string, "__tls_get_addr", 14)
|
||||
&& (h->root.root.string[14] == 0
|
||||
|| h->root.root.string[14] == '@'))
|
||||
{
|
||||
htab->tls_get_addr_fd = (struct ppc_link_hash_entry *) h;
|
||||
sec->has_tls_reloc = 1;
|
||||
}
|
||||
}
|
||||
|
@ -3912,24 +4017,29 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||
|
||||
case R_PPC64_ADDR64:
|
||||
if (opd_sym_map != NULL
|
||||
&& h != NULL
|
||||
&& h->root.root.string[0] == '.'
|
||||
&& h->root.root.string[1] != 0)
|
||||
get_fdh ((struct ppc_link_hash_entry *) h, htab);
|
||||
|
||||
if (opd_sym_map != NULL
|
||||
&& h == NULL
|
||||
&& rel + 1 < rel_end
|
||||
&& ELF64_R_TYPE ((rel + 1)->r_info) == R_PPC64_TOC)
|
||||
{
|
||||
asection *s;
|
||||
if (h != NULL)
|
||||
{
|
||||
if (h->root.root.string[0] == '.'
|
||||
&& h->root.root.string[1] != 0
|
||||
&& get_fdh ((struct ppc_link_hash_entry *) h, htab))
|
||||
;
|
||||
else
|
||||
((struct ppc_link_hash_entry *) h)->is_func = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
asection *s;
|
||||
|
||||
s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, sec,
|
||||
r_symndx);
|
||||
if (s == NULL)
|
||||
return FALSE;
|
||||
else if (s != sec)
|
||||
opd_sym_map[rel->r_offset / 24] = s;
|
||||
s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, sec,
|
||||
r_symndx);
|
||||
if (s == NULL)
|
||||
return FALSE;
|
||||
else if (s != sec)
|
||||
opd_sym_map[rel->r_offset / 24] = s;
|
||||
}
|
||||
}
|
||||
/* Fall through. */
|
||||
|
||||
|
@ -4095,6 +4205,94 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* OFFSET in OPD_SEC specifies a function descriptor. Return the address
|
||||
of the code entry point, and its section. */
|
||||
|
||||
static bfd_vma
|
||||
opd_entry_value (asection *opd_sec,
|
||||
bfd_vma offset,
|
||||
asection **code_sec,
|
||||
bfd_vma *code_off)
|
||||
{
|
||||
bfd *opd_bfd = opd_sec->owner;
|
||||
Elf_Internal_Rela *lo, *hi, *look;
|
||||
|
||||
/* Go find the opd reloc at the sym address. */
|
||||
lo = _bfd_elf_link_read_relocs (opd_bfd, opd_sec, NULL, NULL, TRUE);
|
||||
BFD_ASSERT (lo != NULL);
|
||||
hi = lo + opd_sec->reloc_count - 1; /* ignore last reloc */
|
||||
|
||||
while (lo < hi)
|
||||
{
|
||||
look = lo + (hi - lo) / 2;
|
||||
if (look->r_offset < offset)
|
||||
lo = look + 1;
|
||||
else if (look->r_offset > offset)
|
||||
hi = look;
|
||||
else
|
||||
{
|
||||
Elf_Internal_Shdr *symtab_hdr = &elf_tdata (opd_bfd)->symtab_hdr;
|
||||
if (ELF64_R_TYPE (look->r_info) == R_PPC64_ADDR64
|
||||
&& ELF64_R_TYPE ((look + 1)->r_info) == R_PPC64_TOC)
|
||||
{
|
||||
unsigned long symndx = ELF64_R_SYM (look->r_info);
|
||||
bfd_vma val;
|
||||
asection *sec;
|
||||
|
||||
if (symndx < symtab_hdr->sh_info)
|
||||
{
|
||||
Elf_Internal_Sym *sym;
|
||||
|
||||
sym = (Elf_Internal_Sym *) symtab_hdr->contents;
|
||||
if (sym == NULL)
|
||||
{
|
||||
sym = bfd_elf_get_elf_syms (opd_bfd, symtab_hdr,
|
||||
symtab_hdr->sh_info,
|
||||
0, NULL, NULL, NULL);
|
||||
if (sym == NULL)
|
||||
return (bfd_vma) -1;
|
||||
symtab_hdr->contents = (bfd_byte *) sym;
|
||||
}
|
||||
|
||||
sym += symndx;
|
||||
val = sym->st_value;
|
||||
sec = NULL;
|
||||
if ((sym->st_shndx != SHN_UNDEF
|
||||
&& sym->st_shndx < SHN_LORESERVE)
|
||||
|| sym->st_shndx > SHN_HIRESERVE)
|
||||
sec = bfd_section_from_elf_index (opd_bfd, sym->st_shndx);
|
||||
BFD_ASSERT ((sec->flags & SEC_MERGE) == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct elf_link_hash_entry **sym_hashes;
|
||||
struct elf_link_hash_entry *rh;
|
||||
|
||||
sym_hashes = elf_sym_hashes (opd_bfd);
|
||||
rh = sym_hashes[symndx - symtab_hdr->sh_info];
|
||||
while (rh->root.type == bfd_link_hash_indirect
|
||||
|| rh->root.type == bfd_link_hash_warning)
|
||||
rh = ((struct elf_link_hash_entry *) rh->root.u.i.link);
|
||||
BFD_ASSERT (rh->root.type == bfd_link_hash_defined
|
||||
|| rh->root.type == bfd_link_hash_defweak);
|
||||
val = rh->root.u.def.value;
|
||||
sec = rh->root.u.def.section;
|
||||
}
|
||||
val += look->r_addend;
|
||||
if (code_off != NULL)
|
||||
*code_off = val;
|
||||
if (code_sec != NULL)
|
||||
*code_sec = sec;
|
||||
if (sec != NULL && sec->output_section != NULL)
|
||||
val += sec->output_section->vma + sec->output_offset;
|
||||
return val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (bfd_vma) -1;
|
||||
}
|
||||
|
||||
/* Return the section that should be marked against GC for a given
|
||||
relocation. */
|
||||
|
||||
|
@ -4128,6 +4326,11 @@ ppc64_elf_gc_mark_hook (asection *sec,
|
|||
|
||||
if (eh->is_func_descriptor)
|
||||
rsec = eh->oh->elf.root.u.def.section;
|
||||
else if (get_opd_info (eh->elf.root.u.def.section) != NULL
|
||||
&& opd_entry_value (eh->elf.root.u.def.section,
|
||||
eh->elf.root.u.def.value,
|
||||
&rsec, NULL) != (bfd_vma) -1)
|
||||
;
|
||||
else
|
||||
continue;
|
||||
|
||||
|
@ -4181,6 +4384,15 @@ ppc64_elf_gc_mark_hook (asection *sec,
|
|||
|
||||
rsec = eh->oh->elf.root.u.def.section;
|
||||
}
|
||||
else if (get_opd_info (eh->elf.root.u.def.section) != NULL
|
||||
&& opd_entry_value (eh->elf.root.u.def.section,
|
||||
eh->elf.root.u.def.value,
|
||||
&rsec, NULL) != (bfd_vma) -1)
|
||||
{
|
||||
if (!eh->elf.root.u.def.section->gc_mark)
|
||||
_bfd_elf_gc_mark (info, eh->elf.root.u.def.section,
|
||||
ppc64_elf_gc_mark_hook);
|
||||
}
|
||||
else
|
||||
rsec = h->root.u.def.section;
|
||||
break;
|
||||
|
@ -4445,7 +4657,11 @@ func_desc_adjust (struct elf_link_hash_entry *h, void *inf)
|
|||
| ELF_LINK_NON_GOT_REF));
|
||||
if (ELF_ST_VISIBILITY (fh->elf.other) == STV_DEFAULT)
|
||||
{
|
||||
fdh->elf.plt.plist = fh->elf.plt.plist;
|
||||
struct plt_entry **ep = &fdh->elf.plt.plist;
|
||||
while (*ep != NULL)
|
||||
ep = &(*ep)->next;
|
||||
*ep = fh->elf.plt.plist;
|
||||
fh->elf.plt.plist = NULL;
|
||||
fdh->elf.elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
|
||||
}
|
||||
fdh->is_func_descriptor = 1;
|
||||
|
@ -4606,8 +4822,7 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
|
|||
for (ent = h->plt.plist; ent != NULL; ent = ent->next)
|
||||
if (ent->plt.refcount > 0)
|
||||
break;
|
||||
if (!((struct ppc_link_hash_entry *) h)->is_func_descriptor
|
||||
|| ent == NULL
|
||||
if (ent == NULL
|
||||
|| SYMBOL_CALLS_LOCAL (info, h)
|
||||
|| (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
|
||||
&& h->root.type == bfd_link_hash_undefweak))
|
||||
|
@ -4939,8 +5154,7 @@ get_tls_mask (char **tls_maskp, unsigned long *toc_symndx,
|
|||
}
|
||||
|
||||
/* Adjust all global syms defined in opd sections. In gcc generated
|
||||
code these will already have been done, but I suppose we have to
|
||||
cater for all sorts of hand written assembly. */
|
||||
code for the old ABI, these will already have been done. */
|
||||
|
||||
static bfd_boolean
|
||||
adjust_opd_syms (struct elf_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
|
||||
|
@ -5301,13 +5515,29 @@ ppc64_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)
|
|||
htab = ppc_hash_table (info);
|
||||
if (htab->tls_get_addr != NULL)
|
||||
{
|
||||
struct elf_link_hash_entry *h = htab->tls_get_addr;
|
||||
struct ppc_link_hash_entry *h = htab->tls_get_addr;
|
||||
|
||||
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;
|
||||
while (h->elf.root.type == bfd_link_hash_indirect
|
||||
|| h->elf.root.type == bfd_link_hash_warning)
|
||||
h = (struct ppc_link_hash_entry *) h->elf.root.u.i.link;
|
||||
|
||||
htab->tls_get_addr = h;
|
||||
|
||||
if (htab->tls_get_addr_fd == NULL
|
||||
&& h->oh != NULL
|
||||
&& h->oh->is_func_descriptor)
|
||||
htab->tls_get_addr_fd = h->oh;
|
||||
}
|
||||
|
||||
if (htab->tls_get_addr_fd != NULL)
|
||||
{
|
||||
struct ppc_link_hash_entry *h = htab->tls_get_addr_fd;
|
||||
|
||||
while (h->elf.root.type == bfd_link_hash_indirect
|
||||
|| h->elf.root.type == bfd_link_hash_warning)
|
||||
h = (struct ppc_link_hash_entry *) h->elf.root.u.i.link;
|
||||
|
||||
htab->tls_get_addr_fd = h;
|
||||
}
|
||||
|
||||
return _bfd_elf_tls_setup (obfd, info);
|
||||
|
@ -5457,7 +5687,8 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
|
|||
case R_PPC64_REL14_BRNTAKEN:
|
||||
case R_PPC64_REL24:
|
||||
if (h != NULL
|
||||
&& h == htab->tls_get_addr)
|
||||
&& (h == &htab->tls_get_addr->elf
|
||||
|| h == &htab->tls_get_addr_fd->elf))
|
||||
{
|
||||
if (!expecting_tls_get_addr
|
||||
&& rel != relstart
|
||||
|
@ -5638,8 +5869,6 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
|||
for (pent = h->plt.plist; pent != NULL; pent = pent->next)
|
||||
if (pent->plt.refcount > 0)
|
||||
{
|
||||
BFD_ASSERT (((struct ppc_link_hash_entry *) h)->is_func_descriptor);
|
||||
|
||||
/* If this is the first .plt entry, make room for the special
|
||||
first entry. */
|
||||
s = htab->plt;
|
||||
|
@ -6164,14 +6393,18 @@ ppc_type_of_stub (asection *input_sec,
|
|||
if (h != NULL)
|
||||
{
|
||||
if (h->oh != NULL
|
||||
&& h->oh->elf.dynindx != -1)
|
||||
&& h->oh->is_func_descriptor)
|
||||
h = h->oh;
|
||||
|
||||
if (h->elf.dynindx != -1)
|
||||
{
|
||||
struct plt_entry *ent;
|
||||
for (ent = h->oh->elf.plt.plist; ent != NULL; ent = ent->next)
|
||||
|
||||
for (ent = h->elf.plt.plist; ent != NULL; ent = ent->next)
|
||||
if (ent->addend == rel->r_addend
|
||||
&& ent->plt.offset != (bfd_vma) -1)
|
||||
{
|
||||
*hash = h->oh;
|
||||
*hash = h;
|
||||
return ppc_stub_plt_call;
|
||||
}
|
||||
}
|
||||
|
@ -6377,7 +6610,8 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|||
/* 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->elf.root.type != bfd_link_hash_defined
|
||||
if (stub_entry->h->oh != NULL
|
||||
&& stub_entry->h->oh->elf.root.type != bfd_link_hash_defined
|
||||
&& stub_entry->h->oh->elf.root.type != bfd_link_hash_defweak)
|
||||
{
|
||||
/* Point the symbol at the stub. There may be multiple stubs,
|
||||
|
@ -6430,6 +6664,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|||
|
||||
if (htab->emit_stub_syms
|
||||
&& !(stub_entry->stub_type == ppc_stub_plt_call
|
||||
&& stub_entry->h->oh != NULL
|
||||
&& stub_entry->h->oh->elf.root.type == bfd_link_hash_defined
|
||||
&& stub_entry->h->oh->elf.root.u.def.section == stub_entry->stub_sec
|
||||
&& stub_entry->h->oh->elf.root.u.def.value == stub_entry->stub_offset))
|
||||
|
@ -6942,15 +7177,17 @@ ppc64_elf_size_stubs (bfd *output_bfd,
|
|||
unsigned int r_indx;
|
||||
enum ppc_stub_type stub_type;
|
||||
struct ppc_stub_hash_entry *stub_entry;
|
||||
asection *sym_sec;
|
||||
asection *sym_sec, *code_sec;
|
||||
bfd_vma sym_value;
|
||||
bfd_vma destination;
|
||||
bfd_boolean ok_dest;
|
||||
struct ppc_link_hash_entry *hash;
|
||||
struct ppc_link_hash_entry *fdh;
|
||||
struct elf_link_hash_entry *h;
|
||||
Elf_Internal_Sym *sym;
|
||||
char *stub_name;
|
||||
const asection *id_sec;
|
||||
long *opd_adjust;
|
||||
|
||||
r_type = ELF64_R_TYPE (irela->r_info);
|
||||
r_indx = ELF64_R_SYM (irela->r_info);
|
||||
|
@ -6976,18 +7213,35 @@ ppc64_elf_size_stubs (bfd *output_bfd,
|
|||
hash = (struct ppc_link_hash_entry *) h;
|
||||
|
||||
ok_dest = FALSE;
|
||||
fdh = NULL;
|
||||
if (hash == NULL)
|
||||
{
|
||||
/* It's a local symbol. */
|
||||
sym_value = sym->st_value;
|
||||
ok_dest = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It's an external symbol. */
|
||||
sym_value = 0;
|
||||
if (hash->elf.root.type == bfd_link_hash_defined
|
||||
|| hash->elf.root.type == bfd_link_hash_defweak)
|
||||
/* Recognise an old ABI func code entry sym by
|
||||
the weird section for a defined sym, and use
|
||||
the func descriptor sym instead. */
|
||||
if (hash->elf.root.type == bfd_link_hash_defweak
|
||||
&& hash->elf.root.u.def.section == &bfd_und_section
|
||||
&& hash->elf.root.root.string[0] == '.'
|
||||
&& (fdh = get_fdh (hash, htab)) != NULL)
|
||||
{
|
||||
sym_sec = NULL;
|
||||
if (fdh->elf.root.type == bfd_link_hash_defined
|
||||
|| fdh->elf.root.type == bfd_link_hash_defweak)
|
||||
{
|
||||
sym_sec = fdh->elf.root.u.def.section;
|
||||
sym_value = fdh->elf.root.u.def.value;
|
||||
if (sym_sec->output_section != NULL)
|
||||
ok_dest = TRUE;
|
||||
}
|
||||
}
|
||||
else if (hash->elf.root.type == bfd_link_hash_defined
|
||||
|| hash->elf.root.type == bfd_link_hash_defweak)
|
||||
{
|
||||
sym_value = hash->elf.root.u.def.value;
|
||||
if (sym_sec->output_section != NULL)
|
||||
|
@ -7013,6 +7267,34 @@ ppc64_elf_size_stubs (bfd *output_bfd,
|
|||
+ sym_sec->output_section->vma);
|
||||
}
|
||||
|
||||
code_sec = sym_sec;
|
||||
opd_adjust = get_opd_info (sym_sec);
|
||||
if (opd_adjust != NULL)
|
||||
{
|
||||
bfd_vma dest;
|
||||
|
||||
if (hash == NULL)
|
||||
{
|
||||
long adjust = opd_adjust[sym_value / 24];
|
||||
if (adjust == -1)
|
||||
continue;
|
||||
sym_value += adjust;
|
||||
}
|
||||
dest = opd_entry_value (sym_sec, sym_value,
|
||||
&code_sec, &sym_value);
|
||||
if (dest != (bfd_vma) -1)
|
||||
{
|
||||
destination = dest;
|
||||
if (fdh != NULL)
|
||||
{
|
||||
/* Fixup old ABI sym to point at code
|
||||
entry. */
|
||||
hash->elf.root.u.def.section = code_sec;
|
||||
hash->elf.root.u.def.value = sym_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine what (if any) linker stub is needed. */
|
||||
stub_type = ppc_type_of_stub (section, irela, &hash,
|
||||
destination);
|
||||
|
@ -7025,11 +7307,11 @@ ppc64_elf_size_stubs (bfd *output_bfd,
|
|||
_init and _fini functions, it may be that a
|
||||
call to what looks like a local sym is in
|
||||
fact a call needing a TOC adjustment. */
|
||||
if (sym_sec != NULL
|
||||
&& sym_sec->output_section != NULL
|
||||
&& (htab->stub_group[sym_sec->id].toc_off
|
||||
if (code_sec != NULL
|
||||
&& code_sec->output_section != NULL
|
||||
&& (htab->stub_group[code_sec->id].toc_off
|
||||
!= htab->stub_group[section->id].toc_off)
|
||||
&& sym_sec->has_gp_reloc
|
||||
&& code_sec->has_gp_reloc
|
||||
&& section->has_gp_reloc)
|
||||
stub_type = ppc_stub_long_branch_r2off;
|
||||
}
|
||||
|
@ -7040,7 +7322,8 @@ ppc64_elf_size_stubs (bfd *output_bfd,
|
|||
/* __tls_get_addr calls might be eliminated. */
|
||||
if (stub_type != ppc_stub_plt_call
|
||||
&& hash != NULL
|
||||
&& &hash->elf == htab->tls_get_addr
|
||||
&& (hash == htab->tls_get_addr
|
||||
|| hash == htab->tls_get_addr_fd)
|
||||
&& section->has_tls_reloc
|
||||
&& irela != internal_relocs)
|
||||
{
|
||||
|
@ -7088,7 +7371,7 @@ ppc64_elf_size_stubs (bfd *output_bfd,
|
|||
|
||||
stub_entry->stub_type = stub_type;
|
||||
stub_entry->target_value = sym_value;
|
||||
stub_entry->target_section = sym_sec;
|
||||
stub_entry->target_section = code_sec;
|
||||
stub_entry->h = hash;
|
||||
stub_entry->addend = irela->r_addend;
|
||||
stub_changed = TRUE;
|
||||
|
@ -7772,7 +8055,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||
while (h2->root.type == bfd_link_hash_indirect
|
||||
|| h2->root.type == bfd_link_hash_warning)
|
||||
h2 = (struct elf_link_hash_entry *) h2->root.u.i.link;
|
||||
if (h2 == NULL || h2 != htab->tls_get_addr)
|
||||
if (h2 == NULL || (h2 != &htab->tls_get_addr->elf
|
||||
&& h2 != &htab->tls_get_addr_fd->elf))
|
||||
break;
|
||||
|
||||
/* OK, it checks out. Replace the call. */
|
||||
|
@ -7908,10 +8192,12 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||
will be replaced with an instruction to restore the TOC
|
||||
base pointer. */
|
||||
stub_entry = NULL;
|
||||
fdh = h;
|
||||
if (((h != NULL
|
||||
&& (fdh = &((struct ppc_link_hash_entry *) h)->oh->elf) != NULL
|
||||
&& fdh->plt.plist != NULL)
|
||||
|| ((fdh = h, sec) != NULL
|
||||
&& (((fdh = &((struct ppc_link_hash_entry *) h)->oh->elf) != NULL
|
||||
&& fdh->plt.plist != NULL)
|
||||
|| (fdh = h)->plt.plist != NULL))
|
||||
|| (sec != NULL
|
||||
&& sec->output_section != NULL
|
||||
&& sec->id <= htab->top_id
|
||||
&& (htab->stub_group[sec->id].toc_off
|
||||
|
@ -7990,6 +8276,20 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||
unresolved_reloc = FALSE;
|
||||
}
|
||||
|
||||
if (stub_entry == NULL
|
||||
&& get_opd_info (sec) != NULL)
|
||||
{
|
||||
/* The branch destination is the value of the opd entry. */
|
||||
bfd_vma off = (relocation - sec->output_section->vma
|
||||
- sec->output_offset + rel->r_addend);
|
||||
bfd_vma dest = opd_entry_value (sec, off, NULL, NULL);
|
||||
if (dest != (bfd_vma) -1)
|
||||
{
|
||||
relocation = dest;
|
||||
addend = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the branch is out of reach we ought to have a long
|
||||
branch stub. */
|
||||
from = (rel->r_offset
|
||||
|
@ -8799,41 +9099,37 @@ ppc64_elf_finish_dynamic_symbol (bfd *output_bfd,
|
|||
{
|
||||
struct ppc_link_hash_table *htab;
|
||||
bfd *dynobj;
|
||||
struct plt_entry *ent;
|
||||
Elf_Internal_Rela rela;
|
||||
bfd_byte *loc;
|
||||
|
||||
htab = ppc_hash_table (info);
|
||||
dynobj = htab->elf.dynobj;
|
||||
|
||||
if (((struct ppc_link_hash_entry *) h)->is_func_descriptor)
|
||||
{
|
||||
struct plt_entry *ent;
|
||||
Elf_Internal_Rela rela;
|
||||
bfd_byte *loc;
|
||||
for (ent = h->plt.plist; ent != NULL; ent = ent->next)
|
||||
if (ent->plt.offset != (bfd_vma) -1)
|
||||
{
|
||||
/* This symbol has an entry in the procedure linkage
|
||||
table. Set it up. */
|
||||
|
||||
for (ent = h->plt.plist; ent != NULL; ent = ent->next)
|
||||
if (ent->plt.offset != (bfd_vma) -1)
|
||||
{
|
||||
/* This symbol has an entry in the procedure linkage
|
||||
table. Set it up. */
|
||||
if (htab->plt == NULL
|
||||
|| htab->relplt == NULL
|
||||
|| htab->glink == NULL)
|
||||
abort ();
|
||||
|
||||
if (htab->plt == NULL
|
||||
|| htab->relplt == NULL
|
||||
|| htab->glink == NULL)
|
||||
abort ();
|
||||
/* Create a JMP_SLOT reloc to inform the dynamic linker to
|
||||
fill in the PLT entry. */
|
||||
rela.r_offset = (htab->plt->output_section->vma
|
||||
+ htab->plt->output_offset
|
||||
+ ent->plt.offset);
|
||||
rela.r_info = ELF64_R_INFO (h->dynindx, R_PPC64_JMP_SLOT);
|
||||
rela.r_addend = ent->addend;
|
||||
|
||||
/* Create a JMP_SLOT reloc to inform the dynamic linker to
|
||||
fill in the PLT entry. */
|
||||
rela.r_offset = (htab->plt->output_section->vma
|
||||
+ htab->plt->output_offset
|
||||
+ ent->plt.offset);
|
||||
rela.r_info = ELF64_R_INFO (h->dynindx, R_PPC64_JMP_SLOT);
|
||||
rela.r_addend = ent->addend;
|
||||
|
||||
loc = htab->relplt->contents;
|
||||
loc += ((ent->plt.offset - PLT_INITIAL_ENTRY_SIZE) / PLT_ENTRY_SIZE
|
||||
* sizeof (Elf64_External_Rela));
|
||||
bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
|
||||
}
|
||||
}
|
||||
loc = htab->relplt->contents;
|
||||
loc += ((ent->plt.offset - PLT_INITIAL_ENTRY_SIZE) / PLT_ENTRY_SIZE
|
||||
* sizeof (Elf64_External_Rela));
|
||||
bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
|
||||
}
|
||||
|
||||
if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
|
||||
{
|
||||
|
|
|
@ -4194,6 +4194,55 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* Return the linker hash table entry of a symbol that might be
|
||||
satisfied by an archive symbol. Return -1 on error. */
|
||||
|
||||
struct elf_link_hash_entry *
|
||||
_bfd_elf_archive_symbol_lookup (bfd *abfd,
|
||||
struct bfd_link_info *info,
|
||||
const char *name)
|
||||
{
|
||||
struct elf_link_hash_entry *h;
|
||||
char *p, *copy;
|
||||
size_t len, first;
|
||||
|
||||
h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE);
|
||||
if (h != NULL)
|
||||
return h;
|
||||
|
||||
/* If this is a default version (the name contains @@), look up the
|
||||
symbol again with only one `@' as well as without the version.
|
||||
The effect is that references to the symbol with and without the
|
||||
version will be matched by the default symbol in the archive. */
|
||||
|
||||
p = strchr (name, ELF_VER_CHR);
|
||||
if (p == NULL || p[1] != ELF_VER_CHR)
|
||||
return h;
|
||||
|
||||
/* First check with only one `@'. */
|
||||
len = strlen (name);
|
||||
copy = bfd_alloc (abfd, len);
|
||||
if (copy == NULL)
|
||||
return (struct elf_link_hash_entry *) 0 - 1;
|
||||
|
||||
first = p - name + 1;
|
||||
memcpy (copy, name, first);
|
||||
memcpy (copy + first, name + first + 1, len - first);
|
||||
|
||||
h = elf_link_hash_lookup (elf_hash_table (info), copy, FALSE, FALSE, FALSE);
|
||||
if (h == NULL)
|
||||
{
|
||||
/* We also need to check references to the symbol without the
|
||||
version. */
|
||||
copy[first - 1] = '\0';
|
||||
h = elf_link_hash_lookup (elf_hash_table (info), copy,
|
||||
FALSE, FALSE, FALSE);
|
||||
}
|
||||
|
||||
bfd_release (abfd, copy);
|
||||
return h;
|
||||
}
|
||||
|
||||
/* Add symbols from an ELF archive file to the linker hash table. We
|
||||
don't use _bfd_generic_link_add_archive_symbols because of a
|
||||
problem which arises on UnixWare. The UnixWare libc.so is an
|
||||
|
@ -4228,6 +4277,9 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
|
|||
carsym *symdefs;
|
||||
bfd_boolean loop;
|
||||
bfd_size_type amt;
|
||||
const struct elf_backend_data *bed;
|
||||
struct elf_link_hash_entry * (*archive_symbol_lookup)
|
||||
(bfd *, struct bfd_link_info *, const char *);
|
||||
|
||||
if (! bfd_has_map (abfd))
|
||||
{
|
||||
|
@ -4252,6 +4304,8 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
|
|||
goto error_return;
|
||||
|
||||
symdefs = bfd_ardata (abfd)->symdefs;
|
||||
bed = get_elf_backend_data (abfd);
|
||||
archive_symbol_lookup = bed->elf_backend_archive_symbol_lookup;
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -4280,48 +4334,9 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
|
|||
continue;
|
||||
}
|
||||
|
||||
h = elf_link_hash_lookup (elf_hash_table (info), symdef->name,
|
||||
FALSE, FALSE, FALSE);
|
||||
|
||||
if (h == NULL)
|
||||
{
|
||||
char *p, *copy;
|
||||
size_t len, first;
|
||||
|
||||
/* If this is a default version (the name contains @@),
|
||||
look up the symbol again with only one `@' as well
|
||||
as without the version. The effect is that references
|
||||
to the symbol with and without the version will be
|
||||
matched by the default symbol in the archive. */
|
||||
|
||||
p = strchr (symdef->name, ELF_VER_CHR);
|
||||
if (p == NULL || p[1] != ELF_VER_CHR)
|
||||
continue;
|
||||
|
||||
/* First check with only one `@'. */
|
||||
len = strlen (symdef->name);
|
||||
copy = bfd_alloc (abfd, len);
|
||||
if (copy == NULL)
|
||||
goto error_return;
|
||||
first = p - symdef->name + 1;
|
||||
memcpy (copy, symdef->name, first);
|
||||
memcpy (copy + first, symdef->name + first + 1, len - first);
|
||||
|
||||
h = elf_link_hash_lookup (elf_hash_table (info), copy,
|
||||
FALSE, FALSE, FALSE);
|
||||
|
||||
if (h == NULL)
|
||||
{
|
||||
/* We also need to check references to the symbol
|
||||
without the version. */
|
||||
|
||||
copy[first - 1] = '\0';
|
||||
h = elf_link_hash_lookup (elf_hash_table (info),
|
||||
copy, FALSE, FALSE, FALSE);
|
||||
}
|
||||
|
||||
bfd_release (abfd, copy);
|
||||
}
|
||||
h = archive_symbol_lookup (abfd, info, symdef->name);
|
||||
if (h == (struct elf_link_hash_entry *) 0 - 1)
|
||||
goto error_return;
|
||||
|
||||
if (h == NULL)
|
||||
continue;
|
||||
|
|
|
@ -299,6 +299,9 @@
|
|||
#ifndef elf_backend_get_symbol_type
|
||||
#define elf_backend_get_symbol_type 0
|
||||
#endif
|
||||
#ifndef elf_backend_archive_symbol_lookup
|
||||
#define elf_backend_archive_symbol_lookup _bfd_elf_archive_symbol_lookup
|
||||
#endif
|
||||
#ifndef elf_backend_name_local_section_symbols
|
||||
#define elf_backend_name_local_section_symbols 0
|
||||
#endif
|
||||
|
@ -510,6 +513,7 @@ static const struct elf_backend_data elfNN_bed =
|
|||
elf_backend_symbol_processing,
|
||||
elf_backend_symbol_table_processing,
|
||||
elf_backend_get_symbol_type,
|
||||
elf_backend_archive_symbol_lookup,
|
||||
elf_backend_name_local_section_symbols,
|
||||
elf_backend_section_processing,
|
||||
elf_backend_section_from_shdr,
|
||||
|
|
Loading…
Reference in a new issue