The attached change fixes a startup issue of emacs24 on Debian hppa-linux.  The 
emacs24 build does some tricky
stuff to preinitialize values, so that standard static initialization check is 
skipped.  However, the global offset table has
moved in the final executable and emacs24 crashes.

The attached change changes the check to one against the runtime global offset 
table address.  If its location has changed,
new values to call fixup in the dynamic linker are computed.

The offset order to find the address of _dl_fixup is changed as the template is 
now everywhere.

Tested with no observed regressions on trunk.  Installed to trunk and 4.9.

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


2015-12-01  John David Anglin  <dang...@gcc.gnu.org>

        * config/pa/fptr.c (__canonicalize_funcptr_for_compare): Initialize
        fixup values if saved GOT address doesn't match runtime address.
        (fixup_branch_offset): Reorder list.

Index: config/pa/fptr.c
===================================================================
--- config/pa/fptr.c    (revision 231043)
+++ config/pa/fptr.c    (working copy)
@@ -40,7 +40,7 @@
    the template should it be necessary to change the current branch
    position.  */
 #define NOFFSETS 2
-static int fixup_branch_offset[NOFFSETS] = { 32, -4 };
+static int fixup_branch_offset[NOFFSETS] = { -4, 32 };
 
 #define GET_FIELD(X, FROM, TO) \
   ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
@@ -66,6 +66,7 @@
 {
   static unsigned int fixup_plabel[2];
   static fixup_t fixup;
+  static unsigned int *init_fixup;
   unsigned int *plabel, *got;
 
   /* -1 and page 0 are special.  -1 is used in crtend to mark the end of
@@ -88,9 +89,11 @@
     return plabel[0];
 
   /* Initialize our plabel for calling fixup if we haven't done so already.
-     This code needs to be thread safe but we don't have to be too careful
-     as the result is invariant.  */
-  if (!fixup)
+     We can't rely on static initialization so we check that any previous
+     initialization was done for the current got address.  This code needs
+     to be thread safe but we don't have to be too careful as the result
+     is invariant.  */
+  if (init_fixup != got)
     {
       int i;
       unsigned int *iptr;
@@ -121,6 +124,9 @@
       fixup_plabel[0] = (unsigned int) iptr + 8;  /* address of fixup */
       fixup_plabel[1] = got[-1];                 /* ltp for fixup */
       fixup = (fixup_t) ((int) fixup_plabel | 3);
+
+      /* Save address of the global offset table.  */
+      init_fixup = got;
     }
 
   /* Call fixup to resolve the function address.  got[1] contains the

Reply via email to