112 lines · plain
1## Test the different ways of hooking the fini function for instrumentation (via2## DT_FINI and via DT_FINI_ARRAY). We test the latter for both PIE and non-PIE3## binaries because of the different ways of handling relocations (static or4## dynamic).5## All tests perform the following steps:6## - Compile and link for the case to be tested7## - Some sanity-checks on the dynamic section and relocations in the binary to8## verify it has the shape we want for testing:9## - DT_FINI or DT_FINI_ARRAY in dynamic section10## - No relative relocations for non-PIE11## - Instrument12## - Verify generated binary13# REQUIRES: system-linux,bolt-runtime,target=aarch64{{.*}}14 15# RUN: %clang %cflags -pie %s -Wl,-q -o %t.exe16# RUN: llvm-readelf -d %t.exe | FileCheck --check-prefix=DYN-FINI %s17# RUN: llvm-readelf -r %t.exe | FileCheck --check-prefix=RELOC-PIE %s18# RUN: llvm-bolt %t.exe -o %t --instrument | FileCheck --check-prefix=CHECK-BOLT-RT-FINI %s19# RUN: llvm-readelf -drs %t | FileCheck --check-prefix=CHECK-FINI %s20 21# RUN: %clang %cflags -pie %s -Wl,-q,-fini=0 -o %t-no-fini.exe22# RUN: llvm-readelf -d %t-no-fini.exe | FileCheck --check-prefix=DYN-NO-FINI %s23# RUN: llvm-readelf -r %t-no-fini.exe | FileCheck --check-prefix=RELOC-PIE %s24# RUN: llvm-bolt %t-no-fini.exe -o %t-no-fini --instrument | FileCheck --check-prefix=CHECK-BOLT-RT-FINI-ARRAY %s25# RUN: llvm-readelf -drs %t-no-fini | FileCheck --check-prefix=CHECK-NO-FINI %s26# RUN: llvm-readelf -ds -x .fini_array %t-no-fini | FileCheck --check-prefix=CHECK-NO-FINI-RELOC %s27 28## Create a dummy shared library to link against to force creation of the dynamic section.29# RUN: %clang %cflags %p/../Inputs/stub.c -fPIC -shared -o %t-stub.so30# RUN: %clang %cflags %s -no-pie -Wl,-q,-fini=0 %t-stub.so -o %t-no-pie-no-fini.exe31# RUN: llvm-readelf -r %t-no-pie-no-fini.exe | FileCheck --check-prefix=RELOC-NO-PIE %s32# RUN: llvm-bolt %t-no-pie-no-fini.exe -o %t-no-pie-no-fini --instrument | FileCheck --check-prefix=CHECK-BOLT-RT-FINI-ARRAY %s33# RUN: llvm-readelf -ds -x .fini_array %t-no-pie-no-fini | FileCheck --check-prefix=CHECK-NO-PIE-NO-FINI %s34 35## With fini: dynamic section should contain DT_FINI36# DYN-FINI: (FINI)37 38## Without fini: dynamic section should only contain DT_FINI_ARRAY39# DYN-NO-FINI-NOT: (FINI)40# DYN-NO-FINI: (FINI_ARRAY)41# DYN-NO-FINI: (FINI_ARRAYSZ)42 43## With PIE: binary should have relative relocations44# RELOC-PIE: R_AARCH64_RELATIVE45 46## Without PIE: binary should not have relative relocations47# RELOC-NO-PIE-NOT: R_AARCH64_RELATIVE48 49## Check BOLT output output finalization hook (DT_FINI)50# CHECK-BOLT-RT-FINI: runtime library finalization was hooked via DT_FINI51# CHECK-BOLT-RT-FINI-NOT: runtime library finalization was hooked via .fini_array entry52 53## Check BOLT output output finalization hook (.fini_array entry)54# CHECK-BOLT-RT-FINI-ARRAY-NOT: runtime library finalization was hooked via DT_FINI55# CHECK-BOLT-RT-FINI-ARRAY: runtime library finalization was hooked via .fini_array entry56 57## Check that DT_FINI is set to __bolt_runtime_fini58# CHECK-FINI: Dynamic section at offset {{.*}} contains {{.*}} entries:59# CHECK-FINI-DAG: (FINI) 0x[[FINI:[[:xdigit:]]+]]60# CHECK-FINI-DAG: (FINI_ARRAY) 0x[[FINI_ARRAY:[[:xdigit:]]+]]61## Check that the dynamic relocation at .fini_array was not patched62# CHECK-FINI: Relocation section '.rela.dyn' at offset {{.*}} contains {{.*}} entries63# CHECK-FINI-NOT: {{0+}}[[FINI_ARRAY]] {{.*}} R_AARCH64_RELATIVE [[FINI]]64# CHECK-FINI: Symbol table '.symtab' contains {{.*}} entries:65# CHECK-FINI: {{0+}}[[FINI]] {{.*}} __bolt_runtime_fini66 67## Check that DT_FINI_ARRAY has a dynamic relocation for __bolt_runtime_fini68# CHECK-NO-FINI: Dynamic section at offset {{.*}} contains {{.*}} entries:69# CHECK-NO-FINI-NOT: (FINI)70# CHECK-NO-FINI: (FINI_ARRAY) 0x[[FINI_ARRAY:[[:xdigit:]]+]]71# CHECK-NO-FINI: Relocation section '.rela.dyn' at offset {{.*}} contains {{.*}} entries72# CHECK-NO-FINI: {{0+}}[[FINI_ARRAY]] {{.*}} R_AARCH64_RELATIVE [[FINI_ADDR:[[:xdigit:]]+]]73# CHECK-NO-FINI: Symbol table '.symtab' contains {{.*}} entries:74# CHECK-NO-FINI: {{0+}}[[FINI_ADDR]] {{.*}} __bolt_runtime_fini75 76## Check that the static relocation in .fini_array is patched even for PIE77# CHECK-NO-FINI-RELOC: Dynamic section at offset {{.*}} contains {{.*}} entries:78# CHECK-NO-FINI-RELOC: (FINI_ARRAY) 0x[[FINI_ARRAY:[[:xdigit:]]+]]79# CHECK-NO-FINI-RELOC: Symbol table '.symtab' contains {{.*}} entries:80## Read bytes separately so we can reverse them later81# CHECK-NO-FINI-RELOC: {{0+}}[[FINI_ADDR_B0:[[:xdigit:]]{2}]][[FINI_ADDR_B1:[[:xdigit:]]{2}]][[FINI_ADDR_B2:[[:xdigit:]]{2}]][[FINI_ADDR_B3:[[:xdigit:]]{2}]] {{.*}} __bolt_runtime_fini82# CHECK-NO-FINI-RELOC: Hex dump of section '.fini_array':83# CHECK-NO-FINI-RELOC: 0x{{0+}}[[FINI_ARRAY]] [[FINI_ADDR_B3]][[FINI_ADDR_B2]][[FINI_ADDR_B1]][[FINI_ADDR_B0]] 0000000084 85## Check that DT_FINI_ARRAY has static relocation applied for __bolt_runtime_fini86# CHECK-NO-PIE-NO-FINI: Dynamic section at offset {{.*}} contains {{.*}} entries:87# CHECK-NO-PIE-NO-FINI-NOT: (FINI)88# CHECK-NO-PIE-NO-FINI: (FINI_ARRAY) 0x[[FINI_ARRAY:[a-f0-9]+]]89# CHECK-NO-PIE-NO-FINI: Symbol table '.symtab' contains {{.*}} entries:90## Read address bytes separately so we can reverse them later91# CHECK-NO-PIE-NO-FINI: {{0+}}[[FINI_ADDR_B0:[[:xdigit:]]{2}]][[FINI_ADDR_B1:[[:xdigit:]]{2}]][[FINI_ADDR_B2:[[:xdigit:]]{2}]][[FINI_ADDR_B3:[[:xdigit:]]{2}]] {{.*}} __bolt_runtime_fini92# CHECK-NO-PIE-NO-FINI: Hex dump of section '.fini_array':93# CHECK-NO-PIE-NO-FINI: 0x{{0+}}[[FINI_ARRAY]] [[FINI_ADDR_B3]][[FINI_ADDR_B2]][[FINI_ADDR_B1]][[FINI_ADDR_B0]] 0000000094 95 .globl _start96 .type _start, %function97_start:98 # Dummy relocation to force relocation mode.99 .reloc 0, R_AARCH64_NONE100 ret101.size _start, .-_start102 103 .globl _fini104 .type _fini, %function105_fini:106 ret107 .size _fini, .-_fini108 109 .section .fini_array,"aw"110 .align 3111 .dword _fini112