* elf32-mips.c (elf_backend_hide_symbol): Delete.
	* elfn32-mips.c (elf_backend_hide_symbol): Likewise.
	* elf64-mips.c (elf_backend_hide_symbol): Likewise.
	* elfxx-mips.h (elf_backend_hide_symbol): Likewise.
	* elfxx-mips.c (mips_elf_link_hash_entry): Remove "forced_local"
	and add "needs_lazy_stub".
	(mips_elf_link_hash_newfunc): Update accordingly.
	(mips_elf_link_hash_table): Remove "computed_got_sizes" and
	add "lazy_stub_count".
	(_bfd_mips_elf_link_hash_table_create): Update accordingly.
	(mips_elf_output_extsym): Use hd->needs_lazy_stub to detect
	cases where a lazy stub is being used.
	(mips_elf_sort_hash_table_f): Use h->root.forced_local instead
	of h->forced_local.
	(mips_elf_record_global_got_symbol): Use _bfd_elf_link_hash_hide_symbol
	instead of _bfd_mips_elf_hide_symbol.  Do not increment local_gotno
	here.
	(mips_elf_allocate_dynamic_relocations): Move before new first use.
	(mips_elf_check_recreate_got, mips_elf_recreate_got): New functions.
	(mips_elf_resolve_final_got_entries): Move earlier in file.  Make at
	most two passes over the hash table.  Use mips_elf_check_recreate_got
	to see if there are any indirect or warning entries and
	mips_elf_recreate_got to create a new GOT without them.
	Return a boolean success value.
	(mips_elf_count_forced_local_got_entries): New function.
	(mips_elf_make_got_per_bfd): Check h->root.forced_local instead of
	h->forced_local.
	(mips_elf_set_global_got_offset): Likewise.
	(mips_elf_set_no_stub): Replace with...
	(mips_elf_forbid_lazy_stubs): ...this new function.
	(mips_elf_resolve_final_got_entry): Delete.
	(mips_elf_multi_got): Fix formatting.  Use mips_elf_forbid_lazy_stubs
	instead of mips_elf_set_no_stub.  Move the code that sets
	global offsets and allocates dynamic relocations from the main
	_bfd_mips_elf_size_dynamic_sections loop to here.
	(_bfd_mips_elf_adjust_dynamic_symbol): Do not allocate room in
	.MIPS.stubs here; just set hmips->needs_lazy_stub and increment
	htab->lazy_stub_count.
	(_bfd_mips_elf_always_size_sections): Move the stub-estimation
	code to mips_elf_estimate_stub_size and the GOT-sizing code to
	mips_elf_lay_out_got.  Do not call these functions here.
	(mips_elf_estimate_stub_size): New function, split
	out from _bfd_mips_elf_always_size_sections.  Call
	mips_elf_resolve_final_got_entries earlier.  Count the number
	of forced-local entries.  Do not add stub sizes to loadable_size;
	after this patch, the stub sizes are already included in the main
	estimate.  Allocate dynamic relocations here rather than in the
	main _bfd_mips_elf_size_dynamic_sections loop.
	(mips_elf_estimate_stub_size): New function, split out from
	_bfd_mips_elf_always_size_sections.
	(mips_elf_allocate_lazy_stub): New function.
	(mips_elf_lay_out_lazy_stubs): Likewise.
	(_bfd_mips_elf_size_dynamic_sections): Call mips_elf_estimate_stub_size,
	mips_elf_lay_out_got and mips_elf_lay_out_lazy_stubs.  Do not handle
	the allocation of sreldyn specially.
	(_bfd_mips_elf_hide_symbol): Delete.

ld/testsuite/
	* ld-mips-elf/tlsdyn-o32-2.got, ld-mips-elf/tlsdyn-o32-3.got,
	ld-mips-elf/tlsdyn-o32-2.d, ld-mips-elf/tlsdyn-o32-3.d: Change the
	GOT layout as follows:

	         BEFORE                  AFTER
	   +0x08 %call16(__tls_get_addr) %call16(__tls_get_addr)
	   +0x0c %tlsldm(tlsbin_ld)      %gottprel(tlsvar_ie)
	   +0x10   "  "                  %tlsgd(tlsvar_gd)
	   +0x14 %tlsgd(tlsvar_gd)          "  "
	   +0x18   "  "                  %tlsgd(tlsbin_gd)
	   +0x1c %gottprel(tlsvar_ie)       "  "
	   +0x20 %tlsgd(tlsbin_gd)       %tlsldm(tlsbin_ld)
	   +0x24   "  "                     "  "
	   +0x28 %gottprel(tlsbin_ie)    %gottprel(tlsbin_ie)
This commit is contained in:
Richard Sandiford 2008-08-07 19:57:28 +00:00
parent 63897e2cf0
commit 33bb52fb4e
11 changed files with 513 additions and 452 deletions

View file

