fix clash between sys/user.h and kernel ptrace.h on powerpc[64], sh
authorRich Felker <dalias@aerifal.cx>
Mon, 19 Aug 2019 03:41:17 +0000 (23:41 -0400)
committerRich Felker <dalias@aerifal.cx>
Mon, 19 Aug 2019 04:32:11 +0000 (00:32 -0400)
due to historical accident/sloppiness in glibc, the powerpc,
powerpc64, and sh versions of struct user, defined by sys/user.h, used
struct pt_regs from the kernel asm/ptrace.h for their regs member.
this made it impossible to define the type in an API-compatible manner
without either including asm/ptrace.h like glibc does (contrary to our
policy of not depending on kernel headers), or clashing with
asm/ptrace.h's definition of struct pt_regs if both headers are
included (which is almost always the case in software using
sys/user.h).

for a long time I viewed this problem as having no reasonable fix. I
even explored the possibility of having the powerpc[64] and sh
versions of user.h just include the kernel header (breaking with
policy), but that looked like it might introduce new clashes with
sys/ptrace.h. and it would also bring in a lot of additional cruft
that makes no sense for sys/user.h to expose. glibc goes out of its
way to suppress some of that with #undef, possibly leading to
different problems. this is a rabbit-hole that should be explored no
further.

as it turns out, however, nothing actually uses struct user
sufficiently to care about the type of the regs member; most software
including sys/user.h does not even use struct user at all. so, the
problem can be fixed just by doing away with the insistence on strict
glibc API compatibility for the struct tag of the regs member.

rather than renaming the tag, which might lead to the new name
entering use as API, simply use an untagged structure inside struct
user with the same members/layout as struct pt_regs.

for sh, struct pt_dspregs is just removed entirely since it was not
used.

arch/powerpc/bits/user.h
arch/powerpc64/bits/user.h
arch/sh/bits/user.h

index 6cc8aaf7228864446a9d2fb54cc3f933276586e0..7f528746323b1aac2c08d24a94c89b9c42482c61 100644 (file)
@@ -1,10 +1,8 @@
-struct pt_regs {
-       unsigned long gpr[32], nip, msr, orig_gpr3, ctr, link, xer, ccr, mq;
-       unsigned long trap, dar, dsisr, result;
-};
-
 struct user {
-       struct pt_regs regs;
+       struct {
+               unsigned long gpr[32], nip, msr, orig_gpr3, ctr, link, xer, ccr, mq;
+               unsigned long trap, dar, dsisr, result;
+       } regs;
        unsigned long u_tsize, u_dsize, u_ssize;
        unsigned long start_code, start_data, start_stack;
        long signal;
index 7ca459b327b7a2537a88e05b1a80cd11829a7cfc..7e75d20156b4e78ce6e188cf12b94d187f1881ea 100644 (file)
@@ -1,10 +1,8 @@
-struct pt_regs {
-       unsigned long gpr[32], nip, msr, orig_gpr3, ctr, link, xer, ccr, softe;
-       unsigned long trap, dar, dsisr, result;
-};
-
 struct user {
-       struct pt_regs regs;
+       struct {
+               unsigned long gpr[32], nip, msr, orig_gpr3, ctr, link, xer, ccr, softe;
+               unsigned long trap, dar, dsisr, result;
+       } regs;
        unsigned long u_tsize, u_dsize, u_ssize;
        unsigned long start_code, start_data, start_stack;
        long signal;
index d7363f74a99af663530532128e299d1c8f30841a..07fe843b6e6077ca08e9a8f5118ca531e31da497 100644 (file)
 #define REG_FPSCR      55
 #define REG_FPUL       56
 
-struct pt_regs {
-       unsigned long regs[16];
-       unsigned long pc;
-       unsigned long pr;
-       unsigned long sr;
-       unsigned long gbr;
-       unsigned long mach;
-       unsigned long macl;
-       long tra;
-};
-
-struct pt_dspregs {
-       unsigned long a1;
-       unsigned long a0g;
-       unsigned long a1g;
-       unsigned long m0;
-       unsigned long m1;
-       unsigned long a0;
-       unsigned long x0;
-       unsigned long x1;
-       unsigned long y0;
-       unsigned long y1;
-       unsigned long dsr;
-       unsigned long rs;
-       unsigned long re;
-       unsigned long mod;
-};
-
 struct user_fpu_struct {
        unsigned long fp_regs[16];
        unsigned long xfp_regs[16];
@@ -58,7 +30,11 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 typedef struct user_fpu_struct elf_fpregset_t;
 
 struct user {
-       struct pt_regs regs;
+       struct {
+               unsigned long regs[16];
+               unsigned long pc, pr, sr, gbr, mach, macl;
+               long tra;
+       } regs;
        struct user_fpu_struct fpu;
        int u_fpvalid;
        unsigned long u_tsize;