1
1
mirror of https://github.com/rui314/mold.git synced 2024-11-10 19:26:38 +03:00

[Mach-O] wip

This commit is contained in:
Rui Ueyama 2021-09-18 16:56:00 +09:00
parent e8aa31cd8b
commit da5effd52d
3 changed files with 49 additions and 12 deletions

View File

@ -83,12 +83,12 @@ i64 assign_offsets(Context &ctx) {
assert(seg->cmd.filesize % PAGE_SIZE == 0);
assert(seg->cmd.vmsize % PAGE_SIZE == 0);
seg->cmd.fileoff = fileoff;
seg->cmd.vmaddr = vmaddr;
seg->update_hdr(ctx);
seg->cmd.fileoff = fileoff;
fileoff += seg->cmd.filesize;
seg->cmd.vmaddr = vmaddr;
vmaddr += seg->cmd.vmsize;
}

View File

@ -236,6 +236,22 @@ OutputSegment::OutputSegment(std::string_view name, u32 prot, u32 flags) {
cmd.flags = flags;
}
static i64 compute_text_padding_size(std::span<OutputSection *> sections) {
u64 addr = 0;
// Skip the first two sections which are the mach-o header and the
// load commands.
for (i64 i = sections.size() - 1; i >= 2; i--) {
OutputSection &sec = *sections[i];
addr -= sec.hdr.size;
addr = align_down(addr, 1 << sec.hdr.p2align);
}
addr -= sections[0]->hdr.size;
addr -= sections[1]->hdr.size;
return addr % PAGE_SIZE;
}
void OutputSegment::update_hdr(Context &ctx) {
cmd.cmdsize = sizeof(SegmentCommand);
cmd.nsects = 0;
@ -247,17 +263,33 @@ void OutputSegment::update_hdr(Context &ctx) {
}
}
i64 fileoff = 0;
for (OutputSection *sec : sections) {
sec->update_hdr(ctx);
fileoff = align_to(fileoff, 1 << sec->hdr.p2align);
sec->hdr.offset = fileoff;
fileoff += sec->hdr.size;
i64 offset = 0;
auto set_offset = [&](OutputSection &sec) {
sec.update_hdr(ctx);
offset = align_to(offset, 1 << sec.hdr.p2align);
sec.hdr.addr = offset;
sec.hdr.offset = offset;
offset += sec.hdr.size;
};
if (this == ctx.segments[0]) {
// In the __TEXT segment, any extra space is put after the load commands
// so that a post-processing tool can add more load commands there.
set_offset(*sections[0]);
set_offset(*sections[1]);
offset += compute_text_padding_size(sections);
for (OutputSection *sec : std::span(sections).subspan(2))
set_offset(*sec);
} else {
// In other sections, any extra space is put at end of segment.
for (OutputSection *sec : sections)
set_offset(*sec);
}
fileoff = align_to(fileoff, PAGE_SIZE);
cmd.vmsize = fileoff;
cmd.filesize = fileoff;
offset = align_to(offset, PAGE_SIZE);
cmd.vmsize = offset;
cmd.filesize = offset;
}
void OutputSegment::copy_buf(Context &ctx) {

5
mold.h
View File

@ -134,6 +134,11 @@ inline u64 align_to(u64 val, u64 align) {
return (val + align - 1) & ~(align - 1);
}
inline u64 align_down(u64 val, u64 align) {
assert(__builtin_popcount(align) == 1);
return val & ~(align - 1);
}
inline u64 next_power_of_two(u64 val) {
assert(val >> 63 == 0);
if (val == 0 || val == 1)