@ -1,3 +1,62 @@
2008-08-07 Richard Sandiford <rdsandiford@googlemail.com>
* elf32-mips.c (elf_backend_hide_symbol): Delete.
* elfn32-mips.c (elf_backend_hide_symbol): Likewise.
* elf64-mips.c (elf_backend_hide_symbol): Likewise.
* elfxx-mips.h (elf_backend_hide_symbol): Likewise.
* elfxx-mips.c (mips_elf_link_hash_entry): Remove "forced_local"
and add "needs_lazy_stub".
(mips_elf_link_hash_newfunc): Update accordingly.
(mips_elf_link_hash_table): Remove "computed_got_sizes" and
add "lazy_stub_count".
(_bfd_mips_elf_link_hash_table_create): Update accordingly.
(mips_elf_output_extsym): Use hd->needs_lazy_stub to detect
cases where a lazy stub is being used.
(mips_elf_sort_hash_table_f): Use h->root.forced_local instead
of h->forced_local.
(mips_elf_record_global_got_symbol): Use _bfd_elf_link_hash_hide_symbol
instead of _bfd_mips_elf_hide_symbol. Do not increment local_gotno
here.
(mips_elf_allocate_dynamic_relocations): Move before new first use.
(mips_elf_check_recreate_got, mips_elf_recreate_got): New functions.
(mips_elf_resolve_final_got_entries): Move earlier in file. Make at
most two passes over the hash table. Use mips_elf_check_recreate_got
to see if there are any indirect or warning entries and
mips_elf_recreate_got to create a new GOT without them.
Return a boolean success value.
(mips_elf_count_forced_local_got_entries): New function.
(mips_elf_make_got_per_bfd): Check h->root.forced_local instead of
h->forced_local.
(mips_elf_set_global_got_offset): Likewise.
(mips_elf_set_no_stub): Replace with...
(mips_elf_forbid_lazy_stubs): ...this new function.
(mips_elf_resolve_final_got_entry): Delete.
(mips_elf_multi_got): Fix formatting. Use mips_elf_forbid_lazy_stubs
instead of mips_elf_set_no_stub. Move the code that sets
global offsets and allocates dynamic relocations from the main
_bfd_mips_elf_size_dynamic_sections loop to here.
(_bfd_mips_elf_adjust_dynamic_symbol): Do not allocate room in
.MIPS.stubs here; just set hmips->needs_lazy_stub and increment
htab->lazy_stub_count.
(_bfd_mips_elf_always_size_sections): Move the stub-estimation
code to mips_elf_estimate_stub_size and the GOT-sizing code to
mips_elf_lay_out_got. Do not call these functions here.
(mips_elf_estimate_stub_size): New function, split
out from _bfd_mips_elf_always_size_sections. Call
mips_elf_resolve_final_got_entries earlier. Count the number
of forced-local entries. Do not add stub sizes to loadable_size;
after this patch, the stub sizes are already included in the main
estimate. Allocate dynamic relocations here rather than in the
main _bfd_mips_elf_size_dynamic_sections loop.
(mips_elf_estimate_stub_size): New function, split out from
_bfd_mips_elf_always_size_sections.
(mips_elf_allocate_lazy_stub): New function.
(mips_elf_lay_out_lazy_stubs): Likewise.
(_bfd_mips_elf_size_dynamic_sections): Call mips_elf_estimate_stub_size,
mips_elf_lay_out_got and mips_elf_lay_out_lazy_stubs. Do not handle
the allocation of sreldyn specially.
(_bfd_mips_elf_hide_symbol): Delete.
2008-08-07 Richard Sandiford <rdsandiford@googlemail.com>
* elfxx-mips.c (allocate_dynrelocs): Ignore indirect and warning

View file

@ -1606,7 +1606,6 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
#define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
#define elf_backend_copy_indirect_symbol \
_bfd_mips_elf_copy_indirect_symbol
#define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
#define elf_backend_grok_prstatus elf32_mips_grok_prstatus
#define elf_backend_grok_psinfo elf32_mips_grok_psinfo
#define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap

View file

@ -3179,7 +3179,6 @@ const struct elf_size_info mips_elf64_size_info =
#define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
#define elf_backend_copy_indirect_symbol \
_bfd_mips_elf_copy_indirect_symbol
#define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
#define elf_backend_ignore_discarded_relocs \
_bfd_mips_elf_ignore_discarded_relocs
#define elf_backend_mips_irix_compat elf64_mips_irix_compat

View file

@ -2433,7 +2433,6 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
#define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
#define elf_backend_copy_indirect_symbol \
_bfd_mips_elf_copy_indirect_symbol
#define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
#define elf_backend_grok_prstatus elf32_mips_grok_prstatus
#define elf_backend_grok_psinfo elf32_mips_grok_psinfo
#define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap

View file

