From 993dd2352a64bdccb30038e542a1d9c18a84567a Mon Sep 17 00:00:00 2001 From: Tim Haines Date: Sun, 21 Jan 2024 12:14:39 -0600 Subject: [PATCH] Add symtabAPI --- CMakeLists.txt | 1 + symtabAPI/CMakeLists.txt | 21 +++++++++++++ symtabAPI/addSymbol.cpp | 60 ++++++++++++++++++++++++++++++++++++ symtabAPI/addType.cpp | 57 ++++++++++++++++++++++++++++++++++ symtabAPI/printLineInfo.cpp | 41 ++++++++++++++++++++++++ symtabAPI/printLocalVars.cpp | 54 ++++++++++++++++++++++++++++++++ symtabAPI/printSymbols.cpp | 48 +++++++++++++++++++++++++++++ 7 files changed, 282 insertions(+) create mode 100644 symtabAPI/CMakeLists.txt create mode 100644 symtabAPI/addSymbol.cpp create mode 100644 symtabAPI/addType.cpp create mode 100644 symtabAPI/printLineInfo.cpp create mode 100644 symtabAPI/printLocalVars.cpp create mode 100644 symtabAPI/printSymbols.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f9e9a44..2c2b706 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ add_subdirectory(proccontrol) add_subdirectory(readGlobalVariables) add_subdirectory(stackwalker) add_subdirectory(symbolicEvalInstructions) +add_subdirectory(symtabAPI) add_subdirectory(tracetool) add_subdirectory(unstrip) add_subdirectory(unusedArgs) diff --git a/symtabAPI/CMakeLists.txt b/symtabAPI/CMakeLists.txt new file mode 100644 index 0000000..f880e08 --- /dev/null +++ b/symtabAPI/CMakeLists.txt @@ -0,0 +1,21 @@ +project(symtabAPI LANGUAGES CXX) + +add_executable(printSymbols printSymbols.cpp) +target_compile_options(printSymbols PRIVATE ${EXAMPLES_WARNING_FLAGS}) +target_link_libraries(printSymbols PRIVATE Dyninst::symtabAPI) + +add_executable(addSymbol addSymbol.cpp) +target_compile_options(addSymbol PRIVATE ${EXAMPLES_WARNING_FLAGS}) +target_link_libraries(addSymbol PRIVATE Dyninst::symtabAPI) + +add_executable(addType addType.cpp) +target_compile_options(addType PRIVATE ${EXAMPLES_WARNING_FLAGS}) +target_link_libraries(addType PRIVATE Dyninst::symtabAPI) + +add_executable(printLineInfo printLineInfo.cpp) +target_compile_options(printLineInfo PRIVATE ${EXAMPLES_WARNING_FLAGS}) +target_link_libraries(printLineInfo PRIVATE Dyninst::symtabAPI) + +add_executable(printLocalVars printLocalVars.cpp) +target_compile_options(printLocalVars PRIVATE ${EXAMPLES_WARNING_FLAGS}) +target_link_libraries(printLocalVars PRIVATE Dyninst::symtabAPI) diff --git a/symtabAPI/addSymbol.cpp b/symtabAPI/addSymbol.cpp new file mode 100644 index 0000000..f7a889c --- /dev/null +++ b/symtabAPI/addSymbol.cpp @@ -0,0 +1,60 @@ +#include "Symbol.h" +#include "Symtab.h" + +#include +#include + +namespace st = Dyninst::SymtabAPI; + +std::vector find_all_variables(st::Module* m) { + std::vector vars; + constexpr auto name_type = st::NameType::anyName; + constexpr bool is_regex = true; + constexpr bool case_match = false; + m->findVariablesByName(vars, "*", name_type, is_regex, case_match); + return vars; +} + +void print_module_vars(std::vector const& modules) { + for(auto* m : modules) { + std::cout << "Module '" << m->fileName() << "'\n"; + for(auto* v : find_all_variables(m)) { + std::cout << *v << '\n'; + } + std::cout << "\n\n"; + } +} + +int main(int argc, char** argv) { + if(argc != 2) { + std::cerr << "Usage: " << argv[0] << " file\n"; + return -1; + } + + auto file_name = argv[1]; + + st::Symtab* obj{}; + + if(!st::Symtab::openFile(obj, file_name)) { + std::cerr << "Unable to open " << file_name << '\n'; + return -1; + } + + std::vector modules; + obj->getAllModules(modules); + + std::cout << "**** BEFORE ****\n"; + print_module_vars(modules); + std::cout << "*****************\n\n"; + + for(auto* m : modules) { + obj->createVariable("newIntVar", // Name of new variable + 0x12345, // Offset from data section + sizeof(int), // Size of symbol + m); + } + + std::cout << "**** AFTER ****\n"; + print_module_vars(modules); + std::cout << "***************\n"; +} diff --git a/symtabAPI/addType.cpp b/symtabAPI/addType.cpp new file mode 100644 index 0000000..f1e04e2 --- /dev/null +++ b/symtabAPI/addType.cpp @@ -0,0 +1,57 @@ +#include "Symtab.h" +#include "Type.h" +#include "concurrent.h" + +#include +#include + +namespace st = Dyninst::SymtabAPI; + +int main(int argc, char** argv) { + if(argc != 2) { + std::cerr << "Usage: " << argv[0] << " file\n"; + return -1; + } + + auto file_name = argv[1]; + + st::Symtab* obj{}; + + if(!st::Symtab::openFile(obj, file_name)) { + std::cerr << "Unable to open " << file_name << '\n'; + return -1; + } + + /** Create a new struct type + * + * struct struct1 { + * int field1, + * int field2[10] + * }; + */ + + // Find a handle to the integer type + st::Type *lookupType; + obj->findType(lookupType, "int"); + + // Convert to a scalar + auto* intType = lookupType->getScalarType(); + + //create a new array type for 'field2' + std::string iarr_name{"intArray"}; + auto* intArray = st::typeArray::create(iarr_name, intType, 0, 9, obj); + + // container to hold names and types of the new structure type + using field_t = std::pair; + Dyninst::dyn_c_vector fields; + auto f1 = field_t{"field1", intType}; + auto f2 = field_t{"field2", intArray}; + + fields.emplace_back(&f1); + fields.emplace_back(&f2); + + //create the structure type + std::string struct_name{"struct1"}; + auto* struct1 = st::typeStruct::create(struct_name, fields, obj); + obj->addType(struct1); +} diff --git a/symtabAPI/printLineInfo.cpp b/symtabAPI/printLineInfo.cpp new file mode 100644 index 0000000..1a2e8c7 --- /dev/null +++ b/symtabAPI/printLineInfo.cpp @@ -0,0 +1,41 @@ +#include "LineInformation.h" +#include "Module.h" +#include "Symtab.h" + +#include +#include +#include + +namespace st = Dyninst::SymtabAPI; + +int main(int argc, char** argv) { + if(argc != 2) { + std::cerr << "Usage: " << argv[0] << " file\n"; + return -1; + } + + auto file_name = argv[1]; + + st::Symtab* obj{}; + + if(!st::Symtab::openFile(obj, file_name)) { + std::cerr << "Unable to open " << file_name << '\n'; + return -1; + } + + std::vector modules; + obj->getAllModules(modules); + + for(auto* m : modules) { + std::cout << "Module '" << m->fileName() << "'\n"; + auto* info = m->getLineInformation(); + if(!info) { + std::cout << " No line info\n"; + continue; + } + for(auto li = info->begin(); li != info->end(); ++li) { + st::Statement const* stmt = *li; + std::cout << *stmt << "\n"; + } + } +} diff --git a/symtabAPI/printLocalVars.cpp b/symtabAPI/printLocalVars.cpp new file mode 100644 index 0000000..a33ef0f --- /dev/null +++ b/symtabAPI/printLocalVars.cpp @@ -0,0 +1,54 @@ +#include "Symbol.h" +#include "Symtab.h" + +#include +#include + +namespace st = Dyninst::SymtabAPI; + +int main(int argc, char** argv) { + if(argc != 2) { + std::cerr << "Usage: " << argv[0] << " file\n"; + return -1; + } + + auto file_name = argv[1]; + + st::Symtab* obj{}; + + if(!st::Symtab::openFile(obj, file_name)) { + std::cerr << "Unable to open " << file_name << '\n'; + return -1; + } + + // Local variables in function 'bar' + std::vector funcs; + obj->findFunctionsByName(funcs, "bar"); + + for(auto* f : funcs) { + std::cout << f->getName() << '\n'; + std::vector local_vars; + f->getLocalVariables(local_vars); + for(auto* v : local_vars) { + std::cout << v->getName() << "\n"; + } + } + + // All local variables name 'x' + std::vector vars; + obj->findLocalVariable(vars, "x"); + + // Print the function and file they came from + for(auto* v : vars) { + for(auto loc : v->getLocationLists()) { + st::Function* f; + obj->getContainingFunction(loc.lowPC, f); + // clang-format off + std::cout << f->getName() << ", " + << v->getName() << ", " + << "[" << loc.lowPC << ", " << loc.hiPC << "] " + << v->getFileName() << "[" << v->getLineNum() << "]\n"; + // clang-format on + } + } +} diff --git a/symtabAPI/printSymbols.cpp b/symtabAPI/printSymbols.cpp new file mode 100644 index 0000000..1e3fc5c --- /dev/null +++ b/symtabAPI/printSymbols.cpp @@ -0,0 +1,48 @@ +#include "Symbol.h" +#include "Symtab.h" + +#include +#include + +namespace st = Dyninst::SymtabAPI; + +int main(int argc, char** argv) { + if(argc != 2) { + std::cerr << "Usage: " << argv[0] << " file\n"; + return -1; + } + + auto file_name = argv[1]; + + st::Symtab* obj{}; + + if(!st::Symtab::openFile(obj, file_name)) { + std::cerr << "Unable to open " << file_name << '\n'; + return -1; + } + + // search for a function with demangled (pretty) name "bar". + std::vector funcs; + if(!obj->findFunctionsByName(funcs, "bar")) { + std::cerr << "Didn't find function 'bar' in " << file_name << '\n'; + } + + for(auto* f : funcs) { + std::cout << f->getName() << '\n'; + } + + // search defined symbols for one with a mangled name like "bar". + std::vector syms; + constexpr bool is_regex = true; + constexpr auto symbol_type = st::Symbol::ST_UNKNOWN; + constexpr auto name_type = st::NameType::mangledName; + constexpr bool case_match = false; + constexpr bool include_undefined = false; + if(!obj->findSymbol(syms, "bar", symbol_type, name_type, is_regex, case_match, include_undefined)) { + std::cerr << "Didn't any symbol 'bar' in " << file_name << '\n'; + } + + for(auto* s : syms) { + std::cout << s->getMangledName() << '\n'; + } +}