diff --git a/symtab/CMakeLists.txt b/symtab/CMakeLists.txt index b5b9cd2..6822479 100644 --- a/symtab/CMakeLists.txt +++ b/symtab/CMakeLists.txt @@ -7,6 +7,7 @@ add_executable(st_insertion_operators insertion_operators.cpp) target_link_libraries(st_insertion_operators PRIVATE Dyninst::symtabAPI) add_subdirectory(enum) +add_subdirectory(module) add_executable(symtab_includes includes.cpp) target_link_libraries(symtab_includes PRIVATE Dyninst::symtabAPI) diff --git a/symtab/module/CMakeLists.txt b/symtab/module/CMakeLists.txt new file mode 100644 index 0000000..8ffa110 --- /dev/null +++ b/symtab/module/CMakeLists.txt @@ -0,0 +1,17 @@ +project(module) + +add_executable(module_parser parser.cpp) +target_link_libraries(module_parser PRIVATE Dyninst::symtabAPI) +add_test(NAME module_parser COMMAND module_parser) + +add_library(lib1func1 OBJECT lib1.cpp) +target_compile_definitions(lib1func1 PRIVATE FUNC1) +target_compile_options(lib1func1 PRIVATE -g) + +add_library(lib1func2 OBJECT lib1.cpp) +target_compile_definitions(lib1func2 PRIVATE FUNC2) +target_compile_options(lib1func2 PRIVATE -g) + +add_library(moduletest SHARED lib2.cpp) +target_link_libraries(moduletest PRIVATE lib1func1 lib1func2) +target_compile_options(moduletest PRIVATE -g) diff --git a/symtab/module/lib1.cpp b/symtab/module/lib1.cpp new file mode 100644 index 0000000..a035c35 --- /dev/null +++ b/symtab/module/lib1.cpp @@ -0,0 +1,7 @@ +#ifdef FUNC1 +extern "C" void lib1func1() {} +#endif + +#ifdef FUNC2 +extern "C" void lib1func2() {} +#endif diff --git a/symtab/module/lib2.cpp b/symtab/module/lib2.cpp new file mode 100644 index 0000000..3d96c66 --- /dev/null +++ b/symtab/module/lib2.cpp @@ -0,0 +1,2 @@ +extern "C" void lib2func1() {} +extern "C" void lib2func2() {} diff --git a/symtab/module/parser.cpp b/symtab/module/parser.cpp new file mode 100644 index 0000000..d03f0a4 --- /dev/null +++ b/symtab/module/parser.cpp @@ -0,0 +1,83 @@ +#include "Module.h" +#include "Symtab.h" +#include +#include +#include +#include +#include +#include + +namespace st = Dyninst::SymtabAPI; +namespace bf = boost::filesystem; + +int main() { + st::Symtab *obj{}; + if (!st::Symtab::openFile(obj, "libmoduletest.so")) { + std::cerr << "Unable to open 'libmoduletest.so'\n"; + return -1; + } + + constexpr auto num_expected = 4; + + std::vector modules; + obj->getAllModules(modules); + + if (modules.size() != num_expected) { + std::cerr << "Found " << modules.size() << " modules, but expected " + << num_expected << '\n'; + return -1; + } + + std::unordered_set expected{"lib1.cpp", "lib2.cpp", + "libmoduletest.so"}; + + for (auto *m : modules) { + auto const &basename = bf::path(m->fileName()).stem(); + auto const &extension = bf::path(m->fileName()).extension(); + auto const &name = basename.string() + extension.string(); + if (expected.count(name) == 0) { + std::cerr << "Module '" << m->fileName() << "' not found.\n"; + return -1; + } + } + + std::vector funcs; + obj->getAllFunctions(funcs); + + std::unordered_map funcs_by_mod{ + {"lib1func1", "lib1.cpp"}, + {"lib1func2", "lib1.cpp"}, + {"lib2func1", "lib2.cpp"}, + {"lib2func2", "lib2.cpp"}, + }; + + auto find_func = [&funcs](std::string const &name) -> st::Function* { + auto i = std::find_if(funcs.begin(), funcs.end(), [&name](st::Function *f) { + return f->getName() == name; + }); + if (i != funcs.end()) + return *i; + return nullptr; + }; + + auto find_mod = [&funcs_by_mod](st::Function *f, std::string const &name) { + auto *m = f->getModule(); + auto const &basename = bf::path(m->fileName()).stem(); + auto const &extension = bf::path(m->fileName()).extension(); + auto const &file = basename.string() + extension.string(); + return file == name; + }; + + for (auto const &fm : funcs_by_mod) { + auto *f = find_func(fm.first); + if (!f) { + std::cerr << "symtab doesn't contain function '" << fm.first << "'\n"; + return -1; + } + if (!find_mod(f, fm.second)) { + std::cerr << "Module '" << fm.second << "' doesn't contain function '" + << fm.first << "'\n"; + return -1; + } + } +}