@ -317,15 +317,15 @@ struct mips_elf_link_hash_entry
in any relocs other than a 16 bit call. */
unsigned int need_fn_stub : 1;
/* Are we forced local? This will only be set if we have converted
the initial global GOT entry to a local GOT entry. */
unsigned int forced_local : 1;
/* Are we referenced by some kind of relocation? */
unsigned int is_relocation_target : 1;
/* Are we referenced by branch relocations? */
unsigned int is_branch_target : 1;
/* Does this symbol need a traditional MIPS lazy-binding stub
(as opposed to a PLT entry)? */
unsigned int needs_lazy_stub : 1;
};
/* MIPS ELF linker hash table. */
@ -349,8 +349,6 @@ struct mips_elf_link_hash_table
bfd_vma rld_value;
/* This is set if we see any mips16 stub sections. */
bfd_boolean mips16_stubs_seen;
/* True if we've computed the size of the GOT. */
bfd_boolean computed_got_sizes;
/* True if we're generating code for VxWorks. */
bfd_boolean is_vxworks;
/* True if we already reported the small-data section overflow. */
@ -371,6 +369,8 @@ struct mips_elf_link_hash_table
bfd_vma plt_header_size;
/* The size of a PLT entry in bytes (VxWorks only). */
bfd_vma plt_entry_size;
/* The number of functions that need a lazy-binding stub. */
bfd_vma lazy_stub_count;
/* The size of a function stub entry in bytes. */
bfd_vma function_stub_size;
};
@ -871,9 +871,9 @@ mips_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
ret->readonly_reloc = FALSE;
ret->no_fn_stub = FALSE;
ret->need_fn_stub = FALSE;
ret->forced_local = FALSE;
ret->is_relocation_target = FALSE;
ret->is_branch_target = FALSE;
ret->needs_lazy_stub = FALSE;
}
return (struct bfd_hash_entry *) ret;
@ -2066,18 +2066,14 @@ mips_elf_output_extsym (struct mips_elf_link_hash_entry *h, void *data)
else
h->esym.asym.value = 0;
}
else if (h->root.needs_plt)
else
{
struct mips_elf_link_hash_entry *hd = h;
bfd_boolean no_fn_stub = h->no_fn_stub;
while (hd->root.root.type == bfd_link_hash_indirect)
{
hd = (struct mips_elf_link_hash_entry *)h->root.root.u.i.link;
no_fn_stub = no_fn_stub || hd->no_fn_stub;
}
hd = (struct mips_elf_link_hash_entry *)h->root.root.u.i.link;
if (!no_fn_stub)
if (hd->needs_lazy_stub)
{
/* Set type and value for a symbol with a function stub. */
h->esym.asym.st = stProc;
@ -2965,7 +2961,7 @@ mips_elf_sort_hash_table_f (struct mips_elf_link_hash_entry *h, void *data)
hsd->low = (struct elf_link_hash_entry *) h;
h->root.dynindx = hsd->max_unref_got_dynindx++;
}
else if (h->root.got.offset != 1 || h->forced_local)
else if (h->root.got.offset != 1 || h->root.forced_local)
h->root.dynindx = hsd->max_non_got_dynindx++;
else
{
@ -3001,7 +2997,7 @@ mips_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
{
case STV_INTERNAL:
case STV_HIDDEN:
_bfd_mips_elf_hide_symbol (info, h, TRUE);
_bfd_elf_link_hash_hide_symbol (info, h, TRUE);
break;
}
if (!bfd_elf_link_record_dynamic_symbol (info, h))
@ -3042,14 +3038,10 @@ mips_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
return TRUE;
if (tls_flag == 0)
{
/* By setting this to a value other than -1, we are indicating that
there needs to be a GOT entry for H. Avoid using zero, as the
generic ELF copy_indirect_symbol tests for <= 0. */
h->got.offset = 1;
if (h->forced_local)
g->local_gotno++;
}
/* By setting this to a value other than -1, we are indicating that
there needs to be a GOT entry for H. Avoid using zero, as the
generic ELF copy_indirect_symbol tests for <= 0. */
h->got.offset = 1;
return TRUE;
}
@ -3229,6 +3221,148 @@ mips_elf_record_got_page_entry (struct bfd_link_info *info, bfd *abfd,
return TRUE;
}
/* Add room for N relocations to the .rel(a).dyn section in ABFD. */
static void
mips_elf_allocate_dynamic_relocations (bfd *abfd, struct bfd_link_info *info,
unsigned int n)
{
asection *s;
struct mips_elf_link_hash_table *htab;
htab = mips_elf_hash_table (info);
s = mips_elf_rel_dyn_section (info, FALSE);
BFD_ASSERT (s != NULL);
if (htab->is_vxworks)
s->size += n * MIPS_ELF_RELA_SIZE (abfd);
else
{
if (s->size == 0)
{
/* Make room for a null element. */
s->size += MIPS_ELF_REL_SIZE (abfd);
++s->reloc_count;
}
s->size += n * MIPS_ELF_REL_SIZE (abfd);
}
}
/* A htab_traverse callback for GOT entries. Set boolean *DATA to true
if the GOT entry is for an indirect or warning symbol. */
static int
mips_elf_check_recreate_got (void **entryp, void *data)
{
struct mips_got_entry *entry;
bfd_boolean *must_recreate;
entry = (struct mips_got_entry *) *entryp;
must_recreate = (bfd_boolean *) data;
if (entry->abfd != NULL && entry->symndx == -1)
{
struct mips_elf_link_hash_entry *h;
h = entry->d.h;
if (h->root.root.type == bfd_link_hash_indirect
|| h->root.root.type == bfd_link_hash_warning)
{
*must_recreate = TRUE;
return 0;
}
}
return 1;
}
/* A htab_traverse callback for GOT entries. Add all entries to
hash table *DATA, converting entries for indirect and warning
symbols into entries for the target symbol. Set *DATA to null
on error. */
static int
mips_elf_recreate_got (void **entryp, void *data)
{
htab_t *new_got;
struct mips_got_entry *entry;
void **slot;
new_got = (htab_t *) data;
entry = (struct mips_got_entry *) *entryp;
if (entry->abfd != NULL && entry->symndx == -1)
{
struct mips_elf_link_hash_entry *h;
h = entry->d.h;
while (h->root.root.type == bfd_link_hash_indirect
|| h->root.root.type == bfd_link_hash_warning)
h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
entry->d.h = h;
}
slot = htab_find_slot (*new_got, entry, INSERT);
if (slot == NULL)
{
*new_got = NULL;
return 0;
}
if (*slot == NULL)
*slot = entry;
else
free (entry);
return 1;
}
/* If any entries in G->got_entries are for indirect or warning symbols,
replace them with entries for the target symbol. */
static bfd_boolean
mips_elf_resolve_final_got_entries (struct mips_got_info *g)
{
bfd_boolean must_recreate;
htab_t new_got;
must_recreate = FALSE;
htab_traverse (g->got_entries, mips_elf_check_recreate_got, &must_recreate);
if (must_recreate)
{
new_got = htab_create (htab_size (g->got_entries),
mips_elf_got_entry_hash,
mips_elf_got_entry_eq, NULL);
htab_traverse (g->got_entries, mips_elf_recreate_got, &new_got);
if (new_got == NULL)
return FALSE;
/* Each entry in g->got_entries has either been copied to new_got
or freed. Now delete the hash table itself. */
htab_delete (g->got_entries);
g->got_entries = new_got;
}
return TRUE;
}
/* An elf_link_hash_traverse callback for which DATA points to a mips_got_info.
Add each forced-local GOT symbol to DATA's local_gotno field. */
static int
mips_elf_count_forced_local_got_symbols (struct elf_link_hash_entry *h,
void *data)
{
struct mips_got_info *g;
g = (struct mips_got_info *) data;
if (h->got.offset != MINUS_ONE
&& (h->forced_local || h->dynindx == -1))
{
/* We no longer need this entry if it was only used for
relocations; those relocations will be against the
null or section symbol instead of H. */
if (h->got.offset == 2)
h->got.offset = MINUS_ONE;
else
g->local_gotno++;
}
return 1;
}
/* Compute the hash value of the bfd in a bfd2got hash entry. */
@ -3360,7 +3494,7 @@ mips_elf_make_got_per_bfd (void **entryp, void *p)
if (entry->tls_type & GOT_TLS_IE)
g->tls_gotno += 1;
}
else if (entry->symndx >= 0 || entry->d.h->forced_local)
else if (entry->symndx >= 0 || entry->d.h->root.forced_local)
++g->local_gotno;
else
++g->global_gotno;
@ -3593,7 +3727,7 @@ mips_elf_set_global_got_offset (void **entryp, void *p)
if (entry->abfd != NULL && entry->symndx == -1
&& entry->d.h->root.dynindx != -1
&& !entry->d.h->forced_local
&& !entry->d.h->root.forced_local
&& entry->d.h->tls_type == GOT_NORMAL)
{
if (g)
@ -3614,85 +3748,31 @@ mips_elf_set_global_got_offset (void **entryp, void *p)
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 (void **entryp, void *p ATTRIBUTE_UNUSED)
{
struct mips_got_entry *entry = (struct mips_got_entry *)*entryp;
/* A htab_traverse callback for GOT entries for which DATA is the
bfd_link_info. Forbid any global symbols from having traditional
lazy-binding stubs. */
static int
mips_elf_forbid_lazy_stubs (void **entryp, void *data)
{
struct bfd_link_info *info;
struct mips_elf_link_hash_table *htab;
struct mips_got_entry *entry;
entry = (struct mips_got_entry *) *entryp;
info = (struct bfd_link_info *) data;
htab = mips_elf_hash_table (info);
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
points to the final symbol definition. P must point to a pointer
to the hash table we're traversing. Since this traversal may
modify the hash table, we set this pointer to NULL to indicate
we've made a potentially-destructive change to the hash table, so
the traversal must be restarted. */
static int
mips_elf_resolve_final_got_entry (void **entryp, void *p)
{
struct mips_got_entry *entry = (struct mips_got_entry *)*entryp;
htab_t got_entries = *(htab_t *)p;
if (entry->abfd != NULL && entry->symndx == -1)
&& entry->d.h->needs_lazy_stub)
{
struct mips_elf_link_hash_entry *h = entry->d.h;
while (h->root.root.type == bfd_link_hash_indirect
|| h->root.root.type == bfd_link_hash_warning)
h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
if (entry->d.h == h)
return 1;
entry->d.h = h;
/* If we can't find this entry with the new bfd hash, re-insert
it, and get the traversal restarted. */
if (! htab_find (got_entries, entry))
{
htab_clear_slot (got_entries, entryp);
entryp = htab_find_slot (got_entries, entry, INSERT);
if (! *entryp)
*entryp = entry;
/* Abort the traversal, since the whole table may have
moved, and leave it up to the parent to restart the
process. */
*(htab_t *)p = NULL;
return 0;
}
/* We might want to decrement the global_gotno count, but it's
either too early or too late for that at this point. */
entry->d.h->needs_lazy_stub = FALSE;
htab->lazy_stub_count--;
}
return 1;
}
/* Turn indirect got entries in a got_entries table into their final
locations. */
static void
mips_elf_resolve_final_got_entries (struct mips_got_info *g)
{
htab_t got_entries;
do
{
got_entries = g->got_entries;
htab_traverse (got_entries,
mips_elf_resolve_final_got_entry,
&got_entries);
}
while (got_entries == NULL);
}
/* Return the offset of an input bfd IBFD's GOT from the beginning of
the primary GOT. */
static bfd_vma
@ -3724,8 +3804,10 @@ mips_elf_multi_got (bfd *abfd, struct bfd_link_info *info,
struct mips_elf_got_per_bfd_arg got_per_bfd_arg;
struct mips_elf_set_global_got_offset_arg set_got_offset_arg;
struct mips_got_info *g, *gg;
unsigned int assign;
unsigned int assign, needed_relocs;
bfd *dynobj;
dynobj = elf_hash_table (info)->dynobj;
htab = mips_elf_hash_table (info);
g = htab->got_info;
g->bfd2got = htab_try_create (1, mips_elf_bfd2got_entry_hash,
@ -3916,16 +3998,49 @@ mips_elf_multi_got (bfd *abfd, struct bfd_link_info *info,
/* Move onto the next GOT. It will be a secondary GOT if nonull. */
g = gn;
/* Mark global symbols in every non-primary GOT as ineligible for
stubs. */
/* Forbid global symbols in every non-primary GOT from having
lazy-binding stubs. */
if (g)
htab_traverse (g->got_entries, mips_elf_set_no_stub, NULL);
htab_traverse (g->got_entries, mips_elf_forbid_lazy_stubs, info);
}
while (g);
got->size = (gg->next->local_gotno
+ gg->next->global_gotno
+ gg->next->tls_gotno) * MIPS_ELF_GOT_SIZE (abfd);
+ gg->next->global_gotno
+ gg->next->tls_gotno) * MIPS_ELF_GOT_SIZE (abfd);
needed_relocs = 0;
set_got_offset_arg.value = MIPS_ELF_GOT_SIZE (abfd);
set_got_offset_arg.info = info;
for (g = gg->next; g && g->next != gg; g = g->next)
{
unsigned int save_assign;
/* Assign offsets to global GOT entries. */
save_assign = g->assigned_gotno;
g->assigned_gotno = g->local_gotno;
set_got_offset_arg.g = g;
set_got_offset_arg.needed_relocs = 0;
htab_traverse (g->got_entries,
mips_elf_set_global_got_offset,
&set_got_offset_arg);
needed_relocs += set_got_offset_arg.needed_relocs;
BFD_ASSERT (g->assigned_gotno - g->local_gotno <= g->global_gotno);
g->assigned_gotno = save_assign;
if (info->shared)
{
needed_relocs += g->local_gotno - g->assigned_gotno;
BFD_ASSERT (g->assigned_gotno == g->next->local_gotno
+ g->next->global_gotno
+ g->next->tls_gotno
+ MIPS_RESERVED_GOTNO (info));
}
}
if (needed_relocs)
mips_elf_allocate_dynamic_relocations (dynobj, info,
needed_relocs);
return TRUE;
}
@ -5059,33 +5174,6 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
return TRUE;
}
/* Add room for N relocations to the .rel(a).dyn section in ABFD. */
static void
mips_elf_allocate_dynamic_relocations (bfd *abfd, struct bfd_link_info *info,
unsigned int n)
{
asection *s;
struct mips_elf_link_hash_table *htab;
htab = mips_elf_hash_table (info);
s = mips_elf_rel_dyn_section (info, FALSE);
BFD_ASSERT (s != NULL);
if (htab->is_vxworks)
s->size += n * MIPS_ELF_RELA_SIZE (abfd);
else
{
if (s->size == 0)
{
/* Make room for a null element. */
s->size += MIPS_ELF_REL_SIZE (abfd);
++s->reloc_count;
}
s->size += n * MIPS_ELF_REL_SIZE (abfd);
}
}
/* Create a rel.dyn relocation for the dynamic linker to resolve. REL
is the original relocation, which is now being transformed into a
dynamic relocation. The ADDENDP is adjusted if necessary; the
@ -7547,18 +7635,8 @@ _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
executable and the shared library. */
if (!h->def_regular)
{
/* We need .stub section. */
h->root.u.def.section = htab->sstubs;
h->root.u.def.value = htab->sstubs->size;
/* XXX Write this stub address somewhere. */
h->plt.offset = htab->sstubs->size;
/* Make room for this stub code. */
htab->sstubs->size += htab->function_stub_size;
/* The last half word of the stub will be filled with the index
of this symbol in .dynsym section. */
hmips->needs_lazy_stub = TRUE;
htab->lazy_stub_count++;
return TRUE;
}
}
@ -7757,15 +7835,6 @@ _bfd_mips_elf_always_size_sections (bfd *output_bfd,
struct bfd_link_info *info)
{
asection *ri;
asection *s;
struct mips_got_info *g;
int i;
bfd_size_type loadable_size = 0;
bfd_size_type page_gotno;
bfd_size_type dynsymcount;
bfd *sub;
struct mips_elf_count_tls_arg count_tls_arg;
struct mips_elf_link_hash_table *htab;
htab = mips_elf_hash_table (info);
@ -7780,12 +7849,56 @@ _bfd_mips_elf_always_size_sections (bfd *output_bfd,
mips_elf_link_hash_traverse (mips_elf_hash_table (info),
mips_elf_check_mips16_stubs, info);
return TRUE;
}
/* If the link uses a GOT, lay it out and work out its size. */
static bfd_boolean
mips_elf_lay_out_got (bfd *output_bfd, struct bfd_link_info *info)
{
bfd *dynobj;
asection *s;
struct mips_got_info *g;
int i;
bfd_size_type loadable_size = 0;
bfd_size_type page_gotno;
bfd *sub;
struct mips_elf_count_tls_arg count_tls_arg;
struct mips_elf_link_hash_table *htab;
htab = mips_elf_hash_table (info);
s = htab->sgot;
if (s == NULL)
return TRUE;
dynobj = elf_hash_table (info)->dynobj;
g = htab->got_info;
/* Replace entries for indirect and warning symbols with entries for
the target symbol. */
if (!mips_elf_resolve_final_got_entries (g))
return FALSE;
/* Count the number of forced-local entries. */
elf_link_hash_traverse (elf_hash_table (info),
mips_elf_count_forced_local_got_symbols, g);
/* There has to be a global GOT entry for every symbol with
a dynamic symbol table index of DT_MIPS_GOTSYM or
higher. Therefore, it make sense to put those symbols
that need GOT entries at the end of the symbol table. We
do that here. */
if (! mips_elf_sort_hash_table (info, 1))
return FALSE;
if (g->global_gotsym != NULL)
i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
else
/* If there are no global symbols, or none requiring
relocations, then GLOBAL_GOTSYM will be NULL. */
i = 0;
/* Calculate the total loadable size of the output. That
will give us the maximum number of GOT_PAGE entries
required. */
@ -7804,38 +7917,6 @@ _bfd_mips_elf_always_size_sections (bfd *output_bfd,
}
}
/* There has to be a global GOT entry for every symbol with
a dynamic symbol table index of DT_MIPS_GOTSYM or
higher. Therefore, it make sense to put those symbols
that need GOT entries at the end of the symbol table. We
do that here. */
if (! mips_elf_sort_hash_table (info, 1))
return FALSE;
if (g->global_gotsym != NULL)
i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
else
/* If there are no global symbols, or none requiring
relocations, then GLOBAL_GOTSYM will be NULL. */
i = 0;
/* Get a worst-case estimate of the number of dynamic symbols needed.
At this point, dynsymcount does not account for section symbols
and count_section_dynsyms may overestimate the number that will
be needed. */
dynsymcount = (elf_hash_table (info)->dynsymcount
+ count_section_dynsyms (output_bfd, info));
/* Determine the size of one stub entry. */
htab->function_stub_size = (dynsymcount > 0x10000
? MIPS_FUNCTION_STUB_BIG_SIZE
: MIPS_FUNCTION_STUB_NORMAL_SIZE);
/* In the worst case, we'll get one stub per dynamic symbol, plus
one to account for the dummy entry at the end required by IRIX
rld. */
loadable_size += htab->function_stub_size * (i + 1);
if (htab->is_vxworks)
/* There's no need to allocate page entries for VxWorks; R_MIPS*_GOT16
relocations against local symbols evaluate to "G", and the EABI does
@ -7868,27 +7949,120 @@ _bfd_mips_elf_always_size_sections (bfd *output_bfd,
g->tls_gotno += count_tls_arg.needed;
s->size += g->tls_gotno * MIPS_ELF_GOT_SIZE (output_bfd);
mips_elf_resolve_final_got_entries (g);
/* VxWorks does not support multiple GOTs. It initializes $gp to
__GOTT_BASE__[__GOTT_INDEX__], the value of which is set by the
dynamic loader. */
if (!htab->is_vxworks && s->size > MIPS_ELF_GOT_MAX_SIZE (info))
if (htab->is_vxworks)
{
/* VxWorks executables do not need a GOT. */
if (info->shared)
{
/* Each VxWorks GOT entry needs an explicit relocation. */
unsigned int count;
count = g->global_gotno + g->local_gotno - MIPS_RESERVED_GOTNO (info);
if (count)
mips_elf_allocate_dynamic_relocations (dynobj, info, count);
}
}
else if (s->size > MIPS_ELF_GOT_MAX_SIZE (info))
{
if (!mips_elf_multi_got (output_bfd, info, s, page_gotno))
return FALSE;
}
else
{
/* Set up TLS entries for the first GOT. */
struct mips_elf_count_tls_arg arg;
/* Set up TLS entries. */
g->tls_assigned_gotno = g->global_gotno + g->local_gotno;
htab_traverse (g->got_entries, mips_elf_initialize_tls_index, g);
/* Allocate room for the TLS relocations. */
arg.info = info;
arg.needed = 0;
htab_traverse (g->got_entries, mips_elf_count_local_tls_relocs, &arg);
elf_link_hash_traverse (elf_hash_table (info),
mips_elf_count_global_tls_relocs,
&arg);
if (arg.needed)
mips_elf_allocate_dynamic_relocations (dynobj, info, arg.needed);
}
htab->computed_got_sizes = TRUE;
return TRUE;
}
/* Estimate the size of the .MIPS.stubs section. */
static void
mips_elf_estimate_stub_size (bfd *output_bfd, struct bfd_link_info *info)
{
struct mips_elf_link_hash_table *htab;
bfd_size_type dynsymcount;
htab = mips_elf_hash_table (info);
if (htab->lazy_stub_count == 0)
return;
/* IRIX rld assumes that a function stub isn't at the end of the .text
section, so add a dummy entry to the end. */
htab->lazy_stub_count++;
/* Get a worst-case estimate of the number of dynamic symbols needed.
At this point, dynsymcount does not account for section symbols
and count_section_dynsyms may overestimate the number that will
be needed. */
dynsymcount = (elf_hash_table (info)->dynsymcount
+ count_section_dynsyms (output_bfd, info));
/* Determine the size of one stub entry. */
htab->function_stub_size = (dynsymcount > 0x10000
? MIPS_FUNCTION_STUB_BIG_SIZE
: MIPS_FUNCTION_STUB_NORMAL_SIZE);
htab->sstubs->size = htab->lazy_stub_count * htab->function_stub_size;
}
/* A mips_elf_link_hash_traverse callback for which DATA points to the
MIPS hash table. If H needs a traditional MIPS lazy-binding stub,
allocate an entry in the stubs section. */
static bfd_boolean
mips_elf_allocate_lazy_stub (struct mips_elf_link_hash_entry *h, void **data)
{
struct mips_elf_link_hash_table *htab;
htab = (struct mips_elf_link_hash_table *) data;
if (h->needs_lazy_stub)
{
h->root.root.u.def.section = htab->sstubs;
h->root.root.u.def.value = htab->sstubs->size;
h->root.plt.offset = htab->sstubs->size;
htab->sstubs->size += htab->function_stub_size;
}
return TRUE;
}
/* Allocate offsets in the stubs section to each symbol that needs one.
Set the final size of the .MIPS.stub section. */
static void
mips_elf_lay_out_lazy_stubs (struct bfd_link_info *info)
{
struct mips_elf_link_hash_table *htab;
htab = mips_elf_hash_table (info);
if (htab->lazy_stub_count == 0)
return;
htab->sstubs->size = 0;
mips_elf_link_hash_traverse (mips_elf_hash_table (info),
mips_elf_allocate_lazy_stub, htab);
htab->sstubs->size += htab->function_stub_size;
BFD_ASSERT (htab->sstubs->size
== htab->lazy_stub_count * htab->function_stub_size);
}
/* Set the sizes of the dynamic sections. */
bfd_boolean
@ -7896,7 +8070,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
struct bfd_link_info *info)
{
bfd *dynobj;
asection *s, *sreldyn;
asection *s;
bfd_boolean reltext;
struct mips_elf_link_hash_table *htab;
@ -7918,19 +8092,20 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
}
}
/* IRIX rld assumes that the function stub isn't at the end
of the .text section, so add a dummy entry to the end. */
if (htab->sstubs && htab->sstubs->size > 0)
htab->sstubs->size += htab->function_stub_size;
/* Allocate space for global sym dynamic relocs. */
elf_link_hash_traverse (&htab->root, allocate_dynrelocs, (PTR) info);
mips_elf_estimate_stub_size (output_bfd, info);
if (!mips_elf_lay_out_got (output_bfd, info))
return FALSE;
mips_elf_lay_out_lazy_stubs (info);
/* The check_relocs and adjust_dynamic_symbol entry points have
determined the sizes of the various dynamic sections. Allocate
memory for them. */
reltext = FALSE;
sreldyn = NULL;
for (s = dynobj->sections; s != NULL; s = s->next)
{
const char *name;
@ -7978,88 +8153,6 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
info->combreloc = 0;
}
}
else if (htab->is_vxworks && strcmp (name, ".got") == 0)
{
/* Executables do not need a GOT. */
if (info->shared)
{
/* Allocate relocations for all but the reserved entries. */
unsigned int count;
count = (htab->got_info->global_gotno
+ htab->got_info->local_gotno
- MIPS_RESERVED_GOTNO (info));
mips_elf_allocate_dynamic_relocations (dynobj, info, count);
}
}
else if (!htab->is_vxworks && CONST_STRNEQ (name, ".got"))
{
/* _bfd_mips_elf_always_size_sections() has already done
most of the work, but some symbols may have been mapped
to versions that we must now resolve in the got_entries
hash tables. */
struct mips_got_info *gg = htab->got_info;
struct mips_got_info *g = gg;
struct mips_elf_set_global_got_offset_arg set_got_offset_arg;
unsigned int needed_relocs = 0;
if (gg->next)
{
set_got_offset_arg.value = MIPS_ELF_GOT_SIZE (output_bfd);
set_got_offset_arg.info = info;
/* NOTE 2005-02-03: How can this call, or the next, ever
find any indirect entries to resolve? They were all
resolved in mips_elf_multi_got. */
mips_elf_resolve_final_got_entries (gg);
for (g = gg->next; g && g->next != gg; g = g->next)
{
unsigned int save_assign;
mips_elf_resolve_final_got_entries (g);
/* Assign offsets to global GOT entries. */
save_assign = g->assigned_gotno;
g->assigned_gotno = g->local_gotno;
set_got_offset_arg.g = g;
set_got_offset_arg.needed_relocs = 0;
htab_traverse (g->got_entries,
mips_elf_set_global_got_offset,
&set_got_offset_arg);
needed_relocs += set_got_offset_arg.needed_relocs;
BFD_ASSERT (g->assigned_gotno - g->local_gotno
<= g->global_gotno);
g->assigned_gotno = save_assign;
if (info->shared)
{
needed_relocs += g->local_gotno - g->assigned_gotno;
BFD_ASSERT (g->assigned_gotno == g->next->local_gotno
+ g->next->global_gotno
+ g->next->tls_gotno
+ MIPS_RESERVED_GOTNO (info));
}
}
}
else
{
struct mips_elf_count_tls_arg arg;
arg.info = info;
arg.needed = 0;
htab_traverse (gg->got_entries, mips_elf_count_local_tls_relocs,
&arg);
elf_link_hash_traverse (elf_hash_table (info),
mips_elf_count_global_tls_relocs,
&arg);
needed_relocs += arg.needed;
}
if (needed_relocs)
mips_elf_allocate_dynamic_relocations (dynobj, info,
needed_relocs);
}
else if (! info->shared
&& ! mips_elf_hash_table (info)->use_rld_obj_head
&& CONST_STRNEQ (name, ".rld_map"))
@ -8072,6 +8165,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
&& CONST_STRNEQ (name, ".compact_rel"))
s->size += mips_elf_hash_table (info)->compact_rel_size;
else if (! CONST_STRNEQ (name, ".init")
&& s != htab->sgot
&& s != htab->sgotplt
&& s != htab->splt
&& s != htab->sstubs)
@ -8089,14 +8183,6 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
if ((s->flags & SEC_HAS_CONTENTS) == 0)
continue;
/* Allocate memory for this section last, since we may increase its
size above. */
if (strcmp (name, MIPS_ELF_REL_DYN_NAME (info)) == 0)
{
sreldyn = s;
continue;
}
/* Allocate memory for the section contents. */
s->contents = bfd_zalloc (dynobj, s->size);
if (s->contents == NULL)
@ -8106,17 +8192,6 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
}
}
/* Allocate memory for the .rel(a).dyn section. */
if (sreldyn != NULL)
{
sreldyn->contents = bfd_zalloc (dynobj, sreldyn->size);
if (sreldyn->contents == NULL)
{
bfd_set_error (bfd_error_no_memory);
return FALSE;
}
}
if (elf_hash_table (info)->dynamic_sections_created)
{
/* Add some entries to the .dynamic section. We fill in the
@ -10193,91 +10268,6 @@ _bfd_mips_elf_copy_indirect_symbol (struct bfd_link_info *info,
if (dirmips->tls_type == 0)
dirmips->tls_type = indmips->tls_type;
}
void
_bfd_mips_elf_hide_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *entry,
bfd_boolean force_local)
{
bfd *dynobj;
struct mips_got_info *g;
struct mips_elf_link_hash_entry *h;
struct mips_elf_link_hash_table *htab;
h = (struct mips_elf_link_hash_entry *) entry;
if (h->forced_local)
return;
h->forced_local = force_local;
dynobj = elf_hash_table (info)->dynobj;
htab = mips_elf_hash_table (info);
if (dynobj != NULL
&& force_local
&& h->root.type != STT_TLS
&& htab->got_info != NULL)
{
g = htab->got_info;
if (g->next)
{
struct mips_got_entry e;
struct mips_got_info *gg = g;
/* Since we're turning what used to be a global symbol into a
local one, bump up the number of local entries of each GOT
that had an entry for it. This will automatically decrease
the number of global entries, since global_gotno is actually
the upper limit of global entries. */
e.abfd = dynobj;
e.symndx = -1;
e.d.h = h;
e.tls_type = 0;
for (g = g->next; g != gg; g = g->next)
if (htab_find (g->got_entries, &e))
{
BFD_ASSERT (g->global_gotno > 0);
g->local_gotno++;
g->global_gotno--;
}
/* If this was a global symbol forced into the primary GOT, we
no longer need an entry for it. We can't release the entry
at this point, but we must at least stop counting it as one
of the symbols that required a forced got entry. */
if (h->root.got.offset == 2)
{
BFD_ASSERT (gg->assigned_gotno > 0);
gg->assigned_gotno--;
}
}
else if (h->root.got.offset == 1)
{
/* check_relocs didn't know that this symbol would be
forced-local, so add an extra local got entry. */
g->local_gotno++;
if (htab->computed_got_sizes)
{
/* We'll have treated this symbol as global rather
than local. */
BFD_ASSERT (g->global_gotno > 0);
g->global_gotno--;
}
}
else if (htab->is_vxworks && h->root.needs_plt)
{
/* check_relocs didn't know that this symbol would be
forced-local, so add an extra local got entry. */
g->local_gotno++;
if (htab->computed_got_sizes)
/* The symbol is only used in call relocations, so we'll
have assumed it only needs a .got.plt entry. Increase
the size of .got accordingly. */
htab->sgot->size += MIPS_ELF_GOT_SIZE (dynobj);
}
}
_bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
}
#define PDR_SIZE 32
@ -10734,7 +10724,6 @@ _bfd_mips_elf_link_hash_table_create (bfd *abfd)
ret->use_rld_obj_head = FALSE;
ret->rld_value = 0;
ret->mips16_stubs_seen = FALSE;
ret->computed_got_sizes = FALSE;
ret->is_vxworks = FALSE;
ret->small_data_overflow_reported = FALSE;
ret->srelbss = NULL;
@ -10748,6 +10737,7 @@ _bfd_mips_elf_link_hash_table_create (bfd *abfd)
ret->got_info = NULL;
ret->plt_header_size = 0;
ret->plt_entry_size = 0;
ret->lazy_stub_count = 0;
ret->function_stub_size = 0;
return &ret->root.root;

