1/* Copyright 2021-2023 Free Software Foundation, Inc. 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License as published by 5 the Free Software Foundation; either version 3 of the License, or 6 (at your option) any later version. 7 8 This program is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License 14 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16/* This testcase contains a function where the 'ld', 'c.ld', 'lw' or 'c.lw' 17 instruction is used in the prologue before the RA register have been saved 18 on the stack. 19 20 This mimics a pattern observed in the __pthread_clockjoin_ex function 21 in libpthread.so.0 (from glibc-2.33-0ubuntu5) where a canary value is 22 loaded and placed on the stack in order to detect stack smashing. 23 24 The skeleton for this file was generated using the following command: 25 26 gcc -x c -S -c -o - - <<EOT 27 static long int __canary = 42; 28 extern int bar (); 29 int foo () { return bar(); } 30 EOT 31 32 The result of this command is modified in the following way: 33 - The prologue is adapted to reserve 16 more bytes on the stack. 34 - A part that simulates the installation of a canary on the stack is 35 added. The canary is loaded multiple times to simulate the use of 36 various instructions that could do the work (ld or c.ld for a 64 bit 37 canary, lw or c.lw for a 32 bit canary). 38 - The epilogue is adjusted to be able to return properly. The epilogue 39 does not check the canary value since this testcase is only interested 40 in ensuring GDB can scan the prologue. */ 41 42 .option pic 43 .text 44 .data 45 .align 3 46 .type __canary, @object 47 .size __canary, 8 48__canary: 49 .dword 42 50 .text 51 .align 1 52 .globl foo 53 .type foo, @function 54foo: 55 addi sp,sp,-32 56 lla a5,__canary # Load the fake canary address. 57 lw t4,0(a5) # Load a 32 bit canary (use t4 to force the use of 58 # the non compressed instruction). 59 ld t4,0(a5) # Load a 64 bit canary (use t4 to force the use of 60 # the non compressed instruction). 61 c.lw a4,0(a5) # Load a 32 bit canary using the compressed insn. 62 c.ld a4,0(a5) # Load a 64 bit canary using the compressed insn. 63 sd a4,0(sp) # Place the fake canary on the stack. 64 sd ra,16(sp) 65 sd s0,8(sp) 66 addi s0,sp,32 67 call bar@plt 68 mv a5,a0 69 mv a0,a5 70 ld ra,16(sp) 71 ld s0,8(sp) 72 addi sp,sp,32 73 jr ra 74 .size foo, .-foo 75 .section .note.GNU-stack,"",@progbits 76