[PATCH] D64759: [CodeGen] Don't resolve the stack protector frame accesses until PEI

Francis Visoiu Mistrih via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 24 09:04:44 PDT 2019


thegameg marked an inline comment as done.
thegameg added a comment.

In D64759#1588730 <https://reviews.llvm.org/D64759#1588730>, @thegameg wrote:

> In D64759#1588217 <https://reviews.llvm.org/D64759#1588217>, @efriedma wrote:
>
> > It's hard for me to imagine a scenario where this actually makes stack protection substantially more effective; if you have a wild write, presumably you can use it to do something more useful than just corrupt the address of the guard.  But I guess the performance cost is small.
>
>
> The only important thing I see is that it can be used to bypass the stack protector.
>
> > Is it possible for register scavenging to scavenge the register containing the address of the guard after the frame index is resolved?
>
> I am looking into this.


`llvm/test/CodeGen/AArch64/arm64-big-stack.ll` is one example for this (I reordered the instructions for readability):

  _foo:                                   ; @foo
  ; %bb.0:                                ; %entry
  	stp	x28, x27, [sp, #-32]!
  	stp	x29, x30, [sp, #16]
  
          ; set up sp
  	sub	sp, sp, #4095, lsl #12
  	sub	sp, sp, #4095, lsl #12
  	sub	sp, sp, #2, lsl #12
  	sub	sp, sp, #16
  
          ; load the guard
  	adrp	x8, ___stack_chk_guard at GOTPAGE
  	ldr	x8, [x8, ___stack_chk_guard at GOTPAGEOFF]
  	ldr	x8, [x8]
  
          ; compute the address of the guard's stack slot in x9
  	add	x9, sp, #4095, lsl #12
  	add	x9, x9, #4089, lsl #12
  	add	x9, x9, #16
  
          ; store the guard
  	str	x8, [x9, #32760]

During eliminate frame index, we have:

  renamable $x8 = LOAD_STACK_GUARD :: (dereferenceable invariant load 8 from @__stack_chk_guard)
  STRXui killed renamable $x8, %stack.0.StackGuardSlot, 0 :: (volatile store 8 into %stack.0.StackGuardSlot)

the offset for that is too big and there is no frame pointer, see the first two FIs:

  fi#0: size=8, align=8, at location [SP-40]
  fi#1: size=33554432, align=1, at location [SP-33554472]

so this becomes:

  renamable $x8 = LOAD_STACK_GUARD :: (dereferenceable invariant load 8 from @__stack_chk_guard)
  %0:gpr64 = ADDXri $sp, 4095, 12
  %0:gpr64 = ADDXri %0:gpr64, 4089, 12
  %0:gpr64 = ADDXri %0:gpr64, 16, 0
  STRXui killed renamable $x8, killed %0:gpr64, 4095 :: (volatile store 8 into %stack.0.StackGuardSlot)

Then we end up after `scavengeFrameVirtualRegs` with:

  renamable $x8 = LOAD_STACK_GUARD :: (dereferenceable invariant load 8 from @__stack_chk_guard)
  $x9 = ADDXri $sp, 4095, 12
  $x9 = ADDXri $x9, 4089, 12
  $x9 = ADDXri $x9, 16, 0
  STRXui killed renamable $x8, killed $x9, 4095 :: (volatile store 8 into %stack.0.StackGuardSlot)

I suppose the reg scavenger can also spill it if it really can't find another register, but I'm not sure we can do much about it at that point.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D64759/new/

https://reviews.llvm.org/D64759





More information about the llvm-commits mailing list