This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] MIPS/BFD: Handle MIPS16 stub symbols with n64 relocs
- From: "Maciej W. Rozycki" <macro at linux-mips dot org>
- To: binutils at sourceware dot org
- Cc: Richard Sandiford <rdsandiford at googlemail dot com>
- Date: Tue, 10 Apr 2012 11:17:35 +0100 (BST)
- Subject: [PATCH] MIPS/BFD: Handle MIPS16 stub symbols with n64 relocs
Hello,
While sorting out test suite failures in a modified mips64-linux-gnu
configuration that defaults to n64 (that probably applies to a pristine
mips64-openbsd configuration too) I have noticed that we have a problem
with MIPS16 stub symbols referred to by compound relocation. We try to
locate the symbol in a MIPS16 stub section by checking the first
R_MIPS_NONE relocation against the section, but we fail to disregard
subsequent R_MIPS_NONE relocations of any non-R_MIPS_NONE relocation that
do not refer to any symbol. Only a genuine R_MIPS_NONE relocation must be
accepted for this purpose and in an n64 object that'll be one that has the
type of the first relocation in the triplet set to R_MIPS_NONE.
While our support for MIPS16 stubs in n64 binaries is incomplete, I think
some cases, such as static msym32 binaries, can work and therefore I
propose the problem to be fixed, as below. The problem can be seen with
one of the ld test cases as follows:
./ld-new: tmpdir/dump0.o: Warning: cannot determine the target function for stub section `.mips16.call.F1'
tmpdir/dump0.o: could not read symbols: Bad value
failed with: <./ld-new: tmpdir/dump0.o: Warning: cannot determine the target function for stub section `.mips16.call.F1'
tmpdir/dump0.o: could not read symbols: Bad value>, expected: <>
./ld-new: tmpdir/dump0.o: Warning: cannot determine the target function for stub section `.mips16.call.F1'
tmpdir/dump0.o: could not read symbols: Bad value
failed with: <./ld-new: tmpdir/dump0.o: Warning: cannot determine the target function for stub section `.mips16.call.F1'
tmpdir/dump0.o: could not read symbols: Bad value>, expected: <>
FAIL: MIPS16 interlinking for local functions 1
with a configuration that defaults to n64 and
ld/testsuite/ld-mips-elf/mips16-local-stubs-1.s modified so that DLA is
used rather than LA as appropriate.
The fix removes the problem and causes no regressions with said modified
mips64-linux-gnu configuration nor a pristine mips-linux-gnu one. OK to
apply?
2012-04-10 Maciej W. Rozycki <macro@linux-mips.org>
bfd/
* elfxx-mips.c (mips16_stub_symndx): Handle n64 compound relocs.
(_bfd_mips_elf_check_relocs): Update accordingly.
Maciej
binutils-mips16-stub64.patch
Index: binutils/bfd/elfxx-mips.c
===================================================================
--- binutils.orig/bfd/elfxx-mips.c
+++ binutils/bfd/elfxx-mips.c
@@ -1460,14 +1460,17 @@ section_allows_mips16_refs_p (asection *
function, or 0 if we can't decide which function that is. */
static unsigned long
-mips16_stub_symndx (asection *sec ATTRIBUTE_UNUSED,
+mips16_stub_symndx (const struct elf_backend_data *bed,
+ asection *sec ATTRIBUTE_UNUSED,
const Elf_Internal_Rela *relocs,
const Elf_Internal_Rela *relend)
{
+ int int_rels_per_ext_rel = bed->s->int_rels_per_ext_rel;
const Elf_Internal_Rela *rel;
- /* Trust the first R_MIPS_NONE relocation, if any. */
- for (rel = relocs; rel < relend; rel++)
+ /* Trust the first R_MIPS_NONE relocation, if any, but not a subsequent
+ one in a compound relocation. */
+ for (rel = relocs; rel < relend; rel += int_rels_per_ext_rel)
if (ELF_R_TYPE (sec->owner, rel->r_info) == R_MIPS_NONE)
return ELF_R_SYM (sec->owner, rel->r_info);
@@ -7569,7 +7572,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
/* Look at the relocation information to figure out which symbol
this is for. */
- r_symndx = mips16_stub_symndx (sec, relocs, rel_end);
+ r_symndx = mips16_stub_symndx (bed, sec, relocs, rel_end);
if (r_symndx == 0)
{
(*_bfd_error_handler)
@@ -7694,7 +7697,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
/* Look at the relocation information to figure out which symbol
this is for. */
- r_symndx = mips16_stub_symndx (sec, relocs, rel_end);
+ r_symndx = mips16_stub_symndx (bed, sec, relocs, rel_end);
if (r_symndx == 0)
{
(*_bfd_error_handler)