This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]