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]

[committed] Ensure pc-relative calls can reach their target on hppa64


GCC has put a little weight on over the years.  It turns out GNU ld can
no longer link cc1plus or f951 on hppa64 because the branch distances for
some calls now exceed the maximum distance for branches using the
R_PARISC_PCREL22F relocation.

There is no long branch stub support and out of range branches are silently
accepted.  We need to port the stub management code from elf32-hppa.c to
elf64-hppa.c.  This is a bit tricky since the code has diverged in other
ways.

In the meantime, I have more or less copied the code to check for out of
range branches from elf32-hppa.c to elf-hppa.h.

Tested on hppa64-hp-hpux11.11:

/test/gnu/gcc/objdir/./prev-gcc/xgcc -B/test/gnu/gcc/objdir/./prev-gcc/ -B/opt/gnu64/gcc/gcc-4.4.0/hppa64-hp-hpux11.11/bin/  -g -O2 -DIN_GCC   -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wcast-qual -Wold-style-definition -Wc++-compat -Wmissing-format-attribute -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -Werror -fno-common  -DHAVE_CONFIG_H  -o cc1plus-dummy \
              cp/cp-lang.o stub-objc.o cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o cp/class.o cp/decl2.o cp/error.o cp/lex.o cp/parser.o cp/ptree.o cp/rtti.o cp/typeck.o cp/cvt.o cp/except.o cp/friend.o cp/init.o cp/method.o cp/search.o cp/semantics.o cp/tree.o cp/repo.o cp/dump.o cp/optimize.o cp/mangle.o cp/cp-objcp-common.o cp/name-lookup.o cp/cxx-pretty-print.o cp/cp-gimplify.o tree-mudflap.o attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o c-dump.o c-pretty-print.o c-opts.o c-pch.o incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o prefix.o c-gimplify.o c-omp.o tree-inline.o dummy-checksum.o main.o tree-browser.o libbackend.a ../libcpp/libcpp.a ../libdecnumber/libdecnumber.a ../libcpp/libcpp.a   ../libiberty/libiberty.a ../libdecnumber/libdecnumber.a   -L/opt/gnu64/gcc/gcc-4.4.0/lib -lmpfr -lgmp
/opt/gnu64/bin/ld: /usr/ccs/lib/pa20_64/crt0.o(.text+0x7a4): cannot reach $$rem2I
/opt/gnu64/bin/ld: BFD (GNU Binutils) 2.19.51.20090125 internal error, aborting 
at ../../src/bfd/elf-hppa.h line 2346 in elf64_hppa_relocate_section

/opt/gnu64/bin/ld: Please report this bug.

Committed to binutils trunk.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)

2009-01-25  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

	* elf-hppa.h (elf_hppa_final_link_relocate): Add check to ensure that
	branch targets can be reached for R_PARISC_PCREL22F, R_PARISC_PCREL17F
	and R_PARISC_PCREL12F relocations.

Index: elf-hppa.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-hppa.h,v
retrieving revision 1.89
diff -u -3 -p -r1.89 elf-hppa.h
--- elf-hppa.h	28 Aug 2008 02:33:44 -0000	1.89
+++ elf-hppa.h	25 Jan 2009 22:42:20 -0000
@@ -1606,10 +1606,11 @@ elf_hppa_final_link_relocate (Elf_Intern
 			      bfd_vma value,
 			      struct bfd_link_info *info,
 			      asection *sym_sec,
-			      struct elf_link_hash_entry *h ATTRIBUTE_UNUSED,
+			      struct elf_link_hash_entry *h,
 			      struct elf64_hppa_dyn_hash_entry *dyn_h)
 {
   int insn;
+  bfd_vma max_branch_offset = 0;
   bfd_vma offset = rel->r_offset;
   bfd_signed_vma addend = rel->r_addend;
   reloc_howto_type *howto = elf_hppa_howto_table + ELF_R_TYPE (rel->r_info);
@@ -1629,7 +1630,7 @@ elf_hppa_final_link_relocate (Elf_Intern
        Note for a call to a function defined in another dynamic library
        we want to redirect the call to a stub.  */
 
-    /* Random PC relative relocs.  */
+    /* PC relative relocs without an implicit offset.  */
     case R_PARISC_PCREL21L:
     case R_PARISC_PCREL14R:
     case R_PARISC_PCREL14F:
@@ -1684,6 +1685,27 @@ elf_hppa_final_link_relocate (Elf_Intern
 	value -= (offset + input_section->output_offset
 		  + input_section->output_section->vma);
 
+	if (r_type == (unsigned int) R_PARISC_PCREL22F)
+	  max_branch_offset = (1 << (22-1)) << 2;
+	else if (r_type == (unsigned int) R_PARISC_PCREL17F)
+	  max_branch_offset = (1 << (17-1)) << 2;
+	else if (r_type == (unsigned int) R_PARISC_PCREL12F)
+	  max_branch_offset = (1 << (12-1)) << 2;
+
+	/* Make sure we can reach the branch target.  */
+	if (max_branch_offset != 0
+	    && value + addend + max_branch_offset >= 2*max_branch_offset)
+	  {
+	    (*_bfd_error_handler)
+	      (_("%B(%A+0x%lx): cannot reach %s"),
+	      input_bfd,
+	      input_section,
+	      offset,
+	      h->root.root.string);
+	    bfd_set_error (bfd_error_bad_value);
+	    return bfd_reloc_notsupported;
+	  }
+
 	/* Adjust for any field selectors.  */
 	if (r_type == R_PARISC_PCREL17R)
 	  value = hppa_field_adjust (value, -8 + addend, e_rsel);


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