This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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] Fix two regressions on S/390


Hello,

this patch fixes two regressions on s390 / s390x.

The first bug shows up as incorrect DWARF-2 unwind data
causing the exception handling runtime to crash or hang
in certain cases.  This happens when the epilogue code
changes the stack pointer before restoring the saved
registers (because the stack frame is too large to access
the register save area directly).  That instruction was
tagged with FRAME_RELATED_P by s390_emit_epilogue, which
causes a DWARF-2 FDE to be emitted.

This is fine as long as the epilog is actually at the
end of the function.  However, due to basic block reordering,
the epilog code can be moved in the middle of the function.
Unfortunately, DWARF-2 FDEs are considered valid of all pc
values between the instruction where they are emitted and
the subsequent FDE (or, as in this case, the end of the
function).  This can cause that 'epilog FDE' to be considered
current for other basic blocks; if an exception is unwound
through one of those blocks, and incorrect stack pointer
thus used by the unwinding runtime.

To fix this problem, I'm changing s390_emit_epilogue to never
the FRAME_RELATED_P on any epilogue insn, even if it changes
the stack / frame pointer.  This should not hurt normally,
as no exception should ever be unwound through any insn inside
the epilog code ...


The second problem is that the compiler would sometimes push
a symbolic constant to the literal pool when generating 64-bit
-fPIC code.  This causes a dynamic relocation record for that
literal pool slot to be emitted; however the literal pool
resides in the read-only data secion, which should not be
modified by the dynamic linker at run time.

For normal libraries, this is just somewhat inefficient (as the
corresponding pages are not shared between processes).  For the
read-only data section of the dynamic linker ld.so itself, this
is fatal, as it cannot handle that case when relocating itself.

Unfortunately, this bug was not noticed due to a bug in the
page fault handler in the s390x Linux kernel; that bug basically
caused the read-only memory protection setting to be ignored.
We've recently fixed that bug, which exposed the compiler bug:
when running a ld.so compiled with a broken compiler under a
fixed kernel, every dynamically linked application crashes on
startup :-/

To fix this problem, legitimate_pic_operand_p now rejects all
symbolic operands.  This causes them to be handled correctly
by emit_pic_move in all cases (usually via an LARL instruction).


As both of these bugs are regressions to previous gcc versions,
I've committed them to the 3.1 branch as well.

Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux,
both on the head and on the branch.


ChangeLog:

      * config/s390/s390.c (legitimate_pic_operand_p): Do not
      accept symbolic LARL operands.
      (s390_emit_epilogue): Do not set FRAME_RELATED_P on
      epilogue insns.

Index: gcc/config/s390/s390.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.c,v
retrieving revision 1.38
diff -c -p -r1.38 s390.c
*** gcc/config/s390/s390.c    19 May 2002 05:23:20 -0000    1.38
--- gcc/config/s390/s390.c    29 May 2002 12:54:25 -0000
*************** legitimate_pic_operand_p (op)
*** 1005,1014 ****
    if (!SYMBOLIC_CONST (op))
      return 1;

-   /* Accept immediate LARL operands.  */
-   if (TARGET_64BIT)
-     return larl_operand (op, VOIDmode);
-
    /* Reject everything else; must be handled
       via emit_pic_move.  */
    return 0;
--- 1005,1010 ----
*************** s390_emit_epilogue ()
*** 3217,3229 ****
      frame_off = force_const_mem (Pmode, frame_off);

        insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
-       RTX_FRAME_RELATED_P (insn) = 1;
-       REG_NOTES (insn) =
-     gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
-                    gen_rtx_SET (VOIDmode, frame_pointer,
-                          gen_rtx_PLUS (Pmode, frame_pointer,
-                            GEN_INT (frame.frame_size - offset))),
-                    REG_NOTES (insn));
      }

    /* Restore call saved fprs.  */
--- 3213,3218 ----


Mit freundlichen Gruessen / Best Regards

Ulrich Weigand

--
  Dr. Ulrich Weigand
  Linux for S/390 Design & Development
  IBM Deutschland Entwicklung GmbH, Schoenaicher Str. 220, 71032 Boeblingen
  Phone: +49-7031/16-3727   ---   Email: Ulrich.Weigand@de.ibm.com


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