this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

wrap_elf: Provide accessors to global variables exported from ELFs

+43 -8
+1
cmake/wrap_elf.cmake
··· 9 9 ${CMAKE_BINARY_DIR}/src/libelfloader/wrapgen/wrapgen 10 10 ${elfname} 11 11 ${CMAKE_CURRENT_BINARY_DIR}/${name}.c 12 + ${CMAKE_CURRENT_BINARY_DIR}/${name}_vars.h 12 13 DEPENDS 13 14 wrapgen 14 15 )
+42 -8
src/libelfloader/wrapgen/wrapgen.cpp
··· 21 21 22 22 // TODO: use wrapgen32 to generate 32-bit wrappers. 23 23 24 - void parse_elf(const char* elf, std::string& soname_out, std::set<std::string>& symbols_out); 24 + void parse_elf(const char* elf, std::string& soname_out, std::set<std::string>& functions_out, std::set<std::string>& vars_out); 25 25 void generate_wrapper(std::ofstream& output, const char* soname, const std::set<std::string>& symbols); 26 + void generate_var_wrappers(std::ofstream& output, std::ofstream& outputHeader, const std::set<std::string>& vars); 26 27 27 28 int main(int argc, const char** argv) 28 29 { 29 30 std::string elfLibrary; 30 - std::set<std::string> symbols; 31 + std::set<std::string> functions, vars; 31 32 std::string soname; 32 33 std::ofstream output; 33 34 34 - if (argc != 3) 35 + if (argc != 4) 35 36 { 36 - std::cerr << "Usage: " << argv[0] << " <library-name> <output-file>\n"; 37 + std::cerr << "Usage: " << argv[0] << " <library-name> <output-file> <var-access-header>\n"; 37 38 return 1; 38 39 } 39 40 ··· 75 76 dlclose(handle); 76 77 } 77 78 78 - parse_elf(elfLibrary.c_str(), soname, symbols); 79 - generate_wrapper(output, soname.c_str(), symbols); 79 + parse_elf(elfLibrary.c_str(), soname, functions, vars); 80 + generate_wrapper(output, soname.c_str(), functions); 81 + 82 + if (!vars.empty()) 83 + { 84 + std::ofstream outputHeader(argv[3]); 85 + if (!outputHeader.is_open()) 86 + throw std::runtime_error("Cannot open output macro header file"); 87 + 88 + generate_var_wrappers(output, outputHeader, vars); 89 + } 80 90 } 81 91 catch (const std::exception& e) 82 92 { ··· 87 97 return 0; 88 98 } 89 99 90 - void parse_elf(const char* elf, std::string& soname, std::set<std::string>& symbols) 100 + void parse_elf(const char* elf, std::string& soname, std::set<std::string>& symbols, std::set<std::string>& vars) 91 101 { 92 102 int fd; 93 103 const Elf64_Ehdr* ehdr; ··· 208 218 if (ELF64_ST_VISIBILITY(sym->st_other) != STV_DEFAULT) 209 219 continue; 210 220 211 - symbols.insert(strings + sym->st_name); 221 + if (ELF64_ST_TYPE(sym->st_info) == STT_FUNC) 222 + symbols.insert(strings + sym->st_name); 223 + else 224 + vars.insert(strings + sym->st_name); 212 225 } 213 226 214 227 break; ··· 263 276 "___elfname: .asciz \\\"" << soname << "\\\"\");\n"; 264 277 } 265 278 279 + void generate_var_wrappers(std::ofstream& output, std::ofstream& outputHeader, const std::set<std::string>& vars) 280 + { 281 + outputHeader << "#pragma once\n\n"; 282 + outputHeader << "#ifdef __cplusplus\n" 283 + "extern \"C\" {\n" 284 + "#endif\n\n"; 285 + 286 + for (const std::string& sym : vars) 287 + { 288 + output << "void* __elf_get_" << sym << "(void) {\n" 289 + "\treturn _elfcalls->dlsym_fatal(lib_handle, \"" << sym << "\");\n" 290 + "}\n\n"; 291 + 292 + outputHeader << "extern __typeof(" << sym << ")* __elf_get_" << sym << "(void);\n" 293 + "#define " << sym << "(*__elf_get_" << sym << "())\n\n"; 294 + } 295 + 296 + outputHeader << "\n\n#ifdef __cplusplus\n" 297 + "}\n" 298 + "#endif\n\n"; 299 + }