View file

@ -81,8 +81,6 @@ extern bfd_boolean _bfd_mips_elf_gc_sweep_hook
extern void _bfd_mips_elf_copy_indirect_symbol
(struct bfd_link_info *, struct elf_link_hash_entry *,
struct elf_link_hash_entry *);
extern void _bfd_mips_elf_hide_symbol
(struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean);
extern bfd_boolean _bfd_mips_elf_ignore_discarded_relocs
(asection *);
extern bfd_boolean _bfd_mips_elf_find_nearest_line

View file

@ -1,3 +1,20 @@
2008-08-07 Richard Sandiford <rdsandiford@googlemail.com>
* ld-mips-elf/tlsdyn-o32-2.got, ld-mips-elf/tlsdyn-o32-3.got,
ld-mips-elf/tlsdyn-o32-2.d, ld-mips-elf/tlsdyn-o32-3.d: Change the
GOT layout as follows:
BEFORE AFTER
+0x08 %call16(__tls_get_addr) %call16(__tls_get_addr)
+0x0c %tlsldm(tlsbin_ld) %gottprel(tlsvar_ie)
+0x10 " " %tlsgd(tlsvar_gd)
+0x14 %tlsgd(tlsvar_gd) " "
+0x18 " " %tlsgd(tlsbin_gd)
+0x1c %gottprel(tlsvar_ie) " "
+0x20 %tlsgd(tlsbin_gd) %tlsldm(tlsbin_ld)
+0x24 " " " "
+0x28 %gottprel(tlsbin_ie) %gottprel(tlsbin_ie)
2008-08-07 Richard Sandiford <rdsandiford@googlemail.com>
* ld-mips-elf/reloc-estimate-1.d, ld-mips-elf/reloc-estimate-1.ld,

