mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
macho: rewrite how we allocate space in incremental context
This commit is contained in:
parent
79ab46ec91
commit
e601969244
@ -798,6 +798,11 @@ pub const section_64 = extern struct {
|
||||
return tt == S_ZEROFILL or tt == S_GB_ZEROFILL or tt == S_THREAD_LOCAL_ZEROFILL;
|
||||
}
|
||||
|
||||
pub fn isSymbolStubs(sect: section_64) bool {
|
||||
const tt = sect.@"type"();
|
||||
return tt == S_SYMBOL_STUBS;
|
||||
}
|
||||
|
||||
pub fn isDebug(sect: section_64) bool {
|
||||
return sect.attrs() & S_ATTR_DEBUG != 0;
|
||||
}
|
||||
|
||||
@ -948,7 +948,7 @@ pub fn commitDeclState(
|
||||
new_offset,
|
||||
});
|
||||
|
||||
try File.MachO.copyRangeAllOverlappingAlloc(
|
||||
try copyRangeAllOverlappingAlloc(
|
||||
gpa,
|
||||
d_sym.file,
|
||||
debug_line_sect.offset,
|
||||
@ -1247,7 +1247,7 @@ fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *Atom, dbg_info_buf: []co
|
||||
new_offset,
|
||||
});
|
||||
|
||||
try File.MachO.copyRangeAllOverlappingAlloc(
|
||||
try copyRangeAllOverlappingAlloc(
|
||||
gpa,
|
||||
d_sym.file,
|
||||
debug_info_sect.offset,
|
||||
@ -2338,3 +2338,16 @@ fn addDbgInfoErrorSet(
|
||||
// DW.AT.enumeration_type delimit children
|
||||
try dbg_info_buffer.append(0);
|
||||
}
|
||||
|
||||
fn copyRangeAllOverlappingAlloc(
|
||||
allocator: Allocator,
|
||||
file: std.fs.File,
|
||||
in_offset: u64,
|
||||
out_offset: u64,
|
||||
len: usize,
|
||||
) !void {
|
||||
const buf = try allocator.alloc(u8, len);
|
||||
defer allocator.free(buf);
|
||||
const amt = try file.preadAll(buf, in_offset);
|
||||
try file.pwriteAll(buf[0..amt], out_offset);
|
||||
}
|
||||
|
||||
1283
src/link/MachO.zig
1283
src/link/MachO.zig
File diff suppressed because it is too large
Load Diff
@ -312,9 +312,8 @@ pub fn parseRelocs(self: *Atom, relocs: []align(1) const macho.relocation_info,
|
||||
const sect_id = @intCast(u16, rel.r_symbolnum - 1);
|
||||
const sym_index = object.sections_as_symbols.get(sect_id) orelse blk: {
|
||||
const sect = object.getSourceSection(sect_id);
|
||||
const gop = (try context.macho_file.getOutputSection(sect)) orelse
|
||||
const out_sect_id = (try context.macho_file.getOutputSection(sect)) orelse
|
||||
unreachable;
|
||||
const out_sect_id = gop.sect_id;
|
||||
const sym_index = @intCast(u32, object.symtab.items.len);
|
||||
try object.symtab.append(gpa, .{
|
||||
.n_strx = 0,
|
||||
|
||||
@ -512,7 +512,7 @@ fn writeSymtab(self: *DebugSymbols, lc: *macho.symtab_command) !void {
|
||||
const dwarf_seg = &self.segments.items[self.dwarf_segment_cmd_index.?];
|
||||
seg.filesize = aligned_size;
|
||||
|
||||
try MachO.copyRangeAllOverlappingAlloc(
|
||||
try copyRangeAllOverlappingAlloc(
|
||||
self.base.base.allocator,
|
||||
self.file,
|
||||
dwarf_seg.fileoff,
|
||||
@ -571,7 +571,7 @@ fn writeStrtab(self: *DebugSymbols, lc: *macho.symtab_command) !void {
|
||||
const dwarf_seg = &self.segments.items[self.dwarf_segment_cmd_index.?];
|
||||
seg.filesize = aligned_size;
|
||||
|
||||
try MachO.copyRangeAllOverlappingAlloc(
|
||||
try copyRangeAllOverlappingAlloc(
|
||||
self.base.base.allocator,
|
||||
self.file,
|
||||
dwarf_seg.fileoff,
|
||||
@ -601,3 +601,16 @@ fn writeStrtab(self: *DebugSymbols, lc: *macho.symtab_command) !void {
|
||||
|
||||
try self.file.pwriteAll(self.strtab.buffer.items, lc.stroff);
|
||||
}
|
||||
|
||||
fn copyRangeAllOverlappingAlloc(
|
||||
allocator: Allocator,
|
||||
file: std.fs.File,
|
||||
in_offset: u64,
|
||||
out_offset: u64,
|
||||
len: usize,
|
||||
) !void {
|
||||
const buf = try allocator.alloc(u8, len);
|
||||
defer allocator.free(buf);
|
||||
const amt = try file.preadAll(buf, in_offset);
|
||||
try file.pwriteAll(buf[0..amt], out_offset);
|
||||
}
|
||||
|
||||
@ -220,15 +220,15 @@ fn filterRelocs(
|
||||
|
||||
pub fn scanInputSections(self: Object, macho_file: *MachO) !void {
|
||||
for (self.sections.items) |sect| {
|
||||
const gop = (try macho_file.getOutputSection(sect)) orelse {
|
||||
const sect_id = (try macho_file.getOutputSection(sect)) orelse {
|
||||
log.debug(" unhandled section", .{});
|
||||
continue;
|
||||
};
|
||||
const output = macho_file.sections.items(.header)[gop.sect_id];
|
||||
const output = macho_file.sections.items(.header)[sect_id];
|
||||
log.debug("mapping '{s},{s}' into output sect({d}, '{s},{s}')", .{
|
||||
sect.segName(),
|
||||
sect.sectName(),
|
||||
gop.sect_id + 1,
|
||||
sect_id + 1,
|
||||
output.segName(),
|
||||
output.sectName(),
|
||||
});
|
||||
@ -335,11 +335,10 @@ pub fn splitIntoAtoms(self: *Object, macho_file: *MachO, object_id: u32) !void {
|
||||
log.debug("splitting section '{s},{s}' into atoms", .{ sect.segName(), sect.sectName() });
|
||||
|
||||
// Get matching segment/section in the final artifact.
|
||||
const gop = (try macho_file.getOutputSection(sect)) orelse {
|
||||
const out_sect_id = (try macho_file.getOutputSection(sect)) orelse {
|
||||
log.debug(" unhandled section", .{});
|
||||
continue;
|
||||
};
|
||||
const out_sect_id = gop.sect_id;
|
||||
|
||||
log.debug(" output sect({d}, '{s},{s}')", .{
|
||||
out_sect_id + 1,
|
||||
|
||||
@ -181,7 +181,6 @@ fn resolveAarch64(
|
||||
const offset = @divExact(narrowed, 8);
|
||||
inst.load_store_register.offset = offset;
|
||||
mem.writeIntLittle(u32, &buffer, inst.toU32());
|
||||
log.debug("HMM = {x}", .{std.fmt.fmtSliceHexLower(&buffer)});
|
||||
},
|
||||
.ARM64_RELOC_TLVP_LOAD_PAGEOFF12 => {
|
||||
const RegInfo = struct {
|
||||
|
||||
@ -876,11 +876,23 @@ fn allocateSegments(macho_file: *MachO) !void {
|
||||
}, 0);
|
||||
}
|
||||
|
||||
fn getSegmentAllocBase(macho_file: *MachO, indices: []const ?u8) struct { vmaddr: u64, fileoff: u64 } {
|
||||
for (indices) |maybe_prev_id| {
|
||||
const prev_id = maybe_prev_id orelse continue;
|
||||
const prev = macho_file.segments.items[prev_id];
|
||||
return .{
|
||||
.vmaddr = prev.vmaddr + prev.vmsize,
|
||||
.fileoff = prev.fileoff + prev.filesize,
|
||||
};
|
||||
}
|
||||
return .{ .vmaddr = 0, .fileoff = 0 };
|
||||
}
|
||||
|
||||
fn allocateSegment(macho_file: *MachO, maybe_index: ?u8, indices: []const ?u8, init_size: u64) !void {
|
||||
const index = maybe_index orelse return;
|
||||
const seg = &macho_file.segments.items[index];
|
||||
|
||||
const base = macho_file.getSegmentAllocBase(indices);
|
||||
const base = getSegmentAllocBase(macho_file, indices);
|
||||
seg.vmaddr = base.vmaddr;
|
||||
seg.fileoff = base.fileoff;
|
||||
seg.filesize = init_size;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user