[PATCH] arm: Fix base register when loading canary address with -msingle-pic-base [PR96828]

ilya Oleinik abatur45en@gmail.com
Sun Oct 18 08:11:45 GMT 2020


After PR85434 code generation code with -fstack-protector and
-msingle-pic-base produces
canary value load with wrong pic base register (e.g. r3 instead of r9). On
thumb1 targets
mov insn needed to allow the base register to be used was missing.

'compute_now' in function require_pic_register doesn't make sense, because
it prevents
mov insn generation at pic register reload. So it was removed.
In  set/test insn checks are added to select the correct pic base register
for current pic
mode.

Tested on arm-none-eabi for thumb1, thumb2, arm.
OK for trunk?

2020-10-18  Oleinik Ilya  <abatur45en@gmail.com>

        * config/arm/arm.c (arm_option_override): Forbid switching base
        register for FDPIC.
        (require_pic_register): Restore mov insn generation for Thumb1.
        * config/arm/arm.md (*stack_protect_combined_set_insn): Use
        correct base register for PIC if -msingle-pic-base is set.
        (*stack_protect_combined_test_insn): Likewise.

---
 gcc/config/arm/arm.c  |  5 ++---
 gcc/config/arm/arm.md | 24 ++++++++++++++++++------
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 8105b39e7..23139f207 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -3560,7 +3560,7 @@ arm_option_override (void)
        || pic_register == HARD_FRAME_POINTER_REGNUM
        || pic_register == STACK_POINTER_REGNUM
        || pic_register >= PC_REGNUM
-       || (TARGET_VXWORKS_RTP
+       || ((TARGET_VXWORKS_RTP || TARGET_FDPIC)
    && (unsigned int) pic_register != arm_pic_register))
  error ("unable to use %qs for PIC register", arm_pic_register_string);
       else
@@ -7858,8 +7858,7 @@ require_pic_register (rtx pic_reg, bool compute_now)
       start_sequence ();

       if (TARGET_THUMB1 && arm_pic_register != INVALID_REGNUM
-  && arm_pic_register > LAST_LO_REGNUM
-  && !compute_now)
+  && arm_pic_register > LAST_LO_REGNUM)
  emit_move_insn (cfun->machine->pic_reg,
  gen_rtx_REG (Pmode, arm_pic_register));
       else
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 147c4a50c..c7934275d 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -9199,10 +9199,16 @@
     {
       rtx pic_reg;

-      if (TARGET_FDPIC)
-  pic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
+      if (TARGET_FDPIC || TARGET_SINGLE_PIC_BASE)
+ {
+  if (!TARGET_THUMB1)
+    pic_reg = gen_rtx_REG (Pmode, arm_pic_register);
+  else
+    pic_reg = cfun->machine->pic_reg
+      ? cfun->machine->pic_reg : operands[3];
+ }
       else
-  pic_reg = operands[3];
+ pic_reg = operands[3];

       /* Forces recomputing of GOT base now.  */
       legitimize_pic_address (operands[1], SImode, operands[2], pic_reg,
@@ -9282,10 +9288,16 @@
     {
       rtx pic_reg;

-      if (TARGET_FDPIC)
-  pic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
+      if (TARGET_FDPIC || TARGET_SINGLE_PIC_BASE)
+ {
+  if (!TARGET_THUMB1)
+    pic_reg = gen_rtx_REG (Pmode, arm_pic_register);
+  else
+    pic_reg = cfun->machine->pic_reg
+      ? cfun->machine->pic_reg : operands[4];
+ }
       else
-  pic_reg = operands[4];
+ pic_reg = operands[4];

       /* Forces recomputing of GOT base now.  */
       legitimize_pic_address (operands[1], SImode, operands[3], pic_reg,


More information about the Gcc-patches mailing list