diff options
-rw-r--r-- | eval/CMakeLists.txt | 1 | ||||
-rw-r--r-- | eval/src/tests/eval/addr_to_symbol/CMakeLists.txt | 9 | ||||
-rw-r--r-- | eval/src/tests/eval/addr_to_symbol/addr_to_symbol_test.cpp | 25 | ||||
-rw-r--r-- | eval/src/vespa/eval/eval/llvm/CMakeLists.txt | 1 | ||||
-rw-r--r-- | eval/src/vespa/eval/eval/llvm/addr_to_symbol.cpp | 57 | ||||
-rw-r--r-- | eval/src/vespa/eval/eval/llvm/addr_to_symbol.h | 19 |
6 files changed, 112 insertions, 0 deletions
diff --git a/eval/CMakeLists.txt b/eval/CMakeLists.txt index 4af337dcb67..4b2127d8a3a 100644 --- a/eval/CMakeLists.txt +++ b/eval/CMakeLists.txt @@ -12,6 +12,7 @@ vespa_define_module( TESTS src/tests/ann + src/tests/eval/addr_to_symbol src/tests/eval/aggr src/tests/eval/array_array_map src/tests/eval/cell_type_space diff --git a/eval/src/tests/eval/addr_to_symbol/CMakeLists.txt b/eval/src/tests/eval/addr_to_symbol/CMakeLists.txt new file mode 100644 index 00000000000..eddace54cfe --- /dev/null +++ b/eval/src/tests/eval/addr_to_symbol/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(eval_addr_to_symbol_test_app TEST + SOURCES + addr_to_symbol_test.cpp + DEPENDS + vespaeval + GTest::GTest +) +vespa_add_test(NAME eval_addr_to_symbol_test_app COMMAND eval_addr_to_symbol_test_app) diff --git a/eval/src/tests/eval/addr_to_symbol/addr_to_symbol_test.cpp b/eval/src/tests/eval/addr_to_symbol/addr_to_symbol_test.cpp new file mode 100644 index 00000000000..fade4bf961f --- /dev/null +++ b/eval/src/tests/eval/addr_to_symbol/addr_to_symbol_test.cpp @@ -0,0 +1,25 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <vespa/eval/eval/llvm/addr_to_symbol.h> +#include <vespa/vespalib/gtest/gtest.h> + +using namespace vespalib::eval; + +TEST(AddrToSymbol, null_ptr) { + auto sym = addr_to_symbol(nullptr); + EXPECT_EQ(sym, "<nullptr>"); +} + +TEST(AddrToSymbol, global_symbol) { + auto sym = addr_to_symbol((const void *)addr_to_symbol); + fprintf(stderr, "global symbol: %s\n", sym.c_str()); + EXPECT_TRUE(sym.find("addr_to_symbol") < sym.size()); +} + +TEST(AddrToSymbol, local_symbol) { + auto sym = addr_to_symbol(get_addr_of_local_test_symbol()); + fprintf(stderr, "local symbol: %s\n", sym.c_str()); + EXPECT_TRUE(sym.find("my_local_test_symbol") < sym.size()); +} + +GTEST_MAIN_RUN_ALL_TESTS() diff --git a/eval/src/vespa/eval/eval/llvm/CMakeLists.txt b/eval/src/vespa/eval/eval/llvm/CMakeLists.txt index 898d18c9e4c..a3ca410842a 100644 --- a/eval/src/vespa/eval/eval/llvm/CMakeLists.txt +++ b/eval/src/vespa/eval/eval/llvm/CMakeLists.txt @@ -1,6 +1,7 @@ # Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. vespa_add_library(eval_eval_llvm OBJECT SOURCES + addr_to_symbol.cpp compile_cache.cpp compiled_function.cpp deinline_forest.cpp diff --git a/eval/src/vespa/eval/eval/llvm/addr_to_symbol.cpp b/eval/src/vespa/eval/eval/llvm/addr_to_symbol.cpp new file mode 100644 index 00000000000..566ab931837 --- /dev/null +++ b/eval/src/vespa/eval/eval/llvm/addr_to_symbol.cpp @@ -0,0 +1,57 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "addr_to_symbol.h" +#include <vespa/vespalib/util/classname.h> + +#include <dlfcn.h> +#include <llvm/Object/ObjectFile.h> + +using vespalib::demangle; +using llvm::object::ObjectFile; + +namespace vespalib::eval { + +namespace { + +void my_local_test_symbol() {} + +} // <unnamed> + +vespalib::string addr_to_symbol(const void *addr) { + if (addr == nullptr) { + return {"<nullptr>"}; + } + Dl_info info; + memset(&info, 0, sizeof(info)); + if (dladdr(addr, &info) == 0) { + // address not in any shared object + return {"<invalid>"}; + } + if (info.dli_sname != nullptr) { + // address of global symbol + return demangle(info.dli_sname); + } + // find addr offset into shared object + uint64_t offset = ((const char *)addr) - ((const char *)info.dli_fbase); + // use llvm to look up local symbols... + auto file = ObjectFile::createObjectFile(info.dli_fname); + if (!file) { + return {"<object_error>"}; + } + auto symbols = file.get().getBinary()->symbols(); + for (const auto &symbol: symbols) { + auto sym_name = symbol.getName(); + auto sym_addr = symbol.getAddress(); + if (sym_name && sym_addr && (*sym_addr == offset)) { + return demangle(sym_name->str().c_str()); + } + } + // could not resolve symbol + return {"<unknown>"}; +} + +const void *get_addr_of_local_test_symbol() { + return (const void *) my_local_test_symbol; +} + +} diff --git a/eval/src/vespa/eval/eval/llvm/addr_to_symbol.h b/eval/src/vespa/eval/eval/llvm/addr_to_symbol.h new file mode 100644 index 00000000000..29c83be7260 --- /dev/null +++ b/eval/src/vespa/eval/eval/llvm/addr_to_symbol.h @@ -0,0 +1,19 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <vespa/vespalib/stllike/string.h> + +namespace vespalib::eval { + +// Map an address to a symbolic name. +// Intended for function pointers. + +vespalib::string addr_to_symbol(const void *addr); + +// Return the address of a local symbol. +// Used for testing. + +const void *get_addr_of_local_test_symbol(); + +} |