From 6ad514e4e278f0c3b18eb2db1d45638c9af1c07f Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sun, 18 Aug 2019 23:41:17 -0400 Subject: [PATCH] fix clash between sys/user.h and kernel ptrace.h on powerpc[64], sh 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 | 10 ++++------ arch/powerpc64/bits/user.h | 10 ++++------ arch/sh/bits/user.h | 34 +++++----------------------------- 3 files changed, 13 insertions(+), 41 deletions(-) diff --git a/arch/powerpc/bits/user.h b/arch/powerpc/bits/user.h index 6cc8aaf7..7f528746 100644 --- a/arch/powerpc/bits/user.h +++ b/arch/powerpc/bits/user.h @@ -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; diff --git a/arch/powerpc64/bits/user.h b/arch/powerpc64/bits/user.h index 7ca459b3..7e75d201 100644 --- a/arch/powerpc64/bits/user.h +++ b/arch/powerpc64/bits/user.h @@ -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; diff --git a/arch/sh/bits/user.h b/arch/sh/bits/user.h index d7363f74..07fe843b 100644 --- a/arch/sh/bits/user.h +++ b/arch/sh/bits/user.h @@ -17,34 +17,6 @@ #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; -- 2.25.1