X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felfxx-mips.c;h=d649676e2254f59df12cb292e26af0d269de5afd;hb=5e7fc731f80e0d08385a05ad47dda332a49d9341;hp=cdc5d962897c48c31703c6908c32d1a0e2d34a6e;hpb=54806ffa85643c3a1ee721d5c3f5586d32f86ee1;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index cdc5d96289..d649676e22 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -453,12 +453,8 @@ struct mips_elf_link_hash_table being used. */ asection *srelbss; asection *sdynbss; - asection *srelplt; asection *srelplt2; - asection *sgotplt; - asection *splt; asection *sstubs; - asection *sgot; /* The master GOT information. */ struct mips_got_info *got_info; @@ -913,7 +909,7 @@ static bfd *reldyn_sorting_bfd; : 0x8f998010)) /* lw t9,0x8010(gp) */ #define STUB_MOVE 0x03e07825 /* or t7,ra,zero */ #define STUB_LUI(VAL) (0x3c180000 + (VAL)) /* lui t8,VAL */ -#define STUB_JALR 0x0320f809 /* jalr t9,ra */ +#define STUB_JALR 0x0320f809 /* jalr ra,t9 */ #define STUB_ORI(VAL) (0x37180000 + (VAL)) /* ori t8,t8,VAL */ #define STUB_LI16U(VAL) (0x34180000 + (VAL)) /* ori t8,zero,VAL unsigned */ #define STUB_LI16S(abfd, VAL) \ @@ -1578,12 +1574,13 @@ mips_elf_create_stub_symbol (struct bfd_link_info *info, const char *prefix, asection *s, bfd_vma value, bfd_vma size) { + bfd_boolean micromips_p = ELF_ST_IS_MICROMIPS (h->root.other); struct bfd_link_hash_entry *bh; struct elf_link_hash_entry *elfh; char *name; bfd_boolean res; - if (ELF_ST_IS_MICROMIPS (h->root.other)) + if (micromips_p) value |= 1; /* Create a new symbol. */ @@ -1601,6 +1598,8 @@ mips_elf_create_stub_symbol (struct bfd_link_info *info, elfh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC); elfh->size = size; elfh->forced_local = 1; + if (micromips_p) + elfh->other = ELF_ST_SET_MICROMIPS (elfh->other); return TRUE; } @@ -1805,6 +1804,7 @@ mips_elf_local_pic_function_p (struct mips_elf_link_hash_entry *h) || h->root.root.type == bfd_link_hash_defweak) && h->root.def_regular && !bfd_is_abs_section (h->root.root.u.def.section) + && !bfd_is_und_section (h->root.root.u.def.section) && (!ELF_ST_IS_MIPS16 (h->root.other) || (h->fn_stub && h->need_fn_stub)) && (PIC_OBJECT_P (h->root.root.u.def.section->owner) @@ -1961,6 +1961,8 @@ mips_elf_add_la25_stub (struct bfd_link_info *info, /* Prefer to use LUI/ADDIU stubs if the function is at the beginning of the section and if we would need no more than 2 nops. */ value = mips_elf_get_la25_target (stub, &s); + if (ELF_ST_IS_MICROMIPS (stub->h->root.other)) + value &= ~1; use_trampoline_p = (value != 0 || s->alignment_power > 4); h->la25_stub = stub; @@ -3350,7 +3352,7 @@ mips_elf_initialize_tls_slots (bfd *abfd, struct bfd_link_info *info, if (htab == NULL) return; - sgot = htab->sgot; + sgot = htab->root.sgot; indx = 0; if (h != NULL) @@ -3477,8 +3479,8 @@ mips_elf_gotplt_index (struct bfd_link_info *info, BFD_ASSERT (h->plt.plist->gotplt_index != MINUS_ONE); /* Calculate the address of the associated .got.plt entry. */ - got_address = (htab->sgotplt->output_section->vma - + htab->sgotplt->output_offset + got_address = (htab->root.sgotplt->output_section->vma + + htab->root.sgotplt->output_offset + (h->plt.plist->gotplt_index * MIPS_ELF_GOT_SIZE (info->output_bfd))); @@ -3542,7 +3544,7 @@ mips_elf_primary_global_got_index (bfd *obfd, struct bfd_link_info *info, g = mips_elf_bfd_got (obfd, FALSE); got_index = ((h->dynindx - global_got_dynindx + g->local_gotno) * MIPS_ELF_GOT_SIZE (obfd)); - BFD_ASSERT (got_index < htab->sgot->size); + BFD_ASSERT (got_index < htab->root.sgot->size); return got_index; } @@ -3576,7 +3578,7 @@ mips_elf_global_got_index (bfd *obfd, struct bfd_link_info *info, bfd *ibfd, BFD_ASSERT (entry); gotidx = entry->gotidx; - BFD_ASSERT (gotidx > 0 && gotidx < htab->sgot->size); + BFD_ASSERT (gotidx > 0 && gotidx < htab->root.sgot->size); if (lookup.tls_type) { @@ -3664,7 +3666,7 @@ mips_elf_got_offset_from_index (struct bfd_link_info *info, bfd *output_bfd, htab = mips_elf_hash_table (info); BFD_ASSERT (htab != NULL); - sgot = htab->sgot; + sgot = htab->root.sgot; gp = _bfd_get_gp_value (output_bfd) + mips_elf_adjust_gp (output_bfd, htab->got_info, input_bfd); @@ -3727,7 +3729,7 @@ mips_elf_create_local_got_entry (bfd *abfd, struct bfd_link_info *info, BFD_ASSERT (entry); gotidx = entry->gotidx; - BFD_ASSERT (gotidx > 0 && gotidx < htab->sgot->size); + BFD_ASSERT (gotidx > 0 && gotidx < htab->root.sgot->size); return entry; } @@ -3746,7 +3748,7 @@ mips_elf_create_local_got_entry (bfd *abfd, struct bfd_link_info *info, if (g->assigned_low_gotno > g->assigned_high_gotno) { /* We didn't allocate enough space in the GOT. */ - (*_bfd_error_handler) + _bfd_error_handler (_("not enough GOT space for local GOT entries")); bfd_set_error (bfd_error_bad_value); return NULL; @@ -3767,7 +3769,7 @@ mips_elf_create_local_got_entry (bfd *abfd, struct bfd_link_info *info, *entry = lookup; *loc = entry; - MIPS_ELF_PUT_WORD (abfd, value, htab->sgot->contents + entry->gotidx); + MIPS_ELF_PUT_WORD (abfd, value, htab->root.sgot->contents + entry->gotidx); /* These GOT entries need a dynamic relocation on VxWorks. */ if (htab->is_vxworks) @@ -3778,8 +3780,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 = (htab->sgot->output_section->vma - + htab->sgot->output_offset + got_address = (htab->root.sgot->output_section->vma + + htab->root.sgot->output_offset + entry->gotidx); rloc = s->contents + (s->reloc_count++ * sizeof (Elf32_External_Rela)); @@ -5131,7 +5133,7 @@ mips_elf_create_got_section (bfd *abfd, struct bfd_link_info *info) BFD_ASSERT (htab != NULL); /* This function may be called more than once. */ - if (htab->sgot) + if (htab->root.sgot) return TRUE; flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY @@ -5143,7 +5145,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; + htab->root.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 @@ -5177,7 +5179,7 @@ mips_elf_create_got_section (bfd *abfd, struct bfd_link_info *info) | SEC_LINKER_CREATED); if (s == NULL) return FALSE; - htab->sgotplt = s; + htab->root.sgotplt = s; return TRUE; } @@ -5577,9 +5579,13 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, else if (h != NULL && h->la25_stub && mips_elf_relocation_needs_la25_stub (input_bfd, r_type, target_is_16_bit_code_p)) - symbol = (h->la25_stub->stub_section->output_section->vma - + h->la25_stub->stub_section->output_offset - + h->la25_stub->offset); + { + symbol = (h->la25_stub->stub_section->output_section->vma + + h->la25_stub->stub_section->output_offset + + h->la25_stub->offset); + if (ELF_ST_IS_MICROMIPS (h->root.other)) + symbol |= 1; + } /* For direct MIPS16 and microMIPS calls make sure the compressed PLT entry is used if a standard PLT entry has also been made. In this case the symbol will have been set by mips_elf_set_plt_sym_value @@ -5595,7 +5601,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, { bfd_boolean micromips_p = MICROMIPS_P (abfd); - sec = htab->splt; + sec = htab->root.splt; symbol = (sec->output_section->vma + sec->output_offset + htab->plt_header_size @@ -5611,7 +5617,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, if ((mips16_branch_reloc_p (r_type) && target_is_micromips_code_p) || (micromips_branch_reloc_p (r_type) && target_is_16_bit_code_p)) { - (*_bfd_error_handler) + _bfd_error_handler (_("MIPS16 and microMIPS functions cannot call each other")); return bfd_reloc_notsupported; } @@ -5711,7 +5717,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, if (!TLS_RELOC_P (r_type) && !elf_hash_table (info)->dynamic_sections_created) /* This is a static link. We must initialize the GOT entry. */ - MIPS_ELF_PUT_WORD (dynobj, symbol, htab->sgot->contents + g); + MIPS_ELF_PUT_WORD (dynobj, symbol, htab->root.sgot->contents + g); } } else if (!htab->is_vxworks @@ -5914,7 +5920,6 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, value = mips_elf_high (addend + gp - p - 1); else value = mips_elf_high (addend + gp - p); - overflowed_p = mips_elf_overflow_p (value, 16); } break; @@ -7107,7 +7112,8 @@ _bfd_mips_elf_section_processing (bfd *abfd, Elf_Internal_Shdr *hdr) &intopt); if (intopt.size < sizeof (Elf_External_Options)) { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: Warning: bad `%s' option size %u smaller than its header"), abfd, MIPS_ELF_OPTIONS_SECTION_NAME (abfd), intopt.size); break; @@ -7340,7 +7346,8 @@ _bfd_mips_elf_section_from_shdr (bfd *abfd, &intopt); if (intopt.size < sizeof (Elf_External_Options)) { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: Warning: bad `%s' option size %u smaller than its header"), abfd, MIPS_ELF_OPTIONS_SECTION_NAME (abfd), intopt.size); break; @@ -7887,19 +7894,13 @@ _bfd_mips_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) return FALSE; /* Cache the sections created above. */ - htab->splt = bfd_get_linker_section (abfd, ".plt"); htab->sdynbss = bfd_get_linker_section (abfd, ".dynbss"); if (htab->is_vxworks) - { - htab->srelbss = bfd_get_linker_section (abfd, ".rela.bss"); - htab->srelplt = bfd_get_linker_section (abfd, ".rela.plt"); - } - else - htab->srelplt = bfd_get_linker_section (abfd, ".rel.plt"); + htab->srelbss = bfd_get_linker_section (abfd, ".rela.bss"); if (!htab->sdynbss || (htab->is_vxworks && !htab->srelbss && !bfd_link_pic (info)) - || !htab->srelplt - || !htab->splt) + || !htab->root.srelplt + || !htab->root.splt) abort (); /* Do the usual VxWorks handling. */ @@ -8110,7 +8111,8 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, r_symndx = mips16_stub_symndx (bed, sec, relocs, rel_end); if (r_symndx == 0) { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: Warning: cannot determine the target function for" " stub section `%s'"), abfd, name); @@ -8235,7 +8237,8 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, r_symndx = mips16_stub_symndx (bed, sec, relocs, rel_end); if (r_symndx == 0) { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: Warning: cannot determine the target function for" " stub section `%s'"), abfd, name); @@ -8366,7 +8369,8 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, h = NULL; else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr)) { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: Malformed reloc detected for section %s"), abfd, name); bfd_set_error (bfd_error_bad_value); @@ -8441,7 +8445,8 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, return FALSE; if (htab->is_vxworks && !bfd_link_pic (info)) { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: GOT reloc at 0x%lx not expected in executables"), abfd, (unsigned long) rel->r_offset); bfd_set_error (bfd_error_bad_value); @@ -8578,7 +8583,8 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_MICROMIPS_CALL16: if (h == NULL) { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: CALL16 reloc at 0x%lx not against global symbol"), abfd, (unsigned long) rel->r_offset); bfd_set_error (bfd_error_bad_value); @@ -8863,7 +8869,8 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_MIPS_26: case R_MICROMIPS_26_S1: howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, r_type, FALSE); - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"), abfd, howto->name, (h) ? h->root.root.string : "a local symbol"); @@ -9200,7 +9207,7 @@ _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info, for PLT offset calculations. */ if (htab->plt_mips_offset + htab->plt_comp_offset == 0) { - BFD_ASSERT (htab->sgotplt->size == 0); + BFD_ASSERT (htab->root.sgotplt->size == 0); BFD_ASSERT (htab->plt_got_index == 0); /* If we're using the PLT additions to the psABI, each PLT @@ -9208,12 +9215,12 @@ _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info, Encourage better cache usage by aligning. We do this lazily to avoid pessimizing traditional objects. */ if (!htab->is_vxworks - && !bfd_set_section_alignment (dynobj, htab->splt, 5)) + && !bfd_set_section_alignment (dynobj, htab->root.splt, 5)) return FALSE; /* Make sure that .got.plt is word-aligned. We do this lazily for the same reason as above. */ - if (!bfd_set_section_alignment (dynobj, htab->sgotplt, + if (!bfd_set_section_alignment (dynobj, htab->root.sgotplt, MIPS_ELF_LOG_FILE_ALIGN (dynobj))) return FALSE; @@ -9318,9 +9325,9 @@ _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info, hmips->use_plt_entry = TRUE; /* Make room for the R_MIPS_JUMP_SLOT relocation. */ - htab->srelplt->size += (htab->is_vxworks - ? MIPS_ELF_RELA_SIZE (dynobj) - : MIPS_ELF_REL_SIZE (dynobj)); + htab->root.srelplt->size += (htab->is_vxworks + ? MIPS_ELF_RELA_SIZE (dynobj) + : MIPS_ELF_REL_SIZE (dynobj)); /* Make room for the .rela.plt.unloaded relocations. */ if (htab->is_vxworks && !bfd_link_pic (info)) @@ -9359,9 +9366,9 @@ _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info, some that we can't convert. */ if (!htab->use_plts_and_copy_relocs || bfd_link_pic (info)) { - (*_bfd_error_handler) (_("non-dynamic relocations refer to " - "dynamic symbol %s"), - h->root.root.string); + _bfd_error_handler (_("non-dynamic relocations refer to " + "dynamic symbol %s"), + h->root.root.string); bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -9445,7 +9452,7 @@ mips_elf_lay_out_got (bfd *output_bfd, struct bfd_link_info *info) htab = mips_elf_hash_table (info); BFD_ASSERT (htab != NULL); - s = htab->sgot; + s = htab->root.sgot; if (s == NULL) return TRUE; @@ -9723,7 +9730,7 @@ mips_elf_set_plt_sym_value (struct mips_elf_link_hash_entry *h, void *data) if (htab->is_vxworks) val += 8; - h->root.root.u.def.section = htab->splt; + h->root.root.u.def.section = htab->root.splt; h->root.root.u.def.value = val; h->root.other = other; } @@ -9772,7 +9779,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd, Also create the _PROCEDURE_LINKAGE_TABLE_ symbol if we haven't already in _bfd_elf_create_dynamic_sections. */ - if (htab->splt && htab->plt_mips_offset + htab->plt_comp_offset != 0) + if (htab->root.splt && htab->plt_mips_offset + htab->plt_comp_offset != 0) { bfd_boolean micromips_p = (MICROMIPS_P (output_bfd) && !htab->plt_mips_offset); @@ -9782,8 +9789,8 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd, bfd_vma size; BFD_ASSERT (htab->use_plts_and_copy_relocs); - BFD_ASSERT (htab->sgotplt->size == 0); - BFD_ASSERT (htab->splt->size == 0); + BFD_ASSERT (htab->root.sgotplt->size == 0); + BFD_ASSERT (htab->root.splt->size == 0); if (htab->is_vxworks && bfd_link_pic (info)) size = 4 * ARRAY_SIZE (mips_vxworks_shared_plt0_entry); @@ -9802,17 +9809,17 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd, htab->plt_header_is_comp = micromips_p; htab->plt_header_size = size; - htab->splt->size = (size - + htab->plt_mips_offset - + htab->plt_comp_offset); - htab->sgotplt->size = (htab->plt_got_index - * MIPS_ELF_GOT_SIZE (dynobj)); + htab->root.splt->size = (size + + htab->plt_mips_offset + + htab->plt_comp_offset); + htab->root.sgotplt->size = (htab->plt_got_index + * MIPS_ELF_GOT_SIZE (dynobj)); mips_elf_link_hash_traverse (htab, mips_elf_set_plt_sym_value, info); if (htab->root.hplt == NULL) { - h = _bfd_elf_define_linkage_sym (dynobj, info, htab->splt, + h = _bfd_elf_define_linkage_sym (dynobj, info, htab->root.splt, "_PROCEDURE_LINKAGE_TABLE_"); htab->root.hplt = h; if (h == NULL) @@ -9898,7 +9905,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd, else if (SGI_COMPAT (output_bfd) && CONST_STRNEQ (name, ".compact_rel")) s->size += mips_elf_hash_table (info)->compact_rel_size; - else if (s == htab->splt) + else if (s == htab->root.splt) { /* If the last PLT entry has a branch delay slot, allocate room for an extra nop to fill the delay slot. This is @@ -9908,8 +9915,8 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd, s->size += 4; } else if (! CONST_STRNEQ (name, ".init") - && s != htab->sgot - && s != htab->sgotplt + && s != htab->root.sgot + && s != htab->root.sgotplt && s != htab->sstubs && s != htab->sdynbss) { @@ -10041,7 +10048,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd, && !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_OPTIONS, 0)) return FALSE; } - if (htab->splt->size > 0) + if (htab->root.splt->size > 0) { if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTREL, 0)) return FALSE; @@ -10268,7 +10275,8 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, name = bfd_elf_sym_name (input_bfd, symtab_hdr, local_syms + r_symndx, sec); - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: Can't find matching LO16 reloc against `%s' for %s at 0x%lx in section `%A'"), input_bfd, input_section, name, howto->name, rel->r_offset); @@ -10692,25 +10700,25 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd, BFD_ASSERT (htab->use_plts_and_copy_relocs); BFD_ASSERT (h->dynindx != -1); - BFD_ASSERT (htab->splt != NULL); + BFD_ASSERT (htab->root.splt != NULL); BFD_ASSERT (got_index != MINUS_ONE); BFD_ASSERT (!h->def_regular); /* Calculate the address of the PLT header. */ isa_bit = htab->plt_header_is_comp; - header_address = (htab->splt->output_section->vma - + htab->splt->output_offset + isa_bit); + header_address = (htab->root.splt->output_section->vma + + htab->root.splt->output_offset + isa_bit); /* Calculate the address of the .got.plt entry. */ - got_address = (htab->sgotplt->output_section->vma - + htab->sgotplt->output_offset + got_address = (htab->root.sgotplt->output_section->vma + + htab->root.sgotplt->output_offset + got_index * MIPS_ELF_GOT_SIZE (dynobj)); got_address_high = ((got_address + 0x8000) >> 16) & 0xffff; got_address_low = got_address & 0xffff; /* Initially point the .got.plt entry at the PLT header. */ - loc = (htab->sgotplt->contents + got_index * MIPS_ELF_GOT_SIZE (dynobj)); + loc = (htab->root.sgotplt->contents + got_index * MIPS_ELF_GOT_SIZE (dynobj)); if (ABI_64_P (output_bfd)) bfd_put_64 (output_bfd, header_address, loc); else @@ -10725,10 +10733,10 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd, plt_offset = htab->plt_header_size + h->plt.plist->mips_offset; - BFD_ASSERT (plt_offset <= htab->splt->size); + BFD_ASSERT (plt_offset <= htab->root.splt->size); /* Find out where the .plt entry should go. */ - loc = htab->splt->contents + plt_offset; + loc = htab->root.splt->contents + plt_offset; /* Pick the load opcode. */ load = MIPS_ELF_LOAD_WORD (output_bfd); @@ -10764,10 +10772,10 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd, plt_offset = (htab->plt_header_size + htab->plt_mips_offset + h->plt.plist->comp_offset); - BFD_ASSERT (plt_offset <= htab->splt->size); + BFD_ASSERT (plt_offset <= htab->root.splt->size); /* Find out where the .plt entry should go. */ - loc = htab->splt->contents + plt_offset; + loc = htab->root.splt->contents + plt_offset; /* Fill in the PLT entry itself. */ if (!MICROMIPS_P (output_bfd)) @@ -10803,19 +10811,20 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd, BFD_ASSERT (got_address % 4 == 0); - loc_address = (htab->splt->output_section->vma - + htab->splt->output_offset + plt_offset); + loc_address = (htab->root.splt->output_section->vma + + htab->root.splt->output_offset + plt_offset); gotpc_offset = got_address - ((loc_address | 3) ^ 3); /* ADDIUPC has a span of +/-16MB, check we're in range. */ if (gotpc_offset + 0x1000000 >= 0x2000000) { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: `%A' offset of %ld from `%A' " "beyond the range of ADDIUPC"), output_bfd, - htab->sgotplt->output_section, - htab->splt->output_section, + htab->root.sgotplt->output_section, + htab->root.splt->output_section, (long) gotpc_offset); bfd_set_error (bfd_error_no_error); return FALSE; @@ -10831,7 +10840,7 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd, } /* Emit an R_MIPS_JUMP_SLOT relocation against the .got.plt entry. */ - mips_elf_output_dynamic_relocation (output_bfd, htab->srelplt, + mips_elf_output_dynamic_relocation (output_bfd, htab->root.srelplt, got_index - 2, h->dynindx, R_MIPS_JUMP_SLOT, got_address); @@ -10995,7 +11004,7 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd, BFD_ASSERT (h->dynindx != -1 || h->forced_local); - sgot = htab->sgot; + sgot = htab->root.sgot; g = htab->got_info; BFD_ASSERT (g != NULL); @@ -11031,7 +11040,7 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd, &e))) { offset = p->gotidx; - BFD_ASSERT (offset > 0 && offset < htab->sgot->size); + BFD_ASSERT (offset > 0 && offset < htab->root.sgot->size); if (bfd_link_pic (info) || (elf_hash_table (info)->dynamic_sections_created && p->d.h != NULL @@ -11178,18 +11187,18 @@ _bfd_mips_vxworks_finish_dynamic_symbol (bfd *output_bfd, gotplt_index = h->plt.plist->gotplt_index; BFD_ASSERT (h->dynindx != -1); - BFD_ASSERT (htab->splt != NULL); + BFD_ASSERT (htab->root.splt != NULL); BFD_ASSERT (gotplt_index != MINUS_ONE); - BFD_ASSERT (plt_offset <= htab->splt->size); + BFD_ASSERT (plt_offset <= htab->root.splt->size); /* Calculate the address of the .plt entry. */ - plt_address = (htab->splt->output_section->vma - + htab->splt->output_offset + plt_address = (htab->root.splt->output_section->vma + + htab->root.splt->output_offset + plt_offset); /* Calculate the address of the .got.plt entry. */ - got_address = (htab->sgotplt->output_section->vma - + htab->sgotplt->output_offset + got_address = (htab->root.sgotplt->output_section->vma + + htab->root.sgotplt->output_offset + gotplt_index * MIPS_ELF_GOT_SIZE (output_bfd)); /* Calculate the offset of the .got.plt entry from @@ -11202,11 +11211,11 @@ _bfd_mips_vxworks_finish_dynamic_symbol (bfd *output_bfd, /* Fill in the initial value of the .got.plt entry. */ bfd_put_32 (output_bfd, plt_address, - (htab->sgotplt->contents + (htab->root.sgotplt->contents + gotplt_index * MIPS_ELF_GOT_SIZE (output_bfd))); /* Find out where the .plt entry should go. */ - loc = htab->splt->contents + plt_offset; + loc = htab->root.splt->contents + plt_offset; if (bfd_link_pic (info)) { @@ -11255,7 +11264,7 @@ _bfd_mips_vxworks_finish_dynamic_symbol (bfd *output_bfd, } /* Emit an R_MIPS_JUMP_SLOT relocation against the .got.plt entry. */ - loc = (htab->srelplt->contents + loc = (htab->root.srelplt->contents + gotplt_index * sizeof (Elf32_External_Rela)); rel.r_offset = got_address; rel.r_info = ELF32_R_INFO (h->dynindx, R_MIPS_JUMP_SLOT); @@ -11268,7 +11277,7 @@ _bfd_mips_vxworks_finish_dynamic_symbol (bfd *output_bfd, BFD_ASSERT (h->dynindx != -1 || h->forced_local); - sgot = htab->sgot; + sgot = htab->root.sgot; g = htab->got_info; BFD_ASSERT (g != NULL); @@ -11346,8 +11355,8 @@ mips_finish_exec_plt (bfd *output_bfd, struct bfd_link_info *info) plt_entry = micromips_o32_exec_plt0_entry; /* Calculate the value of .got.plt. */ - gotplt_value = (htab->sgotplt->output_section->vma - + htab->sgotplt->output_offset); + gotplt_value = (htab->root.sgotplt->output_section->vma + + htab->root.sgotplt->output_offset); gotplt_value_high = ((gotplt_value + 0x8000) >> 16) & 0xffff; gotplt_value_low = gotplt_value & 0xffff; @@ -11357,7 +11366,7 @@ mips_finish_exec_plt (bfd *output_bfd, struct bfd_link_info *info) || ~(gotplt_value | 0x7fffffff) == 0); /* Install the PLT header. */ - loc = htab->splt->contents; + loc = htab->root.splt->contents; if (plt_entry == micromips_o32_exec_plt0_entry) { bfd_vma gotpc_offset; @@ -11366,18 +11375,19 @@ mips_finish_exec_plt (bfd *output_bfd, struct bfd_link_info *info) BFD_ASSERT (gotplt_value % 4 == 0); - loc_address = (htab->splt->output_section->vma - + htab->splt->output_offset); + loc_address = (htab->root.splt->output_section->vma + + htab->root.splt->output_offset); gotpc_offset = gotplt_value - ((loc_address | 3) ^ 3); /* ADDIUPC has a span of +/-16MB, check we're in range. */ if (gotpc_offset + 0x1000000 >= 0x2000000) { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: `%A' offset of %ld from `%A' beyond the range of ADDIUPC"), output_bfd, - htab->sgotplt->output_section, - htab->splt->output_section, + htab->root.sgotplt->output_section, + htab->root.splt->output_section, (long) gotpc_offset); bfd_set_error (bfd_error_no_error); return FALSE; @@ -11442,10 +11452,11 @@ mips_vxworks_finish_exec_plt (bfd *output_bfd, struct bfd_link_info *info) got_value_low = got_value & 0xffff; /* Calculate the address of the PLT header. */ - plt_address = htab->splt->output_section->vma + htab->splt->output_offset; + plt_address = (htab->root.splt->output_section->vma + + htab->root.splt->output_offset); /* Install the PLT header. */ - loc = htab->splt->contents; + loc = htab->root.splt->contents; bfd_put_32 (output_bfd, plt_entry[0] | got_value_high, loc); bfd_put_32 (output_bfd, plt_entry[1] | got_value_low, loc + 4); bfd_put_32 (output_bfd, plt_entry[2], loc + 8); @@ -11506,7 +11517,7 @@ mips_vxworks_finish_shared_plt (bfd *output_bfd, struct bfd_link_info *info) /* We just need to copy the entry byte-by-byte. */ for (i = 0; i < ARRAY_SIZE (mips_vxworks_shared_plt0_entry); i++) bfd_put_32 (output_bfd, mips_vxworks_shared_plt0_entry[i], - htab->splt->contents + i * 4); + htab->root.splt->contents + i * 4); } /* Finish up the dynamic sections. */ @@ -11528,7 +11539,7 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd, sdyn = bfd_get_linker_section (dynobj, ".dynamic"); - sgot = htab->sgot; + sgot = htab->root.sgot; gg = htab->got_info; if (elf_hash_table (info)->dynamic_sections_created) @@ -11576,12 +11587,12 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd, break; case DT_PLTGOT: - s = htab->sgot; + s = htab->root.sgot; dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; break; case DT_MIPS_PLTGOT: - s = htab->sgotplt; + s = htab->root.sgotplt; dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; break; @@ -11636,7 +11647,8 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd, } /* In case if we don't have global got symbols we default to setting DT_MIPS_GOTSYM to the same value as - DT_MIPS_SYMTABNO, so we just fall through. */ + DT_MIPS_SYMTABNO. */ + /* Fall through. */ case DT_MIPS_SYMTABNO: name = ".dynsym"; @@ -11701,13 +11713,6 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd, dyn.d_un.d_ptr = s->vma; break; - case DT_RELASZ: - BFD_ASSERT (htab->is_vxworks); - /* The count does not include the JUMP_SLOT relocations. */ - if (htab->srelplt) - dyn.d_un.d_val -= htab->srelplt->size; - break; - case DT_PLTREL: BFD_ASSERT (htab->use_plts_and_copy_relocs); if (htab->is_vxworks) @@ -11718,13 +11723,13 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd, case DT_PLTRELSZ: BFD_ASSERT (htab->use_plts_and_copy_relocs); - dyn.d_un.d_val = htab->srelplt->size; + dyn.d_un.d_val = htab->root.srelplt->size; break; case DT_JMPREL: BFD_ASSERT (htab->use_plts_and_copy_relocs); - dyn.d_un.d_ptr = (htab->srelplt->output_section->vma - + htab->srelplt->output_offset); + dyn.d_un.d_ptr = (htab->root.srelplt->output_section->vma + + htab->root.srelplt->output_offset); break; case DT_TEXTREL: @@ -11955,7 +11960,7 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd, } } - if (htab->splt && htab->splt->size > 0) + if (htab->root.splt && htab->root.splt->size > 0) { if (htab->is_vxworks) { @@ -14285,7 +14290,8 @@ update_mips_abiflags_isa (bfd *abfd, Elf_Internal_ABIFlags_v0 *abiflags) case E_MIPS_ARCH_64R2: new_isa = LEVEL_REV (64, 2); break; case E_MIPS_ARCH_64R6: new_isa = LEVEL_REV (64, 6); break; default: - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: Unknown architecture %s"), abfd, bfd_printable_name (abfd)); } @@ -14814,7 +14820,8 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info) gptab_bss_sec = o; else { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%s: illegal section name `%s'"), bfd_get_filename (abfd), o->name); bfd_set_error (bfd_error_nonrepresentable_section); @@ -15053,8 +15060,9 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info) if there are conflicting settings. */ static bfd_boolean -mips_elf_merge_obj_e_flags (bfd *ibfd, bfd *obfd) +mips_elf_merge_obj_e_flags (bfd *ibfd, struct bfd_link_info *info) { + bfd *obfd = info->output_bfd; struct mips_elf_obj_tdata *out_tdata = mips_elf_tdata (obfd); flagword old_flags; flagword new_flags; @@ -15091,7 +15099,7 @@ mips_elf_merge_obj_e_flags (bfd *ibfd, bfd *obfd) if (((new_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) != 0) != ((old_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) != 0)) { - (*_bfd_error_handler) + _bfd_error_handler (_("%B: warning: linking abicalls files with non-abicalls files"), ibfd); ok = TRUE; @@ -15108,7 +15116,7 @@ mips_elf_merge_obj_e_flags (bfd *ibfd, bfd *obfd) /* Compare the ISAs. */ if (mips_32bit_flags_p (old_flags) != mips_32bit_flags_p (new_flags)) { - (*_bfd_error_handler) + _bfd_error_handler (_("%B: linking 32-bit code with 64-bit code"), ibfd); ok = FALSE; @@ -15139,7 +15147,8 @@ mips_elf_merge_obj_e_flags (bfd *ibfd, bfd *obfd) else { /* The ISAs aren't compatible. */ - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: linking %s module with previous %s modules"), ibfd, bfd_printable_name (ibfd), @@ -15162,7 +15171,8 @@ mips_elf_merge_obj_e_flags (bfd *ibfd, bfd *obfd) || (elf_elfheader (ibfd)->e_ident[EI_CLASS] != elf_elfheader (obfd)->e_ident[EI_CLASS])) { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: ABI mismatch: linking %s module with previous %s modules"), ibfd, elf_mips_abi_name (ibfd), @@ -15186,7 +15196,8 @@ mips_elf_merge_obj_e_flags (bfd *ibfd, bfd *obfd) if (m16_mis || micro_mis) { - (*_bfd_error_handler) + _bfd_error_handler + /* xgettext:c-format */ (_("%B: ASE mismatch: linking %s module with previous %s modules"), ibfd, m16_mis ? "MIPS16" : "microMIPS", @@ -15203,6 +15214,7 @@ mips_elf_merge_obj_e_flags (bfd *ibfd, bfd *obfd) /* Compare NaN encodings. */ if ((new_flags & EF_MIPS_NAN2008) != (old_flags & EF_MIPS_NAN2008)) { + /* xgettext:c-format */ _bfd_error_handler (_("%B: linking %s module with previous %s modules"), ibfd, (new_flags & EF_MIPS_NAN2008 @@ -15217,6 +15229,7 @@ mips_elf_merge_obj_e_flags (bfd *ibfd, bfd *obfd) /* Compare FP64 state. */ if ((new_flags & EF_MIPS_FP64) != (old_flags & EF_MIPS_FP64)) { + /* xgettext:c-format */ _bfd_error_handler (_("%B: linking %s module with previous %s modules"), ibfd, (new_flags & EF_MIPS_FP64 @@ -15231,7 +15244,8 @@ mips_elf_merge_obj_e_flags (bfd *ibfd, bfd *obfd) /* Warn about any other mismatches */ if (new_flags != old_flags) { - (*_bfd_error_handler) + /* xgettext:c-format */ + _bfd_error_handler (_("%B: uses different e_flags (0x%lx) fields than previous modules " "(0x%lx)"), ibfd, (unsigned long) new_flags, @@ -15245,8 +15259,9 @@ mips_elf_merge_obj_e_flags (bfd *ibfd, bfd *obfd) /* Merge object attributes from IBFD into OBFD. Raise an error if there are conflicting attributes. */ static bfd_boolean -mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd) +mips_elf_merge_obj_attributes (bfd *ibfd, struct bfd_link_info *info) { + bfd *obfd = info->output_bfd; obj_attribute *in_attr; obj_attribute *out_attr; bfd *abi_fp_bfd; @@ -15316,17 +15331,20 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd) in_string = _bfd_mips_fp_abi_string (in_fp); /* First warn about cases involving unrecognised ABIs. */ if (!out_string && !in_string) + /* xgettext:c-format */ _bfd_error_handler (_("Warning: %B uses unknown floating point ABI %d " "(set by %B), %B uses unknown floating point ABI %d"), obfd, abi_fp_bfd, ibfd, out_fp, in_fp); else if (!out_string) _bfd_error_handler + /* xgettext:c-format */ (_("Warning: %B uses unknown floating point ABI %d " "(set by %B), %B uses %s"), obfd, abi_fp_bfd, ibfd, out_fp, in_string); else if (!in_string) _bfd_error_handler + /* xgettext:c-format */ (_("Warning: %B uses %s (set by %B), " "%B uses unknown floating point ABI %d"), obfd, abi_fp_bfd, ibfd, out_string, in_fp); @@ -15340,6 +15358,7 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd) else if (out_fp == Val_GNU_MIPS_ABI_FP_SOFT) in_string = "-mhard-float"; _bfd_error_handler + /* xgettext:c-format */ (_("Warning: %B uses %s (set by %B), %B uses %s"), obfd, abi_fp_bfd, ibfd, out_string, in_string); } @@ -15358,6 +15377,7 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd) { case Val_GNU_MIPS_ABI_MSA_128: _bfd_error_handler + /* xgettext:c-format */ (_("Warning: %B uses %s (set by %B), " "%B uses unknown MSA ABI %d"), obfd, abi_msa_bfd, ibfd, @@ -15369,6 +15389,7 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd) { case Val_GNU_MIPS_ABI_MSA_128: _bfd_error_handler + /* xgettext:c-format */ (_("Warning: %B uses unknown MSA ABI %d " "(set by %B), %B uses %s"), obfd, abi_msa_bfd, ibfd, @@ -15377,6 +15398,7 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd) default: _bfd_error_handler + /* xgettext:c-format */ (_("Warning: %B uses unknown MSA ABI %d " "(set by %B), %B uses unknown MSA ABI %d"), obfd, abi_msa_bfd, ibfd, @@ -15388,7 +15410,7 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd) } /* Merge Tag_compatibility attributes and any common GNU ones. */ - return _bfd_elf_merge_object_attributes (ibfd, obfd); + return _bfd_elf_merge_object_attributes (ibfd, info); } /* Merge object ABI flags from IBFD into OBFD. Raise an error if @@ -15427,8 +15449,9 @@ mips_elf_merge_obj_abiflags (bfd *ibfd, bfd *obfd) object file when linking. */ bfd_boolean -_bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd) +_bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) { + bfd *obfd = info->output_bfd; struct mips_elf_obj_tdata *out_tdata; struct mips_elf_obj_tdata *in_tdata; bfd_boolean null_input_bfd = TRUE; @@ -15436,9 +15459,9 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd) bfd_boolean ok; /* Check if we have the same endianness. */ - if (! _bfd_generic_verify_endian_match (ibfd, obfd)) + if (! _bfd_generic_verify_endian_match (ibfd, info)) { - (*_bfd_error_handler) + _bfd_error_handler (_("%B: endianness incompatible with that of the selected emulation"), ibfd); return FALSE; @@ -15452,7 +15475,7 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd) if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0) { - (*_bfd_error_handler) + _bfd_error_handler (_("%B: ABI is incompatible with that of the selected emulation"), ibfd); return FALSE; @@ -15504,27 +15527,27 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd) if (LEVEL_REV (in_abiflags.isa_level, in_abiflags.isa_rev) < LEVEL_REV (abiflags.isa_level, abiflags.isa_rev)) - (*_bfd_error_handler) + _bfd_error_handler (_("%B: warning: Inconsistent ISA between e_flags and " ".MIPS.abiflags"), ibfd); if (abiflags.fp_abi != Val_GNU_MIPS_ABI_FP_ANY && in_abiflags.fp_abi != abiflags.fp_abi) - (*_bfd_error_handler) + _bfd_error_handler (_("%B: warning: Inconsistent FP ABI between .gnu.attributes and " ".MIPS.abiflags"), ibfd); if ((in_abiflags.ases & abiflags.ases) != abiflags.ases) - (*_bfd_error_handler) + _bfd_error_handler (_("%B: warning: Inconsistent ASEs between e_flags and " ".MIPS.abiflags"), ibfd); /* The isa_ext is allowed to be an extension of what can be inferred from e_flags. */ if (!mips_mach_extends_p (bfd_mips_isa_ext_mach (abiflags.isa_ext), bfd_mips_isa_ext_mach (in_abiflags.isa_ext))) - (*_bfd_error_handler) + _bfd_error_handler (_("%B: warning: Inconsistent ISA extensions between e_flags and " ".MIPS.abiflags"), ibfd); if (in_abiflags.flags2 != 0) - (*_bfd_error_handler) + _bfd_error_handler (_("%B: warning: Unexpected flag in the flags2 field of " ".MIPS.abiflags (0x%lx)"), ibfd, (unsigned long) in_abiflags.flags2); @@ -15565,9 +15588,9 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd) ok = TRUE; } else - ok = mips_elf_merge_obj_e_flags (ibfd, obfd); + ok = mips_elf_merge_obj_e_flags (ibfd, info); - ok = mips_elf_merge_obj_attributes (ibfd, obfd) && ok; + ok = mips_elf_merge_obj_attributes (ibfd, info) && ok; ok = mips_elf_merge_obj_abiflags (ibfd, obfd) && ok; @@ -16304,6 +16327,16 @@ _bfd_mips_elf_get_synthetic_symtab (bfd *abfd, return n; } +/* Return the ABI flags associated with ABFD if available. */ + +Elf_Internal_ABIFlags_v0 * +bfd_mips_elf_get_abiflags (bfd *abfd) +{ + struct mips_elf_obj_tdata *tdata = mips_elf_tdata (abfd); + + return tdata->abiflags_valid ? &tdata->abiflags : NULL; +} + void _bfd_mips_post_process_headers (bfd *abfd, struct bfd_link_info *link_info) {