diff --git a/tools/psyq-obj-parser/psyq-obj-parser.cc b/tools/psyq-obj-parser/psyq-obj-parser.cc index 6f5eb4b64..efe24be75 100644 --- a/tools/psyq-obj-parser/psyq-obj-parser.cc +++ b/tools/psyq-obj-parser/psyq-obj-parser.cc @@ -125,7 +125,8 @@ struct PsyqLnkFile { struct Expression; /* The main parser entry point; will return nullptr on error */ - static std::unique_ptr parse(PCSX::IO file, bool verbose, bool sorted); + static std::unique_ptr parse(PCSX::IO file, bool verbose, bool sorted, + bool convertCommToBss); static std::string readPsyqString(PCSX::IO file) { return file->readString(file->byte()); } /* Our list of sections and symbols will be keyed by their id from the LNK file */ @@ -164,6 +165,7 @@ struct PsyqLnkFile { EXPORTED, IMPORTED, UNINITIALIZED, + COMM, } symbolType; uint16_t sectionIndex; uint32_t offset = 0; @@ -172,7 +174,7 @@ struct PsyqLnkFile { ELFIO::Elf_Word elfSym; uint16_t getKey() { return getLow(); } uint32_t getOffset(PsyqLnkFile* psyq) const { - if (symbolType == Type::UNINITIALIZED) { + if (symbolType == Type::UNINITIALIZED || symbolType == Type::COMM) { auto section = psyq->sections.find(sectionIndex); assert(section != psyq->sections.end()); return section->data.size() + section->zeroes + offset; @@ -243,7 +245,8 @@ struct PsyqLnkFile { }; /* The psyq LNK parser code */ -std::unique_ptr PsyqLnkFile::parse(PCSX::IO file, bool verbose, bool sorted) { +std::unique_ptr PsyqLnkFile::parse(PCSX::IO file, bool verbose, bool sorted, + bool convertCommToBss) { std::unique_ptr ret = std::make_unique(); vprint(":: Reading signature.\n"); std::string signature = file->readString(3); @@ -291,7 +294,7 @@ std::unique_ptr PsyqLnkFile::parse(PCSX::IO file, bool // Static bss symbols will be represented as a ZEROES opcode instead of UNINITIALIZED. // This will cause them to have a size of zero, so ignore size zero symbols here. // Their relocs will resolve to an offset of the local .bss instead, so this causes no issues. - if (symbol.size > 0) { + if (symbol.size > 0 && symbol.symbolType != PsyqLnkFile::Symbol::Type::COMM) { auto section = ret->sections.find(symbol.sectionIndex); if (section != ret->sections.end() && section->isBss()) { auto align = std::min((uint32_t)section->alignment, symbol.size) - 1; @@ -498,7 +501,11 @@ std::unique_ptr PsyqLnkFile::parse(PCSX::IO file, bool std::string name = readPsyqString(file); Symbol* symbol = new Symbol(); - symbol->symbolType = Symbol::Type::UNINITIALIZED; + if (convertCommToBss) { + symbol->symbolType = Symbol::Type::UNINITIALIZED; + } else { + symbol->symbolType = Symbol::Type::COMM; + } symbol->sectionIndex = sectionIndex; symbol->size = size; symbol->name = name; @@ -970,7 +977,9 @@ bool PsyqLnkFile::Symbol::generateElfSymbol(PsyqLnkFile* psyq, ELFIO::string_sec bool isWeak = false; fmt::print(" :: Generating symbol {} {} {}\n", name, getOffset(psyq), sectionIndex); - if (symbolType != Type::IMPORTED) { + if (symbolType == Type::COMM) { + elfSectionIndex = ELFIO::SHN_COMMON; + } else if (symbolType != Type::IMPORTED) { auto section = psyq->sections.find(sectionIndex); if (section == psyq->sections.end()) { psyq->setElfConversionError("Couldn't find section index {} for symbol {} ('{}')", sectionIndex, getKey(), @@ -1387,7 +1396,8 @@ bool PsyqLnkFile::Relocation::generateElf(ElfRelocationPass pass, const std::str psyq->setElfConversionError("Couldn't find symbol {} for relocation.", expr->symbolIndex); return false; } - if (symbol->symbolType != PsyqLnkFile::Symbol::Type::IMPORTED) { + if (symbol->symbolType != PsyqLnkFile::Symbol::Type::IMPORTED && + symbol->symbolType != PsyqLnkFile::Symbol::Type::COMM) { return localSymbolReloc(symbol->sectionIndex, symbol->getOffset(psyq) + addend); } if (pass == ElfRelocationPass::PASS1) { @@ -1536,6 +1546,7 @@ Usage: {} input.obj [input2.obj...] [-h] [-v] [-d] [-n] [-p prefix] [-o output.o -o output.o tries to dump the parsed psyq LNK file into an ELF file; can only work with a single input file. -b outputs a big-endian ELF file. + -c converts comm symbols into .bss symbols )", argv[0]); return -1; @@ -1551,7 +1562,7 @@ Usage: {} input.obj [input2.obj...] [-h] [-v] [-d] [-n] [-p prefix] [-o output.o fmt::print(stderr, "Unable to open file: {}\n", input); ret = -2; } else { - auto psyq = PsyqLnkFile::parse(file, verbose, !!args.get("s")); + auto psyq = PsyqLnkFile::parse(file, verbose, !!args.get("s"), !!args.get("c")); if (!psyq) { ret = -3; } else {