aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2021-04-27 12:25:30 +0100
committerRichard Earnshaw <rearnsha@arm.com>2021-04-27 12:27:02 +0100
commit01d0bda8bdf3cd804e1e00915d432ad0cdc49399 (patch)
treef8d88c06e274b69106a5637ef6a33e998066d4a5 /gcc
parent4cea5b8cb715e40e10174e6de405f26202fa3d6a (diff)
downloadgcc-01d0bda8bdf3cd804e1e00915d432ad0cdc49399.zip
gcc-01d0bda8bdf3cd804e1e00915d432ad0cdc49399.tar.gz
gcc-01d0bda8bdf3cd804e1e00915d432ad0cdc49399.tar.bz2
arm: fix UB when compiling thumb2 with PIC [PR100236]
arm_compute_save_core_reg_mask contains UB in that the saved PIC register number is used to create a bit mask. However, for some target options this register is undefined and we end up with a shift of ~0. On native compilations this is benign since the shift will still be large enough to move the bit outside of the range of the mask, but if cross compiling from a system that truncates out-of-range shifts to zero (or worse, raises a trap for such values) we'll get potentially wrong code (or a fault). gcc: PR target/100236 * config/arm/arm.c (THUMB2_WORK_REGS): Check PIC_OFFSET_TABLE_REGNUM is valid before including it in the mask.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/arm/arm.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 340f7c9..352b2cd 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -1051,9 +1051,13 @@ const char *fp_sysreg_names[NB_FP_SYSREGS] = {
#define ARM_LSL_NAME "lsl"
#define streq(string1, string2) (strcmp (string1, string2) == 0)
-#define THUMB2_WORK_REGS (0xff & ~( (1 << THUMB_HARD_FRAME_POINTER_REGNUM) \
- | (1 << SP_REGNUM) | (1 << PC_REGNUM) \
- | (1 << PIC_OFFSET_TABLE_REGNUM)))
+#define THUMB2_WORK_REGS \
+ (0xff & ~((1 << THUMB_HARD_FRAME_POINTER_REGNUM) \
+ | (1 << SP_REGNUM) \
+ | (1 << PC_REGNUM) \
+ | (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM \
+ ? (1 << PIC_OFFSET_TABLE_REGNUM) \
+ : 0)))
/* Initialization code. */