look for symbols in dynsym table (#990)

* look for symbols in dynsym table

* checking both symtab and dynsym

* Avoid symbol duplication in non stripped binaries

* clang-format

* Minor elf_utils.cpp updates

- use 'else if' instead of 'if'
- logging tweaks

* Update registration

- tweak logging

* Update testing

- strip the rocprofiler-sdk-c-tool library
- add test-c-tool-rocp-tool-lib-execute test which does NOT LD_PRELOAD the library (uses only ROCP_TOOL_LIBRARIES instead)

---------

Co-authored-by: Jonathan R. Madsen <jonathanrmadsen@gmail.com>

[ROCm/rocprofiler-sdk commit: dc671497da]
This commit is contained in:
Gopesh Bhardwaj
2024-07-26 10:21:04 +05:30
zatwierdzone przez GitHub
rodzic 185094eee1
commit 2393b2ee45
5 zmienionych plików z 78 dodań i 22 usunięć
@@ -89,6 +89,11 @@ ElfInfo::has_symbol(std::regex&& _re) const
{
if(!itr.name.empty() && std::regex_search(itr.name, _re)) return true;
}
// For stripped binaries
for(const auto& itr : dynamic_symbol_entries)
{
if(!itr.name.empty() && std::regex_search(itr.name, _re)) return true;
}
return false;
}
@@ -96,12 +101,13 @@ ElfInfo::has_symbol(std::regex&& _re) const
ElfInfo
read(const std::string& _inp)
{
auto _info = ElfInfo{_inp};
auto& reader = _info.reader;
auto& sections = _info.sections;
auto& symbol_entries = _info.symbol_entries;
auto& dynamic_entries = _info.dynamic_entries;
auto& reloc_entries = _info.reloc_entries;
auto _info = ElfInfo{_inp};
auto& reader = _info.reader;
auto& sections = _info.sections;
auto& symbol_entries = _info.symbol_entries;
auto& dynamic_symbol_entries = _info.dynamic_symbol_entries;
auto& dynamic_entries = _info.dynamic_entries;
auto& reloc_entries = _info.reloc_entries;
ROCP_TRACE << "\nReading " << _inp;
@@ -148,10 +154,17 @@ read(const std::string& _inp)
if(psec->get_type() == ELFIO::SHT_SYMTAB)
{
const ELFIO::symbol_section_accessor _symbols(reader, psec);
ROCP_TRACE << " Number of symbol_entries: " << _symbols.get_symbols_num();
ROCP_TRACE << " Number of symbol entries: " << _symbols.get_symbols_num();
for(ELFIO::Elf_Xword k = 0; k < _symbols.get_symbols_num(); ++k)
symbol_entries.emplace_back(k, _symbols);
}
else if(psec->get_type() == ELFIO::SHT_DYNSYM)
{
const ELFIO::symbol_section_accessor _symbols(reader, psec);
ROCP_TRACE << " Number of dynamic symbol entries: " << _symbols.get_symbols_num();
for(ELFIO::Elf_Xword k = 0; k < _symbols.get_symbols_num(); ++k)
dynamic_symbol_entries.emplace_back(k, _symbols);
}
else if(psec->get_type() == ELFIO::SHT_DYNAMIC)
{
const ELFIO::dynamic_section_accessor dynamic{reader, psec};
@@ -175,6 +188,13 @@ read(const std::string& _inp)
ROCP_TRACE << " [" << k << "] " << symbol_entries.at(k).name;
}
ROCP_TRACE << "Dynamic Symbols:";
for(size_t k = 0; k < dynamic_symbol_entries.size(); ++k)
{
if(!dynamic_symbol_entries.at(k).name.empty())
ROCP_TRACE << " [" << k << "] " << dynamic_symbol_entries.at(k).name;
}
ROCP_TRACE << "Dynamic entries:";
for(size_t k = 0; k < dynamic_entries.size(); ++k)
{
@@ -86,12 +86,13 @@ struct ElfInfo
{
explicit ElfInfo(std::string);
std::string filename = {};
ELFIO::elfio reader = {};
std::vector<Section*> sections = {};
std::vector<SymbolEntry> symbol_entries = {};
std::vector<DynamicEntry> dynamic_entries = {};
std::vector<RelocationEntry> reloc_entries = {};
std::string filename = {};
ELFIO::elfio reader = {};
std::vector<Section*> sections = {};
std::vector<SymbolEntry> symbol_entries = {};
std::vector<SymbolEntry> dynamic_symbol_entries = {};
std::vector<DynamicEntry> dynamic_entries = {};
std::vector<RelocationEntry> reloc_entries = {};
bool has_symbol(std::regex&&) const;
@@ -246,15 +246,16 @@ find_clients()
{
for(const auto& itr : env)
{
ROCP_INFO << "[env] searching " << itr << " for rocprofiler_configure";
ROCP_INFO << "[ROCP_TOOL_LIBRARIES] searching " << itr << " for rocprofiler_configure";
if(fs::exists(itr))
{
auto elfinfo = common::elf_utils::read(itr);
if(!elfinfo.has_symbol(std::regex{"^rocprofiler_configure$"}))
{
ROCP_FATAL << "rocprofiler tool library " << itr
<< " did not contain rocprofiler_configure symbol";
ROCP_FATAL << "[ROCP_TOOL_LIBRARIES] rocprofiler-sdk tool library '" << itr
<< "' did not contain rocprofiler_configure symbol (search method: "
"ELF parsing)";
}
}
@@ -262,15 +263,14 @@ find_clients()
if(!handle)
{
ROCP_WARNING << "[env] " << itr
<< " is not already loaded, doing a local lazy dlopen...";
ROCP_INFO << "[ROCP_TOOL_LIBRARIES] '" << itr
<< "' is not already loaded, doing a local lazy dlopen...";
handle = dlopen(itr.c_str(), RTLD_LOCAL | RTLD_LAZY);
}
if(!handle)
{
ROCP_ERROR << "error dlopening " << itr;
continue;
ROCP_FATAL << "[ROCP_TOOL_LIBRARIES] error dlopening '" << itr << "'";
}
for(const auto& ditr : data)
@@ -286,8 +286,9 @@ find_clients()
{
auto _sym = rocprofiler_configure_dlsym(handle);
// FATAL bc they explicitly said this was a tool library
ROCP_FATAL_IF(!_sym) << "rocprofiler tool library " << itr
<< " did not contain rocprofiler_configure symbol";
ROCP_FATAL_IF(!_sym)
<< "[ROCP_TOOL_LIBRARIES] rocprofiler-sdk tool library '" << itr
<< "' did not contain rocprofiler_configure symbol (search method: dlsym)";
if(is_unique_configure_func(_sym)) emplace_client(itr, handle, _sym);
}
}
@@ -37,3 +37,26 @@ set_tests_properties(
"Test C tool \\(priority=0\\) is using rocprofiler-sdk v([0-9]+\\.[0-9]+\\.[0-9]+)"
FAIL_REGULAR_EXPRESSION
"${ROCPROFILER_DEFAULT_FAIL_REGEX}")
# this test uses ROCP_TOOL_LIBRARIES instead of LD_PRELOAD
add_test(NAME test-c-tool-rocp-tool-lib-execute COMMAND $<TARGET_FILE:transpose> 1)
set(c-tool-rocp-tool-lib-env
"${ROCPROFILER_MEMCHECK_PRELOAD_ENV}"
"ROCP_TOOL_LIBRARIES=$<TARGET_FILE:rocprofiler-sdk-c-tool>"
"LD_LIBRARY_PATH=$<TARGET_FILE_DIR:rocprofiler-sdk::rocprofiler-shared-library>:$ENV{LD_LIBRARY_PATH}"
)
set_tests_properties(
test-c-tool-rocp-tool-lib-execute
PROPERTIES
TIMEOUT
45
LABELS
"integration-tests"
ENVIRONMENT
"${c-tool-rocp-tool-lib-env}"
PASS_REGULAR_EXPRESSION
"Test C tool \\(priority=0\\) is using rocprofiler-sdk v([0-9]+\\.[0-9]+\\.[0-9]+)"
FAIL_REGULAR_EXPRESSION
"${ROCPROFILER_DEFAULT_FAIL_REGEX}")
@@ -38,3 +38,14 @@ set_target_properties(
VERSION
${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}
INSTALL_RPATH "\$ORIGIN:\$ORIGIN/..")
if(NOT CMAKE_STRIP)
find_program(CMAKE_STRIP NAMES strip REQUIRED)
endif()
add_custom_command(
TARGET rocprofiler-sdk-c-tool
POST_BUILD
COMMAND ${CMAKE_STRIP} $<TARGET_FILE:rocprofiler-sdk-c-tool>
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Stripping rocprofiler-sdk-c-tool...")