brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.9 KiB · 3b45643 Raw
198 lines · cpp
1// Check that loading libraries with different modes (RTLD_LOCAL/RTLD_GLOBAL)2// and dependencies on other DSOs work correctly.3//4 5// RUN: split-file %s %t6//7// Build shared libs with dependencies b->c and e->f8// RUN: %clangxx_xray -g -fPIC -fxray-instrument -fxray-shared -shared -std=c++11 %t/testliba.cpp -o %t/testliba.so9// RUN: %clangxx_xray -g -fPIC -fxray-instrument -fxray-shared -shared -std=c++11 %t/testlibc.cpp -o %t/testlibc.so10// RUN: %clangxx_xray -g -fPIC -fxray-instrument -fxray-shared -shared -std=c++11 %t/testlibb.cpp %t/testlibc.so -o %t/testlibb.so11// RUN: %clangxx_xray -g -fPIC -fxray-instrument -fxray-shared -shared -std=c++11 %t/testlibd.cpp -o %t/testlibd.so12// RUN: %clangxx_xray -g -fPIC -fxray-instrument -fxray-shared -shared -std=c++11 %t/testlibf.cpp -o %t/testlibf.so13// RUN: %clangxx_xray -g -fPIC -fxray-instrument -fxray-shared -shared -std=c++11 %t/testlibe.cpp %t/testlibf.so -o %t/testlibe.so14//15// Executable links with a and b explicitly and loads d and e at runtime.16// RUN: %clangxx_xray -g -fPIC -rdynamic -fxray-instrument -fxray-shared -std=c++11 %t/main.cpp %t/testliba.so %t/testlibb.so -o %t/main.o17//18// RUN:  env XRAY_OPTIONS="patch_premain=true" %run %t/main.o %t/testlibd.so %t/testlibe.so 2>&1 | FileCheck %s19 20// REQUIRES: target={{(aarch64|x86_64)-.*}}21 22//--- main.cpp23 24#include "xray/xray_interface.h"25 26#include <cstdio>27#include <dlfcn.h>28 29[[clang::xray_never_instrument]] void test_handler(int32_t fid,30                                                   XRayEntryType type) {31  printf("called: %d, object=%d, fn=%d, type=%d\n", fid, (fid >> 24) & 0xFF,32         fid & 0x00FFFFFF, static_cast<int32_t>(type));33}34 35[[clang::xray_always_instrument]] void instrumented_in_executable() {36  printf("instrumented_in_executable called\n");37}38 39typedef void (*dso_func_type)();40 41[[clang::xray_never_instrument]] void *load_dso(const char *path, int mode) {42  void *dso_handle = dlopen(path, mode);43  if (!dso_handle) {44    printf("failed to load shared library\n");45    char *error = dlerror();46    if (error) {47      fprintf(stderr, "%s\n", error);48    }49    return nullptr;50  }51  return dso_handle;52}53 54[[clang::xray_never_instrument]] void find_and_call(void *dso_handle,55                                                    const char *fn) {56  dso_func_type dso_fn = (dso_func_type)dlsym(dso_handle, fn);57  if (!dso_fn) {58    printf("failed to find symbol\n");59    char *error = dlerror();60    if (error) {61      fprintf(stderr, "%s\n", error);62    }63    return;64  }65  dso_fn();66}67 68extern void a();69extern void b();70 71int main(int argc, char **argv) {72 73  if (argc < 3) {74    printf("Shared library arguments missing\n");75    // CHECK-NOT: Shared library arguments missing76    return 1;77  }78 79  const char *dso_path_d = argv[1];80  const char *dso_path_e = argv[2];81 82  __xray_set_handler(test_handler);83 84  instrumented_in_executable();85  // CHECK: called: {{[0-9]+}}, object=0, fn={{[0-9]+}}, type=086  // CHECK-NEXT: instrumented_in_executable called87  // CHECK-NEXT: called: {{[0-9]+}}, object=0, fn={{[0-9]+}}, type=188 89  a();90  // CHECK-NEXT: called: {{[0-9]+}}, object=[[OBJ1:[0-9]+]], fn=1, type=091  // CHECK-NEXT: a called92  // CHECK-NEXT: called: {{[0-9]+}}, object=[[OBJ1]], fn=1, type=193 94  // Make sure this object ID does not appear again95  // CHECK-NOT: called: {{[0-9]+}}, object=[[OBJ1]]96 97  b(); // b calls c98  // CHECK-NEXT: called: {{[0-9]+}}, object=[[OBJ2:[0-9]+]], fn=1, type=099  // CHECK-NEXT: b called100  // CHECK-NEXT: called: {{[0-9]+}}, object=[[OBJ3:[0-9]+]], fn=1, type=0101  // CHECK-NEXT: c called102  // CHECK-NEXT: called: {{[0-9]+}}, object=[[OBJ3]], fn=1, type=1103  // CHECK-NOT: called: {{[0-9]+}}, object=[[OBJ3]]104  // CHECK-NEXT: called: {{[0-9]+}}, object=[[OBJ2]], fn=1, type=1105  // CHECK-NOT: called: {{[0-9]+}}, object=[[OBJ2]]106 107  // Now check explicit loading with RTLD_LOCAL108 109  void *dso_handle_d = load_dso(dso_path_d, RTLD_LAZY | RTLD_LOCAL);110  void *dso_handle_e = load_dso(dso_path_e, RTLD_LAZY | RTLD_LOCAL);111  // CHECK-NOT: failed to load shared library112 113  find_and_call(dso_handle_d, "_Z1dv");114  // CHECK-NEXT: called: {{[0-9]+}}, object=[[OBJ4:[0-9]+]], fn=1, type=0115  // CHECK-NEXT: d called116  // CHECK-NEXT: called: {{[0-9]+}}, object=[[OBJ4]], fn=1, type=1117  // CHECK-NOT: called: {{[0-9]+}}, object=[[OBJ4]]118 119  find_and_call(dso_handle_e, "_Z1ev");120  // CHECK-NEXT: called: {{[0-9]+}}, object=[[OBJ5:[0-9]+]], fn=1, type=0121  // CHECK-NEXT: e called122  // CHECK-NEXT: called: {{[0-9]+}}, object=[[OBJ6:[0-9]+]], fn=1, type=0123  // CHECK-NEXT: f called124  // CHECK-NEXT: called: {{[0-9]+}}, object=[[OBJ6]], fn=1, type=1125  // CHECK-NOT: called: {{[0-9]+}}, object=[[OBJ6]]126  // CHECK-NEXT: called: {{[0-9]+}}, object=[[OBJ5]], fn=1, type=1127  // CHECK-NOT: called: {{[0-9]+}}, object=[[OBJ5]]128 129  // Unload DSOs130  dlclose(dso_handle_d);131  dlclose(dso_handle_e);132 133  // Repeat test with RTLD_GLOBAL134  dso_handle_d = load_dso(dso_path_d, RTLD_LAZY | RTLD_GLOBAL);135  dso_handle_e = load_dso(dso_path_e, RTLD_LAZY | RTLD_GLOBAL);136  // CHECK-NOT: failed to load shared library137 138  find_and_call(dso_handle_d, "_Z1dv");139  // CHECK-NEXT: called: {{[0-9]+}}, object=[[OBJ7:[0-9]+]], fn=1, type=0140  // CHECK-NEXT: d called141  // CHECK-NEXT: called: {{[0-9]+}}, object=[[OBJ7]], fn=1, type=1142  // CHECK-NOT: called: {{[0-9]+}}, object=[[OBJ7]]143 144  find_and_call(dso_handle_e, "_Z1ev");145  // CHECK-NEXT: called: {{[0-9]+}}, object=[[OBJ8:[0-9]+]], fn=1, type=0146  // CHECK-NEXT: e called147  // CHECK-NEXT: called: {{[0-9]+}}, object=[[OBJ9:[0-9]+]], fn=1, type=0148  // CHECK-NEXT: f called149  // CHECK-NEXT: called: {{[0-9]+}}, object=[[OBJ9]], fn=1, type=1150  // CHECK-NOT: called: {{[0-9]+}}, object=[[OBJ9]]151  // CHECK-NEXT: called: {{[0-9]+}}, object=[[OBJ8]], fn=1, type=1152  // CHECK-NOT: called: {{[0-9]+}}, object=[[OBJ8]]153 154  auto status = __xray_unpatch();155  printf("unpatching status: %d\n", static_cast<int32_t>(status));156  // CHECK-NEXT: unpatching status: 1157 158  dlclose(dso_handle_d);159  dlclose(dso_handle_e);160}161 162//--- libgenmacro.inc163#include <cstdio>164// Helper macros to quickly generate libraries containing a single function.165#define GENERATE_LIB(NAME)                                                     \166  [[clang::xray_always_instrument]] void NAME() { printf(#NAME " called\n"); }167 168#define GENERATE_LIB_WITH_CALL(NAME, FN)                                       \169  extern void FN();                                                            \170  [[clang::xray_always_instrument]] void NAME() {                              \171    printf(#NAME " called\n");                                                 \172    FN();                                                                      \173  }174 175//--- testliba.cpp176#include "libgenmacro.inc"177GENERATE_LIB(a)178 179//--- testlibb.cpp180#include "libgenmacro.inc"181GENERATE_LIB_WITH_CALL(b, c)182 183//--- testlibc.cpp184#include "libgenmacro.inc"185GENERATE_LIB(c)186 187//--- testlibd.cpp188#include "libgenmacro.inc"189GENERATE_LIB(d)190 191//--- testlibe.cpp192#include "libgenmacro.inc"193GENERATE_LIB_WITH_CALL(e, f)194 195//--- testlibf.cpp196#include "libgenmacro.inc"197GENERATE_LIB(f)198