On arm linux sys/ucontext.h heavilly polloutes the global namespace firstly by including sys/user.h (which defines among other things a type called "struct user" and secondly by defining symbols and #defines named R? to represent the processor registers.
That issue in itself is nothing new but fairly recently* signal.h started including sys/ucontext.h by default causing programs that (quite reasonable IMO) used those names for their own symbols to fail to build on arm. This has been especially noticable recently because debian is trying to build the new "armhf" port. After discussions on debian-arm/debian-glibc/linaro-dev (I do not know which responders came from which list) I was given the following advice on the "struct user" issue by Ulrich Weigand. >Now, glibc also provides a file <sys/ucontext.h> that defines >layouts of register sets for use with signal handlers as well >as the makecontext/setcontext/getcontext family of routines. > >Usually, those layouts tend to be in fact identical to the >layouts described in <sys/user.h> / <sys/procfs.h>. Apparently, >whoever implemented the ARM version of <sys/ucontext.h> was >trying to avoid some seemingly unnecessary code duplication >by making <sys/ucontext.h> *include* <sys/procfs.h> and using >the information from there directly. This is not done on other >platforms, for precisely the reason that the <sys/procfs.h> >and <sys/user.h> headers do pollute the name space ... > >So I think the right thing to do in the short term would be to >stop <sys/ucontext.h> including <sys/procfs.h>, and instead add the >register set information there directly, even if that means some >duplication of code. (Again, since this is never-changing ABI, >duplication isn't actually all that bad. Also, all the other >platforms do it that way too, so why should ARM be different ...) On the issue of the R? definitions I proposed renaming them to REG_R?. The use of a REG_ prefix is consistent with x86, x64 and sparc (I couldn't find any comparable definitions at all on other architectures I looked at) I asked what the impact of this change would be on the aforementioned mailing lists and got the following reply from Konstantinos Margaritis >at worst the packages that had to be workaround on arm* for this, can >have the workaround removed. The attached patch implements these changes. My tests do not show any new failures in the libc testsuite (though I do get failures that debian considers "unexpected" regardless of whether this patch is applied or not) * I have not investigated exactly when this change occoured but it was somewhere between the version in debian squeeze and the version in debian wheezy.
Index: eglibc-2.13/ports/sysdeps/unix/sysv/linux/arm/sys/ucontext.h =================================================================== --- eglibc-2.13.orig/ports/sysdeps/unix/sysv/linux/arm/sys/ucontext.h 2006-08-17 01:23:58.000000000 +0000 +++ eglibc-2.13/ports/sysdeps/unix/sysv/linux/arm/sys/ucontext.h 2011-12-17 12:52:43.000000000 +0000 @@ -23,7 +23,6 @@ #include <features.h> #include <signal.h> -#include <sys/procfs.h> /* We need the signal context definitions even if they are not used included in <signal.h>. */ @@ -35,47 +34,64 @@ #define NGREG 18 /* Container for all general registers. */ -typedef elf_gregset_t gregset_t; +typedef greg_t gregset_t[NGREG]; /* Number of each register is the `gregset_t' array. */ enum { - R0 = 0, -#define R0 R0 - R1 = 1, -#define R1 R1 - R2 = 2, -#define R2 R2 - R3 = 3, -#define R3 R3 - R4 = 4, -#define R4 R4 - R5 = 5, -#define R5 R5 - R6 = 6, -#define R6 R6 - R7 = 7, -#define R7 R7 - R8 = 8, -#define R8 R8 - R9 = 9, -#define R9 R9 - R10 = 10, -#define R10 R10 - R11 = 11, -#define R11 R11 - R12 = 12, -#define R12 R12 - R13 = 13, -#define R13 R13 - R14 = 14, -#define R14 R14 - R15 = 15 -#define R15 R15 + REG_R0 = 0, +#define REG_R0 REG_R0 + REG_R1 = 1, +#define REG_R1 REG_R1 + REG_R2 = 2, +#define REG_R2 REG_R2 + REG_R3 = 3, +#define REG_R3 REG_R3 + REG_R4 = 4, +#define REG_R4 REG_R4 + REG_R5 = 5, +#define REG_R5 REG_R5 + REG_R6 = 6, +#define REG_R6 REG_R6 + REG_R7 = 7, +#define REG_R7 REG_R7 + REG_R8 = 8, +#define REG_R8 REG_R8 + REG_R9 = 9, +#define REG_R9 REG_R9 + REG_R10 = 10, +#define REG_R10 REG_R10 + REG_R11 = 11, +#define REG_R11 REG_R11 + REG_R12 = 12, +#define REG_R12 REG_R12 + REG_R13 = 13, +#define REG_R13 REG_R13 + REG_R14 = 14, +#define REG_R14 REG_R14 + REG_R15 = 15 +#define REG_R15 REG_R15 }; +struct _libc_fpstate +{ + struct + { + unsigned int sign1:1; + unsigned int unused:15; + unsigned int sign2:1; + unsigned int exponent:14; + unsigned int j:1; + unsigned int mantissa1:31; + unsigned int mantissa0:32; + } fpregs[8]; + unsigned int fpsr:32; + unsigned int fpcr:32; + unsigned char ftype[8]; + unsigned int init_flag; +}; /* Structure to describe FPU registers. */ -typedef elf_fpregset_t fpregset_t; +typedef struct _libc_fpstate fpregset_t; /* Context to describe whole processor state. This only describes the core registers; coprocessor registers get saved elsewhere