@@ -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
4952enum 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
708741bool 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