diff options
author | Richard Sandiford <rdsandiford@googlemail.com> | 2008-08-06 19:51:29 +0000 |
---|---|---|
committer | Richard Sandiford <rdsandiford@googlemail.com> | 2008-08-06 19:51:29 +0000 |
commit | a8028dd09a7b4fcd23cb597743652f7bfc36841b (patch) | |
tree | 1e34d60764ddbdc78643fe205162be46de6d5e71 /bfd/elfxx-mips.c | |
parent | 4e41d0d7c3dcff6898ecfe038357e68c47144c70 (diff) | |
download | gdb-a8028dd09a7b4fcd23cb597743652f7bfc36841b.zip gdb-a8028dd09a7b4fcd23cb597743652f7bfc36841b.tar.gz gdb-a8028dd09a7b4fcd23cb597743652f7bfc36841b.tar.bz2 |
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.
Diffstat (limited to 'bfd/elfxx-mips.c')
-rw-r--r-- | bfd/elfxx-mips.c | 278 |
1 files changed, 116 insertions, 162 deletions
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index c71e397..6820e61 100644 --- a/bfd/elfxx-mips.c +++ b/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) -{ - 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, 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) |