mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-23 03:29:47 +08:00
* elfxx-mips.c (mips_elf_set_global_got_offset): Don't set no_fn_stub.
(mips_elf_set_no_stub): New function. (mips_elf_multi_got): Call it. (_bfd_mips_elf_finish_dynamic_symbol): If a relocation is needed for a secondary GOT entry, create an R_MIPS_32 or R_MIPS_64 relocation and use mips_elf_create_dynamic_relocation to deal with any compatibility issues. Store the adjusted addend in the GOT slot.
This commit is contained in:
@ -1,3 +1,14 @@
|
|||||||
|
2003-11-26 Daniel Jacobowitz <drow@mvista.com>
|
||||||
|
Richard Sandiford <rsandifo@redhat.com>
|
||||||
|
|
||||||
|
* elfxx-mips.c (mips_elf_set_global_got_offset): Don't set no_fn_stub.
|
||||||
|
(mips_elf_set_no_stub): New function.
|
||||||
|
(mips_elf_multi_got): Call it.
|
||||||
|
(_bfd_mips_elf_finish_dynamic_symbol): If a relocation is needed for
|
||||||
|
a secondary GOT entry, create an R_MIPS_32 or R_MIPS_64 relocation and
|
||||||
|
use mips_elf_create_dynamic_relocation to deal with any compatibility
|
||||||
|
issues. Store the adjusted addend in the GOT slot.
|
||||||
|
|
||||||
2003-11-25 Mattias Engdeg<65>rd <mattias@virtutech.se>
|
2003-11-25 Mattias Engdeg<65>rd <mattias@virtutech.se>
|
||||||
|
|
||||||
* stabs.c (_bfd_link_section_stabs): Skip N_EXCL stabs when
|
* stabs.c (_bfd_link_section_stabs): Skip N_EXCL stabs when
|
||||||
|
@ -471,6 +471,7 @@ static int mips_elf_bfd2got_entry_eq PARAMS ((const PTR, const PTR));
|
|||||||
static int mips_elf_make_got_per_bfd PARAMS ((void **, void *));
|
static int mips_elf_make_got_per_bfd PARAMS ((void **, void *));
|
||||||
static int mips_elf_merge_gots PARAMS ((void **, void *));
|
static int mips_elf_merge_gots PARAMS ((void **, void *));
|
||||||
static int mips_elf_set_global_got_offset PARAMS ((void**, void *));
|
static int mips_elf_set_global_got_offset PARAMS ((void**, void *));
|
||||||
|
static int mips_elf_set_no_stub PARAMS ((void **, void *));
|
||||||
static int mips_elf_resolve_final_got_entry PARAMS ((void**, void *));
|
static int mips_elf_resolve_final_got_entry PARAMS ((void**, void *));
|
||||||
static void mips_elf_resolve_final_got_entries
|
static void mips_elf_resolve_final_got_entries
|
||||||
PARAMS ((struct mips_got_info *));
|
PARAMS ((struct mips_got_info *));
|
||||||
@ -2338,10 +2339,6 @@ mips_elf_set_global_got_offset (entryp, p)
|
|||||||
BFD_ASSERT (g->global_gotsym == NULL);
|
BFD_ASSERT (g->global_gotsym == NULL);
|
||||||
|
|
||||||
entry->gotidx = arg->value * (long) g->assigned_gotno++;
|
entry->gotidx = arg->value * (long) g->assigned_gotno++;
|
||||||
/* We can't do lazy update of GOT entries for
|
|
||||||
non-primary GOTs since the PLT entries don't use the
|
|
||||||
right offsets, so punt at it for now. */
|
|
||||||
entry->d.h->no_fn_stub = TRUE;
|
|
||||||
if (arg->info->shared
|
if (arg->info->shared
|
||||||
|| (elf_hash_table (arg->info)->dynamic_sections_created
|
|| (elf_hash_table (arg->info)->dynamic_sections_created
|
||||||
&& ((entry->d.h->root.elf_link_hash_flags
|
&& ((entry->d.h->root.elf_link_hash_flags
|
||||||
@ -2357,6 +2354,23 @@ mips_elf_set_global_got_offset (entryp, p)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mark any global symbols referenced in the GOT we are iterating over
|
||||||
|
as inelligible for lazy resolution stubs. */
|
||||||
|
static int
|
||||||
|
mips_elf_set_no_stub (entryp, p)
|
||||||
|
void **entryp;
|
||||||
|
void *p ATTRIBUTE_UNUSED;
|
||||||
|
{
|
||||||
|
struct mips_got_entry *entry = (struct mips_got_entry *)*entryp;
|
||||||
|
|
||||||
|
if (entry->abfd != NULL
|
||||||
|
&& entry->symndx == -1
|
||||||
|
&& entry->d.h->root.dynindx != -1)
|
||||||
|
entry->d.h->no_fn_stub = TRUE;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Follow indirect and warning hash entries so that each got entry
|
/* Follow indirect and warning hash entries so that each got entry
|
||||||
points to the final symbol definition. P must point to a pointer
|
points to the final symbol definition. P must point to a pointer
|
||||||
to the hash table we're traversing. Since this traversal may
|
to the hash table we're traversing. Since this traversal may
|
||||||
@ -2624,6 +2638,11 @@ mips_elf_multi_got (abfd, info, g, got, pages)
|
|||||||
g->next = gg->next;
|
g->next = gg->next;
|
||||||
gg->next = g;
|
gg->next = g;
|
||||||
g = gn;
|
g = gn;
|
||||||
|
|
||||||
|
/* Mark global symbols in every non-primary GOT as ineligible for
|
||||||
|
stubs. */
|
||||||
|
if (g)
|
||||||
|
htab_traverse (g->got_entries, mips_elf_set_no_stub, NULL);
|
||||||
}
|
}
|
||||||
while (g);
|
while (g);
|
||||||
|
|
||||||
@ -6660,10 +6679,8 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
|
|||||||
if (g->next && h->dynindx != -1)
|
if (g->next && h->dynindx != -1)
|
||||||
{
|
{
|
||||||
struct mips_got_entry e, *p;
|
struct mips_got_entry e, *p;
|
||||||
|
bfd_vma entry;
|
||||||
bfd_vma offset;
|
bfd_vma offset;
|
||||||
bfd_vma value;
|
|
||||||
Elf_Internal_Rela rel[3];
|
|
||||||
bfd_vma addend = 0;
|
|
||||||
|
|
||||||
gg = g;
|
gg = g;
|
||||||
|
|
||||||
@ -6671,18 +6688,6 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
|
|||||||
e.symndx = -1;
|
e.symndx = -1;
|
||||||
e.d.h = (struct mips_elf_link_hash_entry *)h;
|
e.d.h = (struct mips_elf_link_hash_entry *)h;
|
||||||
|
|
||||||
if (info->shared
|
|
||||||
|| h->root.type == bfd_link_hash_undefined
|
|
||||||
|| h->root.type == bfd_link_hash_undefweak)
|
|
||||||
value = 0;
|
|
||||||
else if (sym->st_value)
|
|
||||||
value = sym->st_value;
|
|
||||||
else
|
|
||||||
value = h->root.u.def.value;
|
|
||||||
|
|
||||||
memset (rel, 0, sizeof (rel));
|
|
||||||
rel[0].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_REL32);
|
|
||||||
|
|
||||||
for (g = g->next; g->next != gg; g = g->next)
|
for (g = g->next; g->next != gg; g = g->next)
|
||||||
{
|
{
|
||||||
if (g->got_entries
|
if (g->got_entries
|
||||||
@ -6690,22 +6695,37 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
|
|||||||
&e)))
|
&e)))
|
||||||
{
|
{
|
||||||
offset = p->gotidx;
|
offset = p->gotidx;
|
||||||
rel[0].r_offset = rel[1].r_offset = rel[2].r_offset = offset;
|
if (info->shared
|
||||||
|
|
||||||
MIPS_ELF_PUT_WORD (output_bfd, value, sgot->contents + offset);
|
|
||||||
|
|
||||||
if ((info->shared
|
|
||||||
|| (elf_hash_table (info)->dynamic_sections_created
|
|| (elf_hash_table (info)->dynamic_sections_created
|
||||||
&& p->d.h != NULL
|
&& p->d.h != NULL
|
||||||
&& ((p->d.h->root.elf_link_hash_flags
|
&& ((p->d.h->root.elf_link_hash_flags
|
||||||
& ELF_LINK_HASH_DEF_DYNAMIC) != 0)
|
& ELF_LINK_HASH_DEF_DYNAMIC) != 0)
|
||||||
&& ((p->d.h->root.elf_link_hash_flags
|
&& ((p->d.h->root.elf_link_hash_flags
|
||||||
& ELF_LINK_HASH_DEF_REGULAR) == 0)))
|
& ELF_LINK_HASH_DEF_REGULAR) == 0)))
|
||||||
&& ! (mips_elf_create_dynamic_relocation
|
{
|
||||||
|
/* Create an R_MIPS_REL32 relocation for this entry. Due to
|
||||||
|
the various compatibility problems, it's easier to mock
|
||||||
|
up an R_MIPS_32 or R_MIPS_64 relocation and leave
|
||||||
|
mips_elf_create_dynamic_relocation to calculate the
|
||||||
|
appropriate addend. */
|
||||||
|
Elf_Internal_Rela rel[3];
|
||||||
|
|
||||||
|
memset (rel, 0, sizeof (rel));
|
||||||
|
if (ABI_64_P (output_bfd))
|
||||||
|
rel[0].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_64);
|
||||||
|
else
|
||||||
|
rel[0].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_32);
|
||||||
|
rel[0].r_offset = rel[1].r_offset = rel[2].r_offset = offset;
|
||||||
|
|
||||||
|
entry = 0;
|
||||||
|
if (! (mips_elf_create_dynamic_relocation
|
||||||
(output_bfd, info, rel,
|
(output_bfd, info, rel,
|
||||||
e.d.h, NULL, value, &addend, sgot)))
|
e.d.h, NULL, sym->st_value, &entry, sgot)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
BFD_ASSERT (addend == 0);
|
}
|
||||||
|
else
|
||||||
|
entry = sym->st_value;
|
||||||
|
MIPS_ELF_PUT_WORD (output_bfd, entry, sgot->contents + offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user