From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10724 invoked by alias); 7 Jun 2013 21:09:51 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 10676 invoked by uid 89); 7 Jun 2013 21:09:43 -0000 X-Spam-SWARE-Status: No, score=-4.5 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL,TW_FX autolearn=ham version=3.3.1 X-Spam-User: qpsmtpd, 2 recipients Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Fri, 07 Jun 2013 21:09:40 +0000 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1Ul3uk-0005mZ-A8 from Maciej_Rozycki@mentor.com ; Fri, 07 Jun 2013 14:09:38 -0700 Received: from SVR-IES-FEM-01.mgc.mentorg.com ([137.202.0.104]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Fri, 7 Jun 2013 14:09:36 -0700 Received: from [172.30.64.124] (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server id 14.2.247.3; Fri, 7 Jun 2013 22:09:34 +0100 Date: Sat, 08 Jun 2013 00:22:00 -0000 From: "Maciej W. Rozycki" To: Richard Sandiford CC: Joel Brobecker , Catherine Moore , , Subject: Re: [PATCH 1/2] MIPS: Compressed PLT/stubs support In-Reply-To: <87ehfozyhg.fsf@talisman.default> Message-ID: References: <87621mwt3l.fsf@talisman.default> <87ehfozyhg.fsf@talisman.default> User-Agent: Alpine 1.10 (DEB 962 2008-03-14) MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" X-SW-Source: 2013-06/txt/msg00184.txt.bz2 On Sat, 9 Mar 2013, Richard Sandiford wrote: > > Index: binutils-fsf-trunk-quilt/bfd/elfxx-mips.c > > =================================================================== > > --- binutils-fsf-trunk-quilt.orig/bfd/elfxx-mips.c 2013-03-08 11:09:04.000000000 +0000 > > +++ binutils-fsf-trunk-quilt/bfd/elfxx-mips.c 2013-03-09 02:43:31.765430204 +0000 > > @@ -319,6 +319,32 @@ struct mips_elf_hash_sort_data > > long max_non_got_dynindx; > > }; > > > > +/* We make up to two PLT entries if needed, one for standard MIPS code > > + and one for compressed code, either of MIPS16 or microMIPS one. We > > + keep the record of a stub if one is used instead separately, for > > + easier processing. */ > > s/either of MIPS16 or microMIPS one/either a MIPS16 or microMIPS one/. > Suggest "We keep a separate record of traditional lazy-binding stubs, > for easier processing." Done. I wasn't sure if that would sound better as "either MIPS16 or microMIPS one," -- referring to "code" (uncountable) rather than "a PLT entry" -- but eventually I decided it sounded better with the article. ;) > > @@ -5124,13 +5232,55 @@ mips_elf_calculate_relocation (bfd *abfd > > || h->root.root.type == bfd_link_hash_defweak) > > && h->root.root.u.def.section) > > { > > - sec = h->root.root.u.def.section; > > - if (sec->output_section) > > - symbol = (h->root.root.u.def.value > > - + sec->output_section->vma > > - + sec->output_offset); > > + if (h->use_plt_entry) > > + { > > + bfd_boolean micromips_p = MICROMIPS_P (abfd); > > + bfd_vma plt_offset; > > + bfd_vma isa_bit; > > + bfd_vma val; > > + > > + BFD_ASSERT (h->root.plt.plist != NULL); > > + BFD_ASSERT (h->root.plt.plist->mips_offset != MINUS_ONE > > + || h->root.plt.plist->comp_offset != MINUS_ONE); > > + > > + plt_offset = htab->plt_header_size; > > + if (h->root.plt.plist->comp_offset == MINUS_ONE > > + || (h->root.plt.plist->mips_offset != MINUS_ONE > > + && r_type != R_MIPS16_26 && r_type != R_MICROMIPS_26_S1)) > > + { > > + isa_bit = 0; > > + target_is_16_bit_code_p = FALSE; > > + target_is_micromips_code_p = FALSE; > > + plt_offset += h->root.plt.plist->mips_offset; > > + } > > + else > > + { > > + isa_bit = 1; > > + target_is_16_bit_code_p = !micromips_p; > > + target_is_micromips_code_p = micromips_p; > > + plt_offset += (htab->plt_mips_offset > > + + h->root.plt.plist->comp_offset); > > + } > > + BFD_ASSERT (plt_offset <= htab->splt->size); > > + > > + sec = htab->splt; > > + val = plt_offset + isa_bit; > > + /* For VxWorks, point at the PLT load stub rather than the > > + lazy resolution stub. */ > > + if (htab->is_vxworks) > > + val += 8; > > + symbol = sec->output_section->vma + sec->output_offset + val; > > + } > > else > > - symbol = h->root.root.u.def.value; > > + { > > + sec = h->root.root.u.def.section; > > + if (sec->output_section) > > + symbol = (h->root.root.u.def.value > > + + sec->output_section->vma > > + + sec->output_offset); > > + else > > + symbol = h->root.root.u.def.value; > > + } > > } > > else if (h->root.root.type == bfd_link_hash_undefweak) > > /* We allow relocations against undefined weak symbols, giving > > @@ -5177,12 +5327,6 @@ mips_elf_calculate_relocation (bfd *abfd > > { > > return bfd_reloc_notsupported; > > } > > - > > - target_is_16_bit_code_p = ELF_ST_IS_MIPS16 (h->root.other); > > - /* If the output section is the PLT section, > > - then the target is not microMIPS. */ > > - target_is_micromips_code_p = (htab->splt != sec > > - && ELF_ST_IS_MICROMIPS (h->root.other)); > > } > > > > /* If this is a reference to a 16-bit function with a stub, we need > > The block of code that you're changing here is simply calculating the > symbol value. Now that size_dynamic_sections has set that up for us, > these two hunks should be dropped, and the test for whether to use a > compressed PLT entry instead of the symbol value should be made > afterwards, as it is for things like hard-float and LA25 stubs. D'oh, it must have escaped me as the obvious consequence of the introduction of mips_elf_set_plt_sym_value. I haven't merely reverted the latter hunk though -- given that we're going to handle the PLT explicitly later on now, we want to preset target_is_micromips_code_p according to the symbol table here, just as we already do for target_is_16_bit_code_p. > Maybe something like: > > /* If compressed PLT entries are available, make sure that we use them > for MIPS16 and microMIPS calls. */ > else if ((r_type == R_MIPS16_26 || r_type == R_MICROMIPS_26_S1) > && h != NULL > && h->use_plt > && h->root.plt.plist->comp_offset != MINUS_ONE) > { > sec = htab->splt; > symbol = (sec->output_section->vma > + sec->output_offset > + htab->plt_header_size > + htab->plt_mips_offset > + h->root.plt.plist->comp_offset > + 1); > target_is_16_bit_code_p = !MICROMIPS_P (abfd); > target_is_micromips_code_p = MICROMIPS_P (abfd); > } > > at the end of the: > > /* If this is a reference to a 16-bit function with a stub, we need > to redirect the relocation to the stub unless: > > chain of ifs. More or less, though I've decided to push it ahead of the chain so that it sees the state consistent regardless of whether any PLT entry processed has been duplicated for dual-mode support. This probably does not really matter right now (fn_stub/need_fn_stub cases will override any symbol value to use for the relocation and likewise the mode setting anyway, call_stub/call_fp_stub cases will only ever have a standard MIPS PLT entry due to the arrangement in _bfd_mips_elf_adjust_dynamic_symbol and la25_stub cases will never have a PLT entry as these must resolve locally), but I feel a bit uneasy about this half-cooked state. Let me know if you disagree (and why). Also I've decided not to recalculate the symbol's value if what mips_elf_set_plt_sym_value worked out is the right thing for compressed direct calls too (i.e. there is no standard MIPS PLT entry alternative). > > - /* Make room for the .got.plt entry and the R_MIPS_JUMP_SLOT > > - relocation. */ > > - htab->sgotplt->size += MIPS_ELF_GOT_SIZE (dynobj); > > + htab->splt->size = htab->plt_mips_offset + htab->plt_comp_offset; > > + htab->sgotplt->size = htab->plt_got_index * MIPS_ELF_GOT_SIZE (dynobj); > > These last two lines should be done in size_dynamic_sections rather > than once for each symbol. I.e.: > > > @@ -8985,18 +9318,60 @@ _bfd_mips_elf_size_dynamic_sections (bfd > > = (bfd_byte *) ELF_DYNAMIC_INTERPRETER (output_bfd); > > } > > > > - /* Create a symbol for the PLT, if we know that we are using it. */ > > - if (htab->splt && htab->splt->size > 0 && htab->root.hplt == NULL) > > + /* Figure out the size of the PLT header if we know that we > > + are using it. For the sake of cache alignment always use > > + a standard header whenever any standard entries are present > > + even if microMIPS entries are present as well. This also > > + lets the microMIPS header rely on the value of $v0 only set > > + by microMIPS entries, for a small size reduction. > > + > > + Set symbol table entry values for symbols that use the > > + address of their PLT entry now that we can calculate it. > > + > > + Also create the _PROCEDURE_LINKAGE_TABLE_ symbol if we > > + haven't already in _bfd_elf_create_dynamic_sections. */ > > + if (htab->splt && htab->splt->size > 0) > > { > > + bfd_boolean micromips_p = (MICROMIPS_P (output_bfd) > > + && !htab->plt_mips_offset); > > + unsigned int other = micromips_p ? STO_MICROMIPS : 0; > > + bfd_vma isa_bit = micromips_p; > > struct elf_link_hash_entry *h; > > + bfd_vma size; > > > > BFD_ASSERT (htab->use_plts_and_copy_relocs); > > > > - h = _bfd_elf_define_linkage_sym (dynobj, info, htab->splt, > > - "_PROCEDURE_LINKAGE_TABLE_"); > > - htab->root.hplt = h; > > - if (h == NULL) > > - return FALSE; > > + if (htab->is_vxworks && info->shared) > > + size = 4 * ARRAY_SIZE (mips_vxworks_shared_plt0_entry); > > + else if (htab->is_vxworks) > > + size = 4 * ARRAY_SIZE (mips_vxworks_exec_plt0_entry); > > + else if (ABI_64_P (output_bfd)) > > + size = 4 * ARRAY_SIZE (mips_n64_exec_plt0_entry); > > + else if (ABI_N32_P (output_bfd)) > > + size = 4 * ARRAY_SIZE (mips_n32_exec_plt0_entry); > > + else if (!micromips_p) > > + size = 4 * ARRAY_SIZE (mips_o32_exec_plt0_entry); > > + else > > + size = 2 * ARRAY_SIZE (micromips_o32_exec_plt0_entry); > > + > > + htab->plt_header_is_comp = micromips_p; > > + htab->plt_header_size = size; > > + htab->splt->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)); Sure, I had to adjust the condition around this block: if (htab->splt && htab->splt->size > 0) and one in _bfd_mips_elf_adjust_dynamic_symbol accordingly though. > > + /* ADDIUPC has a span of +/-16MB, check we're in range. */ > > + if (gotpc_offset + 0x1000000 >= 0x2000000) > > + { > > + (*_bfd_error_handler) > > + (_("%B: `%A' offset of %ld from `%A' " > > + "beyond the range of ADDIUPC"), > > + output_bfd, > > + htab->sgotplt->output_section, > > + htab->splt->output_section, > > + (long) gotpc_offset); > > The last two arguments should be swapped. Nope, %A and %B are handled specially (ahead of any other format specifiers). See the comment at _bfd_default_error_handler in bfd/bfd.c. I actually verified this range checking triggers correctly (hmm, it might be worth making a dedicated test case for) and it would be outright silly to make such a mistake, wouldn't it (hint, hint!)? > > + /* ADDIUPC has a span of +/-16MB, check we're in range. */ > > + if (gotpc_offset + 0x1000000 >= 0x2000000) > > + { > > + (*_bfd_error_handler) > > + (_("%B: `%A' offset of %ld from `%A' beyond the range of ADDIUPC"), > > + output_bfd, > > + htab->sgotplt->output_section, > > + htab->splt->output_section, > > + (long) gotpc_offset); > > Same here. Ditto. ;) > > + /* Calculating the exact amount of space required for symbols would > > + require two passes over the PLT, so just pessimise assuming two > > + PLT slots per relocation. */ > > + count = relplt->size / hdr->sh_entsize; > > + counti = count * bed->s->int_rels_per_ext_rel; > > + size = 2 * count * sizeof (asymbol); > > + size += count * (sizeof (mipssuffix) + > > + (micromips_p ? sizeof (microsuffix) : sizeof (m16suffix))); > > + addlen = 2 * (sizeof ("+0x") - 1 + 8); > > +#ifdef BFD64 > > + addlen += 2 * 8 * (bed->s->elfclass == ELFCLASS64); > > +#endif > > Now that there are no addends (thanks), the last four lines should be dropped. Missed that, thanks for catching; I guess a newer GCC version would complain about this set-but-unused addlen variable. Dropped that now as well as the variable itself. > OK with those changes if they work, otherwise let me know. Given that (as noted above) the change is more than just what you suggested, here's a new version for you to review, in the form of an incremental change on top of the previous one (let me know if you'd like to see a combined version as well; I've included the intended set of ChangeLog entries only). Please double-check you're all right with it. No regressions across the usual set of MIPS targets (let me know if you want me to remind you of the actual list). Thanks. 2013-06-07 Maciej W. Rozycki bfd/ * elfxx-mips.h (_bfd_mips_elf_get_synthetic_symtab): New prototype. * elf32-mips.c (elf_backend_plt_sym_val): Remove macro. (bfd_elf32_get_synthetic_symtab): New macro. * elfxx-mips.c (plt_entry): New structure. (mips_elf_link_hash_entry): Add use_plt_entry member. (mips_elf_link_hash_table): Rename plt_entry_size member to plt_mips_entry_size. Add plt_comp_entry_size, plt_mips_offset, plt_comp_offset, plt_got_index entries and plt_header_is_comp members. (STUB_LW_MICROMIPS, STUB_MOVE_MICROMIPS): New macros. (STUB_LUI_MICROMIPS, STUB_JALR_MICROMIPS): Likewise. (STUB_ORI_MICROMIPS, STUB_LI16U_MICROMIPS): Likewise. (STUB_LI16S_MICROMIPS): Likewise. (MICROMIPS_FUNCTION_STUB_NORMAL_SIZE): Likewise. (MICROMIPS_FUNCTION_STUB_BIG_SIZE): Likewise. (micromips_o32_exec_plt0_entry): New variable. (mips16_o32_exec_plt_entry): Likewise. (micromips_o32_exec_plt_entry): Likewise. (mips_elf_link_hash_newfunc): Initialize use_plt_entry. (mips_elf_output_extsym): Update to use gotplt_union's plist member rather than offset. (mips_elf_gotplt_index): Likewise. Remove the VxWorks restriction. Use MIPS_ELF_GOT_SIZE to calculate GOT address. (mips_elf_count_got_symbols): Update to use gotplt_union's plist member rather than offset. (mips_elf_calculate_relocation): Handle MIPS16/microMIPS PLT entries. (_bfd_mips_elf_create_dynamic_sections): Don't set PLT sizes here. (mips_elf_make_plt_record): New function. (_bfd_mips_elf_check_relocs): Update comment. Record occurences of JAL relocations that might need a PLT entry. (_bfd_mips_elf_adjust_dynamic_symbol): Update to use gotplt_union's plist member rather than offset. Set individual PLT entry sizes here. Handle MIPS16/microMIPS PLT entries. Don't set the symbol's value in the symbol table for PLT references here. Don't set the PLT or PLT GOT section sizes here. (mips_elf_estimate_stub_size): Handle microMIPS stubs. (mips_elf_allocate_lazy_stub): Likewise. (mips_elf_lay_out_lazy_stubs): Likewise. Define a _MIPS_STUBS_ magic symbol. (mips_elf_set_plt_sym_value): New function. (_bfd_mips_elf_size_dynamic_sections): Set PLT header size and PLT and PLT GOT section sizes here. Set the symbol values in the symbol table for PLT references here. Handle microMIPS annotation of the _PROCEDURE_LINKAGE_TABLE_ magic symbol. (_bfd_mips_elf_finish_dynamic_symbol): Update to use gotplt_union's plist member rather than offset. Handle MIPS16/microMIPS PLT entries. Handle microMIPS stubs. (_bfd_mips_vxworks_finish_dynamic_symbol): Update to use gotplt_union's plist member rather than offset. Use MIPS_ELF_GOT_SIZE to calculate GOT address. (mips_finish_exec_plt): Handle microMIPS PLT. Return status. (_bfd_mips_elf_finish_dynamic_sections): Handle result from mips_finish_exec_plt. (_bfd_mips_elf_link_hash_table_create): Update to use gotplt_union's plist member rather than offset. (_bfd_mips_elf_get_synthetic_symtab): New function. include/elf/ * mips.h (ELF_ST_IS_MIPS_PLT): Respect STO_MIPS16 setting. (ELF_ST_SET_MIPS_PLT): Likewise. gdb/ * mips-tdep.c (mips_elf_make_msymbol_special): Handle MIPS16 and microMIPS synthetic symbols. ld/ * emulparams/elf32btsmip.sh: Arrange for .got.plt to be placed as close to .plt as possible. * scripttempl/elf.sc: Handle $INITIAL_READWRITE_SECTIONS and $PLT_NEXT_DATA variables. ld/testsuite/ * ld-mips-elf/jalx-2.dd: Update for microMIPS PLT support. * ld-mips-elf/pic-and-nonpic-3a.dd: Update for the _MIPS_STUBS_ magic symbol. * ld-mips-elf/pic-and-nonpic-3b.dd: Likewise. * ld-mips-elf/pic-and-nonpic-6-n32.dd: Likewise. * ld-mips-elf/pic-and-nonpic-6-n64.dd: Likewise. * ld-mips-elf/pic-and-nonpic-6-o32.dd: Likewise. * ld-mips-elf/stub-dynsym-1-10000.d: Likewise. * ld-mips-elf/stub-dynsym-1-2fe80.d: Likewise. * ld-mips-elf/stub-dynsym-1-7fff.d: Likewise. * ld-mips-elf/stub-dynsym-1-8000.d: Likewise. * ld-mips-elf/stub-dynsym-1-fff0.d: Likewise. * ld-mips-elf/tlslib-o32.d: Likewise. opcodes/ * mips-dis.c (is_mips16_plt_tail): New function. (print_insn_mips16): Handle MIPS16 PLT entry's GOT slot address word. (is_compressed_mode_p): Handle MIPS16/microMIPS PLT entries. Maciej binutils-umips16-plt-stubs-update.diff Index: binutils-fsf-trunk-quilt/bfd/elfxx-mips.c =================================================================== --- binutils-fsf-trunk-quilt.orig/bfd/elfxx-mips.c 2013-06-07 19:07:47.000000000 +0100 +++ binutils-fsf-trunk-quilt/bfd/elfxx-mips.c 2013-06-07 21:02:39.942586414 +0100 @@ -318,9 +318,9 @@ struct mips_elf_hash_sort_data }; /* We make up to two PLT entries if needed, one for standard MIPS code - and one for compressed code, either of MIPS16 or microMIPS one. We - keep the record of a stub if one is used instead separately, for - easier processing. */ + and one for compressed code, either a MIPS16 or microMIPS one. We + keep a separate record of traditional lazy-binding stubs, for easier + processing. */ struct plt_entry { @@ -5201,9 +5201,6 @@ mips_elf_calculate_relocation (bfd *abfd /* Record the name of this symbol, for our caller. */ *namep = h->root.root.root.string; - target_is_16_bit_code_p = ELF_ST_IS_MIPS16 (h->root.other); - target_is_micromips_code_p = ELF_ST_IS_MICROMIPS (h->root.other); - /* See if this is the special _gp_disp symbol. Note that such a symbol must always be a global symbol. */ if (strcmp (*namep, "_gp_disp") == 0 @@ -5230,55 +5227,13 @@ mips_elf_calculate_relocation (bfd *abfd || h->root.root.type == bfd_link_hash_defweak) && h->root.root.u.def.section) { - if (h->use_plt_entry) - { - bfd_boolean micromips_p = MICROMIPS_P (abfd); - bfd_vma plt_offset; - bfd_vma isa_bit; - bfd_vma val; - - BFD_ASSERT (h->root.plt.plist != NULL); - BFD_ASSERT (h->root.plt.plist->mips_offset != MINUS_ONE - || h->root.plt.plist->comp_offset != MINUS_ONE); - - plt_offset = htab->plt_header_size; - if (h->root.plt.plist->comp_offset == MINUS_ONE - || (h->root.plt.plist->mips_offset != MINUS_ONE - && r_type != R_MIPS16_26 && r_type != R_MICROMIPS_26_S1)) - { - isa_bit = 0; - target_is_16_bit_code_p = FALSE; - target_is_micromips_code_p = FALSE; - plt_offset += h->root.plt.plist->mips_offset; - } - else - { - isa_bit = 1; - target_is_16_bit_code_p = !micromips_p; - target_is_micromips_code_p = micromips_p; - plt_offset += (htab->plt_mips_offset - + h->root.plt.plist->comp_offset); - } - BFD_ASSERT (plt_offset <= htab->splt->size); - - sec = htab->splt; - val = plt_offset + isa_bit; - /* For VxWorks, point at the PLT load stub rather than the - lazy resolution stub. */ - if (htab->is_vxworks) - val += 8; - symbol = sec->output_section->vma + sec->output_offset + val; - } + sec = h->root.root.u.def.section; + if (sec->output_section) + symbol = (h->root.root.u.def.value + + sec->output_section->vma + + sec->output_offset); else - { - sec = h->root.root.u.def.section; - if (sec->output_section) - symbol = (h->root.root.u.def.value - + sec->output_section->vma - + sec->output_offset); - else - symbol = h->root.root.u.def.value; - } + symbol = h->root.root.u.def.value; } else if (h->root.root.type == bfd_link_hash_undefweak) /* We allow relocations against undefined weak symbols, giving @@ -5325,6 +5280,35 @@ mips_elf_calculate_relocation (bfd *abfd { return bfd_reloc_notsupported; } + + target_is_16_bit_code_p = ELF_ST_IS_MIPS16 (h->root.other); + target_is_micromips_code_p = ELF_ST_IS_MICROMIPS (h->root.other); + } + + /* 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 + to point to the standard PLT entry, so redirect to the compressed + one. Adjust the mode settings accordingly. */ + if ((r_type == R_MIPS16_26 || r_type == R_MICROMIPS_26_S1) + && !info->relocatable + && h != NULL + && h->use_plt_entry + && h->root.plt.plist->comp_offset != MINUS_ONE + && h->root.plt.plist->mips_offset != MINUS_ONE) + { + bfd_boolean micromips_p = MICROMIPS_P (abfd); + + sec = htab->splt; + symbol = (sec->output_section->vma + + sec->output_offset + + htab->plt_header_size + + htab->plt_mips_offset + + h->root.plt.plist->comp_offset + + 1); + + target_is_16_bit_code_p = !micromips_p; + target_is_micromips_code_p = micromips_p; } /* If this is a reference to a 16-bit function with a stub, we need @@ -8778,7 +8762,7 @@ _bfd_mips_elf_adjust_dynamic_symbol (str /* If this is the first symbol to need a PLT entry, then make some basic setup. Also work out PLT entry sizes. We'll need them for PLT offset calculations. */ - if (htab->splt->size == 0) + if (htab->plt_mips_offset + htab->plt_comp_offset == 0) { BFD_ASSERT (htab->sgotplt->size == 0); BFD_ASSERT (htab->plt_got_index == 0); @@ -8890,9 +8874,6 @@ _bfd_mips_elf_adjust_dynamic_symbol (str if (!info->shared && !h->def_regular) hmips->use_plt_entry = TRUE; - htab->splt->size = htab->plt_mips_offset + htab->plt_comp_offset; - htab->sgotplt->size = htab->plt_got_index * MIPS_ELF_GOT_SIZE (dynobj); - /* Make room for the R_MIPS_JUMP_SLOT relocation. */ htab->srelplt->size += (htab->is_vxworks ? MIPS_ELF_RELA_SIZE (dynobj) @@ -9338,7 +9319,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd Also create the _PROCEDURE_LINKAGE_TABLE_ symbol if we haven't already in _bfd_elf_create_dynamic_sections. */ - if (htab->splt && htab->splt->size > 0) + if (htab->splt && htab->plt_mips_offset + htab->plt_comp_offset != 0) { bfd_boolean micromips_p = (MICROMIPS_P (output_bfd) && !htab->plt_mips_offset); @@ -9348,6 +9329,8 @@ _bfd_mips_elf_size_dynamic_sections (bfd bfd_vma size; BFD_ASSERT (htab->use_plts_and_copy_relocs); + BFD_ASSERT (htab->sgotplt->size == 0); + BFD_ASSERT (htab->splt->size == 0); if (htab->is_vxworks && info->shared) size = 4 * ARRAY_SIZE (mips_vxworks_shared_plt0_entry); @@ -9364,7 +9347,11 @@ _bfd_mips_elf_size_dynamic_sections (bfd htab->plt_header_is_comp = micromips_p; htab->plt_header_size = size; - htab->splt->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)); mips_elf_link_hash_traverse (htab, mips_elf_set_plt_sym_value, info); @@ -14943,7 +14930,6 @@ _bfd_mips_elf_get_synthetic_symtab (bfd bfd_vma opcode; asection *plt; asymbol *send; - size_t addlen; size_t size; char *names; long counti; @@ -14985,10 +14971,6 @@ _bfd_mips_elf_get_synthetic_symtab (bfd size = 2 * count * sizeof (asymbol); size += count * (sizeof (mipssuffix) + (micromips_p ? sizeof (microsuffix) : sizeof (m16suffix))); - addlen = 2 * (sizeof ("+0x") - 1 + 8); -#ifdef BFD64 - addlen += 2 * 8 * (bed->s->elfclass == ELFCLASS64); -#endif for (pi = 0; pi < counti; pi += bed->s->int_rels_per_ext_rel) size += 2 * strlen ((*p[pi].sym_ptr_ptr)->name); Index: binutils-fsf-trunk-quilt/include/elf/mips.h =================================================================== --- binutils-fsf-trunk-quilt.orig/include/elf/mips.h 2013-06-07 19:06:39.000000000 +0100 +++ binutils-fsf-trunk-quilt/include/elf/mips.h 2013-06-07 19:07:49.052856391 +0100 @@ -803,8 +803,14 @@ extern void bfd_mips_elf32_swap_reginfo_ PLT entries and traditional MIPS lazy binding stubs. We mark the former with STO_MIPS_PLT to distinguish them from the latter. */ #define STO_MIPS_PLT 0x8 -#define ELF_ST_IS_MIPS_PLT(other) (((other) & STO_MIPS_FLAGS) == STO_MIPS_PLT) -#define ELF_ST_SET_MIPS_PLT(other) (((other) & ~STO_MIPS_FLAGS) | STO_MIPS_PLT) +#define ELF_ST_IS_MIPS_PLT(other) \ + ((ELF_ST_IS_MIPS16 (other) \ + ? ((other) & (~STO_MIPS16 & STO_MIPS_FLAGS)) \ + : ((other) & STO_MIPS_FLAGS)) == STO_MIPS_PLT) +#define ELF_ST_SET_MIPS_PLT(other) \ + ((ELF_ST_IS_MIPS16 (other) \ + ? ((other) & (STO_MIPS16 | ~STO_MIPS_FLAGS)) \ + : ((other) & ~STO_MIPS_FLAGS)) | STO_MIPS_PLT) /* This value is used to mark PIC functions in an object that mixes PIC and non-PIC. Note that this bit overlaps with STO_MIPS16,