View file

@ -12,22 +12,22 @@ Disassembly of section .text:
.*: 03a0f021 move s8,sp
.*: afbc0000 sw gp,0\(sp\)
.*: 8f998018 lw t9,-32744\(gp\)
.*: 27848028 addiu a0,gp,-32728
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00000000 nop
.*: 8f998018 lw t9,-32744\(gp\)
.*: 27848020 addiu a0,gp,-32736
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00000000 nop
.*: 8f998018 lw t9,-32744\(gp\)
.*: 27848030 addiu a0,gp,-32720
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00000000 nop
.*: 8f998018 lw t9,-32744\(gp\)
.*: 27848024 addiu a0,gp,-32732
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00000000 nop
.*: 8f998018 lw t9,-32744\(gp\)
.*: 2784801c addiu a0,gp,-32740
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00401021 move v0,v0
.*: 3c030000 lui v1,0x0
.*: 24638000 addiu v1,v1,-32768
@ -36,7 +36,7 @@ Disassembly of section .text:
.*: 8f838038 lw v1,-32712\(gp\)
.*: 00000000 nop
.*: 00621821 addu v1,v1,v0
.*: 8f83802c lw v1,-32724\(gp\)
.*: 8f83801c lw v1,-32740\(gp\)
.*: 00000000 nop
.*: 00621821 addu v1,v1,v0
.*: 7c02283b rdhwr v0,\$5
@ -62,22 +62,22 @@ Disassembly of section .text:
.*: 03a0f021 move s8,sp
.*: afbc0000 sw gp,0\(sp\)
.*: 8f998018 lw t9,-32744\(gp\)
.*: 27848028 addiu a0,gp,-32728
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00000000 nop
.*: 8f998018 lw t9,-32744\(gp\)
.*: 27848020 addiu a0,gp,-32736
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00000000 nop
.*: 8f998018 lw t9,-32744\(gp\)
.*: 27848030 addiu a0,gp,-32720
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00000000 nop
.*: 8f998018 lw t9,-32744\(gp\)
.*: 27848024 addiu a0,gp,-32732
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00000000 nop
.*: 8f998018 lw t9,-32744\(gp\)
.*: 2784801c addiu a0,gp,-32740
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00401021 move v0,v0
.*: 3c030000 lui v1,0x0
.*: 24638000 addiu v1,v1,-32768
@ -86,7 +86,7 @@ Disassembly of section .text:
.*: 8f838038 lw v1,-32712\(gp\)
.*: 00000000 nop
.*: 00621821 addu v1,v1,v0
.*: 8f83802c lw v1,-32724\(gp\)
.*: 8f83801c lw v1,-32740\(gp\)
.*: 00000000 nop
.*: 00621821 addu v1,v1,v0
.*: 7c02283b rdhwr v0,\$5

