Skip to content

Commit 45035e7

Browse files
committed
Add new opcodes to psyq-obj-parser, treat functions as STT_FUNC, fix reloc offset
1 parent a179173 commit 45035e7

File tree

1 file changed

+43
-5
lines changed

1 file changed

+43
-5
lines changed

tools/psyq-obj-parser/psyq-obj-parser.cc

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ enum class PsyqOpcode : uint8_t {
4444
FILENAME = 28,
4545
PROGRAMTYPE = 46,
4646
UNINITIALIZED = 48,
47+
SLD_END = 60,
48+
FUNCTION = 74,
49+
FUNCTION_END = 76,
4750
};
4851

4952
enum class PsyqRelocType : uint8_t {
@@ -409,6 +412,36 @@ std::unique_ptr<PsyqLnkFile> PsyqLnkFile::parse(PCSX::File* file, bool verbose)
409412
ret->symbols.insert(symbolIndex, symbol);
410413
break;
411414
}
415+
case (uint8_t)PsyqOpcode::SLD_END: {
416+
// 2 bytes of nothing
417+
uint16_t zero = file->read<uint16_t>();
418+
assert(zero == 0);
419+
vprint("SLD_END\n");
420+
break;
421+
}
422+
case (uint8_t)PsyqOpcode::FUNCTION: {
423+
uint16_t section = file->read<uint16_t>();
424+
uint32_t offset = file->read<uint32_t>();
425+
uint16_t _file = file->read<uint16_t>();
426+
uint32_t startLine = file->read<uint32_t>();
427+
uint16_t frameReg = file->read<uint16_t>();
428+
uint32_t frameSize = file->read<uint32_t>();
429+
uint16_t retnPcReg = file->read<uint16_t>();
430+
uint32_t mask = file->read<uint32_t>();
431+
uint32_t maskOffset = file->read<uint32_t>();
432+
std::string name = readPsyqString(file);
433+
vprint("FUNCTION: section {}, offset {}, _file {}, startLine {}, frameReg {}, frameSize {}, retnPcReg {}, mask {}, maskOffset {}, name {}\n",
434+
section, offset, _file, startLine, frameReg, frameSize, retnPcReg, mask, maskOffset, name);
435+
break;
436+
}
437+
case (uint8_t)PsyqOpcode::FUNCTION_END: {
438+
uint16_t section = file->read<uint16_t>();
439+
uint32_t offset = file->read<uint32_t>();
440+
uint32_t endLine = file->read<uint32_t>();
441+
vprint("FUNCTION_END: section {}, offset {}, endLine {}\n",
442+
section, offset, endLine);
443+
break;
444+
}
412445
default: {
413446
fmt::print("Unknown opcode {}.\n", opcode);
414447
return nullptr;
@@ -708,6 +741,8 @@ bool PsyqLnkFile::writeElf(const std::string& prefix, const std::string& out, bo
708741
bool PsyqLnkFile::Symbol::generateElfSymbol(PsyqLnkFile* psyq, ELFIO::string_section_accessor& stra,
709742
ELFIO::symbol_section_accessor& syma) {
710743
ELFIO::Elf_Half elfSectionIndex = 0;
744+
bool isText = false;
745+
711746
fmt::print(" :: Generating symbol {}\n", name);
712747
if (symbolType != Type::IMPORTED) {
713748
auto section = psyq->sections.find(sectionIndex);
@@ -717,9 +752,12 @@ bool PsyqLnkFile::Symbol::generateElfSymbol(PsyqLnkFile* psyq, ELFIO::string_sec
717752
return false;
718753
}
719754
elfSectionIndex = section->section->get_index();
755+
isText = section->isText();
720756
}
721757
elfSym = syma.add_symbol(stra, name.c_str(), getOffset(psyq), size,
722-
symbolType == Type::LOCAL ? STB_LOCAL : STB_GLOBAL, STT_NOTYPE, 0, elfSectionIndex);
758+
symbolType == Type::LOCAL ? STB_LOCAL : STB_GLOBAL,
759+
isText ? STT_FUNC : STT_NOTYPE,
760+
0, elfSectionIndex);
723761
return true;
724762
}
725763

@@ -803,7 +841,7 @@ bool PsyqLnkFile::Relocation::generateElf(ElfRelocationPass pass, const std::str
803841
{PsyqRelocType::LO16, elf_mips_reloc_type::R_MIPS_LO16},
804842
{PsyqRelocType::GPREL16, elf_mips_reloc_type::R_MIPS_GPREL16},
805843
};
806-
auto simpleSymbolReloc = [&, this](Expression* expr, ELFIO::Elf_Word elfSym = 0) {
844+
auto simpleSymbolReloc = [&, this](Expression* expr, ELFIO::Elf_Word elfSym = 0, uint16_t symbolOffset = 0) {
807845
if (psyq->twoPartsReloc) {
808846
psyq->setElfConversionError("Two-part relocation missing its second part");
809847
return false;
@@ -830,7 +868,7 @@ bool PsyqLnkFile::Relocation::generateElf(ElfRelocationPass pass, const std::str
830868
break;
831869
}
832870
case PsyqRelocType::REL26: {
833-
sectionData[offset + 0] = 0;
871+
sectionData[offset + 0] = symbolOffset >> 2;
834872
sectionData[offset + 1] = 0;
835873
sectionData[offset + 2] = 0;
836874
sectionData[offset + 3] &= 0xfc;
@@ -866,13 +904,13 @@ bool PsyqLnkFile::Relocation::generateElf(ElfRelocationPass pass, const std::str
866904
ELFIO::Elf_Word elfSym;
867905
if (existing == psyq->localElfSymbols.end()) {
868906
fmt::print(" :: Creating local symbol {}\n", symbolName);
869-
elfSym = syma.add_symbol(stra, symbolName.c_str(), symbolOffset, 0, STB_LOCAL, STT_NOTYPE, 0,
907+
elfSym = syma.add_symbol(stra, symbolName.c_str(), symbolOffset, 0, STB_LOCAL, STT_SECTION, 0,
870908
section->section->get_index());
871909
psyq->localElfSymbols.insert(std::make_pair(symbolName, elfSym));
872910
} else {
873911
elfSym = existing->second;
874912
}
875-
return simpleSymbolReloc(nullptr, elfSym);
913+
return simpleSymbolReloc(nullptr, elfSym, symbolOffset);
876914
};
877915
auto checkZero = [&, this](Expression* expr) {
878916
switch (expr->type) {

0 commit comments

Comments
 (0)