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

[Mach-O] wip

This commit is contained in:
Rui Ueyama 2021-09-17 21:57:34 +09:00
parent c6d3370f07
commit 1dc41ab2d0
3 changed files with 129 additions and 62 deletions

View File

@ -46,8 +46,26 @@ void create_synthetic_sections(Context &ctx) {
ctx.data_segment->sections.push_back(new LaSymbolPtrSection(*ctx.data_segment));
ctx.data_segment->sections.push_back(new DataSection(*ctx.data_segment));
ctx.linkedit.reset(new OutputLinkEditChunk(*ctx.linkedit_segment));
ctx.linkedit_segment->sections.push_back(ctx.linkedit.get());
ctx.rebase.reset(new OutputRebaseSection(*ctx.linkedit_segment));
ctx.linkedit_segment->sections.push_back(ctx.rebase.get());
ctx.bind.reset(new OutputBindSection(*ctx.linkedit_segment));
ctx.linkedit_segment->sections.push_back(ctx.bind.get());
ctx.lazy_bind.reset(new OutputLazyBindSection(*ctx.linkedit_segment));
ctx.linkedit_segment->sections.push_back(ctx.lazy_bind.get());
ctx.export_.reset(new OutputExportSection(*ctx.linkedit_segment));
ctx.linkedit_segment->sections.push_back(ctx.export_.get());
ctx.function_starts.reset(new OutputFunctionStartsSection(*ctx.linkedit_segment));
ctx.linkedit_segment->sections.push_back(ctx.function_starts.get());
ctx.symtab.reset(new OutputSymtabSection(*ctx.linkedit_segment));
ctx.linkedit_segment->sections.push_back(ctx.symtab.get());
ctx.strtab.reset(new OutputStrtabSection(*ctx.linkedit_segment));
ctx.linkedit_segment->sections.push_back(ctx.strtab.get());
}
void compute_segment_sizes(Context &ctx) {

View File

@ -67,42 +67,90 @@ private:
std::vector<u8> contents;
};
class OutputLinkEditChunk : public OutputSection {
class OutputRebaseSection : public OutputSection {
public:
OutputLinkEditChunk(OutputSegment &parent) : OutputSection(parent) {
OutputRebaseSection(OutputSegment &parent) : OutputSection(parent) {
is_hidden = true;
hdr.size = contents.size();
}
void update_hdr(Context &ctx) override;
void copy_buf(Context &ctx) override;
i64 vmaddr = 0;
std::vector<u8> contents = {0x11, 0x23, 0x00, 0x51, 0x00, 0x00, 0x00, 0x00};
};
std::vector<u8> rebase = {0x11, 0x23, 0x00, 0x51, 0x00, 0x00, 0x00, 0x00};
class OutputBindSection : public OutputSection {
public:
OutputBindSection(OutputSegment &parent) : OutputSection(parent) {
is_hidden = true;
hdr.size = contents.size();
}
std::vector<u8> bind = {
void copy_buf(Context &ctx) override;
std::vector<u8> contents = {
0x11, 0x40, 0x64, 0x79, 0x6c, 0x64, 0x5f, 0x73, 0x74, 0x75, 0x62, 0x5f,
0x62, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x00, 0x51, 0x72, 0x00, 0x90, 0x00,
};
};
std::vector<u8> lazy_bind = {
class OutputLazyBindSection : public OutputSection {
public:
OutputLazyBindSection(OutputSegment &parent) : OutputSection(parent) {
is_hidden = true;
hdr.size = contents.size();
}
void copy_buf(Context &ctx) override;
std::vector<u8> contents = {
0x73, 0x00, 0x11, 0x40, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x00,
0x90, 0x00, 0x00, 0x00,
};
};
std::vector<u8> export_ = {
class OutputExportSection : public OutputSection {
public:
OutputExportSection(OutputSegment &parent) : OutputSection(parent) {
is_hidden = true;
hdr.size = contents.size();
}
void copy_buf(Context &ctx) override;
std::vector<u8> contents = {
0x00, 0x01, 0x5f, 0x00, 0x05, 0x00, 0x03, 0x5f, 0x6d, 0x68, 0x5f, 0x65,
0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65,
0x72, 0x00, 0x28, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x00, 0x2c, 0x6d, 0x61,
0x69, 0x6e, 0x00, 0x31, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0xd0, 0x7e,
0x00, 0x03, 0x00, 0xf0, 0x7e, 0x00, 0x00, 0x00,
};
};
std::vector<u8> function_starts = {
class OutputFunctionStartsSection : public OutputSection {
public:
OutputFunctionStartsSection(OutputSegment &parent) : OutputSection(parent) {
is_hidden = true;
hdr.size = contents.size();
}
void copy_buf(Context &ctx) override;
std::vector<u8> contents = {
0xd0, 0x7e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00
};
};
std::vector<u8> symtab = {
class OutputSymtabSection : public OutputSection {
public:
OutputSymtabSection(OutputSegment &parent) : OutputSection(parent) {
is_hidden = true;
hdr.size = contents.size();
}
void copy_buf(Context &ctx) override;
std::vector<u8> contents = {
0x3c, 0x00, 0x00, 0x00, 0x0e, 0x08, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x01, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
@ -112,8 +160,18 @@ public:
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
};
std::vector<u8> strtab = {
class OutputStrtabSection : public OutputSection {
public:
OutputStrtabSection(OutputSegment &parent) : OutputSection(parent) {
is_hidden = true;
hdr.size = contents.size();
}
void copy_buf(Context &ctx) override;
std::vector<u8> contents = {
0x20, 0x00, 0x5f, 0x5f, 0x6d, 0x68, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75,
0x74, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x00, 0x5f, 0x68,
0x65, 0x6c, 0x6c, 0x6f, 0x00, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x5f,
@ -122,9 +180,6 @@ public:
0x5f, 0x5f, 0x64, 0x79, 0x6c, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61,
0x74, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
i64 symoff = 0;
i64 stroff = 0;
};
class TextSection : public OutputSection {
@ -236,7 +291,14 @@ struct Context {
std::unique_ptr<OutputSegment> data_const_segment;
std::unique_ptr<OutputSegment> data_segment;
std::unique_ptr<OutputSegment> linkedit_segment;
std::unique_ptr<OutputLinkEditChunk> linkedit;
std::unique_ptr<OutputRebaseSection> rebase;
std::unique_ptr<OutputBindSection> bind;
std::unique_ptr<OutputLazyBindSection> lazy_bind;
std::unique_ptr<OutputExportSection> export_;
std::unique_ptr<OutputFunctionStartsSection> function_starts;
std::unique_ptr<OutputSymtabSection> symtab;
std::unique_ptr<OutputStrtabSection> strtab;
std::vector<OutputSegment *> segments;
};

View File

@ -20,23 +20,19 @@ static DyldInfoCommand create_dyld_info_only_cmd(Context &ctx) {
cmd.cmd = LC_DYLD_INFO_ONLY;
cmd.cmdsize = sizeof(cmd);
i64 off = ctx.linkedit->parent.cmd.fileoff + ctx.linkedit->hdr.offset;
i64 off = ctx.linkedit_segment->cmd.fileoff;
cmd.rebase_off = off;
cmd.rebase_size = ctx.linkedit->rebase.size();
off += ctx.linkedit->rebase.size();
cmd.rebase_off = off + ctx.rebase->hdr.offset;
cmd.rebase_size = ctx.rebase->contents.size();
cmd.bind_off = off;
cmd.bind_size = ctx.linkedit->bind.size();
off += ctx.linkedit->bind.size();
cmd.bind_size = off + ctx.bind->hdr.offset;
off += ctx.bind->contents.size();
cmd.lazy_bind_off = off;
cmd.lazy_bind_size = ctx.linkedit->lazy_bind.size();
off += ctx.linkedit->lazy_bind.size();
cmd.lazy_bind_size = off + ctx.lazy_bind->hdr.offset;
off += ctx.lazy_bind->contents.size();
cmd.export_off = off;
cmd.export_size = ctx.linkedit->export_.size();
off += ctx.linkedit->export_.size();
cmd.export_size = ctx.export_->hdr.offset;
off += ctx.export_->contents.size();
return cmd;
}
@ -44,12 +40,10 @@ static SymtabCommand create_symtab_cmd(Context &ctx) {
SymtabCommand cmd = {};
cmd.cmd = LC_SYMTAB;
cmd.cmdsize = sizeof(cmd);
cmd.symoff = ctx.linkedit->parent.cmd.fileoff +
ctx.linkedit->hdr.offset + ctx.linkedit->symoff;
cmd.nsyms = ctx.linkedit->symtab.size() / sizeof(MachSym);
cmd.stroff = ctx.linkedit->parent.cmd.fileoff +
ctx.linkedit->hdr.offset + ctx.linkedit->stroff;
cmd.strsize = ctx.linkedit->strtab.size();
cmd.symoff = ctx.linkedit_segment->cmd.fileoff + ctx.symtab->hdr.offset;
cmd.nsyms = ctx.symtab->contents.size() / sizeof(MachSym);
cmd.stroff = ctx.linkedit_segment->cmd.fileoff + ctx.strtab->hdr.offset;
cmd.strsize = ctx.strtab->contents.size();
return cmd;
}
@ -145,39 +139,32 @@ void OutputSegment::copy_buf(Context &ctx) {
sec->copy_buf(ctx);
}
void OutputLinkEditChunk::update_hdr(Context &ctx) {
hdr.size = rebase.size() + bind.size() + lazy_bind.size() +
export_.size() + function_starts.size() + symtab.size() +
strtab.size();
symoff = rebase.size() + bind.size() + lazy_bind.size() +
export_.size() + function_starts.size();
stroff = symoff + symtab.size();
void OutputRebaseSection::copy_buf(Context &ctx) {
write_vector(ctx.buf + parent.cmd.fileoff + hdr.offset, contents);
}
void OutputLinkEditChunk::copy_buf(Context &ctx) {
u8 *ptr = ctx.buf + parent.cmd.fileoff + hdr.offset;
void OutputBindSection::copy_buf(Context &ctx) {
write_vector(ctx.buf + parent.cmd.fileoff + hdr.offset, contents);
}
write_vector(ptr, rebase);
ptr += rebase.size();
void OutputLazyBindSection::copy_buf(Context &ctx) {
write_vector(ctx.buf + parent.cmd.fileoff + hdr.offset, contents);
}
write_vector(ptr, bind);
ptr += bind.size();
void OutputExportSection::copy_buf(Context &ctx) {
write_vector(ctx.buf + parent.cmd.fileoff + hdr.offset, contents);
}
write_vector(ptr, lazy_bind);
ptr += lazy_bind.size();
void OutputFunctionStartsSection::copy_buf(Context &ctx) {
write_vector(ctx.buf + parent.cmd.fileoff + hdr.offset, contents);
}
write_vector(ptr, export_);
ptr += export_.size();
void OutputSymtabSection::copy_buf(Context &ctx) {
write_vector(ctx.buf + parent.cmd.fileoff + hdr.offset, contents);
}
write_vector(ptr, function_starts);
ptr += function_starts.size();
write_vector(ptr, symtab);
ptr += symtab.size();
write_vector(ptr, strtab);
ptr += strtab.size();
void OutputStrtabSection::copy_buf(Context &ctx) {
write_vector(ctx.buf + parent.cmd.fileoff + hdr.offset, contents);
}
OutputSection::OutputSection(OutputSegment &parent)