Skip to content

Commit

Permalink
look for symbols in dynsym table (#990)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
bgopesh and jrmadsen authored Jul 26, 2024
1 parent ba35562 commit dc67149
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 22 deletions.
34 changes: 27 additions & 7 deletions source/lib/common/elf_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,19 +89,25 @@ 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;
}

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;

Expand Down Expand Up @@ -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};
Expand All @@ -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)
{
Expand Down
13 changes: 7 additions & 6 deletions source/lib/common/elf_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
19 changes: 10 additions & 9 deletions source/lib/rocprofiler-sdk/registration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,31 +246,31 @@ 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)";
}
}

void* handle = dlopen(itr.c_str(), RTLD_NOLOAD | RTLD_LAZY);

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)
Expand All @@ -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);
}
}
Expand Down
23 changes: 23 additions & 0 deletions tests/c-tool/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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}")
11 changes: 11 additions & 0 deletions tests/tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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...")

0 comments on commit dc67149

Please sign in to comment.