mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 15:41:46 +00:00
[lld-macho] Reorganize + extend ICF test
I found icf.s a bit hard to work with as it was not possible to extend any of the functions `_a` ... `_k` to test new relocation / referent types without modifying every single one of them. Additionally, their one-letter names were not descriptive (though the comments helped). I've renamed all the functions to reflect the feature they are testing, and shrunk them so that they contain just enough to test that one feature. I've also added tests for non-zero addends (via the `_abs1a_ref_with_addend` and `_defined_ref_with_addend_1` functions). Reviewed By: #lld-macho, gkm Differential Revision: https://reviews.llvm.org/D106211
This commit is contained in:
parent
0ad562b48b
commit
8eac5dcb36
@ -1,60 +1,79 @@
|
||||
# REQUIRES: x86
|
||||
# RUN: rm -rf %t; split-file %s %t
|
||||
|
||||
## Check that we fold identical function bodies correctly. Note: This test
|
||||
## has many different functions; each group of similarly-named functions aim
|
||||
## to test one aspect of ICF's logic. To prevent accidental folding across
|
||||
## groups, we use `mov` instructions with a variety of immediates, with
|
||||
## different immediate values for each group.
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/main.s -o %t/main.o
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/abs.s -o %t/abs.o
|
||||
# RUN: %lld -lSystem --icf=all -o %t/main %t/main.o %t/abs.o
|
||||
# RUN: llvm-objdump -d --syms %t/main | FileCheck %s
|
||||
|
||||
# CHECK-LABEL: SYMBOL TABLE:
|
||||
# CHECK: [[#%x,MAIN:]] g F __TEXT,__text _main
|
||||
# CHECK: [[#%x,A:]] g F __TEXT,__text _a1
|
||||
# CHECK: [[#%x,H:]] g F __TEXT,__text _h
|
||||
# CHECK: [[#%x,A]] g F __TEXT,__text _a2
|
||||
# CHECK: [[#%x,A]] g F __TEXT,__text _a3
|
||||
# CHECK: [[#%x,B:]] g F __TEXT,__text _b
|
||||
# CHECK: [[#%x,B2:]] g F __TEXT,__text _b2
|
||||
# CHECK: [[#%x,C:]] g F __TEXT,__text _c
|
||||
# CHECK: [[#%x,D:]] g F __TEXT,__text _d
|
||||
# CHECK: [[#%x,E:]] g F __TEXT,__text _e
|
||||
# CHECK: [[#%x,F:]] g F __TEXT,__text _f
|
||||
# CHECK: [[#%x,G:]] g F __TEXT,__text _g
|
||||
# CHECK: [[#%x,I:]] g F __TEXT,__text _i
|
||||
# CHECK: [[#%x,J:]] g F __TEXT,__text _j
|
||||
# CHECK: [[#%x,SR:]] g F __TEXT,__text _sr1
|
||||
# CHECK: [[#%x,SR]] g F __TEXT,__text _sr2
|
||||
# CHECK: [[#%x,MR:]] g F __TEXT,__text _mr1
|
||||
# CHECK: [[#%x,MR]] g F __TEXT,__text _mr2
|
||||
# CHECK: [[#%x,K1:]] g O __TEXT,__foo _k1
|
||||
# CHECK: [[#%x,A:]] g F __TEXT,__text _k2
|
||||
# CHECK: [[#%x,ABS1B_REF:]] l F __TEXT,__text _abs1a_ref
|
||||
# CHECK: [[#%x,ABS1B_REF:]] l F __TEXT,__text _abs1b_ref
|
||||
# CHECK: [[#%x,ABS1B_REF_WITH_ADDEND:]] l F __TEXT,__text _abs1a_ref_with_addend
|
||||
# CHECK: [[#%x,ABS1B_REF_WITH_ADDEND:]] l F __TEXT,__text _abs1b_ref_with_addend
|
||||
# CHECK: [[#%x,ABS2_REF:]] l F __TEXT,__text _abs2_ref
|
||||
# CHECK: [[#%x,NOT_ABS_REF:]] l F __TEXT,__text _not_abs_ref
|
||||
# CHECK: [[#%x,DYLIB_REF_2:]] l F __TEXT,__text _dylib_ref_1
|
||||
# CHECK: [[#%x,DYLIB_REF_2:]] l F __TEXT,__text _dylib_ref_2
|
||||
# CHECK: [[#%x,DYLIB_REF_3:]] l F __TEXT,__text _dylib_ref_3
|
||||
# CHECK: [[#%x,ALT:]] l F __TEXT,__text _alt
|
||||
# CHECK: [[#%x,WITH_ALT_ENTRY:]] l F __TEXT,__text _with_alt_entry
|
||||
# CHECK: [[#%x,WITH_ALT_ENTRY:]] l F __TEXT,__text _no_alt_entry
|
||||
# CHECK: [[#%x,DEFINED_REF_WITH_ADDEND_2:]] l F __TEXT,__text _defined_ref_with_addend_1
|
||||
# CHECK: [[#%x,DEFINED_REF_WITH_ADDEND_2:]] l F __TEXT,__text _defined_ref_with_addend_2
|
||||
# CHECK: [[#%x,RECURSIVE:]] l F __TEXT,__text _recursive
|
||||
# CHECK: [[#%x,CALL_RECURSIVE_2:]] l F __TEXT,__text _call_recursive_1
|
||||
# CHECK: [[#%x,CALL_RECURSIVE_2:]] l F __TEXT,__text _call_recursive_2
|
||||
# CHECK: [[#%x,CHECK_LENGTH_1:]] l F __TEXT,__text _check_length_1
|
||||
# CHECK: [[#%x,CHECK_LENGTH_2:]] l F __TEXT,__text _check_length_2
|
||||
# CHECK: [[#%x,HAS_UNWIND_1:]] l F __TEXT,__text _has_unwind_1
|
||||
# CHECK: [[#%x,HAS_UNWIND_2:]] l F __TEXT,__text _has_unwind_2
|
||||
# CHECK: [[#%x,MUTALLY_RECURSIVE_2:]] l F __TEXT,__text _mutually_recursive_1
|
||||
# CHECK: [[#%x,MUTALLY_RECURSIVE_2:]] l F __TEXT,__text _mutually_recursive_2
|
||||
# CHECK: [[#%x,INIT_2:]] l F __TEXT,__text _init_1
|
||||
# CHECK: [[#%x,INIT_2:]] l F __TEXT,__text _init_2
|
||||
# CHECK: [[#%x,INIT_3:]] l O __TEXT,__foo _init_3
|
||||
### FIXME: Mutually-recursive functions with identical bodies (see below)
|
||||
# COM: [[#%x,XR:]] g F __TEXT,__text _xr1
|
||||
# COM: [[#%x,XR]] g F __TEXT,__text _xr2
|
||||
# COM: [[#%x,ASYMMETRIC_RECURSIVE_2:]] l F __TEXT,__text _asymmetric_recursive_1
|
||||
# COM: [[#%x,ASYMMETRIC_RECURSIVE_2]] l F __TEXT,__text _asymmetric_recursive_2
|
||||
|
||||
# CHECK-LABEL: Disassembly of section __TEXT,__text:
|
||||
# CHECK: [[#%x,MAIN]] <_main>:
|
||||
# CHECK-NEXT: callq 0x[[#%x,A]] <_k2>
|
||||
# CHECK-NEXT: callq 0x[[#%x,A]] <_k2>
|
||||
# CHECK-NEXT: callq 0x[[#%x,A]] <_k2>
|
||||
# CHECK-NEXT: callq 0x[[#%x,B]] <_b>
|
||||
# CHECK-NEXT: callq 0x[[#%x,B2]] <_b2>
|
||||
# CHECK-NEXT: callq 0x[[#%x,C]] <_c>
|
||||
# CHECK-NEXT: callq 0x[[#%x,D]] <_d>
|
||||
# CHECK-NEXT: callq 0x[[#%x,E]] <_e>
|
||||
# CHECK-NEXT: callq 0x[[#%x,F]] <_f>
|
||||
# CHECK-NEXT: callq 0x[[#%x,G]] <_g>
|
||||
# CHECK-NEXT: callq 0x[[#%x,H]] <_h>
|
||||
# CHECK-NEXT: callq 0x[[#%x,I]] <_i>
|
||||
# CHECK-NEXT: callq 0x[[#%x,J]] <_j>
|
||||
# CHECK-NEXT: callq 0x[[#%x,K1]] <_k1>
|
||||
# CHECK-NEXT: callq 0x[[#%x,A]] <_k2>
|
||||
# CHECK-NEXT: callq 0x[[#%x,SR]] <_sr2>
|
||||
# CHECK-NEXT: callq 0x[[#%x,SR]] <_sr2>
|
||||
# CHECK-NEXT: callq 0x[[#%x,MR]] <_mr2>
|
||||
# CHECK-NEXT: callq 0x[[#%x,MR]] <_mr2>
|
||||
### FIXME: Mutually-recursive functions with identical bodies (see below)
|
||||
# COM-NEXT: callq 0x[[#%x,XR]] <_xr2>
|
||||
# COM-NEXT: callq 0x[[#%x,XR]] <_xr2>
|
||||
# CHECK: <_main>:
|
||||
# CHECK: callq 0x[[#%x,ABS1B_REF:]] <_abs1b_ref>
|
||||
# CHECK: callq 0x[[#%x,ABS1B_REF:]] <_abs1b_ref>
|
||||
# CHECK: callq 0x[[#%x,ABS1B_REF_WITH_ADDEND:]] <_abs1b_ref_with_addend>
|
||||
# CHECK: callq 0x[[#%x,ABS1B_REF_WITH_ADDEND:]] <_abs1b_ref_with_addend>
|
||||
# CHECK: callq 0x[[#%x,ABS2_REF:]] <_abs2_ref>
|
||||
# CHECK: callq 0x[[#%x,NOT_ABS_REF:]] <_not_abs_ref>
|
||||
# CHECK: callq 0x[[#%x,DYLIB_REF_2:]] <_dylib_ref_2>
|
||||
# CHECK: callq 0x[[#%x,DYLIB_REF_2:]] <_dylib_ref_2>
|
||||
# CHECK: callq 0x[[#%x,DYLIB_REF_3:]] <_dylib_ref_3>
|
||||
# CHECK: callq 0x[[#%x,ALT:]] <_alt>
|
||||
# CHECK: callq 0x[[#%x,WITH_ALT_ENTRY:]] <_with_alt_entry>
|
||||
# CHECK: callq 0x[[#%x,WITH_ALT_ENTRY:]] <_with_alt_entry>
|
||||
# CHECK: callq 0x[[#%x,DEFINED_REF_WITH_ADDEND_2:]] <_defined_ref_with_addend_2>
|
||||
# CHECK: callq 0x[[#%x,DEFINED_REF_WITH_ADDEND_2:]] <_defined_ref_with_addend_2>
|
||||
# CHECK: callq 0x[[#%x,RECURSIVE:]] <_recursive>
|
||||
# CHECK: callq 0x[[#%x,CALL_RECURSIVE_2:]] <_call_recursive_2>
|
||||
# CHECK: callq 0x[[#%x,CALL_RECURSIVE_2:]] <_call_recursive_2>
|
||||
# CHECK: callq 0x[[#%x,CHECK_LENGTH_1:]] <_check_length_1>
|
||||
# CHECK: callq 0x[[#%x,CHECK_LENGTH_2:]] <_check_length_2>
|
||||
# CHECK: callq 0x[[#%x,HAS_UNWIND_1:]] <_has_unwind_1>
|
||||
# CHECK: callq 0x[[#%x,HAS_UNWIND_2:]] <_has_unwind_2>
|
||||
# CHECK: callq 0x[[#%x,MUTALLY_RECURSIVE_2:]] <_mutually_recursive_2>
|
||||
# CHECK: callq 0x[[#%x,MUTALLY_RECURSIVE_2:]] <_mutually_recursive_2>
|
||||
## FIXME: Mutually-recursive functions with identical bodies (see below)
|
||||
# COM: callq 0x[[#%x,ASYMMETRIC_RECURSIVE_2]] <_asymmetric_recursive_2>
|
||||
# COM: callq 0x[[#%x,ASYMMETRIC_RECURSIVE_2]] <_asymmetric_recursive_2>
|
||||
# CHECK: callq 0x[[#%x,INIT_2:]] <_init_2>
|
||||
# CHECK: callq 0x[[#%x,INIT_2:]] <_init_2>
|
||||
# CHECK: callq 0x[[#%x,INIT_3:]] <_init_3>
|
||||
|
||||
### TODO:
|
||||
### * Fold: funcs only differ in alignment
|
||||
@ -77,291 +96,167 @@ _not_abs:
|
||||
#--- main.s
|
||||
.subsections_via_symbols
|
||||
.text
|
||||
.globl _h
|
||||
.alt_entry _h
|
||||
|
||||
### Fold: _a1 & _a2 have identical bodies, flags, relocs
|
||||
|
||||
.globl _a1
|
||||
.p2align 2
|
||||
_a1:
|
||||
callq _d
|
||||
### No fold: _h is an alt entry past _a1
|
||||
_h:
|
||||
mov ___nan@GOTPCREL(%rip), %rax
|
||||
callq ___isnan
|
||||
_abs1a_ref:
|
||||
movabs $_abs1a, %rdx
|
||||
movl $0, %eax
|
||||
ret
|
||||
|
||||
.globl _a2
|
||||
.p2align 2
|
||||
_a2:
|
||||
callq _d
|
||||
mov ___nan@GOTPCREL(%rip), %rax
|
||||
callq ___isnan
|
||||
movabs $_abs1a, %rdx
|
||||
movl $0, %eax
|
||||
ret
|
||||
|
||||
### Fold: reference to absolute symbol with different name but identical value
|
||||
|
||||
.globl _a3
|
||||
.p2align 2
|
||||
_a3:
|
||||
callq _d
|
||||
mov ___nan@GOTPCREL(%rip), %rax
|
||||
callq ___isnan
|
||||
_abs1b_ref:
|
||||
movabs $_abs1b, %rdx
|
||||
movl $0, %eax
|
||||
ret
|
||||
|
||||
### No fold: the absolute symbol value differs
|
||||
_abs1a_ref_with_addend:
|
||||
movabs $_abs1a + 3, %rdx
|
||||
|
||||
.globl _b
|
||||
.p2align 2
|
||||
_b:
|
||||
callq _d
|
||||
mov ___nan@GOTPCREL(%rip), %rax
|
||||
callq ___isnan
|
||||
_abs1b_ref_with_addend:
|
||||
movabs $_abs1b + 3, %rdx
|
||||
|
||||
## No fold: the absolute symbol value differs
|
||||
_abs2_ref:
|
||||
movabs $_abs2, %rdx
|
||||
movl $0, %eax
|
||||
ret
|
||||
|
||||
### No fold: _not_abs has the same value as _abs1{a,b}, but is not absolute.
|
||||
|
||||
.globl _b2
|
||||
.p2align 2
|
||||
_b2:
|
||||
callq _d
|
||||
mov ___nan@GOTPCREL(%rip), %rax
|
||||
callq ___isnan
|
||||
## No fold: _not_abs has the same value as _abs1{a,b}, but is not absolute.
|
||||
_not_abs_ref:
|
||||
movabs $_not_abs, %rdx
|
||||
movl $0, %eax
|
||||
ret
|
||||
|
||||
### No fold: _c has slightly different body from _a1 & _a2
|
||||
|
||||
.globl _c
|
||||
.p2align 2
|
||||
_c:
|
||||
callq _d
|
||||
_dylib_ref_1:
|
||||
mov ___nan@GOTPCREL(%rip), %rax
|
||||
callq ___isnan
|
||||
movabs $_abs1a, %rdx
|
||||
movl $1, %eax
|
||||
ret
|
||||
|
||||
### No fold: _d has the same body as _a1 & _a2, but _d is recursive!
|
||||
|
||||
.globl _d
|
||||
.p2align 2
|
||||
_d:
|
||||
callq _d
|
||||
_dylib_ref_2:
|
||||
mov ___nan@GOTPCREL(%rip), %rax
|
||||
callq ___isnan
|
||||
movabs $_abs1a, %rdx
|
||||
movl $0, %eax
|
||||
ret
|
||||
|
||||
### No fold: the function body is longer
|
||||
|
||||
.globl _e
|
||||
.p2align 2
|
||||
_e:
|
||||
callq _d
|
||||
mov ___nan@GOTPCREL(%rip), %rax
|
||||
callq ___isnan
|
||||
movabs $_abs1a, %rdx
|
||||
movl $0, %eax
|
||||
ret
|
||||
nop
|
||||
|
||||
### No fold: GOT referent dylib symbol differs
|
||||
|
||||
.globl _f
|
||||
.p2align 2
|
||||
_f:
|
||||
callq _d
|
||||
## No fold: referent dylib symbol differs
|
||||
_dylib_ref_3:
|
||||
mov ___inf@GOTPCREL(%rip), %rax
|
||||
callq ___isnan
|
||||
movabs $_abs1a, %rdx
|
||||
movl $0, %eax
|
||||
callq ___inf
|
||||
|
||||
## We can merge two sections even if one of them has an alt entry. Just make
|
||||
## sure we don't merge the alt entry symbol with a regular symbol.
|
||||
.alt_entry _alt
|
||||
_with_alt_entry:
|
||||
movq $3132, %rax
|
||||
_alt:
|
||||
ret
|
||||
|
||||
### No fold: call referent dylib symbol differs
|
||||
|
||||
.globl _g
|
||||
.p2align 2
|
||||
_g:
|
||||
callq _d
|
||||
mov ___nan@GOTPCREL(%rip), %rax
|
||||
callq ___isinf
|
||||
movabs $_abs1a, %rdx
|
||||
movl $0, %eax
|
||||
_no_alt_entry:
|
||||
movq $3132, %rax
|
||||
ret
|
||||
|
||||
### No fold: functions have personality and/or LSDA
|
||||
### Mere presence of personality and/or LSDA isolates a function into its own
|
||||
### equivalence class. We don't care if two functions happen to have identical
|
||||
### personality & LSDA.
|
||||
_defined_ref_with_addend_1:
|
||||
callq _with_alt_entry + 4
|
||||
|
||||
.globl _i
|
||||
.p2align 2
|
||||
_i:
|
||||
_defined_ref_with_addend_2:
|
||||
callq _with_alt_entry + 4
|
||||
|
||||
## _recursive has the same body as its next two callers, but cannot be folded
|
||||
## with them.
|
||||
_recursive:
|
||||
callq _recursive
|
||||
|
||||
_call_recursive_1:
|
||||
callq _recursive
|
||||
|
||||
_call_recursive_2:
|
||||
callq _recursive
|
||||
|
||||
## Functions of different lengths should not be folded
|
||||
_check_length_1:
|
||||
movq $97, %rax
|
||||
|
||||
_check_length_2:
|
||||
movq $97, %rax
|
||||
.space 1
|
||||
|
||||
_my_personality:
|
||||
mov $1345, %rax
|
||||
|
||||
## No fold: functions have unwind info.
|
||||
## FIXME: Fold functions with identical unwind info.
|
||||
_has_unwind_1:
|
||||
.cfi_startproc
|
||||
.cfi_personality 155, _my_personality0
|
||||
.cfi_lsda 16, _exception0
|
||||
.cfi_personality 155, _my_personality
|
||||
.cfi_def_cfa_offset 16
|
||||
callq _d
|
||||
mov ___nan@GOTPCREL(%rip), %rax
|
||||
callq ___isnan
|
||||
movabs $_abs1a, %rdx
|
||||
movl $0, %eax
|
||||
ret
|
||||
.cfi_endproc
|
||||
|
||||
.globl _j
|
||||
.p2align 2
|
||||
_j:
|
||||
_has_unwind_2:
|
||||
.cfi_startproc
|
||||
.cfi_personality 155, _my_personality0
|
||||
.cfi_lsda 16, _exception0
|
||||
.cfi_personality 155, _my_personality
|
||||
.cfi_def_cfa_offset 16
|
||||
callq _d
|
||||
mov ___nan@GOTPCREL(%rip), %rax
|
||||
callq ___isnan
|
||||
movabs $_abs1a, %rdx
|
||||
movl $0, %eax
|
||||
ret
|
||||
.cfi_endproc
|
||||
|
||||
### No fold: _k1 is in a different section from _a1
|
||||
.section __TEXT,__foo
|
||||
.globl _k1
|
||||
.p2align 2
|
||||
_k1:
|
||||
callq _d
|
||||
mov ___nan@GOTPCREL(%rip), %rax
|
||||
callq ___isnan
|
||||
movabs $_abs1a, %rdx
|
||||
movl $0, %eax
|
||||
ret
|
||||
nopl (%rax)
|
||||
## Fold: Mutually-recursive functions with symmetric bodies
|
||||
_mutually_recursive_1:
|
||||
callq _mutually_recursive_1 # call myself
|
||||
callq _mutually_recursive_2 # call my twin
|
||||
|
||||
### Fold: _k2 is in a section that gets renamed and output as __text
|
||||
_mutually_recursive_2:
|
||||
callq _mutually_recursive_2 # call myself
|
||||
callq _mutually_recursive_1 # call my twin
|
||||
|
||||
## Fold: Mutually-recursive functions with identical bodies
|
||||
##
|
||||
## FIXME: This test is currently broken. Recursive call sites have no relocs
|
||||
## and the non-zero displacement field is already written to the section
|
||||
## data, while non-recursive call sites use symbol relocs and section data
|
||||
## contains zeros in the displacement field. Thus, ICF's equalsConstant()
|
||||
## finds that the section data doesn't match.
|
||||
##
|
||||
## ELF folds this case properly because it emits symbol relocs for all calls,
|
||||
## even recursive ones.
|
||||
|
||||
_asymmetric_recursive_1:
|
||||
callq _asymmetric_recursive_1 # call myself
|
||||
callq _asymmetric_recursive_2 # call my twin
|
||||
movl $3, %eax
|
||||
|
||||
_asymmetric_recursive_2:
|
||||
callq _asymmetric_recursive_1 # call my twin
|
||||
callq _asymmetric_recursive_2 # call myself
|
||||
movl $3, %eax
|
||||
|
||||
_init_1:
|
||||
movq $12938, %rax
|
||||
|
||||
## Fold: _init_2 is in a section that gets renamed and output as __text
|
||||
.section __TEXT,__StaticInit
|
||||
.globl _k2
|
||||
.p2align 2
|
||||
_k2:
|
||||
callq _d
|
||||
mov ___nan@GOTPCREL(%rip), %rax
|
||||
callq ___isnan
|
||||
movabs $_abs1a, %rdx
|
||||
movl $0, %eax
|
||||
ret
|
||||
## For some reason, llvm-mc generates different nop encodings when adding
|
||||
## padding for __StaticInit vs __text functions. So we explicitly specify the
|
||||
## nop here to make sure this function can be folded with _a1.
|
||||
nopl (%rax)
|
||||
_init_2:
|
||||
movq $12938, %rax
|
||||
|
||||
### Fold: Simple recursion
|
||||
## No fold: _init_3 is in a different output section from _init_{1,2}
|
||||
.section __TEXT,__foo
|
||||
_init_3:
|
||||
movq $12938, %rax
|
||||
|
||||
.text
|
||||
.globl _sr1
|
||||
.p2align 2
|
||||
_sr1:
|
||||
callq _sr1
|
||||
movl $0, %eax
|
||||
ret
|
||||
|
||||
.globl _sr2
|
||||
.p2align 2
|
||||
_sr2:
|
||||
callq _sr2
|
||||
movl $0, %eax
|
||||
ret
|
||||
|
||||
### Fold: Mutually-recursive functions with symmetric bodies
|
||||
|
||||
.globl _mr1
|
||||
.p2align 2
|
||||
_mr1:
|
||||
callq _mr1 # call myself
|
||||
callq _mr2 # call my twin
|
||||
movl $0, %eax
|
||||
ret
|
||||
|
||||
.globl _mr2
|
||||
.p2align 2
|
||||
_mr2:
|
||||
callq _mr2 # call myself
|
||||
callq _mr1 # call my twin
|
||||
movl $0, %eax
|
||||
ret
|
||||
|
||||
### Fold: Mutually-recursive functions with identical bodies
|
||||
###
|
||||
### FIXME: This test is currently broken. Recursive call sites have no relocs
|
||||
### and the non-zero displacement field is already written to the section
|
||||
### data, while non-recursive call sites use symbol relocs and section data
|
||||
### contains zeros in the displacement field. Thus, ICF's equalsConstant()
|
||||
### finds that the section data doesn't match.
|
||||
###
|
||||
### ELF folds this case properly because it emits symbol relocs for all calls,
|
||||
### even recursive ones.
|
||||
|
||||
.globl _xr1
|
||||
.p2align 2
|
||||
_xr1:
|
||||
callq _xr1 # call myself
|
||||
callq _xr2 # call my twin
|
||||
movl $3, %eax
|
||||
ret
|
||||
|
||||
.globl _xr2
|
||||
.p2align 2
|
||||
_xr2:
|
||||
callq _xr1 # call my twin
|
||||
callq _xr2 # call myself
|
||||
movl $3, %eax
|
||||
ret
|
||||
|
||||
###
|
||||
|
||||
.globl _main
|
||||
.p2align 2
|
||||
_main:
|
||||
callq _a1
|
||||
callq _a2
|
||||
callq _a3
|
||||
callq _b
|
||||
callq _b2
|
||||
callq _c
|
||||
callq _d
|
||||
callq _e
|
||||
callq _f
|
||||
callq _g
|
||||
callq _h
|
||||
callq _i
|
||||
callq _j
|
||||
callq _k1
|
||||
callq _k2
|
||||
callq _sr1
|
||||
callq _sr2
|
||||
callq _mr1
|
||||
callq _mr2
|
||||
callq _xr1
|
||||
callq _xr2
|
||||
ret
|
||||
|
||||
.globl _my_personality0
|
||||
.p2align 2
|
||||
_my_personality0:
|
||||
movl $0, %eax
|
||||
ret
|
||||
|
||||
.section __TEXT,__gcc_except_tab
|
||||
.globl _exception0
|
||||
_exception0:
|
||||
.space 1
|
||||
callq _abs1a_ref
|
||||
callq _abs1b_ref
|
||||
callq _abs1a_ref_with_addend
|
||||
callq _abs1b_ref_with_addend
|
||||
callq _abs2_ref
|
||||
callq _not_abs_ref
|
||||
callq _dylib_ref_1
|
||||
callq _dylib_ref_2
|
||||
callq _dylib_ref_3
|
||||
callq _alt
|
||||
callq _with_alt_entry
|
||||
callq _no_alt_entry
|
||||
callq _defined_ref_with_addend_1
|
||||
callq _defined_ref_with_addend_2
|
||||
callq _recursive
|
||||
callq _call_recursive_1
|
||||
callq _call_recursive_2
|
||||
callq _check_length_1
|
||||
callq _check_length_2
|
||||
callq _has_unwind_1
|
||||
callq _has_unwind_2
|
||||
callq _mutually_recursive_1
|
||||
callq _mutually_recursive_2
|
||||
callq _asymmetric_recursive_1
|
||||
callq _asymmetric_recursive_2
|
||||
callq _init_1
|
||||
callq _init_2
|
||||
callq _init_3
|
||||
|
Loading…
Reference in New Issue
Block a user