Skip to content

Commit

Permalink
macho: allocate sections for object file
Browse files Browse the repository at this point in the history
  • Loading branch information
kubkon committed Dec 31, 2023
1 parent 59d64a9 commit d0a85af
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/MachO.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2740,7 +2740,7 @@ pub fn addSection(
const gpa = self.base.allocator;
const index = @as(u8, @intCast(try self.sections.addOne(gpa)));
self.sections.set(index, .{
.segment_id = undefined, // Segments will be created automatically later down the pipeline.
.segment_id = 0, // Segments will be created automatically later down the pipeline.
.header = .{
.sectname = makeStaticString(sectname),
.segname = makeStaticString(segname),
Expand Down
32 changes: 32 additions & 0 deletions src/MachO/load_commands.zig
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,38 @@ pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) u32 {
return @as(u32, @intCast(sizeofcmds));
}

pub fn calcLoadCommandsSizeObject(macho_file: *MachO) u32 {
const options = &macho_file.options;
var sizeofcmds: u64 = 0;

// LC_SEGMENT_64
{
assert(macho_file.segments.items.len == 1);
sizeofcmds += @sizeOf(macho.segment_command_64);
const seg = macho_file.segments.items[0];
sizeofcmds += seg.nsects * @sizeOf(macho.section_64);
}

// LC_DATA_IN_CODE
sizeofcmds += @sizeOf(macho.linkedit_data_command);
// LC_SYMTAB
sizeofcmds += @sizeOf(macho.symtab_command);
// LC_DYSYMTAB
sizeofcmds += @sizeOf(macho.dysymtab_command);

if (options.platform) |platform| {
if (platform.isBuildVersionCompatible()) {
// LC_BUILD_VERSION
sizeofcmds += @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version);
} else {
// LC_VERSION_MIN_*
sizeofcmds += @sizeOf(macho.version_min_command);
}
}

return @as(u32, @intCast(sizeofcmds));
}

pub fn calcMinHeaderPadSize(macho_file: *MachO) u32 {
const options = &macho_file.options;
var padding: u32 = calcLoadCommandsSize(macho_file, false) + (options.headerpad orelse 0);
Expand Down
39 changes: 39 additions & 0 deletions src/MachO/relocatable.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ pub fn flush(macho_file: *MachO) !void {
try macho_file.addAtomsToSections();
try calcSectionSizes(macho_file);

{
// For relocatable, we only ever need a single segment so create it now.
const prot: macho.vm_prot_t = macho.PROT.READ | macho.PROT.WRITE | macho.PROT.EXEC;
try macho_file.segments.append(macho_file.base.allocator, .{
.cmdsize = @sizeOf(macho.segment_command_64),
.segname = MachO.makeStaticString(""),
.maxprot = prot,
.initprot = prot,
});
}

try allocateSections(macho_file);

state_log.debug("{}", .{macho_file.dumpState()});

macho_file.base.fatal("-r mode unimplemented", .{});
Expand Down Expand Up @@ -92,6 +105,11 @@ fn calcSectionSizes(macho_file: *MachO) !void {
}

// TODO __DWARF sections

// TODO relocations
// they should follow contiguously *after* we lay out contents of each section
// *but* they should be before __LINKEDIT sections (symtab, data-in-code)

}

fn calcCompactUnwindSize(macho_file: *MachO) usize {
Expand All @@ -108,8 +126,29 @@ fn calcCompactUnwindSize(macho_file: *MachO) usize {
return size * @sizeOf(u32);
}

fn allocateSections(macho_file: *MachO) !void {
const headerpad = load_commands.calcLoadCommandsSizeObject(macho_file);
var vmaddr: u64 = 0;
var fileoff = headerpad;
const slice = macho_file.sections.slice();

for (slice.items(.header)) |*header| {
const alignment = try math.powi(u32, 2, header.@"align");
vmaddr = mem.alignForward(u64, vmaddr, alignment);
header.addr = vmaddr;
vmaddr += header.size;

if (!header.isZerofill()) {
fileoff = mem.alignForward(u32, fileoff, alignment);
header.offset = fileoff;
fileoff += @intCast(header.size);
}
}
}

const assert = std.debug.assert;
const eh_frame = @import("eh_frame.zig");
const load_commands = @import("load_commands.zig");
const macho = std.macho;
const math = std.math;
const mem = std.mem;
Expand Down

0 comments on commit d0a85af

Please sign in to comment.