This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc 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]

Proposed change to ppc32 ucontext_t


Since we made the change to the ucontext_t on ppc32 to expand it to
include space for all of the registers, I have received some bug
reports about the change having broken source compatibility.  In
particular some programs were using ucp->uc_mcontext.regs to get at
the register values in a SIGSEGV handler.

Now, I believe that there has not yet been an official release of
glibc since the new ppc32 ucontext_t went into CVS.  What I would like
to do is to change it (before the next release) to improve source
compatibility.  In addition the change will improve binary
compatibility since it moves the uc_sigmask field back to where it was
before.

Previously the ucontext_t had just a pointer to the register values.
When delivering a signal, the kernel would put the registers on the
stack above the ucontext_t.  But the offset between the ucontext_t and
the registers varied in different kernel versions.

What I want to do with the ucontext_t is to keep the pointer to the
registers (with the same name as before) and provide enough untyped
space at the end of the structure to store the register values.  That
means that users will have to go via the pointer and won't be tempted
to access the registers at fixed offsets in the ucontext_t.

Here is the patch to sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h.
The ucontext_t remains the same size and the register pointer is at
the same offset as before.  The uc_sigmask field has moved back to be
at the same offset as in past releases of glibc.

Some changes to {set,get,swap,make}context.S will be needed.  I have
coded them up but I haven't tested them yet (I am still compiling up
the new gcc and binutils that I need to compile current glibc+nptl).

Comments?

Thanks,
Paul.

diff -urN cvs/libc/sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h libc/sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h
--- cvs/libc/sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h	2003-07-04 10:12:48.000000000 +1000
+++ libc/sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h	2003-09-11 16:31:52.000000000 +1000
@@ -74,14 +74,40 @@
     struct ucontext *uc_link;
     stack_t uc_stack;
 #if __WORDSIZE == 32
-    /* These fields are for backwards compatibility. */
+    /*
+     * These fields are set up this way to maximize source and
+     * binary compatibility with code written for the old
+     * ucontext_t definition, which didn't include space for the
+     * registers.
+     *
+     * Different versions of the kernel have stored the registers on
+     * signal delivery at different offsets from the ucontext struct.
+     * Programs should thus use the uc_mcontext.uc_regs pointer to
+     * find where the registers are actually stored.  The registers
+     * will be stored within the ucontext_t struct but not necessarily
+     * at a fixed address.  As a side-effect, this lets us achieve
+     * 16-byte alignment for the register storage space if the
+     * Altivec registers are to be saved, without requiring 16-byte
+     * alignment on the whole ucontext_t.
+     *
+     * The uc_mcontext.regs field is included for source compatibility
+     * with programs written against the older ucontext_t definition,
+     * and its name should therefore not change.  The uc_pad field
+     * is for binary compatibility with programs compiled against the
+     * old ucontext_t; it ensures that uc_mcontext.regs and uc_sigmask
+     * are at the same offset as previously.
+     */
     int uc_pad[7];
-    mcontext_t *uc_regs;
-    unsigned int uc_oldsigmask[2];
-    int uc_pad2;
-#endif
+    union uc_regs_ptr {
+      struct pt_regs *regs;
+      mcontext_t *uc_regs;
+    } uc_mcontext;
+    sigset_t    uc_sigmask;
+    char uc_reg_space[sizeof(mcontext_t) + 12];  /* last for extensibility */
+#else /* 64-bit */
     sigset_t    uc_sigmask;
     mcontext_t  uc_mcontext;  /* last for extensibility */
+#endif
   } ucontext_t;
 
 #endif /* sys/ucontext.h */


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