222 lines · plain
1## Test the different ways of hooking the init function for instrumentation (via2## entry point, DT_INIT and via DT_INIT_ARRAY). We test the latter for both PIE3## and non-PIE binaries because of the different ways of handling relocations4## (static or dynamic), executable and shared library.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## - INTERP in Program Headers10## - DT_INIT or DT_INIT_ARRAY in dynamic section11## - No relative relocations for non-PIE12## - Instrument (with extra --runtime-lib-init-hook=init/init_array options13## in some cases)14## - Verify generated binary15# REQUIRES: system-linux,bolt-runtime,target=aarch64{{.*}}16 17# RUN: %clang %cflags -pie %s -Wl,-q -o %t.exe18# RUN: llvm-readelf -d %t.exe | FileCheck --check-prefix=DYN-INIT %s19# RUN: llvm-readelf -l %t.exe | FileCheck --check-prefix=PH-INTERP %s20# RUN: llvm-readelf -r %t.exe | FileCheck --check-prefix=RELOC-PIE %s21# RUN: llvm-bolt %t.exe -o %t --instrument | FileCheck --check-prefix=CHECK-BOLT-RT-EP %s22# RUN: llvm-readelf -hdrs %t | FileCheck --check-prefix=CHECK-INIT-EP %s23# RUN: llvm-bolt %t.exe -o %t-no-ep --instrument --runtime-lib-init-hook=init | FileCheck --check-prefix=CHECK-BOLT-RT-INIT %s24# RUN: llvm-readelf -hdrs %t-no-ep | FileCheck --check-prefix=CHECK-INIT-NO-EP %s25# RUN: llvm-bolt %t.exe -o %t-no-ep --instrument --runtime-lib-init-hook=init_array | FileCheck --check-prefix=CHECK-BOLT-RT-INIT-ARRAY %s26# RUN: llvm-readelf -hdrs %t-no-ep | FileCheck --check-prefix=CHECK-INIT-ARRAY-NO-EP %s27 28# RUN: %clang -shared %cflags -pie %s -Wl,-q -o %t-shared.exe29# RUN: llvm-readelf -d %t-shared.exe | FileCheck --check-prefix=DYN-INIT %s30# RUN: llvm-readelf -l %t-shared.exe | FileCheck --check-prefix=PH-INTERP-SHARED %s31# RUN: llvm-readelf -r %t-shared.exe | FileCheck --check-prefix=RELOC-SHARED-PIE %s32# RUN: llvm-bolt %t-shared.exe -o %t-shared --instrument | FileCheck --check-prefix=CHECK-BOLT-RT-INIT %s33# RUN: llvm-readelf -hdrs %t-shared | FileCheck --check-prefix=CHECK-SHARED-INIT %s34 35# RUN: %clang %cflags -pie %s -Wl,-q,-init=0 -o %t-no-init.exe36# RUN: llvm-readelf -d %t-no-init.exe | FileCheck --check-prefix=DYN-NO-INIT %s37# RUN: llvm-readelf -l %t-no-init.exe | FileCheck --check-prefix=PH-INTERP %s38# RUN: llvm-readelf -r %t-no-init.exe | FileCheck --check-prefix=RELOC-PIE %s39# RUN: llvm-bolt %t-no-init.exe -o %t-no-init --instrument | FileCheck --check-prefix=CHECK-BOLT-RT-EP %s40# RUN: llvm-readelf -hdrs %t-no-init | FileCheck --check-prefix=CHECK-NO-INIT-EP %s41# RUN: llvm-bolt %t-no-init.exe -o %t-no-init-no-ep --instrument --runtime-lib-init-hook=init | FileCheck --check-prefix=CHECK-BOLT-RT-INIT-ARRAY %s42# RUN: llvm-readelf -hdrs %t-no-init-no-ep | FileCheck --check-prefix=CHECK-NO-INIT-NO-EP %s43 44# RUN: %clang -shared %cflags -pie %s -Wl,-q,-init=0 -o %t-shared-no-init.exe45# RUN: llvm-readelf -d %t-shared-no-init.exe | FileCheck --check-prefix=DYN-NO-INIT %s46# RUN: llvm-readelf -l %t-shared-no-init.exe | FileCheck --check-prefix=PH-INTERP-SHARED %s47# RUN: llvm-readelf -r %t-shared-no-init.exe | FileCheck --check-prefix=RELOC-SHARED-PIE %s48# RUN: llvm-bolt %t-shared-no-init.exe -o %t-shared-no-init --instrument | FileCheck --check-prefix=CHECK-BOLT-RT-INIT-ARRAY %s49# RUN: llvm-readelf -drs %t-shared-no-init | FileCheck --check-prefix=CHECK-SHARED-NO-INIT %s50 51## Create a dummy shared library to link against to force creation of the dynamic section.52# RUN: %clang %cflags %p/../Inputs/stub.c -fPIC -shared -o %t-stub.so53# RUN: %clang %cflags %s -no-pie -Wl,-q,-init=0 %t-stub.so -o %t-no-pie-no-init.exe54# RUN: llvm-readelf -r %t-no-pie-no-init.exe | FileCheck --check-prefix=RELOC-NO-PIE %s55# RUN: llvm-bolt %t-no-pie-no-init.exe -o %t-no-pie-no-init --instrument | FileCheck --check-prefix=CHECK-BOLT-RT-EP %s56# RUN: llvm-readelf -hds %t-no-pie-no-init | FileCheck --check-prefix=CHECK-NO-PIE-NO-INIT-EP %s57 58## With init: dynamic section should contain DT_INIT59# DYN-INIT: (INIT)60 61## Without init: dynamic section should only contain DT_INIT_ARRAY62# DYN-NO-INIT-NOT: (INIT)63# DYN-NO-INIT: (INIT_ARRAY)64# DYN-NO-INIT: (INIT_ARRAYSZ)65 66## With interp program header (executable)67# PH-INTERP: Program Headers:68# PH-INTERP: INTERP69 70## Without interp program header (shared library)71# PH-INTERP-SHARED: Program Headers:72# PH-INTERP-SHARED-NOT: INTERP73 74## With PIE: binary should have relative relocations75# RELOC-PIE: R_AARCH64_RELATIVE76 77## With PIE: binary should have relative relocations78# RELOC-SHARED-PIE: R_AARCH64_ABS6479 80## Without PIE: binary should not have relative relocations81# RELOC-NO-PIE-NOT: R_AARCH64_RELATIVE82 83## Check BOLT output output initialization hook (ELF Header Entry Point)84# CHECK-BOLT-RT-EP: runtime library initialization was hooked via ELF Header Entry Point85# CHECK-BOLT-RT-EP-NOT: runtime library initialization was hooked via DT_INIT86# CHECK-BOLT-RT-EP-NOT: runtime library initialization was hooked via .init_array entry87 88## Check BOLT output output initialization hook (DT_INIT)89# CHECK-BOLT-RT-INIT-NOT: runtime library initialization was hooked via ELF Header Entry Point90# CHECK-BOLT-RT-INIT: runtime library initialization was hooked via DT_INIT91# CHECK-BOLT-RT-INIT-NOT: runtime library initialization was hooked via .init_array entry92 93## Check BOLT output output initialization hook (.init_array entry)94# CHECK-BOLT-RT-INIT-ARRAY-NOT: runtime library initialization was hooked via ELF Header Entry Point95# CHECK-BOLT-RT-INIT-ARRAY-NOT: runtime library initialization was hooked via DT_INIT96# CHECK-BOLT-RT-INIT-ARRAY: runtime library initialization was hooked via .init_array entry97 98## Check that entry point address is set to __bolt_runtime_start for PIE executable with DT_INIT99# CHECK-INIT-EP: ELF Header:100# CHECK-INIT-EP: Entry point address: 0x[[#%x,EP_ADDR:]]101## Check that the dynamic relocation at .init and .init_array were not patched102# CHECK-INIT-EP: Dynamic section at offset {{.*}} contains {{.*}} entries:103# CHECK-INIT-EP-NOT: (INIT) 0x[[#%x, EP_ADDR]]104# CHECK-INIT-EP-NOT: (INIT_ARRAY) 0x[[#%x, EP_ADDR]]105## Check that the new entry point address points to __bolt_runtime_start106# CHECK-INIT-EP: Symbol table '.symtab' contains {{.*}} entries:107# CHECK-INIT-EP: {{0+}}[[#%x, EP_ADDR]] {{.*}} __bolt_runtime_start108 109## Check that DT_INIT address is set to __bolt_runtime_start for PIE executable with DT_INIT110# CHECK-INIT-NO-EP: ELF Header:111# CHECK-INIT-NO-EP: Entry point address: 0x[[#%x,EP_ADDR:]]112## Read Dynamic section DT_INIT and DT_INIT_ARRAY entries113# CHECK-INIT-NO-EP: Dynamic section at offset {{.*}} contains {{.*}} entries:114# CHECK-INIT-NO-EP-DAG: (INIT) 0x[[#%x,INIT:]]115# CHECK-INIT-NO-EP-DAG: (INIT_ARRAY) 0x[[#%x,INIT_ARRAY:]]116## Check if ELF entry point address points to _start symbol and new DT_INIT entry points to __bolt_runtime_start117# CHECK-INIT-NO-EP: Symbol table '.symtab' contains {{.*}} entries:118# CHECK-INIT-NO-EP-DAG: {{0+}}[[#%x, EP_ADDR]] {{.*}} _start119# CHECK-INIT-NO-EP-DAG: {{0+}}[[#%x, INIT]] {{.*}} __bolt_runtime_start120 121## Check that 1st entry of DT_INIT_ARRAY is set to __bolt_runtime_start and DT_INIT was not changed122# CHECK-INIT-ARRAY-NO-EP: ELF Header:123# CHECK-INIT-ARRAY-NO-EP: Entry point address: 0x[[#%x,EP_ADDR:]]124## Read Dynamic section DT_INIT and DT_INIT_ARRAY entries125# CHECK-INIT-ARRAY-NO-EP: Dynamic section at offset {{.*}} contains {{.*}} entries:126# CHECK-INIT-ARRAY-NO-EP-DAG: (INIT) 0x[[#%x,INIT:]]127# CHECK-INIT-ARRAY-NO-EP-DAG: (INIT_ARRAY) 0x[[#%x,INIT_ARRAY:]]128## Read the dynamic relocation from 1st entry of .init_array129# CHECK-INIT-ARRAY-NO-EP: Relocation section '.rela.dyn' at offset {{.*}} contains {{.*}} entries130# CHECK-INIT-ARRAY-NO-EP: {{0+}}[[#%x,INIT_ARRAY]] {{.*}} R_AARCH64_RELATIVE [[#%x,INIT_ADDR:]]131# CHECK-INIT-ARRAY-NO-EP-NOT: {{0+}}[[#%x,INIT_ARRAY]] {{.*}} R_AARCH64_RELATIVE [[#%x,INIT]]132## Check that 1st entry of .init_array points to __bolt_runtime_start133# CHECK-INIT-ARRAY-NO-EP: Symbol table '.symtab' contains {{.*}} entries:134# CHECK-INIT-ARRAY-NO-EP-DAG: {{0+}}[[#%x, EP_ADDR]] {{.*}} _start135# CHECK-INIT-ARRAY-NO-EP-DAG: {{[0-9]]*}}: {{0+}}[[#%x, INIT_ADDR]] {{.*}} __bolt_runtime_start136 137## Check that entry point address is set to __bolt_runtime_start for PIE executable without DT_INIT138# CHECK-NO-INIT-EP: ELF Header:139# CHECK-NO-INIT-EP: Entry point address: 0x[[#%x,EP_ADDR:]]140## Check that the dynamic relocation at .init and .init_array were not patched141# CHECK-NO-INIT-EP: Dynamic section at offset {{.*}} contains {{.*}} entries:142# CHECK-NO-INIT-EP-NOT: (INIT) 0x[[#%x, EP_ADDR]]143# CHECK-NO-INIT-EP-NOT: (INIT_ARRAY) 0x[[#%x, EP_ADDR]]144## Check that the new entry point address points to __bolt_runtime_start145# CHECK-NO-INIT-EP: Symbol table '.symtab' contains {{.*}} entries:146# CHECK-NO-INIT-EP: {{0+}}[[#%x, EP_ADDR]] {{.*}} __bolt_runtime_start147 148## Check that DT_INIT is set to __bolt_runtime_start for shared library with DT_INIT149# CHECK-SHARED-INIT: Dynamic section at offset {{.*}} contains {{.*}} entries:150# CHECK-SHARED-INIT-DAG: (INIT) 0x[[#%x, INIT:]]151# CHECK-SHARED-INIT-DAG: (INIT_ARRAY) 0x[[#%x, INIT_ARRAY:]]152## Check that the dynamic relocation at .init_array was not patched153# CHECK-SHARED-INIT: Relocation section '.rela.dyn' at offset {{.*}} contains {{.*}} entries154# CHECK-SHARED-INIT-NOT: {{0+}}[[#%x, INIT_ARRAY]] {{.*}} R_AARCH64_ABS64 {{0+}}[[#%x, INIT]]155## Check that dynamic section DT_INIT points to __bolt_runtime_start156# CHECK-SHARED-INIT: Symbol table '.symtab' contains {{.*}} entries:157# CHECK-SHARED-INIT: {{0+}}[[#%x, INIT]] {{.*}} __bolt_runtime_start158 159## Check that entry point address is set to __bolt_runtime_start for PIE executable without DT_INIT160# CHECK-NO-INIT-NO-EP: ELF Header:161# CHECK-NO-INIT-NO-EP: Entry point address: 0x[[#%x,EP_ADDR:]]162# CHECK-NO-INIT-NO-EP: Dynamic section at offset {{.*}} contains {{.*}} entries:163# CHECK-NO-INIT-NO-EP-NOT: (INIT)164# CHECK-NO-INIT-NO-EP: (INIT_ARRAY) 0x[[#%x,INIT_ARRAY:]]165## Read the dynamic relocation from 1st entry of .init_array166# CHECK-NO-INIT-NO-EP: Relocation section '.rela.dyn' at offset {{.*}} contains {{.*}} entries167# CHECK-NO-INIT-NO-EP: {{0+}}[[#%x,INIT_ARRAY]] {{.*}} R_AARCH64_RELATIVE [[#%x,INIT_ADDR:]]168## Check that 1st entry of .init_array points to __bolt_runtime_start169# CHECK-NO-INIT-NO-EP: Symbol table '.symtab' contains {{.*}} entries:170# CHECK-NO-INIT-NO-EP-DAG: {{0+}}[[#%x, EP_ADDR]] {{.*}} _start171# CHECK-NO-INIT-NO-EP-DAG: {{[0-9]]*}}: {{0+}}[[#%x, INIT_ADDR]] {{.*}} __bolt_runtime_start172 173## Check that entry point address is set to __bolt_runtime_start for shared library without DT_INIT174# CHECK-SHARED-NO-INIT: Dynamic section at offset {{.*}} contains {{.*}} entries:175# CHECK-SHARED-NO-INIT-NOT: (INIT)176# CHECK-SHARED-NO-INIT: (INIT_ARRAY) 0x[[#%x,INIT_ARRAY:]]177## Read the dynamic relocation from 1st entry of .init_array178# CHECK-SHARED-NO-INIT: Relocation section '.rela.dyn' at offset {{.*}} contains {{.*}} entries179# CHECK-SHARED-NO-INIT: {{0+}}[[#%x, INIT_ARRAY]] {{.*}} R_AARCH64_ABS64 [[#%x,INIT_ADDR:]]180## Check that 1st entry of .init_array points to __bolt_runtime_start181# CHECK-SHARED-NO-INIT: Symbol table '.symtab' contains {{.*}} entries:182# CHECK-SHARED-NO-INIT: {{[0-9]]*}}: {{0+}}[[#%x, INIT_ADDR]] {{.*}} __bolt_runtime_start183 184## Check that entry point address is set to __bolt_runtime_start for non-PIE executable with DT_INIT185# CHECK-NO-PIE-NO-INIT-EP: ELF Header:186# CHECK-NO-PIE-NO-INIT-EP: Entry point address: 0x[[#%x,EP_ADDR:]]187## Check that the dynamic relocation at .init and .init_array were not patched188# CHECK-NO-PIE-NO-INIT-EP: Dynamic section at offset {{.*}} contains {{.*}} entries:189# CHECK-NO-PIE-NO-INIT-EP-NOT: (INIT) 0x[[#%x, EP_ADDR]]190# CHECK-NO-PIE-NO-INIT-EP-NOT: (INIT_ARRAY) 0x[[#%x, EP_ADDR]]191## Check that the new entry point address points to __bolt_runtime_start192# CHECK-NO-PIE-NO-INIT-EP: Symbol table '.symtab' contains {{.*}} entries:193# CHECK-NO-PIE-NO-INIT-EP: {{0+}}[[#%x, EP_ADDR]] {{.*}} __bolt_runtime_start194 195 .globl _start196 .type _start, %function197_start:198 # Dummy relocation to force relocation mode.199 .reloc 0, R_AARCH64_NONE200 ret201.size _start, .-_start202 203 .globl _init204 .type _init, %function205_init:206 ret207 .size _init, .-_init208 209 .globl _fini210 .type _fini, %function211_fini:212 ret213 .size _fini, .-_fini214 215 .section .init_array,"aw"216 .align 3217 .dword _init218 219 .section .fini_array,"aw"220 .align 3221 .dword _fini222