View file

@ -4,16 +4,16 @@
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
00000000 R_MIPS_NONE \*ABS\*
10000040 R_MIPS_TLS_DTPMOD32 tlsbin_gd
10000044 R_MIPS_TLS_DTPREL32 tlsbin_gd
10000034 R_MIPS_TLS_DTPMOD32 tlsvar_gd
10000038 R_MIPS_TLS_DTPREL32 tlsvar_gd
1000003c R_MIPS_TLS_TPREL32 tlsvar_ie
10000038 R_MIPS_TLS_DTPMOD32 tlsbin_gd
1000003c R_MIPS_TLS_DTPREL32 tlsbin_gd
10000030 R_MIPS_TLS_DTPMOD32 tlsvar_gd
10000034 R_MIPS_TLS_DTPREL32 tlsvar_gd
1000002c R_MIPS_TLS_TPREL32 tlsvar_ie
10000048 R_MIPS_TLS_TPREL32 tlsbin_ie
Contents of section .got:
10000020 00000000 80000000 0040053c 00000001 .*
10000020 00000000 80000000 0040053c 00000000 .*
10000030 00000000 00000000 00000000 00000000 .*
10000040 00000000 00000000 00000000 00000000 .*
10000040 00000001 00000000 00000000 00000000 .*
10000050 00000000 00000000 .*

