bfd/
* elfxx-mips.c (mips_got_page_ref): New structure. (mips_got_page_entry): Use a section rather than a (bfd, symndx) pair to represent the anchor point. (mips_got_info): Add a got_page_refs field. (mips_elf_link_hash_table): Add a sym_cache field. (mips_got_page_ref_hash, mips_got_page_ref_eq): New functions. (mips_got_page_entry_hash, mips_got_page_entry_eq): Update for new anchor representation. (mips_elf_create_got_info): Create got_page_refs rather than got_page_entries. (mips_elf_record_got_page_ref): New function. (mips_elf_pages_for_range): Move further down file. (mips_elf_record_got_page_entry): Likewise. Take a got as argument. Use a section rather than a (bfd, symndx) pair to represent the anchor point. (mips_elf_resolve_got_page_ref): New function. (mips_elf_resolve_final_got_entries): Use it to populate got_page_entries. (_bfd_mips_elf_check_relocs): Call mips_elf_record_got_page_ref rather than mips_elf_record_got_page_entry. Only nullify h afterwards. (mips_elf_lay_out_got): Call mips_elf_resolve_final_got_entries earlier. ld/testsuite/ * ld-mips-elf/mips16-pic-2.dd, ld-mips-elf/mips16-pic-2.gd: Remove 3 unused local GOT entries. * ld-mips-elf/got-page-4a.s, ld-mips-elf/got-page-4b.s, ld-mips-elf/got-page-4a.d, ld-mips-elf/got-page-4a.got, ld-mips-elf/got-page-4b.d, ld-mips-elf/got-page-4b.got, ld-mips-elf/got-page-5.s, ld-mips-elf/got-page-5.d, ld-mips-elf/got-page-5.got, ld-mips-elf/got-page-6.s, ld-mips-elf/got-page-6.d, ld-mips-elf/got-page-6.got, ld-mips-elf/got-page-7a.s, ld-mips-elf/got-page-7b.s, ld-mips-elf/got-page-7c.s, ld-mips-elf/got-page-7d.s, ld-mips-elf/got-page-7e.s, ld-mips-elf/got-page-7.d, ld-mips-elf/got-page-7.got: New tests. * ld-mips-elf/mips-elf.exp: Run them.
This commit is contained in:
parent
1d3ffd6bfe
commit
13db6b44ea
@ -1,3 +1,29 @@
|
||||
2013-02-13 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* elfxx-mips.c (mips_got_page_ref): New structure.
|
||||
(mips_got_page_entry): Use a section rather than a (bfd, symndx)
|
||||
pair to represent the anchor point.
|
||||
(mips_got_info): Add a got_page_refs field.
|
||||
(mips_elf_link_hash_table): Add a sym_cache field.
|
||||
(mips_got_page_ref_hash, mips_got_page_ref_eq): New functions.
|
||||
(mips_got_page_entry_hash, mips_got_page_entry_eq): Update for
|
||||
new anchor representation.
|
||||
(mips_elf_create_got_info): Create got_page_refs rather than
|
||||
got_page_entries.
|
||||
(mips_elf_record_got_page_ref): New function.
|
||||
(mips_elf_pages_for_range): Move further down file.
|
||||
(mips_elf_record_got_page_entry): Likewise. Take a got as argument.
|
||||
Use a section rather than a (bfd, symndx) pair to represent the
|
||||
anchor point.
|
||||
(mips_elf_resolve_got_page_ref): New function.
|
||||
(mips_elf_resolve_final_got_entries): Use it to populate
|
||||
got_page_entries.
|
||||
(_bfd_mips_elf_check_relocs): Call mips_elf_record_got_page_ref
|
||||
rather than mips_elf_record_got_page_entry. Only nullify h
|
||||
afterwards.
|
||||
(mips_elf_lay_out_got): Call mips_elf_resolve_final_got_entries
|
||||
earlier.
|
||||
|
||||
2013-02-12 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* elfxx-mips.c (mips_elf_lay_out_got): Count VxWorks GOT relocs
|
||||
|
416
bfd/elfxx-mips.c
416
bfd/elfxx-mips.c
@ -108,6 +108,27 @@ struct mips_got_entry
|
||||
long gotidx;
|
||||
};
|
||||
|
||||
/* This structure represents a GOT page reference from an input bfd.
|
||||
Each instance represents a symbol + ADDEND, where the representation
|
||||
of the symbol depends on whether it is local to the input bfd.
|
||||
If it is, then SYMNDX >= 0, and the symbol has index SYMNDX in U.ABFD.
|
||||
Otherwise, SYMNDX < 0 and U.H points to the symbol's hash table entry.
|
||||
|
||||
Page references with SYMNDX >= 0 always become page references
|
||||
in the output. Page references with SYMNDX < 0 only become page
|
||||
references if the symbol binds locally; in other cases, the page
|
||||
reference decays to a global GOT reference. */
|
||||
struct mips_got_page_ref
|
||||
{
|
||||
long symndx;
|
||||
union
|
||||
{
|
||||
struct mips_elf_link_hash_entry *h;
|
||||
bfd *abfd;
|
||||
} u;
|
||||
bfd_vma addend;
|
||||
};
|
||||
|
||||
/* This structure describes a range of addends: [MIN_ADDEND, MAX_ADDEND].
|
||||
The structures form a non-overlapping list that is sorted by increasing
|
||||
MIN_ADDEND. */
|
||||
@ -119,13 +140,11 @@ struct mips_got_page_range
|
||||
};
|
||||
|
||||
/* This structure describes the range of addends that are applied to page
|
||||
relocations against a given symbol. */
|
||||
relocations against a given section. */
|
||||
struct mips_got_page_entry
|
||||
{
|
||||
/* The input bfd in which the symbol is defined. */
|
||||
bfd *abfd;
|
||||
/* The index of the symbol, as stored in the relocation r_info. */
|
||||
long symndx;
|
||||
/* The section that these entries are based on. */
|
||||
asection *sec;
|
||||
/* The ranges for this page entry. */
|
||||
struct mips_got_page_range *ranges;
|
||||
/* The maximum number of page entries needed for RANGES. */
|
||||
@ -155,6 +174,8 @@ struct mips_got_info
|
||||
unsigned int assigned_gotno;
|
||||
/* A hash table holding members of the got. */
|
||||
struct htab *got_entries;
|
||||
/* A hash table holding mips_got_page_ref structures. */
|
||||
struct htab *got_page_refs;
|
||||
/* A hash table of mips_got_page_entry structures. */
|
||||
struct htab *got_page_entries;
|
||||
/* In multi-got links, a pointer to the next got (err, rather, most
|
||||
@ -444,6 +465,9 @@ struct mips_elf_link_hash_table
|
||||
The function returns the new section on success, otherwise it
|
||||
returns null. */
|
||||
asection *(*add_stub_section) (const char *, asection *, asection *);
|
||||
|
||||
/* Small local sym cache. */
|
||||
struct sym_cache sym_cache;
|
||||
};
|
||||
|
||||
/* Get the MIPS ELF linker hash table from a link_info structure. */
|
||||
@ -2770,13 +2794,39 @@ mips_elf_got_entry_eq (const void *entry1, const void *entry2)
|
||||
: e2->abfd && e1->d.h == e2->d.h));
|
||||
}
|
||||
|
||||
static hashval_t
|
||||
mips_got_page_ref_hash (const void *ref_)
|
||||
{
|
||||
const struct mips_got_page_ref *ref;
|
||||
|
||||
ref = (const struct mips_got_page_ref *) ref_;
|
||||
return ((ref->symndx >= 0
|
||||
? (hashval_t) (ref->u.abfd->id + ref->symndx)
|
||||
: ref->u.h->root.root.root.hash)
|
||||
+ mips_elf_hash_bfd_vma (ref->addend));
|
||||
}
|
||||
|
||||
static int
|
||||
mips_got_page_ref_eq (const void *ref1_, const void *ref2_)
|
||||
{
|
||||
const struct mips_got_page_ref *ref1, *ref2;
|
||||
|
||||
ref1 = (const struct mips_got_page_ref *) ref1_;
|
||||
ref2 = (const struct mips_got_page_ref *) ref2_;
|
||||
return (ref1->symndx == ref2->symndx
|
||||
&& (ref1->symndx < 0
|
||||
? ref1->u.h == ref2->u.h
|
||||
: ref1->u.abfd == ref2->u.abfd)
|
||||
&& ref1->addend == ref2->addend);
|
||||
}
|
||||
|
||||
static hashval_t
|
||||
mips_got_page_entry_hash (const void *entry_)
|
||||
{
|
||||
const struct mips_got_page_entry *entry;
|
||||
|
||||
entry = (const struct mips_got_page_entry *) entry_;
|
||||
return entry->abfd->id + entry->symndx;
|
||||
return entry->sec->id;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -2786,7 +2836,7 @@ mips_got_page_entry_eq (const void *entry1_, const void *entry2_)
|
||||
|
||||
entry1 = (const struct mips_got_page_entry *) entry1_;
|
||||
entry2 = (const struct mips_got_page_entry *) entry2_;
|
||||
return entry1->abfd == entry2->abfd && entry1->symndx == entry2->symndx;
|
||||
return entry1->sec == entry2->sec;
|
||||
}
|
||||
|
||||
/* Create and return a new mips_got_info structure. */
|
||||
@ -2805,9 +2855,9 @@ mips_elf_create_got_info (bfd *abfd)
|
||||
if (g->got_entries == NULL)
|
||||
return NULL;
|
||||
|
||||
g->got_page_entries = htab_try_create (1, mips_got_page_entry_hash,
|
||||
mips_got_page_entry_eq, NULL);
|
||||
if (g->got_page_entries == NULL)
|
||||
g->got_page_refs = htab_try_create (1, mips_got_page_ref_hash,
|
||||
mips_got_page_ref_eq, NULL);
|
||||
if (g->got_page_refs == NULL)
|
||||
return NULL;
|
||||
|
||||
return g;
|
||||
@ -2844,7 +2894,9 @@ mips_elf_replace_bfd_got (bfd *abfd, struct mips_got_info *g)
|
||||
/* The GOT structure itself and the hash table entries are
|
||||
allocated to a bfd, but the hash tables aren't. */
|
||||
htab_delete (tdata->got->got_entries);
|
||||
htab_delete (tdata->got->got_page_entries);
|
||||
htab_delete (tdata->got->got_page_refs);
|
||||
if (tdata->got->got_page_entries)
|
||||
htab_delete (tdata->got->got_page_entries);
|
||||
}
|
||||
tdata->got = g;
|
||||
}
|
||||
@ -3691,30 +3743,18 @@ mips_elf_record_local_got_symbol (bfd *abfd, long symndx, bfd_vma addend,
|
||||
return mips_elf_record_got_entry (info, abfd, &entry);
|
||||
}
|
||||
|
||||
/* Return the maximum number of GOT page entries required for RANGE. */
|
||||
|
||||
static bfd_vma
|
||||
mips_elf_pages_for_range (const struct mips_got_page_range *range)
|
||||
{
|
||||
return (range->max_addend - range->min_addend + 0x1ffff) >> 16;
|
||||
}
|
||||
|
||||
/* Record that ABFD has a page relocation against symbol SYMNDX and
|
||||
that ADDEND is the addend for that relocation.
|
||||
|
||||
This function creates an upper bound on the number of GOT slots
|
||||
required; no attempt is made to combine references to non-overridable
|
||||
global symbols across multiple input files. */
|
||||
/* Record that ABFD has a page relocation against SYMNDX + ADDEND.
|
||||
H is the symbol's hash table entry, or null if SYMNDX is local
|
||||
to ABFD. */
|
||||
|
||||
static bfd_boolean
|
||||
mips_elf_record_got_page_entry (struct bfd_link_info *info, bfd *abfd,
|
||||
long symndx, bfd_signed_vma addend)
|
||||
mips_elf_record_got_page_ref (struct bfd_link_info *info, bfd *abfd,
|
||||
long symndx, struct elf_link_hash_entry *h,
|
||||
bfd_signed_vma addend)
|
||||
{
|
||||
struct mips_elf_link_hash_table *htab;
|
||||
struct mips_got_info *g1, *g2;
|
||||
struct mips_got_page_entry lookup, *entry;
|
||||
struct mips_got_page_range **range_ptr, *range;
|
||||
bfd_vma old_pages, new_pages;
|
||||
struct mips_got_page_ref lookup, *entry;
|
||||
void **loc, **bfd_loc;
|
||||
|
||||
htab = mips_elf_hash_table (info);
|
||||
@ -3723,26 +3763,29 @@ mips_elf_record_got_page_entry (struct bfd_link_info *info, bfd *abfd,
|
||||
g1 = htab->got_info;
|
||||
BFD_ASSERT (g1 != NULL);
|
||||
|
||||
/* Find the mips_got_page_entry hash table entry for this symbol. */
|
||||
lookup.abfd = abfd;
|
||||
lookup.symndx = symndx;
|
||||
loc = htab_find_slot (g1->got_page_entries, &lookup, INSERT);
|
||||
if (h)
|
||||
{
|
||||
lookup.symndx = -1;
|
||||
lookup.u.h = (struct mips_elf_link_hash_entry *) h;
|
||||
}
|
||||
else
|
||||
{
|
||||
lookup.symndx = symndx;
|
||||
lookup.u.abfd = abfd;
|
||||
}
|
||||
lookup.addend = addend;
|
||||
loc = htab_find_slot (g1->got_page_refs, &lookup, INSERT);
|
||||
if (loc == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* Create a mips_got_page_entry if this is the first time we've
|
||||
seen the symbol. */
|
||||
entry = (struct mips_got_page_entry *) *loc;
|
||||
entry = (struct mips_got_page_ref *) *loc;
|
||||
if (!entry)
|
||||
{
|
||||
entry = bfd_alloc (abfd, sizeof (*entry));
|
||||
if (!entry)
|
||||
return FALSE;
|
||||
|
||||
entry->abfd = abfd;
|
||||
entry->symndx = symndx;
|
||||
entry->ranges = NULL;
|
||||
entry->num_pages = 0;
|
||||
*entry = lookup;
|
||||
*loc = entry;
|
||||
}
|
||||
|
||||
@ -3751,67 +3794,13 @@ mips_elf_record_got_page_entry (struct bfd_link_info *info, bfd *abfd,
|
||||
if (!g2)
|
||||
return FALSE;
|
||||
|
||||
bfd_loc = htab_find_slot (g2->got_page_entries, &lookup, INSERT);
|
||||
bfd_loc = htab_find_slot (g2->got_page_refs, &lookup, INSERT);
|
||||
if (!bfd_loc)
|
||||
return FALSE;
|
||||
|
||||
if (!*bfd_loc)
|
||||
*bfd_loc = entry;
|
||||
|
||||
/* Skip over ranges whose maximum extent cannot share a page entry
|
||||
with ADDEND. */
|
||||
range_ptr = &entry->ranges;
|
||||
while (*range_ptr && addend > (*range_ptr)->max_addend + 0xffff)
|
||||
range_ptr = &(*range_ptr)->next;
|
||||
|
||||
/* If we scanned to the end of the list, or found a range whose
|
||||
minimum extent cannot share a page entry with ADDEND, create
|
||||
a new singleton range. */
|
||||
range = *range_ptr;
|
||||
if (!range || addend < range->min_addend - 0xffff)
|
||||
{
|
||||
range = bfd_alloc (abfd, sizeof (*range));
|
||||
if (!range)
|
||||
return FALSE;
|
||||
|
||||
range->next = *range_ptr;
|
||||
range->min_addend = addend;
|
||||
range->max_addend = addend;
|
||||
|
||||
*range_ptr = range;
|
||||
entry->num_pages++;
|
||||
g1->page_gotno++;
|
||||
g2->page_gotno++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Remember how many pages the old range contributed. */
|
||||
old_pages = mips_elf_pages_for_range (range);
|
||||
|
||||
/* Update the ranges. */
|
||||
if (addend < range->min_addend)
|
||||
range->min_addend = addend;
|
||||
else if (addend > range->max_addend)
|
||||
{
|
||||
if (range->next && addend >= range->next->min_addend - 0xffff)
|
||||
{
|
||||
old_pages += mips_elf_pages_for_range (range->next);
|
||||
range->max_addend = range->next->max_addend;
|
||||
range->next = range->next->next;
|
||||
}
|
||||
else
|
||||
range->max_addend = addend;
|
||||
}
|
||||
|
||||
/* Record any change in the total estimate. */
|
||||
new_pages = mips_elf_pages_for_range (range);
|
||||
if (old_pages != new_pages)
|
||||
{
|
||||
entry->num_pages += new_pages - old_pages;
|
||||
g1->page_gotno += new_pages - old_pages;
|
||||
g2->page_gotno += new_pages - old_pages;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -3930,8 +3919,188 @@ mips_elf_recreate_got (void **entryp, void *data)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return the maximum number of GOT page entries required for RANGE. */
|
||||
|
||||
static bfd_vma
|
||||
mips_elf_pages_for_range (const struct mips_got_page_range *range)
|
||||
{
|
||||
return (range->max_addend - range->min_addend + 0x1ffff) >> 16;
|
||||
}
|
||||
|
||||
/* Record that G requires a page entry that can reach SEC + ADDEND. */
|
||||
|
||||
static bfd_boolean
|
||||
mips_elf_record_got_page_entry (struct mips_got_info *g,
|
||||
asection *sec, bfd_signed_vma addend)
|
||||
{
|
||||
struct mips_got_page_entry lookup, *entry;
|
||||
struct mips_got_page_range **range_ptr, *range;
|
||||
bfd_vma old_pages, new_pages;
|
||||
void **loc;
|
||||
|
||||
/* Find the mips_got_page_entry hash table entry for this section. */
|
||||
lookup.sec = sec;
|
||||
loc = htab_find_slot (g->got_page_entries, &lookup, INSERT);
|
||||
if (loc == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* Create a mips_got_page_entry if this is the first time we've
|
||||
seen the section. */
|
||||
entry = (struct mips_got_page_entry *) *loc;
|
||||
if (!entry)
|
||||
{
|
||||
entry = bfd_zalloc (sec->owner, sizeof (*entry));
|
||||
if (!entry)
|
||||
return FALSE;
|
||||
|
||||
entry->sec = sec;
|
||||
*loc = entry;
|
||||
}
|
||||
|
||||
/* Skip over ranges whose maximum extent cannot share a page entry
|
||||
with ADDEND. */
|
||||
range_ptr = &entry->ranges;
|
||||
while (*range_ptr && addend > (*range_ptr)->max_addend + 0xffff)
|
||||
range_ptr = &(*range_ptr)->next;
|
||||
|
||||
/* If we scanned to the end of the list, or found a range whose
|
||||
minimum extent cannot share a page entry with ADDEND, create
|
||||
a new singleton range. */
|
||||
range = *range_ptr;
|
||||
if (!range || addend < range->min_addend - 0xffff)
|
||||
{
|
||||
range = bfd_zalloc (sec->owner, sizeof (*range));
|
||||
if (!range)
|
||||
return FALSE;
|
||||
|
||||
range->next = *range_ptr;
|
||||
range->min_addend = addend;
|
||||
range->max_addend = addend;
|
||||
|
||||
*range_ptr = range;
|
||||
entry->num_pages++;
|
||||
g->page_gotno++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Remember how many pages the old range contributed. */
|
||||
old_pages = mips_elf_pages_for_range (range);
|
||||
|
||||
/* Update the ranges. */
|
||||
if (addend < range->min_addend)
|
||||
range->min_addend = addend;
|
||||
else if (addend > range->max_addend)
|
||||
{
|
||||
if (range->next && addend >= range->next->min_addend - 0xffff)
|
||||
{
|
||||
old_pages += mips_elf_pages_for_range (range->next);
|
||||
range->max_addend = range->next->max_addend;
|
||||
range->next = range->next->next;
|
||||
}
|
||||
else
|
||||
range->max_addend = addend;
|
||||
}
|
||||
|
||||
/* Record any change in the total estimate. */
|
||||
new_pages = mips_elf_pages_for_range (range);
|
||||
if (old_pages != new_pages)
|
||||
{
|
||||
entry->num_pages += new_pages - old_pages;
|
||||
g->page_gotno += new_pages - old_pages;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* A htab_traverse callback for which *REFP points to a mips_got_page_ref
|
||||
and for which DATA points to a mips_elf_traverse_got_arg. Work out
|
||||
whether the page reference described by *REFP needs a GOT page entry,
|
||||
and record that entry in DATA->g if so. Set DATA->g to null on failure. */
|
||||
|
||||
static bfd_boolean
|
||||
mips_elf_resolve_got_page_ref (void **refp, void *data)
|
||||
{
|
||||
struct mips_got_page_ref *ref;
|
||||
struct mips_elf_traverse_got_arg *arg;
|
||||
struct mips_elf_link_hash_table *htab;
|
||||
asection *sec;
|
||||
bfd_vma addend;
|
||||
|
||||
ref = (struct mips_got_page_ref *) *refp;
|
||||
arg = (struct mips_elf_traverse_got_arg *) data;
|
||||
htab = mips_elf_hash_table (arg->info);
|
||||
|
||||
if (ref->symndx < 0)
|
||||
{
|
||||
struct mips_elf_link_hash_entry *h;
|
||||
|
||||
/* Global GOT_PAGEs decay to GOT_DISP and so don't need page entries. */
|
||||
h = ref->u.h;
|
||||
if (!SYMBOL_REFERENCES_LOCAL (arg->info, &h->root))
|
||||
return 1;
|
||||
|
||||
/* Ignore undefined symbols; we'll issue an error later if
|
||||
appropriate. */
|
||||
if (!((h->root.root.type == bfd_link_hash_defined
|
||||
|| h->root.root.type == bfd_link_hash_defweak)
|
||||
&& h->root.root.u.def.section))
|
||||
return 1;
|
||||
|
||||
sec = h->root.root.u.def.section;
|
||||
addend = h->root.root.u.def.value + ref->addend;
|
||||
}
|
||||
else
|
||||
{
|
||||
Elf_Internal_Sym *isym;
|
||||
|
||||
/* Read in the symbol. */
|
||||
isym = bfd_sym_from_r_symndx (&htab->sym_cache, ref->u.abfd,
|
||||
ref->symndx);
|
||||
if (isym == NULL)
|
||||
{
|
||||
arg->g = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the associated input section. */
|
||||
sec = bfd_section_from_elf_index (ref->u.abfd, isym->st_shndx);
|
||||
if (sec == NULL)
|
||||
{
|
||||
arg->g = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If this is a mergable section, work out the section and offset
|
||||
of the merged data. For section symbols, the addend specifies
|
||||
of the offset _of_ the first byte in the data, otherwise it
|
||||
specifies the offset _from_ the first byte. */
|
||||
if (sec->flags & SEC_MERGE)
|
||||
{
|
||||
void *secinfo;
|
||||
|
||||
secinfo = elf_section_data (sec)->sec_info;
|
||||
if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
|
||||
addend = _bfd_merged_section_offset (ref->u.abfd, &sec, secinfo,
|
||||
isym->st_value + ref->addend);
|
||||
else
|
||||
addend = _bfd_merged_section_offset (ref->u.abfd, &sec, secinfo,
|
||||
isym->st_value) + ref->addend;
|
||||
}
|
||||
else
|
||||
addend = isym->st_value + ref->addend;
|
||||
}
|
||||
if (!mips_elf_record_got_page_entry (arg->g, sec, addend))
|
||||
{
|
||||
arg->g = NULL;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If any entries in G->got_entries are for indirect or warning symbols,
|
||||
replace them with entries for the target symbol. */
|
||||
replace them with entries for the target symbol. Convert g->got_page_refs
|
||||
into got_page_entry structures and estimate the number of page entries
|
||||
that they require. */
|
||||
|
||||
static bfd_boolean
|
||||
mips_elf_resolve_final_got_entries (struct bfd_link_info *info,
|
||||
@ -3961,6 +4130,16 @@ mips_elf_resolve_final_got_entries (struct bfd_link_info *info,
|
||||
|
||||
htab_delete (oldg.got_entries);
|
||||
}
|
||||
|
||||
g->got_page_entries = htab_try_create (1, mips_got_page_entry_hash,
|
||||
mips_got_page_entry_eq, NULL);
|
||||
if (g->got_page_entries == NULL)
|
||||
return FALSE;
|
||||
|
||||
tga.info = info;
|
||||
tga.g = g;
|
||||
htab_traverse (g->got_page_refs, mips_elf_resolve_got_page_ref, &tga);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -7823,21 +8002,6 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
|
||||
case R_MIPS_GOT_PAGE:
|
||||
case R_MICROMIPS_GOT_PAGE:
|
||||
/* If this is a global, overridable symbol, GOT_PAGE will
|
||||
decay to GOT_DISP, so we'll need a GOT entry for it. */
|
||||
if (h)
|
||||
{
|
||||
struct mips_elf_link_hash_entry *hmips =
|
||||
(struct mips_elf_link_hash_entry *) h;
|
||||
|
||||
/* This symbol is definitely not overridable. */
|
||||
if (hmips->root.def_regular
|
||||
&& ! (info->shared && ! info->symbolic
|
||||
&& ! hmips->root.forced_local))
|
||||
h = NULL;
|
||||
}
|
||||
/* Fall through. */
|
||||
|
||||
case R_MIPS16_GOT16:
|
||||
case R_MIPS_GOT16:
|
||||
case R_MIPS_GOT_HI16:
|
||||
@ -7866,10 +8030,24 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
}
|
||||
else
|
||||
addend = rel->r_addend;
|
||||
if (!mips_elf_record_got_page_entry (info, abfd, r_symndx,
|
||||
addend))
|
||||
if (!mips_elf_record_got_page_ref (info, abfd, r_symndx,
|
||||
h, addend))
|
||||
return FALSE;
|
||||
|
||||
if (h)
|
||||
{
|
||||
struct mips_elf_link_hash_entry *hmips =
|
||||
(struct mips_elf_link_hash_entry *) h;
|
||||
|
||||
/* This symbol is definitely not overridable. */
|
||||
if (hmips->root.def_regular
|
||||
&& ! (info->shared && ! info->symbolic
|
||||
&& ! hmips->root.forced_local))
|
||||
h = NULL;
|
||||
}
|
||||
}
|
||||
/* If this is a global, overridable symbol, GOT_PAGE will
|
||||
decay to GOT_DISP, so we'll need a GOT entry for it. */
|
||||
/* Fall through. */
|
||||
|
||||
case R_MIPS_GOT_DISP:
|
||||
@ -8602,6 +8780,9 @@ mips_elf_lay_out_got (bfd *output_bfd, struct bfd_link_info *info)
|
||||
count the number of reloc-only GOT symbols. */
|
||||
mips_elf_link_hash_traverse (htab, mips_elf_count_got_symbols, info);
|
||||
|
||||
if (!mips_elf_resolve_final_got_entries (info, g))
|
||||
return FALSE;
|
||||
|
||||
/* Calculate the total loadable size of the output. That
|
||||
will give us the maximum number of GOT_PAGE entries
|
||||
required. */
|
||||
@ -8630,18 +8811,13 @@ mips_elf_lay_out_got (bfd *output_bfd, struct bfd_link_info *info)
|
||||
sections. Is 5 enough? */
|
||||
page_gotno = (loadable_size >> 16) + 5;
|
||||
|
||||
/* Choose the smaller of the two estimates; both are intended to be
|
||||
/* Choose the smaller of the two page estimates; both are intended to be
|
||||
conservative. */
|
||||
if (page_gotno > g->page_gotno)
|
||||
page_gotno = g->page_gotno;
|
||||
|
||||
g->local_gotno += page_gotno;
|
||||
|
||||
/* Replace entries for indirect and warning symbols with entries for
|
||||
the target symbol. Count the number of GOT entries and TLS relocs. */
|
||||
if (!mips_elf_resolve_final_got_entries (info, g))
|
||||
return FALSE;
|
||||
|
||||
s->size += g->local_gotno * MIPS_ELF_GOT_SIZE (output_bfd);
|
||||
s->size += g->global_gotno * MIPS_ELF_GOT_SIZE (output_bfd);
|
||||
s->size += g->tls_gotno * MIPS_ELF_GOT_SIZE (output_bfd);
|
||||
|
@ -1,3 +1,19 @@
|
||||
2013-02-13 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* ld-mips-elf/mips16-pic-2.dd,
|
||||
ld-mips-elf/mips16-pic-2.gd: Remove 3 unused local GOT entries.
|
||||
* ld-mips-elf/got-page-4a.s, ld-mips-elf/got-page-4b.s,
|
||||
ld-mips-elf/got-page-4a.d, ld-mips-elf/got-page-4a.got,
|
||||
ld-mips-elf/got-page-4b.d, ld-mips-elf/got-page-4b.got,
|
||||
ld-mips-elf/got-page-5.s, ld-mips-elf/got-page-5.d,
|
||||
ld-mips-elf/got-page-5.got, ld-mips-elf/got-page-6.s,
|
||||
ld-mips-elf/got-page-6.d, ld-mips-elf/got-page-6.got,
|
||||
ld-mips-elf/got-page-7a.s, ld-mips-elf/got-page-7b.s,
|
||||
ld-mips-elf/got-page-7c.s, ld-mips-elf/got-page-7d.s,
|
||||
ld-mips-elf/got-page-7e.s, ld-mips-elf/got-page-7.d,
|
||||
ld-mips-elf/got-page-7.got: New tests.
|
||||
* ld-mips-elf/mips-elf.exp: Run them.
|
||||
|
||||
2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* ld-mips-elf/tlsdyn-o32-1.d, ld-mips-elf/tlsdyn-o32-1.got,
|
||||
|
35
ld/testsuite/ld-mips-elf/got-page-4a.d
Normal file
35
ld/testsuite/ld-mips-elf/got-page-4a.d
Normal file
@ -0,0 +1,35 @@
|
||||
#...
|
||||
.* <foo>:
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,0
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,4
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,8
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,12
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,16
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,20
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,24
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,28
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,32
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,36
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,40
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,44
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,48
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,52
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,56
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,60
|
||||
#pass
|
7
ld/testsuite/ld-mips-elf/got-page-4a.got
Normal file
7
ld/testsuite/ld-mips-elf/got-page-4a.got
Normal file
@ -0,0 +1,7 @@
|
||||
#...
|
||||
Local entries:
|
||||
Address Access Initial
|
||||
00090008 -32744\(gp\) 00080000
|
||||
0009000c -32740\(gp\) 00000000
|
||||
|
||||
#pass
|
14
ld/testsuite/ld-mips-elf/got-page-4a.s
Normal file
14
ld/testsuite/ld-mips-elf/got-page-4a.s
Normal file
@ -0,0 +1,14 @@
|
||||
.section .rodata.cst4,"aM",@progbits,4
|
||||
.set x,0x01000000
|
||||
.set y,0x02000000
|
||||
# Add the 16 values that the next input file wants, but in such
|
||||
# a way that each one lives on a separate page.
|
||||
.rept 15
|
||||
.word y
|
||||
.set y,y+1
|
||||
.rept 0x4000
|
||||
.word x
|
||||
.set x,x+1
|
||||
.endr
|
||||
.endr
|
||||
.word y
|
36
ld/testsuite/ld-mips-elf/got-page-4b.d
Normal file
36
ld/testsuite/ld-mips-elf/got-page-4b.d
Normal file
@ -0,0 +1,36 @@
|
||||
#...
|
||||
.* <foo>:
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,0
|
||||
.* lw a0,-32740\(gp\)
|
||||
.* addiu a0,a0,4
|
||||
.* lw a0,-32736\(gp\)
|
||||
.* addiu a0,a0,8
|
||||
.* lw a0,-32732\(gp\)
|
||||
.* addiu a0,a0,12
|
||||
.* lw a0,-32728\(gp\)
|
||||
.* addiu a0,a0,16
|
||||
.* lw a0,-32724\(gp\)
|
||||
.* addiu a0,a0,20
|
||||
.* lw a0,-32720\(gp\)
|
||||
.* addiu a0,a0,24
|
||||
.* lw a0,-32716\(gp\)
|
||||
.* addiu a0,a0,28
|
||||
.* lw a0,-32712\(gp\)
|
||||
.* addiu a0,a0,32
|
||||
.* lw a0,-32708\(gp\)
|
||||
.* addiu a0,a0,36
|
||||
.* lw a0,-32704\(gp\)
|
||||
.* addiu a0,a0,40
|
||||
.* lw a0,-32700\(gp\)
|
||||
.* addiu a0,a0,44
|
||||
.* lw a0,-32696\(gp\)
|
||||
.* addiu a0,a0,48
|
||||
.* lw a0,-32692\(gp\)
|
||||
.* addiu a0,a0,52
|
||||
.* lw a0,-32688\(gp\)
|
||||
.* addiu a0,a0,56
|
||||
.* lw a0,-32684\(gp\)
|
||||
.* addiu a0,a0,60
|
||||
|
||||
#pass
|
21
ld/testsuite/ld-mips-elf/got-page-4b.got
Normal file
21
ld/testsuite/ld-mips-elf/got-page-4b.got
Normal file
@ -0,0 +1,21 @@
|
||||
#...
|
||||
Local entries:
|
||||
Address Access Initial
|
||||
00180008 -32744\(gp\) 00080000
|
||||
0018000c -32740\(gp\) 00090000
|
||||
00180010 -32736\(gp\) 000a0000
|
||||
00180014 -32732\(gp\) 000b0000
|
||||
00180018 -32728\(gp\) 000c0000
|
||||
0018001c -32724\(gp\) 000d0000
|
||||
00180020 -32720\(gp\) 000e0000
|
||||
00180024 -32716\(gp\) 000f0000
|
||||
00180028 -32712\(gp\) 00100000
|
||||
0018002c -32708\(gp\) 00110000
|
||||
00180030 -32704\(gp\) 00120000
|
||||
00180034 -32700\(gp\) 00130000
|
||||
00180038 -32696\(gp\) 00140000
|
||||
0018003c -32692\(gp\) 00150000
|
||||
00180040 -32688\(gp\) 00160000
|
||||
00180044 -32684\(gp\) 00170000
|
||||
|
||||
#pass
|
21
ld/testsuite/ld-mips-elf/got-page-4b.s
Normal file
21
ld/testsuite/ld-mips-elf/got-page-4b.s
Normal file
@ -0,0 +1,21 @@
|
||||
.globl foo
|
||||
.ent foo
|
||||
foo:
|
||||
# Create page references to 16 values. The layout of the values
|
||||
# in this input file requires at most 2 page entries.
|
||||
.set y,0x02000000
|
||||
.rept 16
|
||||
lw $4,%got_page(1f)($gp)
|
||||
addiu $4,$4,%got_ofst(1f)
|
||||
.section .rodata.cst4,"aM",@progbits,4
|
||||
1: .word y
|
||||
.set y,y+1
|
||||
.text
|
||||
.endr
|
||||
.end foo
|
||||
|
||||
# Make sure the loadable size of the library is large.
|
||||
.section .bss
|
||||
.globl g
|
||||
g:
|
||||
.space 0x800000
|
10
ld/testsuite/ld-mips-elf/got-page-5.d
Normal file
10
ld/testsuite/ld-mips-elf/got-page-5.d
Normal file
@ -0,0 +1,10 @@
|
||||
#...
|
||||
.* <foo>:
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,0
|
||||
.* lw a0,-32740\(gp\)
|
||||
.* addiu a0,a0,-32768
|
||||
.* lw a0,-32740\(gp\)
|
||||
.* addiu a0,a0,0
|
||||
.* lw a0,-32736\(gp\)
|
||||
.* addiu a0,a0,-32768
|
8
ld/testsuite/ld-mips-elf/got-page-5.got
Normal file
8
ld/testsuite/ld-mips-elf/got-page-5.got
Normal file
@ -0,0 +1,8 @@
|
||||
#...
|
||||
Local entries:
|
||||
Address Access Initial
|
||||
00090008 -32744\(gp\) 00080000
|
||||
0009000c -32740\(gp\) 00090000
|
||||
00090010 -32736\(gp\) 000a0000
|
||||
|
||||
#pass
|
31
ld/testsuite/ld-mips-elf/got-page-5.s
Normal file
31
ld/testsuite/ld-mips-elf/got-page-5.s
Normal file
@ -0,0 +1,31 @@
|
||||
# Create a mergeable section full of a single value,
|
||||
# and page references relative to one entry called "data".
|
||||
#
|
||||
# The mergeable entries collapse to one, but the offsets
|
||||
# from "data" must still be retained, and need 3 page entries.
|
||||
#
|
||||
# Technically this isn't valid, because it creates out-of-section
|
||||
# page references. It's still a useful way of making sure that
|
||||
# offsets in mergeable sections are handled correctly.
|
||||
.globl foo
|
||||
.ent foo
|
||||
foo:
|
||||
.set y,0
|
||||
.rept 4
|
||||
lw $4,%got_page(data + y)($gp)
|
||||
addiu $4,$4,%got_ofst(data + y)
|
||||
.set y,y+0x8000
|
||||
.endr
|
||||
.end foo
|
||||
|
||||
.section .rodata.cst4,"aM",@progbits,4
|
||||
data:
|
||||
.rept 0x8000*4
|
||||
.word 123456
|
||||
.endr
|
||||
|
||||
# Make sure the loadable size of the library is large.
|
||||
.section .bss
|
||||
.globl g
|
||||
g:
|
||||
.space 0x800000
|
10
ld/testsuite/ld-mips-elf/got-page-6.d
Normal file
10
ld/testsuite/ld-mips-elf/got-page-6.d
Normal file
@ -0,0 +1,10 @@
|
||||
#...
|
||||
.* <foo>:
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,0
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,0
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,0
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,0
|
6
ld/testsuite/ld-mips-elf/got-page-6.got
Normal file
6
ld/testsuite/ld-mips-elf/got-page-6.got
Normal file
@ -0,0 +1,6 @@
|
||||
#...
|
||||
Local entries:
|
||||
Address Access Initial
|
||||
00090008 -32744\(gp\) 00080000
|
||||
|
||||
#pass
|
27
ld/testsuite/ld-mips-elf/got-page-6.s
Normal file
27
ld/testsuite/ld-mips-elf/got-page-6.s
Normal file
@ -0,0 +1,27 @@
|
||||
# Create a mergeable section full of a single value.
|
||||
# Create page references relative to instances of the value
|
||||
# that are large distances apart.
|
||||
#
|
||||
# The mergeable entries collapse to one, so even with the
|
||||
# large distances in the original file, we should end
|
||||
# up with a single page entry.
|
||||
.globl foo
|
||||
.ent foo
|
||||
foo:
|
||||
.rept 4
|
||||
lw $4,%got_page(1f)($gp)
|
||||
addiu $4,$4,%got_ofst(1f)
|
||||
.section .rodata.cst4,"aM",@progbits,4
|
||||
1:
|
||||
.rept 0x8000
|
||||
.word 123456
|
||||
.endr
|
||||
.text
|
||||
.endr
|
||||
.end foo
|
||||
|
||||
# Make sure the loadable size of the library is large.
|
||||
.section .bss
|
||||
.globl g
|
||||
g:
|
||||
.space 0x800000
|
17
ld/testsuite/ld-mips-elf/got-page-7.d
Normal file
17
ld/testsuite/ld-mips-elf/got-page-7.d
Normal file
@ -0,0 +1,17 @@
|
||||
#...
|
||||
.* <f1>:
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,1024
|
||||
#...
|
||||
.* <f2>:
|
||||
.* lw a0,-32744\(gp\)
|
||||
.* addiu a0,a0,17408
|
||||
#...
|
||||
.* <f3>:
|
||||
.* lw a0,-32740\(gp\)
|
||||
.* addiu a0,a0,-31744
|
||||
#...
|
||||
.* <f4>:
|
||||
.* lw a0,-32740\(gp\)
|
||||
.* addiu a0,a0,1024
|
||||
#pass
|
7
ld/testsuite/ld-mips-elf/got-page-7.got
Normal file
7
ld/testsuite/ld-mips-elf/got-page-7.got
Normal file
@ -0,0 +1,7 @@
|
||||
#...
|
||||
Local entries:
|
||||
Address Access Initial
|
||||
00090008 -32744\(gp\) 00090000
|
||||
0009000c -32740\(gp\) 000a0000
|
||||
|
||||
#pass
|
6
ld/testsuite/ld-mips-elf/got-page-7a.s
Normal file
6
ld/testsuite/ld-mips-elf/got-page-7a.s
Normal file
@ -0,0 +1,6 @@
|
||||
.globl f1
|
||||
.ent f1
|
||||
f1:
|
||||
lw $4,%got_page(g)($gp)
|
||||
addiu $4,$4,%got_ofst(g)
|
||||
.end f1
|
6
ld/testsuite/ld-mips-elf/got-page-7b.s
Normal file
6
ld/testsuite/ld-mips-elf/got-page-7b.s
Normal file
@ -0,0 +1,6 @@
|
||||
.globl f2
|
||||
.ent f2
|
||||
f2:
|
||||
lw $4,%got_page(g + 0x4000)($gp)
|
||||
addiu $4,$4,%got_ofst(g + 0x4000)
|
||||
.end f2
|
6
ld/testsuite/ld-mips-elf/got-page-7c.s
Normal file
6
ld/testsuite/ld-mips-elf/got-page-7c.s
Normal file
@ -0,0 +1,6 @@
|
||||
.globl f3
|
||||
.ent f3
|
||||
f3:
|
||||
lw $4,%got_page(g + 0x8000)($gp)
|
||||
addiu $4,$4,%got_ofst(g + 0x8000)
|
||||
.end f3
|
6
ld/testsuite/ld-mips-elf/got-page-7d.s
Normal file
6
ld/testsuite/ld-mips-elf/got-page-7d.s
Normal file
@ -0,0 +1,6 @@
|
||||
.globl f4
|
||||
.ent f4
|
||||
f4:
|
||||
lw $4,%got_page(g + 0x10000)($gp)
|
||||
addiu $4,$4,%got_ofst(g + 0x10000)
|
||||
.end f4
|
6
ld/testsuite/ld-mips-elf/got-page-7e.s
Normal file
6
ld/testsuite/ld-mips-elf/got-page-7e.s
Normal file
@ -0,0 +1,6 @@
|
||||
# Make sure the loadable size of the library is large.
|
||||
.section .bss
|
||||
.globl g
|
||||
.hidden g
|
||||
g:
|
||||
.space 0x800000
|
@ -453,6 +453,46 @@ if { $linux_gnu } {
|
||||
run_dump_test "dyn-sec64"
|
||||
}
|
||||
run_dump_test "got-page-3"
|
||||
run_ld_link_tests [subst {
|
||||
{"GOT page 4 (one file)" "-shared $abi_ldflags(o32) -T got-page-1.ld"
|
||||
"$abi_asflags(o32) -mips2" {got-page-4b.s}
|
||||
{{objdump -dr got-page-4a.d}
|
||||
{readelf -A got-page-4a.got}}
|
||||
"got-page-4a.so"}
|
||||
{"GOT page 4 (two files)" "-shared $abi_ldflags(o32) -T got-page-1.ld"
|
||||
"$abi_asflags(o32) -mips2" {got-page-4a.s got-page-4b.s}
|
||||
{{objdump -dr got-page-4b.d}
|
||||
{readelf -A got-page-4b.got}}
|
||||
"got-page-4b.so"}
|
||||
}]
|
||||
if $has_newabi {
|
||||
run_ld_link_tests [subst {
|
||||
{"GOT page 5" "-shared $abi_ldflags(n32) -T got-page-1.ld"
|
||||
"$abi_asflags(n32)" {got-page-5.s}
|
||||
{{objdump -dr got-page-5.d}
|
||||
{readelf -A got-page-5.got}}
|
||||
"got-page-5.so"}
|
||||
{"GOT page 6" "-shared $abi_ldflags(n32) -T got-page-1.ld"
|
||||
"$abi_asflags(n32)" {got-page-6.s}
|
||||
{{objdump -dr got-page-6.d}
|
||||
{readelf -A got-page-6.got}}
|
||||
"got-page-6.so"}
|
||||
{"GOT page 7 (order 1)" "-shared $abi_ldflags(n32) -T got-page-1.ld"
|
||||
"$abi_asflags(n32)"
|
||||
{got-page-7a.s got-page-7b.s got-page-7c.s got-page-7d.s
|
||||
got-page-7e.s}
|
||||
{{objdump -dr got-page-7.d}
|
||||
{readelf -A got-page-7.got}}
|
||||
"got-page-7a.so"}
|
||||
{"GOT page 7 (order 2)" "-shared $abi_ldflags(n32) -T got-page-1.ld"
|
||||
"$abi_asflags(n32)"
|
||||
{got-page-7e.s got-page-7a.s got-page-7b.s got-page-7c.s
|
||||
got-page-7d.s}
|
||||
{{objdump -dr got-page-7.d}
|
||||
{readelf -A got-page-7.got}}
|
||||
"got-page-7b.so"}
|
||||
}]
|
||||
}
|
||||
run_dump_test "got-dump-1"
|
||||
if $has_newabi {
|
||||
run_dump_test "got-dump-2"
|
||||
|
@ -77,7 +77,7 @@ Disassembly of section \.text:
|
||||
.*: [^\t]* move t9,v0
|
||||
.*: [^\t]* lw v0,16\(sp\)
|
||||
.*: [^\t]* move gp,v0
|
||||
.*: [^\t]* lw v0,-32716\(v0\)
|
||||
.*: [^\t]* lw v0,-32728\(v0\)
|
||||
.*: [^\t]* jalr v0
|
||||
.*: [^\t]* move t9,v0
|
||||
.*: [^\t]* lw v0,16\(sp\)
|
||||
@ -101,7 +101,7 @@ Disassembly of section \.text:
|
||||
.*: [^\t]* move t9,v0
|
||||
.*: [^\t]* lw v0,16\(sp\)
|
||||
.*: [^\t]* move gp,v0
|
||||
.*: [^\t]* lw v0,-32712\(v0\)
|
||||
.*: [^\t]* lw v0,-32724\(v0\)
|
||||
.*: [^\t]* jalr v0
|
||||
.*: [^\t]* move t9,v0
|
||||
.*: [^\t]* lw v0,16\(sp\)
|
||||
|
@ -13,14 +13,11 @@ Primary GOT:
|
||||
0005000c -32740\(gp\) 00040409
|
||||
00050010 -32736\(gp\) 0004040d
|
||||
00050014 -32732\(gp\) 00000000
|
||||
00050018 -32728\(gp\) 00000000
|
||||
0005001c -32724\(gp\) 00000000
|
||||
00050020 -32720\(gp\) 00000000
|
||||
|
||||
Global entries:
|
||||
Address Access Initial Sym\.Val\. Type Ndx Name
|
||||
00050024 -32716\(gp\) 00040574 00040574 FUNC 6 used6
|
||||
00050028 -32712\(gp\) 00040598 00040598 FUNC 6 used7
|
||||
0005002c -32708\(gp\) 00040550 00040550 FUNC 6 used5
|
||||
00050030 -32704\(gp\) 0004052c 0004052c FUNC 6 used4
|
||||
00050018 -32728\(gp\) 00040574 00040574 FUNC 6 used6
|
||||
0005001c -32724\(gp\) 00040598 00040598 FUNC 6 used7
|
||||
00050020 -32720\(gp\) 00040550 00040550 FUNC 6 used5
|
||||
00050024 -32716\(gp\) 0004052c 0004052c FUNC 6 used4
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user