mirror of
https://github.com/ziglang/zig.git
synced 2025-12-24 23:23:07 +00:00
macho: alloc improvement for relocatable
This commit is contained in:
parent
102846315c
commit
dcb7f5791a
@ -3202,20 +3202,22 @@ fn detectAllocCollision(self: *MachO, start: u64, size: u64) ?u64 {
|
||||
|
||||
const end = start + padToIdeal(size);
|
||||
|
||||
for (self.sections.items(.header)) |header| {
|
||||
if (header.isZerofill()) continue;
|
||||
const increased_size = padToIdeal(header.size);
|
||||
const test_end = header.offset +| increased_size;
|
||||
if (end > header.offset and start < test_end) {
|
||||
return test_end;
|
||||
if (self.base.isRelocatable()) {
|
||||
for (self.sections.items(.header)) |header| {
|
||||
if (header.isZerofill()) continue;
|
||||
const increased_size = padToIdeal(header.size);
|
||||
const test_end = header.offset +| increased_size;
|
||||
if (end > header.offset and start < test_end) {
|
||||
return test_end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (self.segments.items) |seg| {
|
||||
const increased_size = padToIdeal(seg.filesize);
|
||||
const test_end = seg.fileoff +| increased_size;
|
||||
if (end > seg.fileoff and start < test_end) {
|
||||
return test_end;
|
||||
} else {
|
||||
for (self.segments.items) |seg| {
|
||||
const increased_size = padToIdeal(seg.filesize);
|
||||
const test_end = seg.fileoff +| increased_size;
|
||||
if (end > seg.fileoff and start < test_end) {
|
||||
return test_end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3223,27 +3225,29 @@ fn detectAllocCollision(self: *MachO, start: u64, size: u64) ?u64 {
|
||||
}
|
||||
|
||||
fn detectAllocCollisionVirtual(self: *MachO, start: u64, size: u64) ?u64 {
|
||||
// Conservatively commit one page size as reserved space for the headers as we
|
||||
// expect it to grow and everything else be moved in flush anyhow.
|
||||
const header_size = self.getPageSize();
|
||||
if (start < header_size)
|
||||
return header_size;
|
||||
|
||||
const end = start + padToIdeal(size);
|
||||
|
||||
for (self.sections.items(.header)) |header| {
|
||||
const increased_size = padToIdeal(header.size);
|
||||
const test_end = header.addr +| increased_size;
|
||||
if (end > header.addr and start < test_end) {
|
||||
return test_end;
|
||||
if (self.base.isRelocatable()) {
|
||||
for (self.sections.items(.header)) |header| {
|
||||
const increased_size = padToIdeal(header.size);
|
||||
const test_end = header.addr +| increased_size;
|
||||
if (end > header.addr and start < test_end) {
|
||||
return test_end;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Conservatively commit one page size as reserved space for the headers as we
|
||||
// expect it to grow and everything else be moved in flush anyhow.
|
||||
const header_size = self.getPageSize();
|
||||
if (start < header_size)
|
||||
return header_size;
|
||||
|
||||
for (self.segments.items) |seg| {
|
||||
const increased_size = padToIdeal(seg.vmsize);
|
||||
const test_end = seg.vmaddr +| increased_size;
|
||||
if (end > seg.vmaddr and start < test_end) {
|
||||
return test_end;
|
||||
for (self.segments.items) |seg| {
|
||||
const increased_size = padToIdeal(seg.vmsize);
|
||||
const test_end = seg.vmaddr +| increased_size;
|
||||
if (end > seg.vmaddr and start < test_end) {
|
||||
return test_end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3252,21 +3256,29 @@ fn detectAllocCollisionVirtual(self: *MachO, start: u64, size: u64) ?u64 {
|
||||
|
||||
pub fn allocatedSize(self: *MachO, start: u64) u64 {
|
||||
if (start == 0) return 0;
|
||||
|
||||
var min_pos: u64 = std.math.maxInt(u64);
|
||||
for (self.sections.items(.header)) |header| {
|
||||
if (header.offset <= start) continue;
|
||||
if (header.offset < min_pos) min_pos = header.offset;
|
||||
}
|
||||
for (self.segments.items) |seg| {
|
||||
if (seg.fileoff <= start) continue;
|
||||
if (seg.fileoff < min_pos) min_pos = seg.fileoff;
|
||||
|
||||
if (self.base.isRelocatable()) {
|
||||
for (self.sections.items(.header)) |header| {
|
||||
if (header.offset <= start) continue;
|
||||
if (header.offset < min_pos) min_pos = header.offset;
|
||||
}
|
||||
} else {
|
||||
for (self.segments.items) |seg| {
|
||||
if (seg.fileoff <= start) continue;
|
||||
if (seg.fileoff < min_pos) min_pos = seg.fileoff;
|
||||
}
|
||||
}
|
||||
|
||||
return min_pos - start;
|
||||
}
|
||||
|
||||
pub fn allocatedSizeVirtual(self: *MachO, start: u64) u64 {
|
||||
if (start == 0) return 0;
|
||||
|
||||
var min_pos: u64 = std.math.maxInt(u64);
|
||||
|
||||
if (self.base.isRelocatable()) {
|
||||
for (self.sections.items(.header)) |header| {
|
||||
if (header.addr <= start) continue;
|
||||
|
||||
@ -437,18 +437,20 @@ fn calcCompactUnwindSize(macho_file: *MachO, sect_index: u8) void {
|
||||
|
||||
fn allocateSections(macho_file: *MachO) !void {
|
||||
const slice = macho_file.sections.slice();
|
||||
|
||||
const last_index = for (0..slice.items(.header).len) |i| {
|
||||
if (macho_file.isZigSection(@intCast(i))) break i;
|
||||
} else slice.items(.header).len;
|
||||
|
||||
for (slice.items(.header)[0..last_index]) |*header| {
|
||||
for (slice.items(.header)) |*header| {
|
||||
const needed_size = header.size;
|
||||
header.size = 0;
|
||||
const alignment = try math.powi(u32, 2, header.@"align");
|
||||
if (!header.isZerofill()) {
|
||||
header.offset = math.cast(u32, macho_file.findFreeSpace(header.size, alignment)) orelse
|
||||
return error.Overflow;
|
||||
if (needed_size > macho_file.allocatedSize(header.offset)) {
|
||||
header.offset = math.cast(u32, macho_file.findFreeSpace(needed_size, alignment)) orelse
|
||||
return error.Overflow;
|
||||
}
|
||||
}
|
||||
header.addr = macho_file.findFreeSpaceVirtual(header.size, alignment);
|
||||
if (needed_size > macho_file.allocatedSizeVirtual(header.addr)) {
|
||||
header.addr = macho_file.findFreeSpaceVirtual(needed_size, alignment);
|
||||
}
|
||||
header.size = needed_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user