about summary refs log tree commit diff
path: root/arch/powerpc64
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2019-08-18 23:41:17 -0400
committerRich Felker <dalias@aerifal.cx>2019-08-19 00:32:11 -0400
commit6ad514e4e278f0c3b18eb2db1d45638c9af1c07f (patch)
tree57543a815e7fb9387af0a7f8bf94228464d6ae36 /arch/powerpc64
parentd0209a2a334ff714063b70dc69c1fea131304836 (diff)
downloadmusl-6ad514e4e278f0c3b18eb2db1d45638c9af1c07f.tar.gz
musl-6ad514e4e278f0c3b18eb2db1d45638c9af1c07f.tar.xz
musl-6ad514e4e278f0c3b18eb2db1d45638c9af1c07f.zip
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.
Diffstat (limited to 'arch/powerpc64')
-rw-r--r--arch/powerpc64/bits/user.h10
1 files changed, 4 insertions, 6 deletions
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;