Skip to content

Commit

Permalink
options/rtdl: Unify late relocation code
Browse files Browse the repository at this point in the history
  • Loading branch information
Qwinci committed Feb 4, 2024
1 parent 84d7a13 commit ad602bc
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 35 deletions.
56 changes: 22 additions & 34 deletions options/rtdl/generic/linker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -776,40 +776,26 @@ SharedObject::SharedObject(const char *name, const char *path,
frg::string<MemoryAllocator> { path, getAllocator() },
is_main_object, localScope, object_rts) {}

void processCopyRela(SharedObject *object, elf_rela *reloc) {
auto type = ELF_R_TYPE(reloc->r_info);
auto symbol_index = ELF_R_SYM(reloc->r_info);

if(type != R_COPY)
return;

uintptr_t rel_addr = object->baseAddress + reloc->r_offset;

auto symbol = (elf_sym *)(object->baseAddress + object->symbolTableOffset
+ symbol_index * sizeof(elf_sym));
ObjectSymbol r(object, symbol);
frg::optional<ObjectSymbol> p = Scope::resolveGlobalOrLocal(*globalScope, object->localScope, r.getString(), object->objectRts, Scope::resolveCopy);
__ensure(p);

memcpy((void *)rel_addr, (void *)p->virtualAddress(), symbol->st_size);
}

void processCopyRel(SharedObject *object, elf_rel *reloc) {
auto type = ELF_R_TYPE(reloc->r_info);
auto symbol_index = ELF_R_SYM(reloc->r_info);

if(type != R_COPY)
return;

uintptr_t rel_addr = object->baseAddress + reloc->r_offset;
void processLateRelocation(Relocation rel) {
// resolve the symbol if there is a symbol
frg::optional<ObjectSymbol> p;
if(rel.symbol_index()) {
auto symbol = (elf_sym *)(rel.object()->baseAddress + rel.object()->symbolTableOffset
+ rel.symbol_index() * sizeof(elf_sym));
ObjectSymbol r(rel.object(), symbol);

auto symbol = (elf_sym *)(object->baseAddress + object->symbolTableOffset
+ symbol_index * sizeof(elf_sym));
ObjectSymbol r(object, symbol);
frg::optional<ObjectSymbol> p = Scope::resolveGlobalOrLocal(*globalScope, object->localScope, r.getString(), object->objectRts, Scope::resolveCopy);
__ensure(p);
p = Scope::resolveGlobalOrLocal(*globalScope, rel.object()->localScope,
r.getString(), rel.object()->objectRts, Scope::resolveCopy);
__ensure(p);
}

memcpy((void *)rel_addr, (void *)p->virtualAddress(), symbol->st_size);
switch(rel.type()) {
case R_COPY:
memcpy(rel.destination(), (void *)p->virtualAddress(), p->symbol()->st_size);
break;
default:
__ensure(!"Unknown late relocation type");
}
}

void processCopyRelocations(SharedObject *object) {
Expand Down Expand Up @@ -847,12 +833,14 @@ void processCopyRelocations(SharedObject *object) {
if(rela_offset && rela_length) {
for(size_t offset = 0; offset < *rela_length; offset += sizeof(elf_rela)) {
auto reloc = (elf_rela *)(object->baseAddress + *rela_offset + offset);
processCopyRela(object, reloc);
auto r = Relocation(object, reloc);
processLateRelocation(object, r);
}
} else if(rel_offset && rel_length) {
for(size_t offset = 0; offset < *rel_length; offset += sizeof(elf_rel)) {
auto reloc = (elf_rel *)(object->baseAddress + *rel_offset + offset);
processCopyRel(object, reloc);
auto r = Relocation(object, reloc);
processLateRelocation(object, r);
}
}else{
__ensure(!rela_offset && !rela_length);
Expand Down
6 changes: 5 additions & 1 deletion options/rtdl/generic/linker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,12 @@ struct Relocation {
__builtin_unreachable();
}

void *destination() {
return reinterpret_cast<void *>(object_->baseAddress + offset_);
}

void relocate(elf_addr addr) {
auto ptr = reinterpret_cast<void *>(object_->baseAddress + offset_);
auto ptr = destination();
memcpy(ptr, &addr, sizeof(addr));
}

Expand Down

0 comments on commit ad602bc

Please sign in to comment.