summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAetias <aetias@outlook.com>2024-10-12 16:16:17 +0200
committerAetias <aetias@outlook.com>2024-10-12 16:16:17 +0200
commit74a29deff311fb7bc51028ae9bf4272d7835cb8c (patch)
tree5e0c551c877abb1bf04c79a111e5a9325191d73e
parentb2f57385a053a3d9bbb8166b0b139430e8db5fb2 (diff)
Remove `elfkill`
-rw-r--r--include/global.h2
-rw-r--r--src/00_Core/Actor/Actor.cpp4
-rw-r--r--src/Main/Actor/ActorType.cpp4
-rw-r--r--tools/elf/.gitignore2
-rw-r--r--tools/elf/Makefile22
-rw-r--r--tools/elf/elfkill.cpp297
6 files changed, 1 insertions, 330 deletions
diff --git a/include/global.h b/include/global.h
index 838b1732..4bb45910 100644
--- a/include/global.h
+++ b/include/global.h
@@ -7,8 +7,6 @@
#define SET_FLAG(arr, pos) ((arr)[((u32)(pos)) >> 5] |= 1 << ((pos) & 0x1f))
#define RESET_FLAG(arr, pos) ((arr)[((u32)(pos)) >> 5] &= ~(1 << ((pos) & 0x1f)))
-// KILL(name) causes a function to be excluded from the output ROM, see elfkill.cpp
-#define KILL(name)
// Prevent the IDE from reporting errors that the compiler/linker won't report
#ifdef __INTELLISENSE__
diff --git a/src/00_Core/Actor/Actor.cpp b/src/00_Core/Actor/Actor.cpp
index b15fee13..04994a03 100644
--- a/src/00_Core/Actor/Actor.cpp
+++ b/src/00_Core/Actor/Actor.cpp
@@ -53,7 +53,6 @@ const UnkStruct3 sUnkTable[] = {
{ 2, 2 },
};
-KILL(_ZN19Actor_UnkStruct_020C2Ev)
Actor_UnkStruct_020::Actor_UnkStruct_020():
mUnk_0c(-1),
mUnk_0d(0),
@@ -69,8 +68,7 @@ Actor_UnkStruct_020::Actor_UnkStruct_020():
}
}
-KILL(_ZN5ActorC1Ev)
-ARM Actor::Actor():
+ARM Actor::Actor() :
mType(ActorTypeId_Null),
mRef(-1, -1),
mUnk_010(0),
diff --git a/src/Main/Actor/ActorType.cpp b/src/Main/Actor/ActorType.cpp
index 39579811..69282898 100644
--- a/src/Main/Actor/ActorType.cpp
+++ b/src/Main/Actor/ActorType.cpp
@@ -2,10 +2,6 @@
ActorTypeList sActorTypeList;
-// Kill duplicate dtors
-KILL(_ZN9ActorTypeC2EjPFP5ActorvEPFivE)
-KILL(_ZN9ActorTypeD2Ev)
-
ARM ActorType::ActorType(ActorTypeId id, ActorCreateFunc create, unk32 (*unk_08)()) {
this->id = id;
this->create = create;
diff --git a/tools/elf/.gitignore b/tools/elf/.gitignore
deleted file mode 100644
index ea95eb29..00000000
--- a/tools/elf/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-elfkill
-elfkill.exe
diff --git a/tools/elf/Makefile b/tools/elf/Makefile
deleted file mode 100644
index 16cfdfca..00000000
--- a/tools/elf/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-CXX := g++
-CFLAGS := -std=c++17 -g -Wall -I../include -I../deps/elfio
-
-ifneq ($(DEBUG),1)
- CFLAGS += -O2 -DNDEBUG
-endif
-
-ifeq ($(OS),Windows_NT)
- ELFKILLFILE := elfkill.exe
-else
- ELFKILLFILE := elfkill
-endif
-
-.PHONY: all clean
-
-all: $(ELFKILLFILE)
-
-clean:
- rm -f $(ELFKILLFILE)
-
-$(ELFKILLFILE): elfkill.cpp
- $(CXX) $(CFLAGS) -o $(ELFKILLFILE) elfkill.cpp
diff --git a/tools/elf/elfkill.cpp b/tools/elf/elfkill.cpp
deleted file mode 100644
index d86d378d..00000000
--- a/tools/elf/elfkill.cpp
+++ /dev/null
@@ -1,297 +0,0 @@
-#include <iostream> // cout, cerr, endl
-#include <iomanip> // setw
-#include <vector> // vector
-#include <string> // string
-#include <unordered_set> // unordered_set
-#include <cstring> // strcmp, strncpy
-#include <fstream> // ifstream
-#include <cstdio> // remove
-
-#include <elfio/elfio.hpp>
-#include <elfio/elfio_dump.hpp>
-
-#define VERSION "1.0"
-
-using namespace ELFIO;
-
-struct SymbolSection {
- Elf_Half index;
- section *elfSection;
- std::string name;
-
- bool Get(const elfio &elf, Elf_Half index) {
- this->index = index;
-
- elfSection = elf.sections[index];
- if (elfSection == nullptr) {
- std::cerr << "Failed to get section " << index << std::endl;
- return false;
- }
-
- name = elfSection->get_name();
- return true;
- }
-
- bool SetName(const elfio &elf, const std::string &name) {
- elfSection->set_name(name);
- this->name = name;
-
- Elf_Word nameIndex = elfSection->get_name_string_offset();
-
- section *shstrtab = elf.sections[".shstrtab"];
- if (shstrtab == nullptr) {
- std::cerr << "Failed to get string section" << std::endl;
- return false;
- }
-
- string_section_accessor strAccessor(shstrtab);
- const char *tabStr = strAccessor.get_string(nameIndex);
- size_t len = strlen(tabStr);
-
- if (len < name.length()) {
- std::cerr << "Cannot rename section " << tabStr << " because it is shorter than " << name << std::endl;
- return false;
- }
-
- // HACK: Strings shorter than `name` can't be renamed due to lack of space
- strncpy((char*) tabStr, name.c_str(), len);
- return true;
- }
-};
-
-struct Symbol {
- Elf_Xword index;
- std::string name;
- Elf64_Addr value;
- Elf_Xword size;
- unsigned char bind;
- unsigned char type;
- SymbolSection section;
- unsigned char other;
-
- bool Get(const elfio &elf, const symbol_section_accessor &accessor, Elf_Xword index) {
- this->index = index;
-
- if (!accessor.get_symbol(index, name, value, size, bind, type, section.index, other)) {
- std::cerr << "Failed to get symbol at index " << index << std::endl;
- return false;
- }
-
- if (!section.Get(elf, section.index)) {
- std::cerr << "...for symbol '" << name << "'" << std::endl;
- return false;
- }
-
- return true;
- }
-
- static void PrintHeader() {
- std::cout
- << std::setw(75) << "name"
- << std::setw(6) << "value"
- << std::setw(6) << "size"
- << std::setw(5) << "bind"
- << std::setw(5) << "type"
- << std::setw(8) << "section"
- << std::setw(12) << ""
- << std::setw(6) << "other"
- << std::endl;
- }
-
- void Print() const {
- std::cout
- << std::setw(75) << name
- << std::setw(6) << value
- << std::setw(6) << size
- << std::setw(5) << (int) bind
- << std::setw(5) << (int) type
- << std::setw(5) << section.index << ' '
- << std::setw(14) << std::left << section.name << std::right
- << std::setw(6) << (int) other
- << std::endl;
- }
-};
-
-bool GetFunctionSymbols(const elfio &elf, std::vector<Symbol> &outSymbols) {
- section *symtab = elf.sections[".symtab"];
- if (symtab == nullptr) {
- std::cerr << "No section called .symtab" << std::endl;
- return false;
- }
-
- symbol_section_accessor symAccessor(elf, symtab);
- std::vector<Symbol> symbols;
- for (Elf_Xword i = 0; i < symAccessor.get_symbols_num(); ++i) {
- Symbol symbol;
- if (!symbol.Get(elf, symAccessor, i)) return false;
-
- if (symbol.name.find("@", 0) == 0) continue;
- if (symbol.name.find("$", 0) == 0) continue;
- if (symbol.name.find(".", 0) == 0) continue;
- if (symbol.section.name != ".text" && symbol.section.name != ".data") continue;
-
- symbols.push_back(symbol);
- }
-
- outSymbols = symbols;
- return true;
-}
-
-bool FindSymbolsToKill(const char *srcFile, std::unordered_set<std::string> &outSymbolsToKill) {
- std::ifstream file(srcFile);
-
- const std::string killMacro = "KILL(";
- const std::string lineComment = "//";
- std::string line;
- size_t row = 0;
- std::unordered_set<std::string> symbolsToKill;
- while (std::getline(file, line)) {
- row += 1;
- size_t endOffset = 0;
- while (true) {
- size_t macroOffset = line.find(killMacro, endOffset);
- if (macroOffset == std::string::npos) break;
-
- size_t commentOffset = line.find(lineComment, endOffset);
- if (macroOffset > commentOffset) break;
-
- size_t symbolOffset = macroOffset + killMacro.length();
- symbolOffset = line.find_first_not_of(" \t", symbolOffset);
- if (symbolOffset == std::string::npos) {
- std::cerr
- << srcFile << ':' << row << ':' << macroOffset + 1
- << ": Expected non-whitespace character after " << killMacro << std::endl;
- return false;
- }
-
- endOffset = line.find_first_of(" \t)", symbolOffset);
- if (endOffset == std::string::npos) {
- std::cerr
- << srcFile << ':' << row << ':' << symbolOffset + 1
- << ": Expected whitespace character or ')' after kill symbol" << std::endl;
- return false;
- }
-
- std::string symbolToKill = line.substr(symbolOffset, endOffset - symbolOffset);
- symbolsToKill.insert(symbolToKill);
- }
- }
-
- file.close();
- outSymbolsToKill = symbolsToKill;
- return true;
-}
-
-bool KillFunctionSymbols(
- const elfio &elf,
- std::vector<Symbol> &symbols,
- std::unordered_set<std::string> &symbolsToKill,
- const char *srcFile
-) {
- for (Symbol &symbol : symbols) {
- auto it = symbolsToKill.find(symbol.name);
- if (it == symbolsToKill.end()) continue;
-
- if (!symbol.section.SetName(elf, ".dead")) return false;
- symbolsToKill.erase(it);
- }
-
- if (symbolsToKill.empty()) return true;
-
- std::cerr << srcFile << ": the following functions couldn't be killed because they do not exist:\n";
- for (const std::string &symbolToKill : symbolsToKill) {
- std::cerr << " " << symbolToKill << '\n';
- }
- std::cerr << std::endl;
- return false;
-}
-
-bool DeleteElf(const char *elfFile) {
- // Delete ELF file so the Makefile doesn't skip elfkill on next build
- if (std::remove(elfFile) == 0) return true;
- std::cerr << "Failed to delete ELF '" << elfFile << "' upon previous error" << std::endl;
- return false;
-}
-
-void PrintUsage(const char *program) {
- std::cout
- << "elfkill " VERSION "\n"
- << "\n"
- << "Usage: " << program << " -s SRCFILE -e ELFFILE\n"
- << " -s SRCFILE\tSource C/C++ file\n"
- << " -e ELFFILE\tELF file corresponding to SRCFILE\n"
- << std::endl;
-}
-
-int main(int argc, const char **argv) {
- const char *program = argv[0];
- if (argc == 1) {
- PrintUsage(program);
- return 0;
- }
- const char *srcFile = nullptr;
- const char *elfFile = nullptr;
- for (int i = 1; i < argc; ++i) {
- if (strcmp(argv[i], "-s") == 0) {
- if (++i >= argc) {
- std::cerr << "Expected filename after -s" << std::endl;
- return 1;
- }
- srcFile = argv[i];
- } else if (strcmp(argv[i], "-e") == 0) {
- if (++i >= argc) {
- std::cerr << "Expected filename after -e" << std::endl;
- return 1;
- }
- elfFile = argv[i];
- } else {
- std::cerr << "Unknown option '" << argv[i] << "'" << std::endl;
- return 1;
- }
- }
- if (srcFile == nullptr) {
- PrintUsage(program);
- std::cerr << "Please provide a source file, see usage above" << std::endl;
- return 1;
- }
- if (elfFile == nullptr) {
- PrintUsage(program);
- std::cerr << "Please provide an ELF file, see usage above" << std::endl;
- return 1;
- }
-
- elfio elf;
- if (!elf.load(elfFile)) {
- std::cerr << "Failed to load ELF file '" << elfFile << "'" << std::endl;
- return 1;
- }
-
- std::vector<Symbol> symbols;
- if (!GetFunctionSymbols(elf, symbols)) {
- DeleteElf(elfFile);
- return 1;
- }
-
- // Symbol::PrintHeader();
- // for (const Symbol &symbol : symbols) {
- // symbol.Print();
- // }
- // return 0;
-
- std::unordered_set<std::string> symbolsToKill;
- if (!FindSymbolsToKill(srcFile, symbolsToKill)) {
- DeleteElf(elfFile);
- return 1;
- }
- if (!KillFunctionSymbols(elf, symbols, symbolsToKill, srcFile)) {
- DeleteElf(elfFile);
- return 1;
- }
-
- // Symbol::PrintHeader();
- // for (const Symbol &symbol : symbols) {
- // symbol.Print();
- // }
-
- elf.save(elfFile);
-}