Home | History | Annotate | Line # | Download | only in gdb.arch
      1 /* Copyright 2021-2024 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
     54 foo:
     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 t4to 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