View file

@ -12,22 +12,22 @@ Disassembly of section .text:
.*: 03a0f021 move s8,sp
.*: afbc0000 sw gp,0\(sp\)
.*: 8f998018 lw t9,-32744\(gp\)
.*: 27848028 addiu a0,gp,-32728
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00000000 nop
.*: 8f998018 lw t9,-32744\(gp\)
.*: 27848020 addiu a0,gp,-32736
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00000000 nop
.*: 8f998018 lw t9,-32744\(gp\)
.*: 27848030 addiu a0,gp,-32720
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00000000 nop
.*: 8f998018 lw t9,-32744\(gp\)
.*: 27848024 addiu a0,gp,-32732
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00000000 nop
.*: 8f998018 lw t9,-32744\(gp\)
.*: 2784801c addiu a0,gp,-32740
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00401021 move v0,v0
.*: 3c030000 lui v1,0x0
.*: 24638000 addiu v1,v1,-32768
@ -36,7 +36,7 @@ Disassembly of section .text:
.*: 8f838038 lw v1,-32712\(gp\)
.*: 00000000 nop
.*: 00621821 addu v1,v1,v0
.*: 8f83802c lw v1,-32724\(gp\)
.*: 8f83801c lw v1,-32740\(gp\)
.*: 00000000 nop
.*: 00621821 addu v1,v1,v0
.*: 7c02283b rdhwr v0,\$5
@ -58,22 +58,22 @@ Disassembly of section .text:
.*: 03a0f021 move s8,sp
.*: afbc0000 sw gp,0\(sp\)
.*: 8f998018 lw t9,-32744\(gp\)
.*: 27848028 addiu a0,gp,-32728
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00000000 nop
.*: 8f998018 lw t9,-32744\(gp\)
.*: 27848020 addiu a0,gp,-32736
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00000000 nop
.*: 8f998018 lw t9,-32744\(gp\)
.*: 27848030 addiu a0,gp,-32720
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00000000 nop
.*: 8f998018 lw t9,-32744\(gp\)
.*: 27848024 addiu a0,gp,-32732
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00000000 nop
.*: 8f998018 lw t9,-32744\(gp\)
.*: 2784801c addiu a0,gp,-32740
.*: 0320f809 jalr t9
.*: 00000000 nop
.*: 8fdc0000 lw gp,0\(s8\)
.*: 00401021 move v0,v0
.*: 3c030000 lui v1,0x0
.*: 24638000 addiu v1,v1,-32768
@ -82,7 +82,7 @@ Disassembly of section .text:
.*: 8f838038 lw v1,-32712\(gp\)
.*: 00000000 nop
.*: 00621821 addu v1,v1,v0
.*: 8f83802c lw v1,-32724\(gp\)
.*: 8f83801c lw v1,-32740\(gp\)
.*: 00000000 nop
.*: 00621821 addu v1,v1,v0
.*: 7c02283b rdhwr v0,\$5

