/* Copyright 2020-2023 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include /* Define these for each architecture: 1) RETURN_ADDRESS_REGNO: The register number representing the return address in the DWARF CFI. It can be easily be looked up using `readelf --debug-dump=frames-interp` on an existing binary of that architecture, where it says `ra=X`. 2) exit_0: a sequence of instruction to execute the exit syscall with argument 0. */ #if defined(__x86_64__) # define RETURN_ADDRESS_REGNO 16 .macro exit_0 mov $__NR_exit, %rax mov $0, %rdi syscall .endm #elif defined(__i386__) # define RETURN_ADDRESS_REGNO 8 .macro exit_0 mov $__NR_exit, %eax mov $0, %ebx int $0x80 .endm #elif defined(__aarch64__) # define RETURN_ADDRESS_REGNO 30 .macro exit_0 mov x0, #0 mov x8, #__NR_exit svc #0 .endm #elif defined(__arm__) # define RETURN_ADDRESS_REGNO 14 .macro exit_0 ldr r7, =__NR_exit ldr r0, =0 swi 0x0 .endm #elif defined __powerpc64__ # define RETURN_ADDRESS_REGNO 65 .macro exit_0 li 0, __NR_exit /* r0 - contains system call number */ li 3, 0 /* r3 - contains first argument for sys call */ sc .endm #else # error "Unsupported architecture" #endif /* The following assembly program mimics this pseudo C program, where everything has been inlined: 1 void bar(void) { 2 nop; 3 } 4 5 void foo(void) { 6 nop; 7 bar(); 8 nop; 9 } 10 11 void _start(void) { 12 nop; 13 foo(); 14 nop; 15 exit(0); 16 } */ #if defined __powerpc64__ # if _CALL_ELF == 2 .abiversion 2 /* Tell gdb what ELF version to use. */ .global _start _start: # else .abiversion 1 /* Tell gdb what ELF version to use. */ .align 2 .global _start .section ".opd", "aw" .align 3 _start: .quad ._start,.TOC.@tocbase,0 .previous .type ._start,@function ._start: # endif #else .global _start _start: #endif .cfi_startproc /* State that the return address for this frame is undefined. */ .cfi_undefined RETURN_ADDRESS_REGNO .global __cu_low_pc __cu_low_pc: .global __start_low_pc __start_low_pc: /* Line 12 */ nop .global __foo_low_pc __foo_low_pc: /* Line 6 */ nop .global __bar_low_pc __bar_low_pc: /* Line 2 */ nop .global __bar_high_pc __bar_high_pc: /* Line 8 */ nop .global __foo_high_pc __foo_high_pc: /* Line 14 */ nop /* Line 15 */ exit_0 .cfi_endproc .global __start_high_pc __start_high_pc: .global __cu_high_pc __cu_high_pc: .section .note.GNU-stack,"",@progbits