From a00804a22da906034f7ab9e44af9b750c41db7e8 Mon Sep 17 00:00:00 2001 From: James Benton Date: Mon, 11 Jun 2018 15:36:21 +0100 Subject: [PATCH] readrpl: Add --exports-def to generate exports.def file for an rpl. --- tools/readrpl/CMakeLists.txt | 12 ++- tools/readrpl/generate_exports_def.cpp | 106 +++++++++++++++++++++++++ tools/readrpl/generate_exports_def.h | 8 ++ tools/readrpl/main.cpp | 29 ++++++- 4 files changed, 150 insertions(+), 5 deletions(-) create mode 100644 tools/readrpl/generate_exports_def.cpp create mode 100644 tools/readrpl/generate_exports_def.h diff --git a/tools/readrpl/CMakeLists.txt b/tools/readrpl/CMakeLists.txt index b2e55992..c4d0b0ca 100644 --- a/tools/readrpl/CMakeLists.txt +++ b/tools/readrpl/CMakeLists.txt @@ -1,10 +1,14 @@ project(readrpl) -file(GLOB_RECURSE SOURCE_FILES *.cpp) -file(GLOB_RECURSE HEADER_FILES *.h) - add_executable(readrpl - ${SOURCE_FILES} ${HEADER_FILES}) + generate_exports_def.cpp + generate_exports_def.h + main.cpp + print.cpp + print.h + readrpl.h + verify.cpp + verify.h) target_link_libraries(readrpl excmd diff --git a/tools/readrpl/generate_exports_def.cpp b/tools/readrpl/generate_exports_def.cpp new file mode 100644 index 00000000..b9099b3a --- /dev/null +++ b/tools/readrpl/generate_exports_def.cpp @@ -0,0 +1,106 @@ +#include "generate_exports_def.h" + +#include +#include +#include + +static const char * +sExportBlacklist[] = { + "__get_eh_globals", + "__get_eh_init_block", + "__get_eh_mem_manage", + "__get_eh_store_globals", + "__get_eh_store_globals_tdeh", + "__gh_errno_ptr", + "__gh_get_errno", + "__gh_iob_init", + "__gh_lock_init", + "__gh_set_errno", + "__ghsLock", + "__ghsUnlock", + "__ghs_at_exit", + "__ghs_at_exit_cleanup", + "__ghs_flock_create", + "__ghs_flock_destroy", + "__ghs_flock_file", + "__ghs_flock_ptr", + "__ghs_ftrylock_file", + "__ghs_funlock_file", + "__ghs_mtx_dst", + "__ghs_mtx_init", + "__ghs_mtx_lock", + "__ghs_mtx_unlock", + "__tls_get_addr", + "memclr", + "memcpy", + "memmove", + "memset", + "__atexit_cleanup", + "__cpp_exception_cleanup_ptr", + "__cpp_exception_init_ptr", + "__gh_FOPEN_MAX", + "__ghs_cpp_locks", + "__stdio_cleanup", + "_iob", + "_iob_lock", + "environ", + "errno", +}; + +static bool +inBlacklist(const char *name) +{ + for (auto i = 0u; i < sizeof(sExportBlacklist) / sizeof(sExportBlacklist[0]); ++i) { + if (strcmp(name, sExportBlacklist[i]) == 0) { + return true; + } + } + + return false; +} + +bool +generateExportsDef(const Rpl &rpl, + const std::string &rplName, + const std::string &outFileName) +{ + FILE *fh = fopen(outFileName.c_str(), "w"); + if (!fh) { + fmt::print("Failed to open {} for writing!", outFileName); + return false; + } + + fmt::print(fh, ":NAME {}\n", rplName); + + for (auto §ion : rpl.sections) { + if (section.header.type == elf::SHT_RPL_EXPORTS) { + auto exports = reinterpret_cast(section.data.data()); + auto strTab = section.data.data(); + + if (section.header.flags & elf::SHF_EXECINSTR) { + fmt::print(fh, "\n:TEXT\n"); + } else { + fmt::print(fh, "\n:DATA\n"); + } + + for (auto i = 0u; i < exports->count; ++i) { + if (exports->exports[i].name & 0x80000000) { + // Skip TLS exports for now. + continue; + } + + auto name = strTab + (exports->exports[i].name & 0x7FFFFFFF); + + if (inBlacklist(name)) { + fmt::print(fh, "//"); + } + + fmt::print(fh, "{}\n", name); + } + + } + } + + fclose(fh); + return true; +} diff --git a/tools/readrpl/generate_exports_def.h b/tools/readrpl/generate_exports_def.h new file mode 100644 index 00000000..581fa0fd --- /dev/null +++ b/tools/readrpl/generate_exports_def.h @@ -0,0 +1,8 @@ +#pragma once +#include "readrpl.h" +#include + +bool +generateExportsDef(const Rpl &rpl, + const std::string &rplName, + const std::string &outFileName); diff --git a/tools/readrpl/main.cpp b/tools/readrpl/main.cpp index 3b678714..35b501a5 100644 --- a/tools/readrpl/main.cpp +++ b/tools/readrpl/main.cpp @@ -1,4 +1,5 @@ #include "elf.h" +#include "generate_exports_def.h" #include "print.h" #include "verify.h" @@ -9,6 +10,22 @@ #include #include +static std::string +getFileBasename(std::string path) +{ + auto pos = path.find_last_of("\\/"); + if (pos != std::string::npos) { + path.erase(0, pos + 1); + } + + pos = path.rfind('.'); + if (pos != std::string::npos) { + path.erase(pos); + } + + return path; +} + uint32_t getSectionIndex(const Rpl &rpl, const Section §ion) @@ -109,7 +126,10 @@ int main(int argc, char **argv) .add_option("c,crc", description { "Display the RPL crc" }) .add_option("f,file-info", - description { "Display the RPL file info" }); + description { "Display the RPL file info" }) + .add_option("exports-def", + description { "Generate exports.def for wut library linking" }, + value {}); parser.default_command() .add_argument("path", @@ -267,5 +287,12 @@ int main(int argc, char **argv) } } + if (options.has("exports-def")) { + auto output = options.get("exports-def"); + if (!generateExportsDef(rpl, getFileBasename(path), output)) { + return -1; + } + } + return 0; }