View file

@ -4,16 +4,16 @@
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
00000000 R_MIPS_NONE \*ABS\*
10000040 R_MIPS_TLS_DTPMOD32 tlsbin_gd
10000044 R_MIPS_TLS_DTPREL32 tlsbin_gd
10000034 R_MIPS_TLS_DTPMOD32 tlsvar_gd
10000038 R_MIPS_TLS_DTPREL32 tlsvar_gd
1000003c R_MIPS_TLS_TPREL32 tlsvar_ie
10000038 R_MIPS_TLS_DTPMOD32 tlsbin_gd
1000003c R_MIPS_TLS_DTPREL32 tlsbin_gd
10000030 R_MIPS_TLS_DTPMOD32 tlsvar_gd
10000034 R_MIPS_TLS_DTPREL32 tlsvar_gd
1000002c R_MIPS_TLS_TPREL32 tlsvar_ie
10000048 R_MIPS_TLS_TPREL32 tlsbin_ie
Contents of section .got:
10000020 00000000 80000000 004005ec 00000001 .*
10000020 00000000 80000000 004005ec 00000000 .*
10000030 00000000 00000000 00000000 00000000 .*
10000040 00000000 00000000 00000000 00000000 .*
10000040 00000001 00000000 00000000 00000000 .*
10000050 00000000 00000000 .*