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 13:54:40 +09:00
parent 211bc1810b
commit 079900fa84
5 changed files with 44 additions and 4 deletions

View File

@ -250,7 +250,7 @@ void dump_file(std::string path) {
}
case LC_FUNCTION_STARTS: {
std::cout << "LC_FUNCTION_STARTS\n";
LinkeditDataCommand &cmd = *(LinkeditDataCommand *)&lc;
LinkEditDataCommand &cmd = *(LinkEditDataCommand *)&lc;
std::cout << " dataoff: 0x" << cmd.dataoff
<< "\n datasize: 0x" << cmd.datasize
<< "\n";
@ -258,7 +258,7 @@ void dump_file(std::string path) {
}
case LC_MAIN: {
std::cout << "LC_MAIN\n";
LinkeditDataCommand &cmd = *(LinkeditDataCommand *)&lc;
LinkEditDataCommand &cmd = *(LinkEditDataCommand *)&lc;
std::cout << " dataoff: 0x" << cmd.dataoff
<< "\n datasize: 0x" << cmd.datasize
<< "\n";
@ -266,7 +266,7 @@ void dump_file(std::string path) {
}
case LC_DATA_IN_CODE: {
std::cout << "LC_DATA_IN_CODE\n";
LinkeditDataCommand &cmd = *(LinkeditDataCommand *)&lc;
LinkEditDataCommand &cmd = *(LinkEditDataCommand *)&lc;
std::cout << " dataoff: 0x" << cmd.dataoff
<< "\n datasize: 0x" << cmd.datasize
<< "\n";

View File

@ -367,7 +367,7 @@ struct DyldInfoCommand {
u32 export_size;
};
struct LinkeditDataCommand {
struct LinkEditDataCommand {
u32 cmd;
u32 cmdsize;
u32 dataoff;

View File

@ -24,6 +24,7 @@ void create_synthetic_sections(Context &ctx) {
SG_READ_ONLY));
add(ctx.data_segment =
std::make_unique<OutputSegment>("__DATA", VM_PROT_READ | VM_PROT_WRITE, 0));
add(ctx.linkedit_chunk = std::make_unique<OutputLinkEditChunk>());
ctx.text_segment->sections.push_back(new TextSection(*ctx.text_segment));
ctx.text_segment->sections.push_back(new StubsSection(*ctx.text_segment));
@ -58,6 +59,7 @@ i64 assign_offsets(Context &ctx) {
}
}
ctx.linkedit_chunk->vmaddr = align_to(vmaddr, PAGE_SIZE);
return fileoff;
}

View File

@ -65,6 +65,16 @@ public:
std::vector<OutputSection *> sections;
};
class OutputLinkEditChunk : public Chunk {
public:
OutputLinkEditChunk();
void update_hdr(Context &ctx) override;
void copy_buf(Context &ctx) override;
i64 vmaddr = 0;
std::vector<u8> rebase = {0, 0, 0, 0, 0, 0, 0, 0};
};
class OutputSection {
public:
virtual ~OutputSection() = default;
@ -186,6 +196,7 @@ struct Context {
std::unique_ptr<OutputSegment> text_segment;
std::unique_ptr<OutputSegment> data_const_segment;
std::unique_ptr<OutputSegment> data_segment;
std::unique_ptr<OutputLinkEditChunk> linkedit_chunk;
std::vector<Chunk *> chunks;
};

View File

@ -48,6 +48,21 @@ create_load_commands(Context &ctx) {
}
}
// Add a __LINKEDIT command
SegmentCommand lnk = {};
lnk.cmd = LC_SEGMENT_64;
lnk.cmdsize = sizeof(SegmentCommand);
strcpy(lnk.segname, "__LINKEDIT");
lnk.vmaddr = ctx.linkedit_chunk->vmaddr;
lnk.vmsize = align_to(ctx.linkedit_chunk->filesize, PAGE_SIZE);
lnk.fileoff = ctx.linkedit_chunk->fileoff;
lnk.filesize = ctx.linkedit_chunk->filesize;
lnk.maxprot = VM_PROT_READ;
lnk.initprot = VM_PROT_READ;
add(lnk);
ncmds++;
return {vec, ncmds};
}
@ -97,6 +112,18 @@ void OutputSegment::copy_buf(Context &ctx) {
sec->copy_buf(ctx);
}
OutputLinkEditChunk::OutputLinkEditChunk() {
p2align = __builtin_ctz(PAGE_SIZE);
}
void OutputLinkEditChunk::update_hdr(Context &ctx) {
filesize = rebase.size();
}
void OutputLinkEditChunk::copy_buf(Context &ctx) {
write_vector(ctx.buf + fileoff, rebase);
}
OutputSection::OutputSection(OutputSegment &parent, std::string_view name)
: parent(parent) {
assert(name.size() <= sizeof(hdr.sectname));