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:
parent
96b07d875d
commit
d176ed8fbb
@ -27,46 +27,13 @@ Subsection *InputSection::find_subsection(Context &ctx, u32 addr) {
|
||||
return &*(it - 1);
|
||||
}
|
||||
|
||||
static i64 read_addend(u8 *buf, u32 offset, u32 p2size) {
|
||||
switch (p2size) {
|
||||
case 0: return *(i8 *)(buf + offset);
|
||||
case 1: return *(i16 *)(buf + offset);
|
||||
case 2: return *(i32 *)(buf + offset);
|
||||
case 3: return *(i64 *)(buf + offset);
|
||||
}
|
||||
unreachable();
|
||||
}
|
||||
|
||||
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++) {
|
||||
MachRel &r = rel[i];
|
||||
i64 addend = read_addend((u8 *)contents.data(), r.offset, r.p2size);
|
||||
|
||||
if (r.is_extern) {
|
||||
rels.push_back({r.offset, (bool)r.is_pcrel, addend, file.syms[r.idx],
|
||||
nullptr});
|
||||
} else {
|
||||
u32 addr;
|
||||
if (r.is_pcrel) {
|
||||
if (r.p2size != 2)
|
||||
Fatal(ctx) << *this << ": invalid PC-relative reloc: " << i;
|
||||
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) << *this << ": bad relocation: " << i;
|
||||
|
||||
rels.push_back({r.offset, (bool)r.is_pcrel, addr - target->input_addr,
|
||||
nullptr, target});
|
||||
}
|
||||
}
|
||||
for (i64 i = 0; i < hdr.nreloc; i++)
|
||||
rels.push_back(file.read_reloc(ctx, hdr, rel[i]));
|
||||
|
||||
// Sort `rels` vector
|
||||
sort(rels, [](const Relocation &a, const Relocation &b) {
|
||||
|
@ -45,6 +45,8 @@ public:
|
||||
void parse_compact_unwind(Context &ctx, MachSection &hdr);
|
||||
void resolve_symbols(Context &ctx);
|
||||
|
||||
Relocation read_reloc(Context &ctx, const MachSection &hdr, MachRel r);
|
||||
|
||||
MappedFile<Context> *mf;
|
||||
std::vector<std::unique_ptr<InputSection>> sections;
|
||||
std::vector<Symbol *> syms;
|
||||
|
@ -79,18 +79,33 @@ void ObjectFile::parse_compact_unwind(Context &ctx, MachSection &hdr) {
|
||||
|
||||
// Read comapct unwind entries
|
||||
for (i64 i = 0; i < num_entries; i++) {
|
||||
CompactUnwindEntry &src = ((CompactUnwindEntry *)contents.data())[i];
|
||||
unwind_entries.push_back({{}, src.code_len, src.compact_unwind_info, {}, {}});
|
||||
CompactUnwindEntry &ent = ((CompactUnwindEntry *)contents.data())[i];
|
||||
unwind_entries.push_back({{}, ent.code_len, ent.compact_unwind_info, {}, {}});
|
||||
}
|
||||
|
||||
// Read relocations
|
||||
std::vector<MachRel> mach_rels((MachRel *)(mf->data + hdr.reloff),
|
||||
(MachRel *)(mf->data + hdr.reloff) + hdr.nreloc);
|
||||
MachRel *mach_rels = (MachRel *)(mf->data + hdr.reloff);
|
||||
for (i64 i = 0; i < hdr.nreloc; i++) {
|
||||
MachRel &r = mach_rels[i];
|
||||
i64 idx = r.offset / sizeof(CompactUnwindEntry);
|
||||
i64 offset = r.offset % sizeof(CompactUnwindEntry);
|
||||
|
||||
sort(mach_rels, [](const MachRel &a, const MachRel &b) {
|
||||
return a.offset < b.offset;
|
||||
});
|
||||
// if (idx >= unwind_entries.size())
|
||||
// Fatal(ctx) << *this << ": relocation offset too large: " << i;
|
||||
UnwindEntry &ent = unwind_entries[idx];
|
||||
|
||||
if (offset == offsetof(CompactUnwindEntry, code_start)) {
|
||||
|
||||
}
|
||||
|
||||
if (offset == offsetof(CompactUnwindEntry, personality)) {
|
||||
}
|
||||
|
||||
if (offset == offsetof(CompactUnwindEntry, lsda)) {
|
||||
}
|
||||
|
||||
// Fatal(ctx) << *this << ": unsupported relocation: " << i;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectFile::resolve_symbols(Context &ctx) {
|
||||
@ -113,4 +128,35 @@ 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->get_contents().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
|
||||
|
Loading…
Reference in New Issue
Block a user