1/* Copyright 2020-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#include <asm/unistd.h> 17 18/* Define these for each architecture: 19 20 1) RETURN_ADDRESS_REGNO: The register number representing the return 21 address in the DWARF CFI. It can be easily be looked up using 22 `readelf --debug-dump=frames-interp` on an existing binary of that 23 architecture, where it says `ra=X`. 24 25 2) exit_0: a sequence of instruction to execute the exit syscall with 26 argument 0. */ 27 28#if defined(__x86_64__) 29 30# define RETURN_ADDRESS_REGNO 16 31 32.macro exit_0 33 mov $__NR_exit, %rax 34 mov $0, %rdi 35 syscall 36.endm 37 38#elif defined(__i386__) 39 40# define RETURN_ADDRESS_REGNO 8 41 42.macro exit_0 43 mov $__NR_exit, %eax 44 mov $0, %ebx 45 int $0x80 46.endm 47 48#elif defined(__aarch64__) 49 50# define RETURN_ADDRESS_REGNO 30 51 52.macro exit_0 53 mov x0, #0 54 mov x8, #__NR_exit 55 svc #0 56.endm 57 58#elif defined(__arm__) 59 60# define RETURN_ADDRESS_REGNO 14 61 62.macro exit_0 63 ldr r7, =__NR_exit 64 ldr r0, =0 65 swi 0x0 66.endm 67 68#elif defined __powerpc64__ 69 70# define RETURN_ADDRESS_REGNO 65 71 72.macro exit_0 73 li 0, __NR_exit /* r0 - contains system call number */ 74 li 3, 0 /* r3 - contains first argument for sys call */ 75 sc 76.endm 77 78#else 79# error "Unsupported architecture" 80#endif 81 82/* The following assembly program mimics this pseudo C program, where 83 everything has been inlined: 84 85 1 void bar(void) { 86 2 nop; 87 3 } 88 4 89 5 void foo(void) { 90 6 nop; 91 7 bar(); 92 8 nop; 93 9 } 94 10 95 11 void _start(void) { 96 12 nop; 97 13 foo(); 98 14 nop; 99 15 exit(0); 100 16 } 101*/ 102 103#if defined __powerpc64__ 104# if _CALL_ELF == 2 105.abiversion 2 /* Tell gdb what ELF version to use. */ 106.global _start 107_start: 108# else 109.abiversion 1 /* Tell gdb what ELF version to use. */ 110.align 2 111.global _start 112.section ".opd", "aw" 113.align 3 114_start: 115.quad ._start,.TOC.@tocbase,0 116.previous 117.type ._start,@function 118._start: 119# endif 120#else 121.global _start 122_start: 123#endif 124.cfi_startproc 125 126/* State that the return address for this frame is undefined. */ 127.cfi_undefined RETURN_ADDRESS_REGNO 128 129.global __cu_low_pc 130__cu_low_pc: 131 132.global __start_low_pc 133__start_low_pc: 134 /* Line 12 */ 135 nop 136 137.global __foo_low_pc 138__foo_low_pc: 139 /* Line 6 */ 140 nop 141 142.global __bar_low_pc 143__bar_low_pc: 144 /* Line 2 */ 145 nop 146 147.global __bar_high_pc 148__bar_high_pc: 149 /* Line 8 */ 150 nop 151 152.global __foo_high_pc 153__foo_high_pc: 154 /* Line 14 */ 155 nop 156 157 /* Line 15 */ 158 exit_0 159 160.cfi_endproc 161 162.global __start_high_pc 163__start_high_pc: 164 165.global __cu_high_pc 166__cu_high_pc: 167 .section .note.GNU-stack,"",@progbits 168