macho: rewrite how we allocate space in incremental context

This commit is contained in:
Jakub Konka 2022-09-13 15:27:25 +02:00
parent 79ab46ec91
commit e601969244
8 changed files with 516 additions and 833 deletions

View File

@ -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;
}

View File

@ -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);
}

File diff suppressed because it is too large Load Diff

View File

@ -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,

View File

@ -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);
}

View File

@ -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,

View File

@ -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 {

View File

@ -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;