Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tile: avoid undefined behavior with regs[TREG_TP] etc

Recent compilers warn about accesses to arrays past the end,
which is supported for pt_regs and sigcontext with the
intended alias past the end of regs[] to sp, tp, and lr
using TREG_SP, TREG_TP, and TREG_LR.

Make the intended usage explict by providing an anonymous
union of regs[56] on the one hand, and a short __regs[53]
on the other followed by the sp, tp, and lr fields, so the
aliasing is done explicitly and is visible to the compiler.

Reviewed-by: Jeff Epler <jepler@unpythonic.net>
Signed-off-by: Chris Metcalf <cmetcalf@ezchip.com>

+20 -10
+10 -6
arch/tile/include/uapi/asm/ptrace.h
··· 52 52 * system call or exception. "struct sigcontext" has the same shape. 53 53 */ 54 54 struct pt_regs { 55 - /* Saved main processor registers; 56..63 are special. */ 56 - /* tp, sp, and lr must immediately follow regs[] for aliasing. */ 57 - pt_reg_t regs[53]; 58 - pt_reg_t tp; /* aliases regs[TREG_TP] */ 59 - pt_reg_t sp; /* aliases regs[TREG_SP] */ 60 - pt_reg_t lr; /* aliases regs[TREG_LR] */ 55 + union { 56 + /* Saved main processor registers; 56..63 are special. */ 57 + pt_reg_t regs[56]; 58 + struct { 59 + pt_reg_t __regs[53]; 60 + pt_reg_t tp; /* aliases regs[TREG_TP] */ 61 + pt_reg_t sp; /* aliases regs[TREG_SP] */ 62 + pt_reg_t lr; /* aliases regs[TREG_LR] */ 63 + }; 64 + }; 61 65 62 66 /* Saved special registers. */ 63 67 pt_reg_t pc; /* stored in EX_CONTEXT_K_0 */
+10 -4
arch/tile/include/uapi/asm/sigcontext.h
··· 24 24 * but is simplified since we know the fault is from userspace. 25 25 */ 26 26 struct sigcontext { 27 - __uint_reg_t gregs[53]; /* General-purpose registers. */ 28 - __uint_reg_t tp; /* Aliases gregs[TREG_TP]. */ 29 - __uint_reg_t sp; /* Aliases gregs[TREG_SP]. */ 30 - __uint_reg_t lr; /* Aliases gregs[TREG_LR]. */ 27 + __extension__ union { 28 + /* General-purpose registers. */ 29 + __uint_reg_t gregs[56]; 30 + __extension__ struct { 31 + __uint_reg_t __gregs[53]; 32 + __uint_reg_t tp; /* Aliases gregs[TREG_TP]. */ 33 + __uint_reg_t sp; /* Aliases gregs[TREG_SP]. */ 34 + __uint_reg_t lr; /* Aliases gregs[TREG_LR]. */ 35 + }; 36 + }; 31 37 __uint_reg_t pc; /* Program counter. */ 32 38 __uint_reg_t ics; /* In Interrupt Critical Section? */ 33 39 __uint_reg_t faultnum; /* Fault number. */