[PATCH] Cache the MIPS GOT section
Richard Sandiford
rdsandiford@googlemail.com
Sat Jun 28 16:43:00 GMT 2008
Following on from:
http://sources.redhat.com/ml/binutils/2008-06/msg00267.html
we also find the .got section each time we need it, rather than caching
it in the hash table. We then read the got info from the MIPS-specific
section data, rather than making that information available in the hash
table too.
Specifically, we use the function:
mips_elf_got_section (dynobj, maybe_excluded)
to find the .got section for DYNOBJ. It returns null if the section
doesn't exist. If MAYBE_EXCLUDED is false, the function also returns
null if the .got section has been excluded.
We use:
mips_elf_got_info (dynobj, sgot_ptr)
to read both the .got section (*SGOT_PTR) and the GOT info.
There are three uses of MAYBE_EXCLUDED:
(1) within mips_elf_got_info itself, which returns the GOT info even
when .got has been excluded.
(2) within _bfd_mips_elf_hide_symbol, which likewise wants
access to the GOT info even when .got has been excluded.
(3) within mips_elf_create_got_section, which simply wants to
know if .got has already been created. This function may be called
several times during the same link, and only the first call needs
to do something.
If we put the got info in the hash table, uses like (1) and (2) can
get the info directly from there, without going through the .got
section data. And if we put the .got _section_ in the hash table,
(3) can just read that field.
The only interesting uses of mips_got_section are then those for
which MAYBE_EXCLUDED == FALSE. The patch therefore changes the
interface to:
mips_elf_got_section (struct bfd_link_info *info)
and updates the callers accordingly. (Note that later patches will
remove the function altogether. This is just one step in a longer
process.)
The patch also replaces calls to mips_elf_got_info with direct accesses
to the hash-table field. Functions like mips_elf_create_local_got_entry
already have access to the bfd_link_info, so there's no need for the
caller to provide the GOT info as a separate parameter.
Tested on mips64-linux-gnu and mips64el-linux-gnu. OK to install?
Richard
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.
Index: bfd/elfxx-mips.c
===================================================================
--- bfd/elfxx-mips.c 2008-06-28 17:14:30.000000000 +0100
+++ bfd/elfxx-mips.c 2008-06-28 17:14:33.000000000 +0100
@@ -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 @@ #define cbRPDR sizeof (RPDR)
#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_lin
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)
-{
- asection *sgot = bfd_get_section_by_name (abfd, ".got");
- if (sgot == NULL
- || (! maybe_excluded && (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)
+mips_elf_got_section (struct bfd_link_info *info)
{
- 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;
+ struct mips_elf_link_hash_table *htab;
- return g;
+ htab = mips_elf_hash_table (info);
+ if (htab->sgot == NULL || (htab->sgot->flags & SEC_EXCLUDE) != 0)
+ return NULL;
+ 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
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
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 @@ mips_elf_local_got_index (bfd *abfd, bfd
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, bf
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 @@ mips_elf_global_got_index (bfd *abfd, bf
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 @@ mips_elf_got_page (bfd *abfd, bfd *ibfd,
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 *ib
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 *ib
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 *dyn
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 *ab
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 *ab
}
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 *ab
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 *ab
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_
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 (struc
}
/* 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 (struc
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 m
}
/* 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 mi
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,
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,
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,
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
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
|| (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
}
/* 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;
}
@@ -4837,7 +4822,7 @@ mips_elf_calculate_relocation (bfd *abfd
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;
}
@@ -4891,7 +4876,7 @@ mips_elf_calculate_relocation (bfd *abfd
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, s
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;
@@ -6894,24 +6877,6 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
}
}
- 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;
bed = get_elf_backend_data (abfd);
rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
@@ -6948,7 +6913,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
}
/* Some relocs require a global offset table. */
- if (dynobj == NULL || sgot == NULL)
+ if (dynobj == NULL || htab->sgot == NULL)
{
switch (r_type)
{
@@ -6970,7 +6935,6 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
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)
@@ -7033,8 +6997,8 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
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;
}
@@ -7060,7 +7024,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
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
@@ -7117,14 +7081,15 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
}
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;
@@ -7156,15 +7121,17 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
(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;
}
}
@@ -7223,8 +7190,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
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;
}
}
@@ -7735,7 +7701,6 @@ _bfd_mips_elf_always_size_sections (bfd
{
asection *ri;
- bfd *dynobj;
asection *s;
struct mips_got_info *g;
int i;
@@ -7758,15 +7723,12 @@ _bfd_mips_elf_always_size_sections (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. */
@@ -7856,7 +7818,7 @@ _bfd_mips_elf_always_size_sections (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
@@ -7962,12 +7924,10 @@ _bfd_mips_elf_size_dynamic_sections (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);
}
@@ -7978,7 +7938,7 @@ _bfd_mips_elf_size_dynamic_sections (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;
@@ -8747,10 +8707,9 @@ _bfd_mips_elf_finish_dynamic_symbol (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
@@ -9021,10 +8980,9 @@ _bfd_mips_vxworks_finish_dynamic_symbol
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. */
@@ -9185,14 +9143,12 @@ _bfd_mips_elf_finish_dynamic_sections (b
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);
}
@@ -10186,7 +10142,6 @@ _bfd_mips_elf_hide_symbol (struct bfd_li
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;
@@ -10198,10 +10153,12 @@ _bfd_mips_elf_hide_symbol (struct bfd_li
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;
@@ -10257,7 +10214,7 @@ _bfd_mips_elf_hide_symbol (struct bfd_li
/* 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);
}
}
@@ -10729,6 +10686,8 @@ _bfd_mips_elf_link_hash_table_create (bf
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;
@@ -10795,8 +10754,6 @@ _bfd_mips_elf_final_link (bfd *abfd, str
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;
@@ -10812,10 +10769,7 @@ _bfd_mips_elf_final_link (bfd *abfd, str
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)
More information about the Binutils
mailing list