123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- /* Copyright 2020-2022 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 <http://www.gnu.org/licenses/>. */
- #include <asm/unistd.h>
- /* 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:
|