mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-12-01 16:35:04 +00:00
bfd/
* elfxx-mips.c (_mips_elf_section_data): Remove the "u.got_info" field. (mips_elf_link_hash_table): Add "sgot" and "got_info" fields. (_bfd_mips_elf_link_hash_table_create): Initialize them. (mips_elf_got_section): Always apply the !maybe_excluded behavior. (mips_elf_got_info): Delete. (mips_elf_initialize_tls_slots): Remove the DYNOBJ local variable. Adjust the call to mips_elf_got_section. (mips_elf_local_got_index): Don't call mips_elf_got_info. Update the call to mips_elf_create_local_got_entry. Use htab->got_info. (mips_elf_global_got_index): Don't call mips_elf_got_info; use htab->got_info and htab->sgot instead. (mips_elf_got_page): Don't call mips_elf_got_info. Update the call to mips_elf_create_local_got_entry. (mips_elf_got16_entry): Likewise. (mips_elf_got_offset_from_index): Replace with DYNOBJ parameter with an INFO parameter. Don't call mips_elf_got_info; use htab->sgot and htab->got_info instead. (mips_elf_create_local_got_entry): Remove the GG and SGOT parameters. Use htab->sgot and htab->got_info. (mips_elf_sort_hash_table): Remove the DYNOBJ local variable. Don't call mips_elf_got_info; use htab->got_info instead. (mips_elf_record_global_got_symbol): Turn G from a paramter to a local variable and read it from htab->got_info. (mips_elf_record_local_got_symbol): Replace the G parameter with an INFO parameter. Make G a local variable and read it from htab->got_info instead. (mips_elf_record_got_page_entry): Likewise. (mips_elf_multi_got): Remove the G parameter and make it a local variable instead. Read it from htab->got_info. (mips_elf_create_got_section): Cache the GOT section in htab->sgot. Store the GOT information in htab->got_info. (mips_elf_calculate_relocation): Don't call mips_elf_got_section and mips_elf_got_info; use htab->sgot and htab->got_info instead. Adjust the calls to mips_elf_got_offset_from_index and mips_elf_adjust_gp. (_bfd_mips_elf_check_relocs): Remove the G and SGOT local variables. Adjust the calls to mips_elf_record_local_got_symbol, mips_elf_record_global_got_symbol and mips_elf_record_got_page_entry. Use htab->sgot. (_bfd_mips_elf_always_size_sections): Remove the DYNOBJ local variable. Don't call mips_elf_got_info; use htab->sgot and htab->got_info instead. Update the call to mips_elf_multi_got. (_bfd_mips_elf_size_dynamic_sections): Don't call mips_elf_got_info; use htab->got_info instead. (_bfd_mips_elf_finish_dynamic_symbol): Update the call to mips_elf_got_section. Get the got_info from the hash table rather than the GOT section. (_bfd_mips_vxworks_finish_dynamic_symbol): Likewise. (_bfd_mips_elf_finish_dynamic_sections): Likewise. (_bfd_mips_elf_hide_symbol): Don't call mips_elf_got_section; get the got_info from the hash table instead. Remove the GOT local variable. (_bfd_mips_elf_final_link): Likewise. Also remove the DYNOBJ local variable.
This commit is contained in:
parent
4e41d0d7c3
commit
a8028dd09a
@ -1,3 +1,61 @@
|
||||
2008-08-06 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* elfxx-mips.c (_mips_elf_section_data): Remove the "u.got_info" field.
|
||||
(mips_elf_link_hash_table): Add "sgot" and "got_info" fields.
|
||||
(_bfd_mips_elf_link_hash_table_create): Initialize them.
|
||||
(mips_elf_got_section): Always apply the !maybe_excluded behavior.
|
||||
(mips_elf_got_info): Delete.
|
||||
(mips_elf_initialize_tls_slots): Remove the DYNOBJ local variable.
|
||||
Adjust the call to mips_elf_got_section.
|
||||
(mips_elf_local_got_index): Don't call mips_elf_got_info.
|
||||
Update the call to mips_elf_create_local_got_entry.
|
||||
Use htab->got_info.
|
||||
(mips_elf_global_got_index): Don't call mips_elf_got_info;
|
||||
use htab->got_info and htab->sgot instead.
|
||||
(mips_elf_got_page): Don't call mips_elf_got_info. Update the
|
||||
call to mips_elf_create_local_got_entry.
|
||||
(mips_elf_got16_entry): Likewise.
|
||||
(mips_elf_got_offset_from_index): Replace with DYNOBJ parameter
|
||||
with an INFO parameter. Don't call mips_elf_got_info; use htab->sgot
|
||||
and htab->got_info instead.
|
||||
(mips_elf_create_local_got_entry): Remove the GG and SGOT parameters.
|
||||
Use htab->sgot and htab->got_info.
|
||||
(mips_elf_sort_hash_table): Remove the DYNOBJ local variable.
|
||||
Don't call mips_elf_got_info; use htab->got_info instead.
|
||||
(mips_elf_record_global_got_symbol): Turn G from a paramter to
|
||||
a local variable and read it from htab->got_info.
|
||||
(mips_elf_record_local_got_symbol): Replace the G parameter with
|
||||
an INFO parameter. Make G a local variable and read it from
|
||||
htab->got_info instead.
|
||||
(mips_elf_record_got_page_entry): Likewise.
|
||||
(mips_elf_multi_got): Remove the G parameter and make it a local
|
||||
variable instead. Read it from htab->got_info.
|
||||
(mips_elf_create_got_section): Cache the GOT section in htab->sgot.
|
||||
Store the GOT information in htab->got_info.
|
||||
(mips_elf_calculate_relocation): Don't call mips_elf_got_section
|
||||
and mips_elf_got_info; use htab->sgot and htab->got_info instead.
|
||||
Adjust the calls to mips_elf_got_offset_from_index and
|
||||
mips_elf_adjust_gp.
|
||||
(_bfd_mips_elf_check_relocs): Remove the G and SGOT local variables.
|
||||
Adjust the calls to mips_elf_record_local_got_symbol,
|
||||
mips_elf_record_global_got_symbol and mips_elf_record_got_page_entry.
|
||||
Use htab->sgot.
|
||||
(_bfd_mips_elf_always_size_sections): Remove the DYNOBJ local variable.
|
||||
Don't call mips_elf_got_info; use htab->sgot and htab->got_info instead.
|
||||
Update the call to mips_elf_multi_got.
|
||||
(_bfd_mips_elf_size_dynamic_sections): Don't call mips_elf_got_info;
|
||||
use htab->got_info instead.
|
||||
(_bfd_mips_elf_finish_dynamic_symbol): Update the call to
|
||||
mips_elf_got_section. Get the got_info from the hash table
|
||||
rather than the GOT section.
|
||||
(_bfd_mips_vxworks_finish_dynamic_symbol): Likewise.
|
||||
(_bfd_mips_elf_finish_dynamic_sections): Likewise.
|
||||
(_bfd_mips_elf_hide_symbol): Don't call mips_elf_got_section;
|
||||
get the got_info from the hash table instead. Remove the GOT
|
||||
local variable.
|
||||
(_bfd_mips_elf_final_link): Likewise. Also remove the DYNOBJ
|
||||
local variable.
|
||||
|
||||
2008-08-06 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* elfxx-mips.c (mips_elf_link_hash_table): Add an "sstubs" field.
|
||||
|
278
bfd/elfxx-mips.c
278
bfd/elfxx-mips.c
@ -234,7 +234,6 @@ struct _mips_elf_section_data
|
||||
struct bfd_elf_section_data elf;
|
||||
union
|
||||
{
|
||||
struct mips_got_info *got_info;
|
||||
bfd_byte *tdata;
|
||||
} u;
|
||||
};
|
||||
@ -364,6 +363,9 @@ struct mips_elf_link_hash_table
|
||||
asection *sgotplt;
|
||||
asection *splt;
|
||||
asection *sstubs;
|
||||
asection *sgot;
|
||||
/* The master GOT information. */
|
||||
struct mips_got_info *got_info;
|
||||
/* The size of the PLT header in bytes (VxWorks only). */
|
||||
bfd_vma plt_header_size;
|
||||
/* The size of a PLT entry in bytes (VxWorks only). */
|
||||
@ -520,8 +522,8 @@ typedef struct runtime_pdr {
|
||||
#define rpdNil ((pRPDR) 0)
|
||||
|
||||
static struct mips_got_entry *mips_elf_create_local_got_entry
|
||||
(bfd *, struct bfd_link_info *, bfd *, struct mips_got_info *, asection *,
|
||||
bfd_vma, unsigned long, struct mips_elf_link_hash_entry *, int);
|
||||
(bfd *, struct bfd_link_info *, bfd *, bfd_vma, unsigned long,
|
||||
struct mips_elf_link_hash_entry *, int);
|
||||
static bfd_boolean mips_elf_sort_hash_table_f
|
||||
(struct mips_elf_link_hash_entry *, void *);
|
||||
static bfd_vma mips_elf_high
|
||||
@ -2256,38 +2258,17 @@ mips_elf_rel_dyn_section (struct bfd_link_info *info, bfd_boolean create_p)
|
||||
return sreloc;
|
||||
}
|
||||
|
||||
/* Returns the GOT section for ABFD. */
|
||||
/* Returns the GOT section, if it hasn't been excluded. */
|
||||
|
||||
static asection *
|
||||
mips_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded)
|
||||
mips_elf_got_section (struct bfd_link_info *info)
|
||||
{
|
||||
asection *sgot = bfd_get_section_by_name (abfd, ".got");
|
||||
if (sgot == NULL
|
||||
|| (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0))
|
||||
struct mips_elf_link_hash_table *htab;
|
||||
|
||||
htab = mips_elf_hash_table (info);
|
||||
if (htab->sgot == NULL || (htab->sgot->flags & SEC_EXCLUDE) != 0)
|
||||
return NULL;
|
||||
return sgot;
|
||||
}
|
||||
|
||||
/* Returns the GOT information associated with the link indicated by
|
||||
INFO. If SGOTP is non-NULL, it is filled in with the GOT
|
||||
section. */
|
||||
|
||||
static struct mips_got_info *
|
||||
mips_elf_got_info (bfd *abfd, asection **sgotp)
|
||||
{
|
||||
asection *sgot;
|
||||
struct mips_got_info *g;
|
||||
|
||||
sgot = mips_elf_got_section (abfd, TRUE);
|
||||
BFD_ASSERT (sgot != NULL);
|
||||
BFD_ASSERT (mips_elf_section_data (sgot) != NULL);
|
||||
g = mips_elf_section_data (sgot)->u.got_info;
|
||||
BFD_ASSERT (g != NULL);
|
||||
|
||||
if (sgotp)
|
||||
*sgotp = (sgot->flags & SEC_EXCLUDE) == 0 ? sgot : NULL;
|
||||
|
||||
return g;
|
||||
return htab->sgot;
|
||||
}
|
||||
|
||||
/* Count the number of relocations needed for a TLS GOT entry, with
|
||||
@ -2423,11 +2404,9 @@ mips_elf_initialize_tls_slots (bfd *abfd, bfd_vma got_offset,
|
||||
int indx;
|
||||
asection *sreloc, *sgot;
|
||||
bfd_vma offset, offset2;
|
||||
bfd *dynobj;
|
||||
bfd_boolean need_relocs = FALSE;
|
||||
|
||||
dynobj = elf_hash_table (info)->dynobj;
|
||||
sgot = mips_elf_got_section (dynobj, FALSE);
|
||||
sgot = mips_elf_got_section (info);
|
||||
|
||||
indx = 0;
|
||||
if (h != NULL)
|
||||
@ -2614,20 +2593,18 @@ mips_elf_local_got_index (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
|
||||
bfd_vma value, unsigned long r_symndx,
|
||||
struct mips_elf_link_hash_entry *h, int r_type)
|
||||
{
|
||||
asection *sgot;
|
||||
struct mips_got_info *g;
|
||||
struct mips_elf_link_hash_table *htab;
|
||||
struct mips_got_entry *entry;
|
||||
|
||||
g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
|
||||
|
||||
entry = mips_elf_create_local_got_entry (abfd, info, ibfd, g, sgot,
|
||||
value, r_symndx, h, r_type);
|
||||
htab = mips_elf_hash_table (info);
|
||||
entry = mips_elf_create_local_got_entry (abfd, info, ibfd, value,
|
||||
r_symndx, h, r_type);
|
||||
if (!entry)
|
||||
return MINUS_ONE;
|
||||
|
||||
if (TLS_RELOC_P (r_type))
|
||||
{
|
||||
if (entry->symndx == -1 && g->next == NULL)
|
||||
if (entry->symndx == -1 && htab->got_info->next == NULL)
|
||||
/* A type (3) entry in the single-GOT case. We use the symbol's
|
||||
hash table entry to track the index. */
|
||||
return mips_tls_got_index (abfd, h->tls_got_offset, &h->tls_type,
|
||||
@ -2646,12 +2623,13 @@ static bfd_vma
|
||||
mips_elf_global_got_index (bfd *abfd, bfd *ibfd, struct elf_link_hash_entry *h,
|
||||
int r_type, struct bfd_link_info *info)
|
||||
{
|
||||
struct mips_elf_link_hash_table *htab;
|
||||
bfd_vma index;
|
||||
asection *sgot;
|
||||
struct mips_got_info *g, *gg;
|
||||
long global_got_dynindx = 0;
|
||||
|
||||
gg = g = mips_elf_got_info (abfd, &sgot);
|
||||
htab = mips_elf_hash_table (info);
|
||||
gg = g = htab->got_info;
|
||||
if (g->bfd2got && ibfd)
|
||||
{
|
||||
struct mips_got_entry e, *p;
|
||||
@ -2717,7 +2695,7 @@ mips_elf_global_got_index (bfd *abfd, bfd *ibfd, struct elf_link_hash_entry *h,
|
||||
index = ((h->dynindx - global_got_dynindx + g->local_gotno)
|
||||
* MIPS_ELF_GOT_SIZE (abfd));
|
||||
}
|
||||
BFD_ASSERT (index < sgot->size);
|
||||
BFD_ASSERT (index < htab->sgot->size);
|
||||
|
||||
return index;
|
||||
}
|
||||
@ -2732,16 +2710,12 @@ static bfd_vma
|
||||
mips_elf_got_page (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
|
||||
bfd_vma value, bfd_vma *offsetp)
|
||||
{
|
||||
asection *sgot;
|
||||
struct mips_got_info *g;
|
||||
bfd_vma page, index;
|
||||
struct mips_got_entry *entry;
|
||||
|
||||
g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
|
||||
|
||||
page = (value + 0x8000) & ~(bfd_vma) 0xffff;
|
||||
entry = mips_elf_create_local_got_entry (abfd, info, ibfd, g, sgot,
|
||||
page, 0, NULL, R_MIPS_GOT_PAGE);
|
||||
entry = mips_elf_create_local_got_entry (abfd, info, ibfd, page, 0,
|
||||
NULL, R_MIPS_GOT_PAGE);
|
||||
|
||||
if (!entry)
|
||||
return MINUS_ONE;
|
||||
@ -2762,8 +2736,6 @@ static bfd_vma
|
||||
mips_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
|
||||
bfd_vma value, bfd_boolean external)
|
||||
{
|
||||
asection *sgot;
|
||||
struct mips_got_info *g;
|
||||
struct mips_got_entry *entry;
|
||||
|
||||
/* GOT16 relocations against local symbols are followed by a LO16
|
||||
@ -2773,13 +2745,11 @@ mips_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
|
||||
if (! external)
|
||||
value = mips_elf_high (value) << 16;
|
||||
|
||||
g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
|
||||
|
||||
/* It doesn't matter whether the original relocation was R_MIPS_GOT16,
|
||||
R_MIPS16_GOT16, R_MIPS_CALL16, etc. The format of the entry is the
|
||||
same in all cases. */
|
||||
entry = mips_elf_create_local_got_entry (abfd, info, ibfd, g, sgot,
|
||||
value, 0, NULL, R_MIPS_GOT16);
|
||||
entry = mips_elf_create_local_got_entry (abfd, info, ibfd, value, 0,
|
||||
NULL, R_MIPS_GOT16);
|
||||
if (entry)
|
||||
return entry->gotidx;
|
||||
else
|
||||
@ -2790,16 +2760,17 @@ mips_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
|
||||
in the GOT. */
|
||||
|
||||
static bfd_vma
|
||||
mips_elf_got_offset_from_index (bfd *dynobj, bfd *output_bfd,
|
||||
mips_elf_got_offset_from_index (struct bfd_link_info *info, bfd *output_bfd,
|
||||
bfd *input_bfd, bfd_vma index)
|
||||
{
|
||||
struct mips_elf_link_hash_table *htab;
|
||||
asection *sgot;
|
||||
bfd_vma gp;
|
||||
struct mips_got_info *g;
|
||||
|
||||
g = mips_elf_got_info (dynobj, &sgot);
|
||||
htab = mips_elf_hash_table (info);
|
||||
sgot = htab->sgot;
|
||||
gp = _bfd_get_gp_value (output_bfd)
|
||||
+ mips_elf_adjust_gp (output_bfd, g, input_bfd);
|
||||
+ mips_elf_adjust_gp (output_bfd, htab->got_info, input_bfd);
|
||||
|
||||
return sgot->output_section->vma + sgot->output_offset + index - gp;
|
||||
}
|
||||
@ -2811,8 +2782,7 @@ mips_elf_got_offset_from_index (bfd *dynobj, bfd *output_bfd,
|
||||
|
||||
static struct mips_got_entry *
|
||||
mips_elf_create_local_got_entry (bfd *abfd, struct bfd_link_info *info,
|
||||
bfd *ibfd, struct mips_got_info *gg,
|
||||
asection *sgot, bfd_vma value,
|
||||
bfd *ibfd, bfd_vma value,
|
||||
unsigned long r_symndx,
|
||||
struct mips_elf_link_hash_entry *h,
|
||||
int r_type)
|
||||
@ -2828,10 +2798,10 @@ mips_elf_create_local_got_entry (bfd *abfd, struct bfd_link_info *info,
|
||||
entry.d.address = value;
|
||||
entry.tls_type = 0;
|
||||
|
||||
g = mips_elf_got_for_ibfd (gg, ibfd);
|
||||
g = mips_elf_got_for_ibfd (htab->got_info, ibfd);
|
||||
if (g == NULL)
|
||||
{
|
||||
g = mips_elf_got_for_ibfd (gg, abfd);
|
||||
g = mips_elf_got_for_ibfd (htab->got_info, abfd);
|
||||
BFD_ASSERT (g != NULL);
|
||||
}
|
||||
|
||||
@ -2892,7 +2862,7 @@ mips_elf_create_local_got_entry (bfd *abfd, struct bfd_link_info *info,
|
||||
}
|
||||
|
||||
MIPS_ELF_PUT_WORD (abfd, value,
|
||||
(sgot->contents + entry.gotidx));
|
||||
(htab->sgot->contents + entry.gotidx));
|
||||
|
||||
/* These GOT entries need a dynamic relocation on VxWorks. */
|
||||
if (htab->is_vxworks)
|
||||
@ -2903,8 +2873,8 @@ mips_elf_create_local_got_entry (bfd *abfd, struct bfd_link_info *info,
|
||||
bfd_vma got_address;
|
||||
|
||||
s = mips_elf_rel_dyn_section (info, FALSE);
|
||||
got_address = (sgot->output_section->vma
|
||||
+ sgot->output_offset
|
||||
got_address = (htab->sgot->output_section->vma
|
||||
+ htab->sgot->output_offset
|
||||
+ entry.gotidx);
|
||||
|
||||
loc = s->contents + (s->reloc_count++ * sizeof (Elf32_External_Rela));
|
||||
@ -2927,13 +2897,12 @@ mips_elf_create_local_got_entry (bfd *abfd, struct bfd_link_info *info,
|
||||
static bfd_boolean
|
||||
mips_elf_sort_hash_table (struct bfd_link_info *info, unsigned long max_local)
|
||||
{
|
||||
struct mips_elf_link_hash_table *htab;
|
||||
struct mips_elf_hash_sort_data hsd;
|
||||
struct mips_got_info *g;
|
||||
bfd *dynobj;
|
||||
|
||||
dynobj = elf_hash_table (info)->dynobj;
|
||||
|
||||
g = mips_elf_got_info (dynobj, NULL);
|
||||
htab = mips_elf_hash_table (info);
|
||||
g = htab->got_info;
|
||||
|
||||
hsd.low = NULL;
|
||||
hsd.max_unref_got_dynindx =
|
||||
@ -3015,10 +2984,13 @@ mips_elf_sort_hash_table_f (struct mips_elf_link_hash_entry *h, void *data)
|
||||
static bfd_boolean
|
||||
mips_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
|
||||
bfd *abfd, struct bfd_link_info *info,
|
||||
struct mips_got_info *g,
|
||||
unsigned char tls_flag)
|
||||
{
|
||||
struct mips_elf_link_hash_table *htab;
|
||||
struct mips_got_entry entry, **loc;
|
||||
struct mips_got_info *g;
|
||||
|
||||
htab = mips_elf_hash_table (info);
|
||||
|
||||
/* A global symbol in the GOT must also be in the dynamic symbol
|
||||
table. */
|
||||
@ -3036,6 +3008,7 @@ mips_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
|
||||
}
|
||||
|
||||
/* Make sure we have a GOT to put this entry into. */
|
||||
g = htab->got_info;
|
||||
BFD_ASSERT (g != NULL);
|
||||
|
||||
entry.abfd = abfd;
|
||||
@ -3085,11 +3058,17 @@ mips_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
|
||||
|
||||
static bfd_boolean
|
||||
mips_elf_record_local_got_symbol (bfd *abfd, long symndx, bfd_vma addend,
|
||||
struct mips_got_info *g,
|
||||
struct bfd_link_info *info,
|
||||
unsigned char tls_flag)
|
||||
{
|
||||
struct mips_elf_link_hash_table *htab;
|
||||
struct mips_got_info *g;
|
||||
struct mips_got_entry entry, **loc;
|
||||
|
||||
htab = mips_elf_hash_table (info);
|
||||
g = htab->got_info;
|
||||
BFD_ASSERT (g != NULL);
|
||||
|
||||
entry.abfd = abfd;
|
||||
entry.symndx = symndx;
|
||||
entry.d.addend = addend;
|
||||
@ -3151,20 +3130,27 @@ mips_elf_pages_for_range (const struct mips_got_page_range *range)
|
||||
}
|
||||
|
||||
/* Record that ABFD has a page relocation against symbol SYMNDX and
|
||||
that ADDEND is the addend for that relocation. G is the GOT
|
||||
information. 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. */
|
||||
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. */
|
||||
|
||||
static bfd_boolean
|
||||
mips_elf_record_got_page_entry (bfd *abfd, long symndx, bfd_signed_vma addend,
|
||||
struct mips_got_info *g)
|
||||
mips_elf_record_got_page_entry (struct bfd_link_info *info, bfd *abfd,
|
||||
long symndx, bfd_signed_vma addend)
|
||||
{
|
||||
struct mips_elf_link_hash_table *htab;
|
||||
struct mips_got_info *g;
|
||||
struct mips_got_page_entry lookup, *entry;
|
||||
struct mips_got_page_range **range_ptr, *range;
|
||||
bfd_vma old_pages, new_pages;
|
||||
void **loc;
|
||||
|
||||
htab = mips_elf_hash_table (info);
|
||||
g = htab->got_info;
|
||||
BFD_ASSERT (g != NULL);
|
||||
|
||||
/* Find the mips_got_page_entry hash table entry for this symbol. */
|
||||
lookup.abfd = abfd;
|
||||
lookup.symndx = symndx;
|
||||
@ -3731,14 +3717,16 @@ mips_elf_adjust_gp (bfd *abfd, struct mips_got_info *g, bfd *ibfd)
|
||||
|
||||
static bfd_boolean
|
||||
mips_elf_multi_got (bfd *abfd, struct bfd_link_info *info,
|
||||
struct mips_got_info *g, asection *got,
|
||||
bfd_size_type pages)
|
||||
asection *got, bfd_size_type pages)
|
||||
{
|
||||
struct mips_elf_link_hash_table *htab;
|
||||
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 *gg;
|
||||
struct mips_got_info *g, *gg;
|
||||
unsigned int assign;
|
||||
|
||||
htab = mips_elf_hash_table (info);
|
||||
g = htab->got_info;
|
||||
g->bfd2got = htab_try_create (1, mips_elf_bfd2got_entry_hash,
|
||||
mips_elf_bfd2got_entry_eq, NULL);
|
||||
if (g->bfd2got == NULL)
|
||||
@ -4113,7 +4101,7 @@ mips_elf_create_got_section (bfd *abfd, struct bfd_link_info *info,
|
||||
htab = mips_elf_hash_table (info);
|
||||
|
||||
/* This function may be called more than once. */
|
||||
s = mips_elf_got_section (abfd, TRUE);
|
||||
s = htab->sgot;
|
||||
if (s)
|
||||
{
|
||||
if (! maybe_exclude)
|
||||
@ -4133,6 +4121,7 @@ mips_elf_create_got_section (bfd *abfd, struct bfd_link_info *info,
|
||||
if (s == NULL
|
||||
|| ! bfd_set_section_alignment (abfd, s, 4))
|
||||
return FALSE;
|
||||
htab->sgot = s;
|
||||
|
||||
/* Define the symbol _GLOBAL_OFFSET_TABLE_. We don't do this in the
|
||||
linker script because we don't want to define the symbol if we
|
||||
@ -4174,7 +4163,7 @@ mips_elf_create_got_section (bfd *abfd, struct bfd_link_info *info,
|
||||
mips_got_page_entry_eq, NULL);
|
||||
if (g->got_page_entries == NULL)
|
||||
return FALSE;
|
||||
mips_elf_section_data (s)->u.got_info = g;
|
||||
htab->got_info = g;
|
||||
mips_elf_section_data (s)->elf.this_hdr.sh_flags
|
||||
|= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
|
||||
|
||||
@ -4517,8 +4506,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
|
||||
gp0 = _bfd_get_gp_value (input_bfd);
|
||||
gp = _bfd_get_gp_value (abfd);
|
||||
if (dynobj)
|
||||
gp += mips_elf_adjust_gp (abfd, mips_elf_got_info (dynobj, NULL),
|
||||
input_bfd);
|
||||
gp += mips_elf_adjust_gp (abfd, htab->got_info, input_bfd);
|
||||
|
||||
if (gnu_local_gp_p)
|
||||
symbol = gp;
|
||||
@ -4583,13 +4571,10 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
|
||||
|| (info->shared
|
||||
&& (info->symbolic || h->root.forced_local)
|
||||
&& h->root.def_regular)))
|
||||
{
|
||||
/* This is a static link or a -Bsymbolic link. The
|
||||
symbol is defined locally, or was forced to be local.
|
||||
We must initialize this entry in the GOT. */
|
||||
asection *sgot = mips_elf_got_section (dynobj, FALSE);
|
||||
MIPS_ELF_PUT_WORD (dynobj, symbol, sgot->contents + g);
|
||||
}
|
||||
/* This is a static link or a -Bsymbolic link. The
|
||||
symbol is defined locally, or was forced to be local.
|
||||
We must initialize this entry in the GOT. */
|
||||
MIPS_ELF_PUT_WORD (dynobj, symbol, htab->sgot->contents + g);
|
||||
}
|
||||
}
|
||||
else if (!htab->is_vxworks
|
||||
@ -4605,7 +4590,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
|
||||
}
|
||||
|
||||
/* Convert GOT indices to actual offsets. */
|
||||
g = mips_elf_got_offset_from_index (dynobj, abfd, input_bfd, g);
|
||||
g = mips_elf_got_offset_from_index (info, abfd, input_bfd, g);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4840,7 +4825,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
|
||||
if (value == MINUS_ONE)
|
||||
return bfd_reloc_outofrange;
|
||||
value
|
||||
= mips_elf_got_offset_from_index (dynobj, abfd, input_bfd, value);
|
||||
= mips_elf_got_offset_from_index (info, abfd, input_bfd, value);
|
||||
overflowed_p = mips_elf_overflow_p (value, 16);
|
||||
break;
|
||||
}
|
||||
@ -4894,7 +4879,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
|
||||
value = mips_elf_got_page (abfd, input_bfd, info, symbol + addend, NULL);
|
||||
if (value == MINUS_ONE)
|
||||
return bfd_reloc_outofrange;
|
||||
value = mips_elf_got_offset_from_index (dynobj, abfd, input_bfd, value);
|
||||
value = mips_elf_got_offset_from_index (info, abfd, input_bfd, value);
|
||||
overflowed_p = mips_elf_overflow_p (value, 16);
|
||||
break;
|
||||
|
||||
@ -6617,11 +6602,9 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
bfd *dynobj;
|
||||
Elf_Internal_Shdr *symtab_hdr;
|
||||
struct elf_link_hash_entry **sym_hashes;
|
||||
struct mips_got_info *g;
|
||||
size_t extsymoff;
|
||||
const Elf_Internal_Rela *rel;
|
||||
const Elf_Internal_Rela *rel_end;
|
||||
asection *sgot;
|
||||
asection *sreloc;
|
||||
const struct elf_backend_data *bed;
|
||||
struct mips_elf_link_hash_table *htab;
|
||||
@ -6892,24 +6875,6 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
}
|
||||
}
|
||||
|
||||
if (dynobj == NULL)
|
||||
{
|
||||
sgot = NULL;
|
||||
g = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
sgot = mips_elf_got_section (dynobj, FALSE);
|
||||
if (sgot == NULL)
|
||||
g = NULL;
|
||||
else
|
||||
{
|
||||
BFD_ASSERT (mips_elf_section_data (sgot) != NULL);
|
||||
g = mips_elf_section_data (sgot)->u.got_info;
|
||||
BFD_ASSERT (g != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
sreloc = NULL;
|
||||
contents = NULL;
|
||||
for (rel = relocs; rel < rel_end; ++rel)
|
||||
@ -6944,7 +6909,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
}
|
||||
|
||||
/* Some relocs require a global offset table. */
|
||||
if (dynobj == NULL || sgot == NULL)
|
||||
if (dynobj == NULL || htab->sgot == NULL)
|
||||
{
|
||||
switch (r_type)
|
||||
{
|
||||
@ -6966,7 +6931,6 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
elf_hash_table (info)->dynobj = dynobj = abfd;
|
||||
if (! mips_elf_create_got_section (dynobj, info, FALSE))
|
||||
return FALSE;
|
||||
g = mips_elf_got_info (dynobj, &sgot);
|
||||
if (htab->is_vxworks && !info->shared)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
@ -7029,8 +6993,8 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
always evaluate to "G". We don't count R_MIPS_GOT_HI16, or
|
||||
R_MIPS_CALL_HI16 because these are always followed by an
|
||||
R_MIPS_GOT_LO16 or R_MIPS_CALL_LO16. */
|
||||
if (! mips_elf_record_local_got_symbol (abfd, r_symndx,
|
||||
rel->r_addend, g, 0))
|
||||
if (!mips_elf_record_local_got_symbol (abfd, r_symndx,
|
||||
rel->r_addend, info, 0))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -7056,7 +7020,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
entry, which will be allocated by adjust_dynamic_symbol.
|
||||
Otherwise, this symbol requires a global GOT entry. */
|
||||
if ((!htab->is_vxworks || h->forced_local)
|
||||
&& !mips_elf_record_global_got_symbol (h, abfd, info, g, 0))
|
||||
&& !mips_elf_record_global_got_symbol (h, abfd, info, 0))
|
||||
return FALSE;
|
||||
|
||||
/* We need a stub, not a plt entry for the undefined
|
||||
@ -7113,14 +7077,15 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
}
|
||||
else
|
||||
addend = rel->r_addend;
|
||||
if (!mips_elf_record_got_page_entry (abfd, r_symndx, addend, g))
|
||||
if (!mips_elf_record_got_page_entry (info, abfd, r_symndx,
|
||||
addend))
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
/* Fall through. */
|
||||
|
||||
case R_MIPS_GOT_DISP:
|
||||
if (h && ! mips_elf_record_global_got_symbol (h, abfd, info, g, 0))
|
||||
if (h && !mips_elf_record_global_got_symbol (h, abfd, info, 0))
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
@ -7152,15 +7117,17 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
(struct mips_elf_link_hash_entry *) h;
|
||||
hmips->tls_type |= flag;
|
||||
|
||||
if (h && ! mips_elf_record_global_got_symbol (h, abfd, info, g, flag))
|
||||
if (h && !mips_elf_record_global_got_symbol (h, abfd,
|
||||
info, flag))
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
BFD_ASSERT (flag == GOT_TLS_LDM || r_symndx != 0);
|
||||
|
||||
if (! mips_elf_record_local_got_symbol (abfd, r_symndx,
|
||||
rel->r_addend, g, flag))
|
||||
if (!mips_elf_record_local_got_symbol (abfd, r_symndx,
|
||||
rel->r_addend,
|
||||
info, flag))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -7228,8 +7195,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
elf_hash_table (info)->dynobj = dynobj = abfd;
|
||||
if (! mips_elf_create_got_section (dynobj, info, TRUE))
|
||||
return FALSE;
|
||||
g = mips_elf_got_info (dynobj, &sgot);
|
||||
if (! mips_elf_record_global_got_symbol (h, abfd, info, g, 0))
|
||||
if (!mips_elf_record_global_got_symbol (h, abfd, info, 0))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -7785,7 +7751,6 @@ _bfd_mips_elf_always_size_sections (bfd *output_bfd,
|
||||
{
|
||||
asection *ri;
|
||||
|
||||
bfd *dynobj;
|
||||
asection *s;
|
||||
struct mips_got_info *g;
|
||||
int i;
|
||||
@ -7808,15 +7773,12 @@ _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);
|
||||
|
||||
dynobj = elf_hash_table (info)->dynobj;
|
||||
if (dynobj == NULL)
|
||||
/* Relocatable links don't have it. */
|
||||
return TRUE;
|
||||
|
||||
g = mips_elf_got_info (dynobj, &s);
|
||||
s = htab->sgot;
|
||||
if (s == NULL)
|
||||
return TRUE;
|
||||
|
||||
g = htab->got_info;
|
||||
|
||||
/* Calculate the total loadable size of the output. That
|
||||
will give us the maximum number of GOT_PAGE entries
|
||||
required. */
|
||||
@ -7906,7 +7868,7 @@ _bfd_mips_elf_always_size_sections (bfd *output_bfd,
|
||||
dynamic loader. */
|
||||
if (!htab->is_vxworks && s->size > MIPS_ELF_GOT_MAX_SIZE (info))
|
||||
{
|
||||
if (! mips_elf_multi_got (output_bfd, info, g, s, page_gotno))
|
||||
if (!mips_elf_multi_got (output_bfd, info, s, page_gotno))
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
@ -8015,12 +7977,10 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
|
||||
if (info->shared)
|
||||
{
|
||||
/* Allocate relocations for all but the reserved entries. */
|
||||
struct mips_got_info *g;
|
||||
unsigned int count;
|
||||
|
||||
g = mips_elf_got_info (dynobj, NULL);
|
||||
count = (g->global_gotno
|
||||
+ g->local_gotno
|
||||
count = (htab->got_info->global_gotno
|
||||
+ htab->got_info->local_gotno
|
||||
- MIPS_RESERVED_GOTNO (info));
|
||||
mips_elf_allocate_dynamic_relocations (dynobj, info, count);
|
||||
}
|
||||
@ -8031,7 +7991,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
|
||||
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 = mips_elf_got_info (dynobj, NULL);
|
||||
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;
|
||||
@ -8800,10 +8760,9 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
|
||||
BFD_ASSERT (h->dynindx != -1
|
||||
|| h->forced_local);
|
||||
|
||||
sgot = mips_elf_got_section (dynobj, FALSE);
|
||||
sgot = mips_elf_got_section (info);
|
||||
BFD_ASSERT (sgot != NULL);
|
||||
BFD_ASSERT (mips_elf_section_data (sgot) != NULL);
|
||||
g = mips_elf_section_data (sgot)->u.got_info;
|
||||
g = htab->got_info;
|
||||
BFD_ASSERT (g != NULL);
|
||||
|
||||
/* Run through the global symbol table, creating GOT entries for all
|
||||
@ -9072,10 +9031,9 @@ _bfd_mips_vxworks_finish_dynamic_symbol (bfd *output_bfd,
|
||||
|
||||
BFD_ASSERT (h->dynindx != -1 || h->forced_local);
|
||||
|
||||
sgot = mips_elf_got_section (dynobj, FALSE);
|
||||
sgot = mips_elf_got_section (info);
|
||||
BFD_ASSERT (sgot != NULL);
|
||||
BFD_ASSERT (mips_elf_section_data (sgot) != NULL);
|
||||
g = mips_elf_section_data (sgot)->u.got_info;
|
||||
g = htab->got_info;
|
||||
BFD_ASSERT (g != NULL);
|
||||
|
||||
/* See if this symbol has an entry in the GOT. */
|
||||
@ -9236,14 +9194,12 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd,
|
||||
|
||||
sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
|
||||
|
||||
sgot = mips_elf_got_section (dynobj, FALSE);
|
||||
sgot = mips_elf_got_section (info);
|
||||
if (sgot == NULL)
|
||||
gg = g = NULL;
|
||||
else
|
||||
{
|
||||
BFD_ASSERT (mips_elf_section_data (sgot) != NULL);
|
||||
gg = mips_elf_section_data (sgot)->u.got_info;
|
||||
BFD_ASSERT (gg != NULL);
|
||||
gg = htab->got_info;
|
||||
g = mips_elf_got_for_ibfd (gg, output_bfd);
|
||||
BFD_ASSERT (g != NULL);
|
||||
}
|
||||
@ -10237,7 +10193,6 @@ _bfd_mips_elf_hide_symbol (struct bfd_link_info *info,
|
||||
bfd_boolean force_local)
|
||||
{
|
||||
bfd *dynobj;
|
||||
asection *got;
|
||||
struct mips_got_info *g;
|
||||
struct mips_elf_link_hash_entry *h;
|
||||
struct mips_elf_link_hash_table *htab;
|
||||
@ -10249,10 +10204,12 @@ _bfd_mips_elf_hide_symbol (struct bfd_link_info *info,
|
||||
|
||||
dynobj = elf_hash_table (info)->dynobj;
|
||||
htab = mips_elf_hash_table (info);
|
||||
if (dynobj != NULL && force_local && h->root.type != STT_TLS
|
||||
&& (got = mips_elf_got_section (dynobj, TRUE)) != NULL
|
||||
&& (g = mips_elf_section_data (got)->u.got_info) != NULL)
|
||||
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;
|
||||
@ -10308,7 +10265,7 @@ _bfd_mips_elf_hide_symbol (struct bfd_link_info *info,
|
||||
/* 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. */
|
||||
got->size += MIPS_ELF_GOT_SIZE (dynobj);
|
||||
htab->sgot->size += MIPS_ELF_GOT_SIZE (dynobj);
|
||||
}
|
||||
}
|
||||
|
||||
@ -10780,6 +10737,8 @@ _bfd_mips_elf_link_hash_table_create (bfd *abfd)
|
||||
ret->sgotplt = NULL;
|
||||
ret->splt = NULL;
|
||||
ret->sstubs = NULL;
|
||||
ret->sgot = NULL;
|
||||
ret->got_info = NULL;
|
||||
ret->plt_header_size = 0;
|
||||
ret->plt_entry_size = 0;
|
||||
ret->function_stub_size = 0;
|
||||
@ -10846,8 +10805,6 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info)
|
||||
htab = mips_elf_hash_table (info);
|
||||
if (elf_hash_table (info)->dynamic_sections_created)
|
||||
{
|
||||
bfd *dynobj;
|
||||
asection *got;
|
||||
struct mips_got_info *g;
|
||||
bfd_size_type dynsecsymcount;
|
||||
|
||||
@ -10863,10 +10820,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info)
|
||||
return FALSE;
|
||||
|
||||
/* Make sure we didn't grow the global .got region. */
|
||||
dynobj = elf_hash_table (info)->dynobj;
|
||||
got = mips_elf_got_section (dynobj, FALSE);
|
||||
g = mips_elf_section_data (got)->u.got_info;
|
||||
|
||||
g = htab->got_info;
|
||||
if (g->global_gotsym != NULL)
|
||||
BFD_ASSERT ((elf_hash_table (info)->dynsymcount
|
||||
- g->global_gotsym->dynindx)
|
||||
|
Loading…
Reference in New Issue
Block a user