Skip to content

Commit 7802a02

Browse files
committed
elf2rel: Add early self-relocation resolving
1 parent 488fb55 commit 7802a02

File tree

2 files changed

+68
-6
lines changed

2 files changed

+68
-6
lines changed

ttyd-tools/elf2rel/elf2rel.cpp

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ int main(int argc, char **argv)
192192

193193
// Write sections
194194
std::vector<uint8_t> sectionInfoBuffer;
195-
std::vector<ELFIO::section *> writtenSections;
195+
std::map<ELFIO::section *, int> writtenSections;
196196
int totalBssSize = 0;
197197
int maxAlign = 1;
198198
int maxBssAlign = 1;
@@ -229,16 +229,18 @@ int main(int argc, char **argv)
229229
}
230230

231231
int offset = outputBuffer.size();
232+
233+
int encodedOffset = offset;
232234
// Mark executable sections
233235
if (section->get_flags() & SHF_EXECINSTR)
234236
{
235-
offset |= 1;
237+
encodedOffset |= 1;
236238
}
237-
writeSectionInfo(sectionInfoBuffer, offset, static_cast<int>(section->get_size()));
239+
writeSectionInfo(sectionInfoBuffer, encodedOffset, static_cast<int>(section->get_size()));
238240
std::vector<uint8_t> sectionData(section->get_data(), section->get_data() + section->get_size());
239241
outputBuffer.insert(outputBuffer.end(), sectionData.begin(), sectionData.end());
240242

241-
writtenSections.emplace_back(section);
243+
writtenSections[section] = offset;
242244
}
243245
}
244246
else
@@ -269,7 +271,7 @@ int main(int argc, char **argv)
269271
int relocatedSectionIndex = section->get_info();
270272
ELFIO::section *relocatedSection = inputElf.sections[relocatedSectionIndex];
271273
// Only relocate sections that were written
272-
if (std::find(writtenSections.begin(), writtenSections.end(), relocatedSection) != writtenSections.end())
274+
if (writtenSections.find(relocatedSection) != writtenSections.end())
273275
{
274276
ELFIO::relocation_section_accessor relocations(inputElf, section);
275277
// #todo-elf2rel: Process relocations
@@ -387,6 +389,30 @@ int main(int argc, char **argv)
387389
Relocation nextRel = allRelocations.front();
388390
allRelocations.pop_front();
389391

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+
390416
// Change module if necessary
391417
if (currentModuleID != nextRel.moduleID)
392418
{
@@ -416,8 +442,31 @@ int main(int argc, char **argv)
416442
writeRelocation(outputBuffer, 0, R_DOLPHIN_NOP, 0, 0);
417443
targetDelta -= 0xFFFF;
418444
}
419-
// #todo-elf2rel: Resolve potential self-relocations at build time here
445+
420446
// #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+
421470
writeRelocation(outputBuffer, targetDelta, nextRel.type, nextRel.targetSection, nextRel.addend);
422471
currentOffset = nextRel.offset;
423472
}

ttyd-tools/elf2rel/elf2rel.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ enum RelRelocationType
1717
R_PPC_REL24,
1818
R_PPC_REL14,
1919

20+
R_PPC_REL32 = 26,
21+
2022
R_DOLPHIN_NOP = 201,
2123
R_DOLPHIN_SECTION,
2224
R_DOLPHIN_END,
@@ -29,4 +31,15 @@ void save(std::vector<uint8_t> &buffer, const T &value)
2931
{
3032
buffer.emplace_back(static_cast<uint8_t>((value >> (i - 1) * 8) & 0xFF));
3133
}
34+
}
35+
36+
template<typename T>
37+
void load(std::vector<uint8_t> &buffer, T &value)
38+
{
39+
value = 0;
40+
for (size_t i = sizeof(T); i > 0; --i)
41+
{
42+
value |= static_cast<T>(buffer.front()) << ((i - 1) * 8);
43+
buffer.erase(buffer.begin());
44+
}
3245
}

0 commit comments

Comments
 (0)