@@ -125,7 +125,8 @@ struct PsyqLnkFile {
125
125
struct Expression ;
126
126
127
127
/* The main parser entry point; will return nullptr on error */
128
- static std::unique_ptr<PsyqLnkFile> parse (PCSX::IO<PCSX::File> file, bool verbose, bool sorted);
128
+ static std::unique_ptr<PsyqLnkFile> parse (PCSX::IO<PCSX::File> file, bool verbose, bool sorted,
129
+ bool convertCommToBss);
129
130
static std::string readPsyqString (PCSX::IO<PCSX::File> file) { return file->readString (file->byte ()); }
130
131
131
132
/* Our list of sections and symbols will be keyed by their id from the LNK file */
@@ -164,6 +165,7 @@ struct PsyqLnkFile {
164
165
EXPORTED,
165
166
IMPORTED,
166
167
UNINITIALIZED,
168
+ COMM,
167
169
} symbolType;
168
170
uint16_t sectionIndex;
169
171
uint32_t offset = 0 ;
@@ -172,7 +174,7 @@ struct PsyqLnkFile {
172
174
ELFIO::Elf_Word elfSym;
173
175
uint16_t getKey () { return getLow (); }
174
176
uint32_t getOffset (PsyqLnkFile* psyq) const {
175
- if (symbolType == Type::UNINITIALIZED) {
177
+ if (symbolType == Type::UNINITIALIZED || symbolType == Type::COMM ) {
176
178
auto section = psyq->sections .find (sectionIndex);
177
179
assert (section != psyq->sections .end ());
178
180
return section->data .size () + section->zeroes + offset;
@@ -243,7 +245,8 @@ struct PsyqLnkFile {
243
245
};
244
246
245
247
/* The psyq LNK parser code */
246
- std::unique_ptr<PsyqLnkFile> PsyqLnkFile::parse (PCSX::IO<PCSX::File> file, bool verbose, bool sorted) {
248
+ std::unique_ptr<PsyqLnkFile> PsyqLnkFile::parse (PCSX::IO<PCSX::File> file, bool verbose, bool sorted,
249
+ bool convertCommToBss) {
247
250
std::unique_ptr<PsyqLnkFile> ret = std::make_unique<PsyqLnkFile>();
248
251
vprint (" :: Reading signature.\n " );
249
252
std::string signature = file->readString (3 );
@@ -291,7 +294,7 @@ std::unique_ptr<PsyqLnkFile> PsyqLnkFile::parse(PCSX::IO<PCSX::File> file, bool
291
294
// Static bss symbols will be represented as a ZEROES opcode instead of UNINITIALIZED.
292
295
// This will cause them to have a size of zero, so ignore size zero symbols here.
293
296
// Their relocs will resolve to an offset of the local .bss instead, so this causes no issues.
294
- if (symbol.size > 0 ) {
297
+ if (symbol.size > 0 && symbol. symbolType != PsyqLnkFile::Symbol::Type::COMM ) {
295
298
auto section = ret->sections .find (symbol.sectionIndex );
296
299
if (section != ret->sections .end () && section->isBss ()) {
297
300
auto align = std::min ((uint32_t )section->alignment , symbol.size ) - 1 ;
@@ -498,7 +501,11 @@ std::unique_ptr<PsyqLnkFile> PsyqLnkFile::parse(PCSX::IO<PCSX::File> file, bool
498
501
std::string name = readPsyqString (file);
499
502
500
503
Symbol* symbol = new Symbol ();
501
- symbol->symbolType = Symbol::Type::UNINITIALIZED;
504
+ if (convertCommToBss) {
505
+ symbol->symbolType = Symbol::Type::UNINITIALIZED;
506
+ } else {
507
+ symbol->symbolType = Symbol::Type::COMM;
508
+ }
502
509
symbol->sectionIndex = sectionIndex;
503
510
symbol->size = size;
504
511
symbol->name = name;
@@ -970,7 +977,9 @@ bool PsyqLnkFile::Symbol::generateElfSymbol(PsyqLnkFile* psyq, ELFIO::string_sec
970
977
bool isWeak = false ;
971
978
972
979
fmt::print (" :: Generating symbol {} {} {}\n " , name, getOffset (psyq), sectionIndex);
973
- if (symbolType != Type::IMPORTED) {
980
+ if (symbolType == Type::COMM) {
981
+ elfSectionIndex = ELFIO::SHN_COMMON;
982
+ } else if (symbolType != Type::IMPORTED) {
974
983
auto section = psyq->sections .find (sectionIndex);
975
984
if (section == psyq->sections .end ()) {
976
985
psyq->setElfConversionError (" Couldn't find section index {} for symbol {} ('{}')" , sectionIndex, getKey (),
@@ -1387,7 +1396,8 @@ bool PsyqLnkFile::Relocation::generateElf(ElfRelocationPass pass, const std::str
1387
1396
psyq->setElfConversionError (" Couldn't find symbol {} for relocation." , expr->symbolIndex );
1388
1397
return false ;
1389
1398
}
1390
- if (symbol->symbolType != PsyqLnkFile::Symbol::Type::IMPORTED) {
1399
+ if (symbol->symbolType != PsyqLnkFile::Symbol::Type::IMPORTED &&
1400
+ symbol->symbolType != PsyqLnkFile::Symbol::Type::COMM) {
1391
1401
return localSymbolReloc (symbol->sectionIndex , symbol->getOffset (psyq) + addend);
1392
1402
}
1393
1403
if (pass == ElfRelocationPass::PASS1) {
@@ -1536,6 +1546,7 @@ Usage: {} input.obj [input2.obj...] [-h] [-v] [-d] [-n] [-p prefix] [-o output.o
1536
1546
-o output.o tries to dump the parsed psyq LNK file into an ELF file;
1537
1547
can only work with a single input file.
1538
1548
-b outputs a big-endian ELF file.
1549
+ -c converts comm symbols into .bss symbols
1539
1550
)" ,
1540
1551
argv[0 ]);
1541
1552
return -1 ;
@@ -1551,7 +1562,7 @@ Usage: {} input.obj [input2.obj...] [-h] [-v] [-d] [-n] [-p prefix] [-o output.o
1551
1562
fmt::print (stderr, " Unable to open file: {}\n " , input);
1552
1563
ret = -2 ;
1553
1564
} else {
1554
- auto psyq = PsyqLnkFile::parse (file, verbose, !!args.get <bool >(" s" ));
1565
+ auto psyq = PsyqLnkFile::parse (file, verbose, !!args.get <bool >(" s" ), !!args. get < bool >( " c " ) );
1555
1566
if (!psyq) {
1556
1567
ret = -3 ;
1557
1568
} else {
0 commit comments