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]

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


On Sun, Jan 25, 2009 at 11:20 PM, John David Anglin
<dave@hiauly1.hia.nrc.ca> wrote:
> 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.

The long branch stub code does seem like it would be a worthy target
for trying to abstract out so more architectures can use it. For the
port of binutils I have here (still out of tree pending copyright
assignment) I adapted the elf32-hppa code. I believe powerpc also has
similar code, and I'm sure other architectures do as well.

Do you think it would be possible to make this code generic? Would
such a patch be accepted?

> 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]