Skip to content

Commit e7c7796

Browse files
committed
psyq-obj-parser: Handle comm symbols properly
Convert .comm symbols into the proper ELF equivalent, instead of converting them to local symbol in the .bss segment. This makes it possible use the converted PSY-Q libraries to recreate a bit-exact executable of Frogger - without proper comm symbol support controlling the order of some .bss symbols in the libraries is impossible. Even though this is more correct than before there is a chance some users of psyq-obj-parser are relying on the old behaviour thus this could be a breaking change for them. If so command line option could be added to control between old and new behaviour.
1 parent 3b8f0a0 commit e7c7796

File tree

1 file changed

+5
-21
lines changed

1 file changed

+5
-21
lines changed

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

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -283,25 +283,6 @@ std::unique_ptr<PsyqLnkFile> PsyqLnkFile::parse(PCSX::IO<PCSX::File> file, bool
283283
ret->symbolsList.push_back(&symbol);
284284
}
285285
}
286-
// Determine bss symbol placement
287-
// This has to be done after parsing the whole psyq object, as bss may be out of order in the file.
288-
// Doing it here ensures that we process symbols in their id order, instead of by psyq object file
289-
// order, if the user requested ordering by id - otherwise, it'll indeed be order of appearance.
290-
for (auto& symbol : ret->symbolsList) {
291-
// Static bss symbols will be represented as a ZEROES opcode instead of UNINITIALIZED.
292-
// This will cause them to have a size of zero, so ignore size zero symbols here.
293-
// Their relocs will resolve to an offset of the local .bss instead, so this causes no issues.
294-
if (symbol.size > 0) {
295-
auto section = ret->sections.find(symbol.sectionIndex);
296-
if (section != ret->sections.end() && section->isBss()) {
297-
auto align = std::min((uint32_t)section->alignment, symbol.size) - 1;
298-
section->uninitializedOffset += align;
299-
section->uninitializedOffset &= ~align;
300-
symbol.offset = section->uninitializedOffset;
301-
section->uninitializedOffset += symbol.size;
302-
}
303-
}
304-
}
305286
return ret;
306287
}
307288
case (uint8_t)PsyqOpcode::BYTES: {
@@ -970,7 +951,9 @@ bool PsyqLnkFile::Symbol::generateElfSymbol(PsyqLnkFile* psyq, ELFIO::string_sec
970951
bool isWeak = false;
971952

972953
fmt::print(" :: Generating symbol {} {} {}\n", name, getOffset(psyq), sectionIndex);
973-
if (symbolType != Type::IMPORTED) {
954+
if (symbolType == Type::UNINITIALIZED) {
955+
elfSectionIndex = ELFIO::SHN_COMMON;
956+
} else if (symbolType != Type::IMPORTED) {
974957
auto section = psyq->sections.find(sectionIndex);
975958
if (section == psyq->sections.end()) {
976959
psyq->setElfConversionError("Couldn't find section index {} for symbol {} ('{}')", sectionIndex, getKey(),
@@ -1387,7 +1370,8 @@ bool PsyqLnkFile::Relocation::generateElf(ElfRelocationPass pass, const std::str
13871370
psyq->setElfConversionError("Couldn't find symbol {} for relocation.", expr->symbolIndex);
13881371
return false;
13891372
}
1390-
if (symbol->symbolType != PsyqLnkFile::Symbol::Type::IMPORTED) {
1373+
if (symbol->symbolType != PsyqLnkFile::Symbol::Type::IMPORTED &&
1374+
symbol->symbolType != PsyqLnkFile::Symbol::Type::UNINITIALIZED) {
13911375
return localSymbolReloc(symbol->sectionIndex, symbol->getOffset(psyq) + addend);
13921376
}
13931377
if (pass == ElfRelocationPass::PASS1) {

0 commit comments

Comments
 (0)