Skip to content

Commit a770cb7

Browse files
author
Solid Snake
committed
Fix R_MIPS_GPREL16 by setting the correction section attributes. Fix .bss and .sbss symbol offsets.
1 parent 246a6e8 commit a770cb7

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

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

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include "support/slice.h"
3030
#include "support/windowswrapper.h"
3131

32+
#define SHF_MIPS_GPREL 0x10000000
33+
3234
#define vprint(...) \
3335
if (verbose) fmt::print(__VA_ARGS__)
3436

@@ -400,22 +402,30 @@ std::unique_ptr<PsyqLnkFile> PsyqLnkFile::parse(PCSX::File* file, bool verbose)
400402
uint16_t sectionIndex = file->read<uint16_t>();
401403
uint32_t size = file->read<uint32_t>();
402404
std::string name = readPsyqString(file);
403-
vprint("Uninitialized: id {}, section {}, size {:08x}, name {}\n", symbolIndex, sectionIndex, size,
404-
name);
405+
405406
Symbol* symbol = new Symbol();
406407
symbol->symbolType = Symbol::Type::UNINITIALIZED;
407408
symbol->sectionIndex = sectionIndex;
408409
symbol->size = size;
409410
symbol->name = name;
410411
auto section = ret->sections.find(sectionIndex);
411412
if (section == ret->sections.end()) {
412-
fmt::print("Section {} not found.\n", sectionIndex);
413+
fmt::print("Section {} not found for.\n", sectionIndex);
413414
return nullptr;
414415
}
415-
auto align = section->alignment - 1;
416+
417+
// A PSYQ section may have an alignment of 8, but each var within the section seems to always be aligned to 4.
418+
// So the section alignment appears to apply to the section as a whole rather than the invidual entries within it.
419+
const auto bssAlignment = 4;
420+
auto align = bssAlignment - 1;
416421
section->uninitializedOffset += align;
417422
section->uninitializedOffset &= ~align;
418423
symbol->offset = section->uninitializedOffset;
424+
425+
vprint("Uninitialized: id {}, section {}, offset {:08x}, size {:08x}, name {}\n", symbolIndex,
426+
sectionIndex, symbol->offset, size,
427+
name);
428+
419429
section->uninitializedOffset += size;
420430
ret->symbols.insert(symbolIndex, symbol);
421431
break;
@@ -829,8 +839,9 @@ bool PsyqLnkFile::Section::generateElfSection(PsyqLnkFile* psyq, ELFIO::elfio& w
829839
if (getFullSize() == 0) return true;
830840
fmt::print(" :: Generating section {}\n", name);
831841
static const std::map<std::string, ELFIO::Elf_Xword> flagsMap = {
832-
{".text", SHF_ALLOC | SHF_EXECINSTR}, {".rdata", SHF_ALLOC}, {".data", SHF_ALLOC | SHF_WRITE},
833-
{".sdata", SHF_ALLOC | SHF_WRITE}, {".bss", SHF_ALLOC | SHF_WRITE}, {".sbss", SHF_ALLOC | SHF_WRITE},
842+
{".text", SHF_ALLOC | SHF_EXECINSTR}, {".rdata", SHF_ALLOC},
843+
{".data", SHF_ALLOC | SHF_WRITE}, {".sdata", SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL},
844+
{".bss", SHF_ALLOC | SHF_WRITE}, {".sbss", SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL},
834845
};
835846
auto flags = flagsMap.find(name);
836847
if (flags == flagsMap.end()) {

0 commit comments

Comments
 (0)