Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions tools/psyq-obj-parser/psyq-obj-parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ struct PsyqLnkFile {
struct Expression;

/* The main parser entry point; will return nullptr on error */
static std::unique_ptr<PsyqLnkFile> parse(PCSX::IO<PCSX::File> file, bool verbose, bool sorted);
static std::unique_ptr<PsyqLnkFile> parse(PCSX::IO<PCSX::File> file, bool verbose, bool sorted,
bool convertCommToBss);
static std::string readPsyqString(PCSX::IO<PCSX::File> file) { return file->readString(file->byte()); }

/* Our list of sections and symbols will be keyed by their id from the LNK file */
Expand Down Expand Up @@ -164,6 +165,7 @@ struct PsyqLnkFile {
EXPORTED,
IMPORTED,
UNINITIALIZED,
COMM,
} symbolType;
uint16_t sectionIndex;
uint32_t offset = 0;
Expand All @@ -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;
Expand Down Expand Up @@ -243,7 +245,8 @@ struct PsyqLnkFile {
};

/* The psyq LNK parser code */
std::unique_ptr<PsyqLnkFile> PsyqLnkFile::parse(PCSX::IO<PCSX::File> file, bool verbose, bool sorted) {
std::unique_ptr<PsyqLnkFile> PsyqLnkFile::parse(PCSX::IO<PCSX::File> file, bool verbose, bool sorted,
bool convertCommToBss) {
std::unique_ptr<PsyqLnkFile> ret = std::make_unique<PsyqLnkFile>();
vprint(":: Reading signature.\n");
std::string signature = file->readString(3);
Expand Down Expand Up @@ -291,7 +294,7 @@ std::unique_ptr<PsyqLnkFile> PsyqLnkFile::parse(PCSX::IO<PCSX::File> 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;
Expand Down Expand Up @@ -498,7 +501,11 @@ std::unique_ptr<PsyqLnkFile> PsyqLnkFile::parse(PCSX::IO<PCSX::File> 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;
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand All @@ -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<bool>("s"));
auto psyq = PsyqLnkFile::parse(file, verbose, !!args.get<bool>("s"), !!args.get<bool>("c"));
if (!psyq) {
ret = -3;
} else {
Expand Down