1
1
mirror of https://github.com/rui314/mold.git synced 2024-09-21 09:57:18 +03:00

[Mach-O] wip

This commit is contained in:
Rui Ueyama 2021-10-11 21:56:18 +09:00
parent d72c1bf62c
commit 8124a07e07
2 changed files with 35 additions and 32 deletions

View File

@ -27,13 +27,47 @@ Subsection *InputSection::find_subsection(Context &ctx, u32 addr) {
return &*(it - 1);
}
static Relocation read_reloc(Context &ctx, ObjectFile &file,
const MachSection &hdr, MachRel r) {
u8 *buf = (u8 *)file.mf->data + hdr.offset;
i64 addend;
if (r.p2size == 0)
addend = *(i8 *)(buf + r.offset);
else if (r.p2size == 1)
addend = *(i16 *)(buf + r.offset);
else if (r.p2size == 2)
addend = *(i32 *)(buf + r.offset);
else if (r.p2size == 3)
addend = *(i64 *)(buf + r.offset);
else
unreachable();
if (r.is_extern)
return {r.offset, (bool)r.is_pcrel, addend, file.syms[r.idx], nullptr};
u32 addr;
if (r.is_pcrel) {
if (r.p2size != 2)
Fatal(ctx) << file << ": invalid PC-relative reloc: " << r.offset;
addr = hdr.addr + r.offset + 4 + addend;
} else {
addr = addend;
}
Subsection *target = file.sections[r.idx - 1]->find_subsection(ctx, addr);
if (!target)
Fatal(ctx) << file << ": bad relocation: " << r.offset;
return {r.offset, (bool)r.is_pcrel, addr - target->input_addr, nullptr, target};
}
void InputSection::parse_relocations(Context &ctx) {
rels.reserve(hdr.nreloc);
// Parse mach-o relocations to fill `rels` vector
MachRel *rel = (MachRel *)(file.mf->data + hdr.reloff);
for (i64 i = 0; i < hdr.nreloc; i++)
rels.push_back(file.read_reloc(ctx, hdr, rel[i]));
rels.push_back(read_reloc(ctx, file, hdr, rel[i]));
// Sort `rels` vector
sort(rels, [](const Relocation &a, const Relocation &b) {

View File

@ -173,35 +173,4 @@ void ObjectFile::resolve_symbols(Context &ctx) {
}
}
static i64 read_addend(u8 *buf, MachRel r) {
switch (r.p2size) {
case 0: return *(i8 *)(buf + r.offset);
case 1: return *(i16 *)(buf + r.offset);
case 2: return *(i32 *)(buf + r.offset);
case 3: return *(i64 *)(buf + r.offset);
}
unreachable();
}
Relocation ObjectFile::read_reloc(Context &ctx, const MachSection &hdr, MachRel r) {
i64 addend = read_addend((u8 *)mf->data + hdr.offset, r);
if (r.is_extern)
return {r.offset, (bool)r.is_pcrel, addend, syms[r.idx], nullptr};
u32 addr;
if (r.is_pcrel) {
if (r.p2size != 2)
Fatal(ctx) << *this << ": invalid PC-relative reloc: " << r.offset;
addr = hdr.addr + r.offset + 4 + addend;
} else {
addr = addend;
}
Subsection *target = sections[r.idx - 1]->find_subsection(ctx, addr);
if (!target)
Fatal(ctx) << *this << ": bad relocation: " << r.offset;
return {r.offset, (bool)r.is_pcrel, addr - target->input_addr, nullptr, target};
}
} // namespace mold::macho