@@ -44,6 +44,9 @@ enum class PsyqOpcode : uint8_t {
44
44
FILENAME = 28 ,
45
45
PROGRAMTYPE = 46 ,
46
46
UNINITIALIZED = 48 ,
47
+ SLD_END = 60 ,
48
+ FUNCTION = 74 ,
49
+ FUNCTION_END = 76 ,
47
50
};
48
51
49
52
enum class PsyqRelocType : uint8_t {
@@ -409,6 +412,36 @@ std::unique_ptr<PsyqLnkFile> PsyqLnkFile::parse(PCSX::File* file, bool verbose)
409
412
ret->symbols .insert (symbolIndex, symbol);
410
413
break ;
411
414
}
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
+ }
412
445
default : {
413
446
fmt::print (" Unknown opcode {}.\n " , opcode);
414
447
return nullptr ;
@@ -708,6 +741,8 @@ bool PsyqLnkFile::writeElf(const std::string& prefix, const std::string& out, bo
708
741
bool PsyqLnkFile::Symbol::generateElfSymbol (PsyqLnkFile* psyq, ELFIO::string_section_accessor& stra,
709
742
ELFIO::symbol_section_accessor& syma) {
710
743
ELFIO::Elf_Half elfSectionIndex = 0 ;
744
+ bool isText = false ;
745
+
711
746
fmt::print (" :: Generating symbol {}\n " , name);
712
747
if (symbolType != Type::IMPORTED) {
713
748
auto section = psyq->sections .find (sectionIndex);
@@ -717,9 +752,12 @@ bool PsyqLnkFile::Symbol::generateElfSymbol(PsyqLnkFile* psyq, ELFIO::string_sec
717
752
return false ;
718
753
}
719
754
elfSectionIndex = section->section ->get_index ();
755
+ isText = section->isText ();
720
756
}
721
757
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);
723
761
return true ;
724
762
}
725
763
@@ -803,7 +841,7 @@ bool PsyqLnkFile::Relocation::generateElf(ElfRelocationPass pass, const std::str
803
841
{PsyqRelocType::LO16, elf_mips_reloc_type::R_MIPS_LO16},
804
842
{PsyqRelocType::GPREL16, elf_mips_reloc_type::R_MIPS_GPREL16},
805
843
};
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 ) {
807
845
if (psyq->twoPartsReloc ) {
808
846
psyq->setElfConversionError (" Two-part relocation missing its second part" );
809
847
return false ;
@@ -830,7 +868,7 @@ bool PsyqLnkFile::Relocation::generateElf(ElfRelocationPass pass, const std::str
830
868
break ;
831
869
}
832
870
case PsyqRelocType::REL26: {
833
- sectionData[offset + 0 ] = 0 ;
871
+ sectionData[offset + 0 ] = symbolOffset >> 2 ;
834
872
sectionData[offset + 1 ] = 0 ;
835
873
sectionData[offset + 2 ] = 0 ;
836
874
sectionData[offset + 3 ] &= 0xfc ;
@@ -866,13 +904,13 @@ bool PsyqLnkFile::Relocation::generateElf(ElfRelocationPass pass, const std::str
866
904
ELFIO::Elf_Word elfSym;
867
905
if (existing == psyq->localElfSymbols .end ()) {
868
906
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 ,
870
908
section->section ->get_index ());
871
909
psyq->localElfSymbols .insert (std::make_pair (symbolName, elfSym));
872
910
} else {
873
911
elfSym = existing->second ;
874
912
}
875
- return simpleSymbolReloc (nullptr , elfSym);
913
+ return simpleSymbolReloc (nullptr , elfSym, symbolOffset );
876
914
};
877
915
auto checkZero = [&, this ](Expression* expr) {
878
916
switch (expr->type ) {
0 commit comments