@@ -192,7 +192,7 @@ int main(int argc, char **argv)
192
192
193
193
// Write sections
194
194
std::vector<uint8_t > sectionInfoBuffer;
195
- std::vector <ELFIO::section *> writtenSections;
195
+ std::map <ELFIO::section *, int > writtenSections;
196
196
int totalBssSize = 0 ;
197
197
int maxAlign = 1 ;
198
198
int maxBssAlign = 1 ;
@@ -229,16 +229,18 @@ int main(int argc, char **argv)
229
229
}
230
230
231
231
int offset = outputBuffer.size ();
232
+
233
+ int encodedOffset = offset;
232
234
// Mark executable sections
233
235
if (section->get_flags () & SHF_EXECINSTR)
234
236
{
235
- offset |= 1 ;
237
+ encodedOffset |= 1 ;
236
238
}
237
- writeSectionInfo (sectionInfoBuffer, offset , static_cast <int >(section->get_size ()));
239
+ writeSectionInfo (sectionInfoBuffer, encodedOffset , static_cast <int >(section->get_size ()));
238
240
std::vector<uint8_t > sectionData (section->get_data (), section->get_data () + section->get_size ());
239
241
outputBuffer.insert (outputBuffer.end (), sectionData.begin (), sectionData.end ());
240
242
241
- writtenSections. emplace_back ( section) ;
243
+ writtenSections[ section] = offset ;
242
244
}
243
245
}
244
246
else
@@ -269,7 +271,7 @@ int main(int argc, char **argv)
269
271
int relocatedSectionIndex = section->get_info ();
270
272
ELFIO::section *relocatedSection = inputElf.sections [relocatedSectionIndex];
271
273
// Only relocate sections that were written
272
- if (std::find ( writtenSections.begin (), writtenSections. end (), relocatedSection) != writtenSections.end ())
274
+ if (writtenSections.find ( relocatedSection) != writtenSections.end ())
273
275
{
274
276
ELFIO::relocation_section_accessor relocations (inputElf, section);
275
277
// #todo-elf2rel: Process relocations
@@ -387,6 +389,30 @@ int main(int argc, char **argv)
387
389
Relocation nextRel = allRelocations.front ();
388
390
allRelocations.pop_front ();
389
391
392
+ // Resolve early if possible
393
+ if (nextRel.moduleID == moduleID && (nextRel.type == R_PPC_REL24 || nextRel.type == R_PPC_REL32))
394
+ {
395
+ int offset = writtenSections.at (inputElf.sections [nextRel.section ]) + nextRel.offset ;
396
+ int delta = writtenSections.at (inputElf.sections [nextRel.targetSection ]) + nextRel.addend - offset;
397
+ std::vector<uint8_t > instructionBuffer (outputBuffer.begin () + offset, outputBuffer.begin () + offset + 4 );
398
+ uint32_t patchedData;
399
+ load (instructionBuffer, patchedData);
400
+
401
+ if (nextRel.type == R_PPC_REL24)
402
+ {
403
+ patchedData |= (delta & 0x03FFFFFC );
404
+ }
405
+ else if (nextRel.type == R_PPC_REL32)
406
+ {
407
+ patchedData = delta;
408
+ }
409
+
410
+ save (instructionBuffer, patchedData);
411
+ std::copy (instructionBuffer.begin (), instructionBuffer.end (), outputBuffer.begin () + offset);
412
+
413
+ continue ;
414
+ }
415
+
390
416
// Change module if necessary
391
417
if (currentModuleID != nextRel.moduleID )
392
418
{
@@ -416,8 +442,31 @@ int main(int argc, char **argv)
416
442
writeRelocation (outputBuffer, 0 , R_DOLPHIN_NOP, 0 , 0 );
417
443
targetDelta -= 0xFFFF ;
418
444
}
419
- // #todo-elf2rel: Resolve potential self-relocations at build time here
445
+
420
446
// #todo-elf2rel: Add runtime unresolved symbol handling here
447
+ // At this point, only symbols that OSLink can handle should remain
448
+ switch (nextRel.type )
449
+ {
450
+ case R_PPC_NONE:
451
+ case R_PPC_ADDR32:
452
+ case R_PPC_ADDR24:
453
+ case R_PPC_ADDR16:
454
+ case R_PPC_ADDR16_LO:
455
+ case R_PPC_ADDR16_HI:
456
+ case R_PPC_ADDR16_HA:
457
+ case R_PPC_ADDR14:
458
+ case R_PPC_ADDR14_BRTAKEN:
459
+ case R_PPC_ADDR14_BRNKTAKEN:
460
+ case R_PPC_REL24:
461
+ case R_DOLPHIN_NOP:
462
+ case R_DOLPHIN_SECTION:
463
+ case R_DOLPHIN_END:
464
+ break ;
465
+ default :
466
+ printf (" Unsupported relocation type %d" , nextRel.type );
467
+ break ;
468
+ }
469
+
421
470
writeRelocation (outputBuffer, targetDelta, nextRel.type , nextRel.targetSection , nextRel.addend );
422
471
currentOffset = nextRel.offset ;
423
472
}
0 commit comments