This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH 1/3] MIPS/BFD: Correct protected symbol relocation processing
- From: "Maciej W. Rozycki" <macro at codesourcery dot com>
- To: <binutils at sourceware dot org>
- Cc: Richard Sandiford <rdsandiford at googlemail dot com>
- Date: Wed, 8 Aug 2012 23:46:56 +0100
- Subject: [PATCH 1/3] MIPS/BFD: Correct protected symbol relocation processing
Hello,
The change below fixes a problem where an R_MIPS_CALL16 relocation
against a protected symbol makes BFD treat the symbol as a global
(preemptible) one. This cannot succeed as protected symbols are local
(non-preemptible) and therefore assigned to the local part of the GOT (as
long as they are not referred to for a purpose other than making a call;
strictly speaking this is a divergence from how export classess have been
originally specified[1] for the MIPS target by SGI).
Such relocations are produced by GCC when compiling to PIC code where
calls are made to functions that have not been declared with the
"protected" visibility attribute (of course handcoded assembly code may
have them as well). The problem triggers when the references
(relocations) are satisfied with a symbol whose export class (visibility)
has been set to "protected", but not either of "hidden" or "internal".
An assertion has been placed in code to ensure that references to global
symbols end up in the global part of the GOT and as a result of the
mistreatment described the assertion fails:
mips-linux-gnu-ld: BFD (...) 2.23.51.20120807 assertion fail .../bfd/elfxx-mips.c:3321
-- that's:
BFD_ASSERT (got_index < htab->sgot->size);
in mips_elf_global_got_index.
The change adjusts the treatment of protected symbols in relocation
processing to match code that assigns them to the local part of the GOT.
The difference between SYMBOL_REFERENCES_LOCAL and SYMBOL_CALLS_LOCAL is
the former treats protected symbols as global and the latter treats them
as local. The got_only_for_calls condition has been set to treat
protected symbols as global or local as appropriate (depending on whether
they are only used for making a call or not; as noted above).
The change causes no regressions in binutils testsuites on the 23 MIPS
targets I've been using for testing recently. There have been no
regressions in the glibc test suite on Linux targets either (o32 and n64
tested).
OK to apply?
I have prepared specific test cases to cover this problem and will be
sending them separately. Additionally the test cases triggered a
segmentation fault in LD with the mips-sgi-irix6 target that I have fixed
with the second patch of this series.
2012-08-08 Maciej W. Rozycki <macro@codesourcery.com>
bfd/
* elfxx-mips.c (mips_elf_calculate_relocation): Fix the handling
of protected symbols.
Maciej
[1] "64-bit ELF Object File Specification Draft Version 2.5", SGI doc
#007-4658-001
binutils-bfd-mips-protected-call16.diff
Index: binutils-fsf-trunk-quilt/bfd/elfxx-mips.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/bfd/elfxx-mips.c 2012-08-08 02:12:20.120577868 +0100
+++ binutils-fsf-trunk-quilt/bfd/elfxx-mips.c 2012-08-08 14:03:37.480542340 +0100
@@ -5343,7 +5343,10 @@ mips_elf_calculate_relocation (bfd *abfd
&& (target_is_16_bit_code_p
|| target_is_micromips_code_p))));
- local_p = h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->root);
+ local_p = (h == NULL
+ || (h->got_only_for_calls
+ ? SYMBOL_CALLS_LOCAL (info, &h->root)
+ : SYMBOL_REFERENCES_LOCAL (info, &h->root)));
gp0 = _bfd_get_gp_value (input_bfd);
gp = _bfd_get_gp_value (abfd);