mirror of
https://github.com/ziglang/zig.git
synced 2026-02-20 00:08:56 +00:00
macho: prealloc DATA_CONST and DATA segments
This commit is contained in:
parent
5487dd13ea
commit
3d07f057b1
@ -52,6 +52,8 @@ load_commands: std.ArrayListUnmanaged(LoadCommand) = .{},
|
||||
pagezero_segment_cmd_index: ?u16 = null,
|
||||
/// __TEXT segment
|
||||
text_segment_cmd_index: ?u16 = null,
|
||||
/// __DATA_CONST segment
|
||||
data_const_segment_cmd_index: ?u16 = null,
|
||||
/// __DATA segment
|
||||
data_segment_cmd_index: ?u16 = null,
|
||||
/// __LINKEDIT segment
|
||||
@ -1519,6 +1521,64 @@ pub fn populateMissingMetadata(self: *MachO) !void {
|
||||
self.header_dirty = true;
|
||||
self.load_commands_dirty = true;
|
||||
}
|
||||
if (self.data_const_segment_cmd_index == null) {
|
||||
self.data_const_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
|
||||
const maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE | macho.VM_PROT_EXECUTE;
|
||||
const initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE;
|
||||
const address_and_offset = self.nextSegmentAddressAndOffset();
|
||||
|
||||
const ideal_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
|
||||
const needed_size = mem.alignForwardGeneric(u64, satMul(ideal_size, alloc_num) / alloc_den, self.page_size);
|
||||
|
||||
log.debug("found __DATA_CONST segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size });
|
||||
|
||||
try self.load_commands.append(self.base.allocator, .{
|
||||
.Segment = SegmentCommand.empty(.{
|
||||
.cmd = macho.LC_SEGMENT_64,
|
||||
.cmdsize = @sizeOf(macho.segment_command_64),
|
||||
.segname = makeStaticString("__DATA_CONST"),
|
||||
.vmaddr = address_and_offset.address,
|
||||
.vmsize = needed_size,
|
||||
.fileoff = address_and_offset.offset,
|
||||
.filesize = needed_size,
|
||||
.maxprot = maxprot,
|
||||
.initprot = initprot,
|
||||
.nsects = 0,
|
||||
.flags = 0,
|
||||
}),
|
||||
});
|
||||
self.header_dirty = true;
|
||||
self.load_commands_dirty = true;
|
||||
}
|
||||
if (self.data_segment_cmd_index == null) {
|
||||
self.data_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
|
||||
const maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE | macho.VM_PROT_EXECUTE;
|
||||
const initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE;
|
||||
const address_and_offset = self.nextSegmentAddressAndOffset();
|
||||
|
||||
const ideal_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
|
||||
const needed_size = mem.alignForwardGeneric(u64, satMul(ideal_size, alloc_num) / alloc_den, self.page_size);
|
||||
|
||||
log.debug("found __DATA segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size });
|
||||
|
||||
try self.load_commands.append(self.base.allocator, .{
|
||||
.Segment = SegmentCommand.empty(.{
|
||||
.cmd = macho.LC_SEGMENT_64,
|
||||
.cmdsize = @sizeOf(macho.segment_command_64),
|
||||
.segname = makeStaticString("__DATA"),
|
||||
.vmaddr = address_and_offset.address,
|
||||
.vmsize = needed_size,
|
||||
.fileoff = address_and_offset.offset,
|
||||
.filesize = needed_size,
|
||||
.maxprot = maxprot,
|
||||
.initprot = initprot,
|
||||
.nsects = 0,
|
||||
.flags = 0,
|
||||
}),
|
||||
});
|
||||
self.header_dirty = true;
|
||||
self.load_commands_dirty = true;
|
||||
}
|
||||
if (self.linkedit_segment_cmd_index == null) {
|
||||
self.linkedit_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
|
||||
|
||||
@ -1907,16 +1967,13 @@ const NextSegmentAddressAndOffset = struct {
|
||||
};
|
||||
|
||||
fn nextSegmentAddressAndOffset(self: *MachO) NextSegmentAddressAndOffset {
|
||||
const prev_segment_idx = blk: {
|
||||
if (self.data_segment_cmd_index) |idx| {
|
||||
break :blk idx;
|
||||
} else if (self.text_segment_cmd_index) |idx| {
|
||||
break :blk idx;
|
||||
} else {
|
||||
unreachable; // unhandled LC_SEGMENT_64 load command before __TEXT
|
||||
var prev_segment_idx: ?usize = null; // We use optional here for safety.
|
||||
for (self.load_commands.items) |cmd, i| {
|
||||
if (cmd == .Segment) {
|
||||
prev_segment_idx = i;
|
||||
}
|
||||
};
|
||||
const prev_segment = self.load_commands.items[prev_segment_idx].Segment;
|
||||
}
|
||||
const prev_segment = self.load_commands.items[prev_segment_idx.?].Segment;
|
||||
const address = prev_segment.inner.vmaddr + prev_segment.inner.vmsize;
|
||||
const offset = prev_segment.inner.fileoff + prev_segment.inner.filesize;
|
||||
return .{
|
||||
@ -2464,6 +2521,8 @@ fn parseFromFile(self: *MachO, file: fs.File) !void {
|
||||
}
|
||||
} else if (parseAndCmpName(&x.inner.segname, "__DATA")) {
|
||||
self.data_segment_cmd_index = i;
|
||||
} else if (parseAndCmpName(&x.inner.segname, "__DATA_CONST")) {
|
||||
self.data_const_segment_cmd_index = i;
|
||||
}
|
||||
},
|
||||
macho.LC_DYLD_INFO_ONLY => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user