The attached change fixes the PR. This problem affects building texmaker and a few other Debian
packages.

The code in pa_asm_output_mi_thunk originally checked whether the function was reachable with a pc-relative branch, but the assembler complains if the branch can't reach the stub table. I don't think thunks need to reach the stub table in this case but it's probably hard to distinguish in the assembler this case from situations where a "call" needs to reach the stub table. So, I fixed the problem in the compiler.

In debugging this problem, I noticed a small regression in the computation of last_address which was introduced when we changed to using final_start_function and final_end_function to get debug info for thunks. The final_end_function call messed up the value of last_address.

Tested on hppa2.0w-hp-hpux11.11, hppa64-hp-hpux11.11 and hppa-unknown- linux-gnu. Committed
to trunk, 4.9 and 4.8.

Dave
--
John David Anglin       dave.ang...@bell.net


2014-08-23  John David Anglin  <dang...@gcc.gnu.org>

        PR target/62038
        * config/pa/pa.c (pa_output_function_epilogue): Don't set
        last_address when the current function is a thunk.
        (pa_asm_output_mi_thunk): When we don't have named sections or they
        are not being used, check that thunk can reach the stub table with a
        short branch.

Index: config/pa/pa.c
===================================================================
--- config/pa/pa.c      (revision 214251)
+++ config/pa/pa.c      (working copy)
@@ -4137,9 +4137,8 @@
 pa_output_function_epilogue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
 {
   rtx insn = get_last_insn ();
+  bool extra_nop;
 
-  last_address = 0;
-
   /* pa_expand_epilogue does the dirty work now.  We just need
      to output the assembler directives which denote the end
      of a function.
@@ -4162,8 +4161,10 @@
   if (insn && CALL_P (insn))
     {
       fputs ("\tnop\n", file);
-      last_address += 4;
+      extra_nop = true;
     }
+  else
+    extra_nop = false;
 
   fputs ("\t.EXIT\n\t.PROCEND\n", file);
 
@@ -4176,12 +4177,13 @@
       cfun->machine->in_nsubspa = 2;
     }
 
-  /* Thunks do their own accounting.  */
+  /* Thunks do their own insn accounting.  */
   if (cfun->is_thunk)
     return;
 
   if (INSN_ADDRESSES_SET_P ())
     {
+      last_address = extra_nop ? 4 : 0;
       insn = get_last_nonnote_insn ();
       last_address += INSN_ADDRESSES (INSN_UID (insn));
       if (INSN_P (insn))
@@ -8275,12 +8277,16 @@
                   || ((DECL_SECTION_NAME (thunk_fndecl)
                        == DECL_SECTION_NAME (function))
                       && last_address < 262132)))
+             /* In this case, we need to be able to reach the start of
+                the stub table even though the function is likely closer
+                and can be jumped to directly.  */
              || (targetm_common.have_named_sections
                  && DECL_SECTION_NAME (thunk_fndecl) == NULL
                  && DECL_SECTION_NAME (function) == NULL
-                 && last_address < 262132)
+                 && total_code_bytes < MAX_PCREL17F_OFFSET)
+             /* Likewise.  */
              || (!targetm_common.have_named_sections
-                 && last_address < 262132))))
+                 && total_code_bytes < MAX_PCREL17F_OFFSET))))
     {
       if (!val_14)
        output_asm_insn ("addil L'%2,%%r26", xoperands);

Reply via email to