@@ -70,7 +70,9 @@ enum class PsyqOpcode : uint8_t {
70
70
71
71
enum class PsyqRelocType : uint8_t {
72
72
REL32_BE = 8 ,
73
+ GPREL16_BE = 12 ,
73
74
REL32 = 16 ,
75
+ GPREL16_LE = 30 ,
74
76
REL26 = 74 ,
75
77
HI16 = 82 ,
76
78
LO16 = 84 ,
@@ -339,6 +341,14 @@ std::unique_ptr<PsyqLnkFile> PsyqLnkFile::parse(PCSX::IO<PCSX::File> file, bool
339
341
vprint (" (GPREL16), " );
340
342
break ;
341
343
}
344
+ case (uint8_t )PsyqRelocType::GPREL16_LE: {
345
+ vprint (" (GPREL16 LE), " );
346
+ break ;
347
+ }
348
+ case (uint8_t )PsyqRelocType::GPREL16_BE: {
349
+ vprint (" (GPREL16 BE), " );
350
+ break ;
351
+ }
342
352
case (uint8_t )PsyqRelocType::HI16_BE: {
343
353
vprint (" (HI16 BE), " );
344
354
break ;
@@ -764,10 +774,11 @@ void PsyqLnkFile::Section::displayRelocs(PsyqLnkFile* lnk) {
764
774
765
775
void PsyqLnkFile::Relocation::display (PsyqLnkFile* lnk, PsyqLnkFile::Section* sec) {
766
776
static const std::map<PsyqRelocType, std::string> typeStr = {
767
- {PsyqRelocType::REL32, " REL32" }, {PsyqRelocType::REL26, " REL26" },
768
- {PsyqRelocType::HI16, " HI16" }, {PsyqRelocType::LO16, " LO16" },
769
- {PsyqRelocType::GPREL16, " GPREL16" }, {PsyqRelocType::REL32_BE, " REL32 BE" },
770
- {PsyqRelocType::REL26_BE, " REL26 BE" }, {PsyqRelocType::HI16_BE, " HI16 BE" },
777
+ {PsyqRelocType::REL32, " REL32" }, {PsyqRelocType::REL26, " REL26" },
778
+ {PsyqRelocType::HI16, " HI16" }, {PsyqRelocType::LO16, " LO16" },
779
+ {PsyqRelocType::GPREL16, " GPREL16" }, {PsyqRelocType::GPREL16_LE, " GPREL16 LE" },
780
+ {PsyqRelocType::GPREL16_BE, " GPREL16 BE" }, {PsyqRelocType::REL32_BE, " REL32 BE" },
781
+ {PsyqRelocType::REL26_BE, " REL26 BE" }, {PsyqRelocType::HI16_BE, " HI16 BE" },
771
782
{PsyqRelocType::LO16_BE, " LO16 BE" },
772
783
};
773
784
fmt::print (" {:8} {:>12}::{:08x} " , typeStr.find (type)->second , sec->name , offset);
@@ -994,6 +1005,8 @@ static const std::map<PsyqRelocType, elf_mips_reloc_type> typeMap = {
994
1005
{PsyqRelocType::HI16, elf_mips_reloc_type::R_MIPS_HI16},
995
1006
{PsyqRelocType::LO16, elf_mips_reloc_type::R_MIPS_LO16},
996
1007
{PsyqRelocType::GPREL16, elf_mips_reloc_type::R_MIPS_GPREL16},
1008
+ {PsyqRelocType::GPREL16_LE, elf_mips_reloc_type::R_MIPS_GPREL16},
1009
+ {PsyqRelocType::GPREL16_BE, elf_mips_reloc_type::R_MIPS_GPREL16},
997
1010
{PsyqRelocType::REL26_BE, elf_mips_reloc_type::R_MIPS_26},
998
1011
{PsyqRelocType::HI16_BE, elf_mips_reloc_type::R_MIPS_HI16},
999
1012
{PsyqRelocType::LO16_BE, elf_mips_reloc_type::R_MIPS_LO16},
@@ -1182,7 +1195,7 @@ bool PsyqLnkFile::Relocation::generateElf(ElfRelocationPass pass, const std::str
1182
1195
}
1183
1196
elfSym = symbol->elfSym ;
1184
1197
}
1185
- if (type == PsyqRelocType::HI16_BE || type == PsyqRelocType::LO16_BE) {
1198
+ if (type == PsyqRelocType::HI16_BE || type == PsyqRelocType::LO16_BE || type == PsyqRelocType::GPREL16_BE ) {
1186
1199
offset -= 0x2 ;
1187
1200
}
1188
1201
auto elfType = typeMap.find (type);
@@ -1230,6 +1243,18 @@ bool PsyqLnkFile::Relocation::generateElf(ElfRelocationPass pass, const std::str
1230
1243
sectionData[offset + 1 ] = 0 ;
1231
1244
break ;
1232
1245
}
1246
+ case PsyqRelocType::GPREL16_LE: {
1247
+ uint16_t lo = symbolOffset & 0xFFFF ;
1248
+ sectionData[offset + 0 ] = (uint8_t )(lo >> 0 );
1249
+ sectionData[offset + 1 ] = (uint8_t )(lo >> 8 );
1250
+ break ;
1251
+ }
1252
+ case PsyqRelocType::GPREL16_BE: {
1253
+ uint16_t lo = symbolOffset & 0xFFFF ;
1254
+ sectionData[offset + 3 ] = (uint8_t )(lo >> 0 );
1255
+ sectionData[offset + 2 ] = (uint8_t )(lo >> 8 );
1256
+ break ;
1257
+ }
1233
1258
case PsyqRelocType::REL32_BE: {
1234
1259
sectionData[offset + 3 ] = (uint8_t )(symbolOffset >> 0x00 );
1235
1260
sectionData[offset + 2 ] = (uint8_t )(symbolOffset >> 0x08 );
@@ -1300,6 +1325,7 @@ bool PsyqLnkFile::Relocation::generateElf(ElfRelocationPass pass, const std::str
1300
1325
case PsyqExprOpcode::SECTION_BASE: {
1301
1326
return localSymbolReloc (expr->sectionIndex , 0 );
1302
1327
}
1328
+ case PsyqExprOpcode::SECTION_START:
1303
1329
case PsyqExprOpcode::SYMBOL: {
1304
1330
if (pass == ElfRelocationPass::PASS1) {
1305
1331
skipped.skipped = true ;
@@ -1425,6 +1451,16 @@ bool PsyqLnkFile::Relocation::generateElf(ElfRelocationPass pass, const std::str
1425
1451
} else {
1426
1452
return check (expression->left .get (), -((int32_t )expression->right ->value ));
1427
1453
}
1454
+ } else if (expression->right ->type == PsyqExprOpcode::SECTION_START) {
1455
+ // Why
1456
+ if (expression->left ->type == PsyqExprOpcode::ADD) {
1457
+ if (expression->left ->left ->type == PsyqExprOpcode::VALUE) {
1458
+ return check (expression->left ->right .get (),
1459
+ expression->left ->left ->value - expression->right ->value );
1460
+ }
1461
+ } else {
1462
+ return checkZero (expression->left .get ());
1463
+ }
1428
1464
} else {
1429
1465
psyq->setElfConversionError (" Unsupported SUB operation in relocation" );
1430
1466
return false ;
0 commit comments