authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-01-19 22:54:34+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-01-19 22:54:34+01:00
loga26ab9afeeeca405118fb3411dce0810ca723b5f
treea748d51c0fe3e477e9afba5df63aef62ea34b8c8
parent0e56d4cc02ce1a09670bf6c50149cb59fd80e9d1

Backport Elf changes from d5d0619


3 files changed, 38 insertions(+), 47 deletions(-)

src/link/MachO.zig+24-29
...@@ -143,11 +143,11 @@ string_table_needs_relocation: bool = false,...@@ -143,11 +143,11 @@ string_table_needs_relocation: bool = false,
143/// or removed from the freelist.143/// or removed from the freelist.
144///144///
145/// A text block has surplus capacity when its overcapacity value is greater than145/// A text block has surplus capacity when its overcapacity value is greater than
146/// minimum_text_block_size * alloc_num / alloc_den. That is, when it has so146/// padToIdeal(minimum_text_block_size). That is, when it has so
147/// much extra capacity, that we could fit a small new symbol in it, itself with147/// much extra capacity, that we could fit a small new symbol in it, itself with
148/// ideal_capacity or more.148/// ideal_capacity or more.
149///149///
150/// Ideal capacity is defined by size * alloc_num / alloc_den.150/// Ideal capacity is defined by size + (size / ideal_factor).
151///151///
152/// Overcapacity is measured by actual_capacity - ideal_capacity. Note that152/// Overcapacity is measured by actual_capacity - ideal_capacity. Note that
153/// overcapacity can be negative. A simple way to have negative overcapacity is to153/// overcapacity can be negative. A simple way to have negative overcapacity is to
...@@ -192,9 +192,9 @@ pub const StubFixup = struct {...@@ -192,9 +192,9 @@ pub const StubFixup = struct {
192 len: usize,192 len: usize,
193};193};
194194
195/// `alloc_num / alloc_den` is the factor of padding when allocating.195/// When allocating, the ideal_capacity is calculated by
196pub const alloc_num = 4;196/// actual_capacity + (actual_capacity / ideal_factor)
197pub const alloc_den = 3;197const ideal_factor = 2;
198198
199/// Default path to dyld199/// Default path to dyld
200/// TODO instead of hardcoding it, we should probably look through some env vars and search paths200/// TODO instead of hardcoding it, we should probably look through some env vars and search paths
...@@ -214,7 +214,7 @@ const LIB_SYSTEM_PATH: [*:0]const u8 = DEFAULT_LIB_SEARCH_PATH ++ "/libSystem.B....@@ -214,7 +214,7 @@ const LIB_SYSTEM_PATH: [*:0]const u8 = DEFAULT_LIB_SEARCH_PATH ++ "/libSystem.B.
214/// it as a possible place to put new symbols, it must have enough room for this many bytes214/// it as a possible place to put new symbols, it must have enough room for this many bytes
215/// (plus extra for reserved capacity).215/// (plus extra for reserved capacity).
216const minimum_text_block_size = 64;216const minimum_text_block_size = 64;
217const min_text_capacity = minimum_text_block_size * alloc_num / alloc_den;217const min_text_capacity = padToIdeal(minimum_text_block_size);
218218
219pub const TextBlock = struct {219pub const TextBlock = struct {
220 /// Each decl always gets a local symbol with the fully qualified name.220 /// Each decl always gets a local symbol with the fully qualified name.
...@@ -277,7 +277,7 @@ pub const TextBlock = struct {...@@ -277,7 +277,7 @@ pub const TextBlock = struct {
277 const self_sym = macho_file.local_symbols.items[self.local_sym_index];277 const self_sym = macho_file.local_symbols.items[self.local_sym_index];
278 const next_sym = macho_file.local_symbols.items[next.local_sym_index];278 const next_sym = macho_file.local_symbols.items[next.local_sym_index];
279 const cap = next_sym.n_value - self_sym.n_value;279 const cap = next_sym.n_value - self_sym.n_value;
280 const ideal_cap = self.size * alloc_num / alloc_den;280 const ideal_cap = padToIdeal(self.size);
281 if (cap <= ideal_cap) return false;281 if (cap <= ideal_cap) return false;
282 const surplus = cap - ideal_cap;282 const surplus = cap - ideal_cap;
283 return surplus >= min_text_capacity;283 return surplus >= min_text_capacity;
...@@ -873,7 +873,7 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {...@@ -873,7 +873,7 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
873 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;873 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
874 const text_section = text_segment.sections.items[self.text_section_index.?];874 const text_section = text_segment.sections.items[self.text_section_index.?];
875 const after_last_cmd_offset = self.header.?.sizeofcmds + @sizeOf(macho.mach_header_64);875 const after_last_cmd_offset = self.header.?.sizeofcmds + @sizeOf(macho.mach_header_64);
876 const needed_size = @sizeOf(macho.linkedit_data_command) * alloc_num / alloc_den;876 const needed_size = padToIdeal(@sizeOf(macho.linkedit_data_command));
877877
878 if (needed_size + after_last_cmd_offset > text_section.offset) {878 if (needed_size + after_last_cmd_offset > text_section.offset) {
879 log.err("Unable to extend padding between the end of load commands and start of __text section.", .{});879 log.err("Unable to extend padding between the end of load commands and start of __text section.", .{});
...@@ -943,7 +943,7 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {...@@ -943,7 +943,7 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
943 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;943 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
944 const text_section = text_segment.sections.items[self.text_section_index.?];944 const text_section = text_segment.sections.items[self.text_section_index.?];
945 const after_last_cmd_offset = self.header.?.sizeofcmds + @sizeOf(macho.mach_header_64);945 const after_last_cmd_offset = self.header.?.sizeofcmds + @sizeOf(macho.mach_header_64);
946 const needed_size = @sizeOf(macho.linkedit_data_command) * alloc_num / alloc_den;946 const needed_size = padToIdeal(@sizeOf(macho.linkedit_data_command));
947947
948 if (needed_size + after_last_cmd_offset > text_section.offset) {948 if (needed_size + after_last_cmd_offset > text_section.offset) {
949 log.err("Unable to extend padding between the end of load commands and start of __text section.", .{});949 log.err("Unable to extend padding between the end of load commands and start of __text section.", .{});
...@@ -1491,7 +1491,7 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -1491,7 +1491,7 @@ pub fn populateMissingMetadata(self: *MachO) !void {
1491 const program_code_size_hint = self.base.options.program_code_size_hint;1491 const program_code_size_hint = self.base.options.program_code_size_hint;
1492 const offset_table_size_hint = @sizeOf(u64) * self.base.options.symbol_count_hint;1492 const offset_table_size_hint = @sizeOf(u64) * self.base.options.symbol_count_hint;
1493 const ideal_size = self.header_pad + program_code_size_hint + 3 * offset_table_size_hint;1493 const ideal_size = self.header_pad + program_code_size_hint + 3 * offset_table_size_hint;
1494 const needed_size = mem.alignForwardGeneric(u64, satMul(ideal_size, alloc_num) / alloc_den, self.page_size);1494 const needed_size = mem.alignForwardGeneric(u64, padToIdeal(ideal_size), self.page_size);
14951495
1496 log.debug("found __TEXT segment free space 0x{x} to 0x{x}", .{ 0, needed_size });1496 log.debug("found __TEXT segment free space 0x{x} to 0x{x}", .{ 0, needed_size });
14971497
...@@ -1656,7 +1656,7 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -1656,7 +1656,7 @@ pub fn populateMissingMetadata(self: *MachO) !void {
1656 const address_and_offset = self.nextSegmentAddressAndOffset();1656 const address_and_offset = self.nextSegmentAddressAndOffset();
16571657
1658 const ideal_size = @sizeOf(u64) * self.base.options.symbol_count_hint;1658 const ideal_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
1659 const needed_size = mem.alignForwardGeneric(u64, satMul(ideal_size, alloc_num) / alloc_den, self.page_size);1659 const needed_size = mem.alignForwardGeneric(u64, padToIdeal(ideal_size), self.page_size);
16601660
1661 log.debug("found __DATA_CONST segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size });1661 log.debug("found __DATA_CONST segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size });
16621662
...@@ -1713,7 +1713,7 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -1713,7 +1713,7 @@ pub fn populateMissingMetadata(self: *MachO) !void {
1713 const address_and_offset = self.nextSegmentAddressAndOffset();1713 const address_and_offset = self.nextSegmentAddressAndOffset();
17141714
1715 const ideal_size = 2 * @sizeOf(u64) * self.base.options.symbol_count_hint;1715 const ideal_size = 2 * @sizeOf(u64) * self.base.options.symbol_count_hint;
1716 const needed_size = mem.alignForwardGeneric(u64, satMul(ideal_size, alloc_num) / alloc_den, self.page_size);1716 const needed_size = mem.alignForwardGeneric(u64, padToIdeal(ideal_size), self.page_size);
17171717
1718 log.debug("found __DATA segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size });1718 log.debug("found __DATA segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size });
17191719
...@@ -2133,7 +2133,7 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -2133,7 +2133,7 @@ pub fn populateMissingMetadata(self: *MachO) !void {
2133fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 {2133fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 {
2134 const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;2134 const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;
2135 const text_section = &text_segment.sections.items[self.text_section_index.?];2135 const text_section = &text_segment.sections.items[self.text_section_index.?];
2136 const new_block_ideal_capacity = new_block_size * alloc_num / alloc_den;2136 const new_block_ideal_capacity = padToIdeal(new_block_size);
21372137
2138 // We use these to indicate our intention to update metadata, placing the new block,2138 // We use these to indicate our intention to update metadata, placing the new block,
2139 // and possibly removing a free list node.2139 // and possibly removing a free list node.
...@@ -2153,13 +2153,8 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64,...@@ -2153,13 +2153,8 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64,
2153 // Is it enough that we could fit this new text block?2153 // Is it enough that we could fit this new text block?
2154 const sym = self.local_symbols.items[big_block.local_sym_index];2154 const sym = self.local_symbols.items[big_block.local_sym_index];
2155 const capacity = big_block.capacity(self.*);2155 const capacity = big_block.capacity(self.*);
2156 const ideal_capacity_end_vaddr: u64 = ideal_cap: {2156 const ideal_capacity = padToIdeal(capacity);
2157 if (math.mul(u64, @divTrunc(capacity, alloc_den), alloc_num)) |cap| {2157 const ideal_capacity_end_vaddr = sym.n_value + ideal_capacity;
2158 break :ideal_cap math.add(u64, sym.n_value, cap) catch math.maxInt(u64);
2159 } else |_| {
2160 break :ideal_cap math.maxInt(u64);
2161 }
2162 };
2163 const capacity_end_vaddr = sym.n_value + capacity;2158 const capacity_end_vaddr = sym.n_value + capacity;
2164 const new_start_vaddr_unaligned = capacity_end_vaddr - new_block_ideal_capacity;2159 const new_start_vaddr_unaligned = capacity_end_vaddr - new_block_ideal_capacity;
2165 const new_start_vaddr = mem.alignBackwardGeneric(u64, new_start_vaddr_unaligned, alignment);2160 const new_start_vaddr = mem.alignBackwardGeneric(u64, new_start_vaddr_unaligned, alignment);
...@@ -2190,7 +2185,7 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64,...@@ -2190,7 +2185,7 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64,
2190 const last_symbol = self.local_symbols.items[last.local_sym_index];2185 const last_symbol = self.local_symbols.items[last.local_sym_index];
2191 // TODO We should pad out the excess capacity with NOPs. For executables,2186 // TODO We should pad out the excess capacity with NOPs. For executables,
2192 // no padding seems to be OK, but it will probably not be for objects.2187 // no padding seems to be OK, but it will probably not be for objects.
2193 const ideal_capacity = last.size * alloc_num / alloc_den;2188 const ideal_capacity = padToIdeal(last.size);
2194 const ideal_capacity_end_vaddr = last_symbol.n_value + ideal_capacity;2189 const ideal_capacity_end_vaddr = last_symbol.n_value + ideal_capacity;
2195 const new_start_vaddr = mem.alignForwardGeneric(u64, ideal_capacity_end_vaddr, alignment);2190 const new_start_vaddr = mem.alignForwardGeneric(u64, ideal_capacity_end_vaddr, alignment);
2196 block_placement = last;2191 block_placement = last;
...@@ -2365,7 +2360,7 @@ fn allocatedSizeLinkedit(self: *MachO, start: u64) u64 {...@@ -2365,7 +2360,7 @@ fn allocatedSizeLinkedit(self: *MachO, start: u64) u64 {
2365}2360}
23662361
2367inline fn checkForCollision(start: u64, end: u64, off: u64, size: u64) ?u64 {2362inline fn checkForCollision(start: u64, end: u64, off: u64, size: u64) ?u64 {
2368 const increased_size = satMul(size, alloc_num) / alloc_den;2363 const increased_size = padToIdeal(size);
2369 const test_end = off + increased_size;2364 const test_end = off + increased_size;
2370 if (end > off and start < test_end) {2365 if (end > off and start < test_end) {
2371 return test_end;2366 return test_end;
...@@ -2374,7 +2369,7 @@ inline fn checkForCollision(start: u64, end: u64, off: u64, size: u64) ?u64 {...@@ -2374,7 +2369,7 @@ inline fn checkForCollision(start: u64, end: u64, off: u64, size: u64) ?u64 {
2374}2369}
23752370
2376fn detectAllocCollisionLinkedit(self: *MachO, start: u64, size: u64) ?u64 {2371fn detectAllocCollisionLinkedit(self: *MachO, start: u64, size: u64) ?u64 {
2377 const end = start + satMul(size, alloc_num) / alloc_den;2372 const end = start + padToIdeal(size);
23782373
2379 // __LINKEDIT is a weird segment where sections get their own load commands so we2374 // __LINKEDIT is a weird segment where sections get their own load commands so we
2380 // special-case it.2375 // special-case it.
...@@ -2455,12 +2450,6 @@ fn findFreeSpaceLinkedit(self: *MachO, object_size: u64, min_alignment: u16, sta...@@ -2455,12 +2450,6 @@ fn findFreeSpaceLinkedit(self: *MachO, object_size: u64, min_alignment: u16, sta
2455 return st;2450 return st;
2456}2451}
24572452
2458/// Saturating multiplication
2459pub fn satMul(a: anytype, b: anytype) @TypeOf(a, b) {
2460 const T = @TypeOf(a, b);
2461 return std.math.mul(T, a, b) catch std.math.maxInt(T);
2462}
2463
2464fn writeOffsetTableEntry(self: *MachO, index: usize) !void {2453fn writeOffsetTableEntry(self: *MachO, index: usize) !void {
2465 const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;2454 const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;
2466 const sect = &text_segment.sections.items[self.got_section_index.?];2455 const sect = &text_segment.sections.items[self.got_section_index.?];
...@@ -3275,3 +3264,9 @@ fn fixupInfoCommon(self: *MachO, buffer: []u8, dylib_ordinal: u32) !void {...@@ -3275,3 +3264,9 @@ fn fixupInfoCommon(self: *MachO, buffer: []u8, dylib_ordinal: u32) !void {
3275 }3264 }
3276 }3265 }
3277}3266}
3267
3268pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {
3269 // TODO https://github.com/ziglang/zig/issues/1284
3270 return std.math.add(@TypeOf(actual_size), actual_size, actual_size / ideal_factor) catch
3271 std.math.maxInt(@TypeOf(actual_size));
3272}
src/link/MachO/DebugSymbols.zig+11-13
...@@ -18,9 +18,7 @@ const link = @import("../../link.zig");...@@ -18,9 +18,7 @@ const link = @import("../../link.zig");
18const MachO = @import("../MachO.zig");18const MachO = @import("../MachO.zig");
19const SrcFn = MachO.SrcFn;19const SrcFn = MachO.SrcFn;
20const TextBlock = MachO.TextBlock;20const TextBlock = MachO.TextBlock;
21const satMul = MachO.satMul;21const padToIdeal = MachO.padToIdeal;
22const alloc_num = MachO.alloc_num;
23const alloc_den = MachO.alloc_den;
24const makeStaticString = MachO.makeStaticString;22const makeStaticString = MachO.makeStaticString;
2523
26usingnamespace @import("commands.zig");24usingnamespace @import("commands.zig");
...@@ -207,7 +205,7 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void...@@ -207,7 +205,7 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
207205
208 const linkedit = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;206 const linkedit = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
209 const ideal_size: u16 = 200 + 128 + 160 + 250;207 const ideal_size: u16 = 200 + 128 + 160 + 250;
210 const needed_size = mem.alignForwardGeneric(u64, satMul(ideal_size, alloc_num) / alloc_den, page_size);208 const needed_size = mem.alignForwardGeneric(u64, padToIdeal(ideal_size), page_size);
211 const off = linkedit.inner.fileoff + linkedit.inner.filesize;209 const off = linkedit.inner.fileoff + linkedit.inner.filesize;
212 const vmaddr = linkedit.inner.vmaddr + linkedit.inner.vmsize;210 const vmaddr = linkedit.inner.vmaddr + linkedit.inner.vmsize;
213211
...@@ -804,7 +802,7 @@ fn allocatedSizeLinkedit(self: *DebugSymbols, start: u64) u64 {...@@ -804,7 +802,7 @@ fn allocatedSizeLinkedit(self: *DebugSymbols, start: u64) u64 {
804}802}
805803
806fn detectAllocCollisionLinkedit(self: *DebugSymbols, start: u64, size: u64) ?u64 {804fn detectAllocCollisionLinkedit(self: *DebugSymbols, start: u64, size: u64) ?u64 {
807 const end = start + satMul(size, alloc_num) / alloc_den;805 const end = start + padToIdeal(size);
808806
809 if (self.symtab_cmd_index) |idx| outer: {807 if (self.symtab_cmd_index) |idx| outer: {
810 if (self.load_commands.items.len == idx) break :outer;808 if (self.load_commands.items.len == idx) break :outer;
...@@ -812,7 +810,7 @@ fn detectAllocCollisionLinkedit(self: *DebugSymbols, start: u64, size: u64) ?u64...@@ -812,7 +810,7 @@ fn detectAllocCollisionLinkedit(self: *DebugSymbols, start: u64, size: u64) ?u64
812 {810 {
813 // Symbol table811 // Symbol table
814 const symsize = symtab.nsyms * @sizeOf(macho.nlist_64);812 const symsize = symtab.nsyms * @sizeOf(macho.nlist_64);
815 const increased_size = satMul(symsize, alloc_num) / alloc_den;813 const increased_size = padToIdeal(symsize);
816 const test_end = symtab.symoff + increased_size;814 const test_end = symtab.symoff + increased_size;
817 if (end > symtab.symoff and start < test_end) {815 if (end > symtab.symoff and start < test_end) {
818 return test_end;816 return test_end;
...@@ -820,7 +818,7 @@ fn detectAllocCollisionLinkedit(self: *DebugSymbols, start: u64, size: u64) ?u64...@@ -820,7 +818,7 @@ fn detectAllocCollisionLinkedit(self: *DebugSymbols, start: u64, size: u64) ?u64
820 }818 }
821 {819 {
822 // String table820 // String table
823 const increased_size = satMul(symtab.strsize, alloc_num) / alloc_den;821 const increased_size = padToIdeal(symtab.strsize);
824 const test_end = symtab.stroff + increased_size;822 const test_end = symtab.stroff + increased_size;
825 if (end > symtab.stroff and start < test_end) {823 if (end > symtab.stroff and start < test_end) {
826 return test_end;824 return test_end;
...@@ -1099,7 +1097,7 @@ pub fn commitDeclDebugInfo(...@@ -1099,7 +1097,7 @@ pub fn commitDeclDebugInfo(
1099 last.next = src_fn;1097 last.next = src_fn;
1100 self.dbg_line_fn_last = src_fn;1098 self.dbg_line_fn_last = src_fn;
11011099
1102 src_fn.off = last.off + (last.len * alloc_num / alloc_den);1100 src_fn.off = last.off + padToIdeal(last.len);
1103 }1101 }
1104 } else if (src_fn.prev == null) {1102 } else if (src_fn.prev == null) {
1105 // Append new function.1103 // Append new function.
...@@ -1108,14 +1106,14 @@ pub fn commitDeclDebugInfo(...@@ -1108,14 +1106,14 @@ pub fn commitDeclDebugInfo(
1108 last.next = src_fn;1106 last.next = src_fn;
1109 self.dbg_line_fn_last = src_fn;1107 self.dbg_line_fn_last = src_fn;
11101108
1111 src_fn.off = last.off + (last.len * alloc_num / alloc_den);1109 src_fn.off = last.off + padToIdeal(last.len);
1112 }1110 }
1113 } else {1111 } else {
1114 // This is the first function of the Line Number Program.1112 // This is the first function of the Line Number Program.
1115 self.dbg_line_fn_first = src_fn;1113 self.dbg_line_fn_first = src_fn;
1116 self.dbg_line_fn_last = src_fn;1114 self.dbg_line_fn_last = src_fn;
11171115
1118 src_fn.off = self.dbgLineNeededHeaderBytes(module) * alloc_num / alloc_den;1116 src_fn.off = padToIdeal(self.dbgLineNeededHeaderBytes(module));
1119 }1117 }
11201118
1121 const last_src_fn = self.dbg_line_fn_last.?;1119 const last_src_fn = self.dbg_line_fn_last.?;
...@@ -1259,7 +1257,7 @@ fn updateDeclDebugInfoAllocation(...@@ -1259,7 +1257,7 @@ fn updateDeclDebugInfoAllocation(
1259 last.dbg_info_next = text_block;1257 last.dbg_info_next = text_block;
1260 self.dbg_info_decl_last = text_block;1258 self.dbg_info_decl_last = text_block;
12611259
1262 text_block.dbg_info_off = last.dbg_info_off + (last.dbg_info_len * alloc_num / alloc_den);1260 text_block.dbg_info_off = last.dbg_info_off + padToIdeal(last.dbg_info_len);
1263 }1261 }
1264 } else if (text_block.dbg_info_prev == null) {1262 } else if (text_block.dbg_info_prev == null) {
1265 // Append new Decl.1263 // Append new Decl.
...@@ -1268,14 +1266,14 @@ fn updateDeclDebugInfoAllocation(...@@ -1268,14 +1266,14 @@ fn updateDeclDebugInfoAllocation(
1268 last.dbg_info_next = text_block;1266 last.dbg_info_next = text_block;
1269 self.dbg_info_decl_last = text_block;1267 self.dbg_info_decl_last = text_block;
12701268
1271 text_block.dbg_info_off = last.dbg_info_off + (last.dbg_info_len * alloc_num / alloc_den);1269 text_block.dbg_info_off = last.dbg_info_off + padToIdeal(last.dbg_info_len);
1272 }1270 }
1273 } else {1271 } else {
1274 // This is the first Decl of the .debug_info1272 // This is the first Decl of the .debug_info
1275 self.dbg_info_decl_first = text_block;1273 self.dbg_info_decl_first = text_block;
1276 self.dbg_info_decl_last = text_block;1274 self.dbg_info_decl_last = text_block;
12771275
1278 text_block.dbg_info_off = self.dbgInfoNeededHeaderBytes() * alloc_num / alloc_den;1276 text_block.dbg_info_off = padToIdeal(self.dbgInfoNeededHeaderBytes());
1279 }1277 }
1280}1278}
12811279
src/link/MachO/commands.zig+3-5
...@@ -10,9 +10,7 @@ const assert = std.debug.assert;...@@ -10,9 +10,7 @@ const assert = std.debug.assert;
10const Allocator = std.mem.Allocator;10const Allocator = std.mem.Allocator;
11const MachO = @import("../MachO.zig");11const MachO = @import("../MachO.zig");
12const makeStaticString = MachO.makeStaticString;12const makeStaticString = MachO.makeStaticString;
13const satMul = MachO.satMul;13const padToIdeal = MachO.padToIdeal;
14const alloc_num = MachO.alloc_num;
15const alloc_den = MachO.alloc_den;
1614
17pub const LoadCommand = union(enum) {15pub const LoadCommand = union(enum) {
18 Segment: SegmentCommand,16 Segment: SegmentCommand,
...@@ -214,9 +212,9 @@ pub const SegmentCommand = struct {...@@ -214,9 +212,9 @@ pub const SegmentCommand = struct {
214 }212 }
215213
216 fn detectAllocCollision(self: SegmentCommand, start: u64, size: u64) ?u64 {214 fn detectAllocCollision(self: SegmentCommand, start: u64, size: u64) ?u64 {
217 const end = start + satMul(size, alloc_num) / alloc_den;215 const end = start + padToIdeal(size);
218 for (self.sections.items) |section| {216 for (self.sections.items) |section| {
219 const increased_size = satMul(section.size, alloc_num) / alloc_den;217 const increased_size = padToIdeal(section.size);
220 const test_end = section.offset + increased_size;218 const test_end = section.offset + increased_size;
221 if (end > section.offset and start < test_end) {219 if (end > section.offset and start < test_end) {
222 return test_end;220 return test_end;