macho: re-implement updateDeclCode
This commit is contained in:
@@ -296,8 +296,16 @@ pub fn updateDecl(
|
||||
},
|
||||
};
|
||||
const sect_index = try self.getDeclOutputSection(macho_file, decl, code);
|
||||
_ = sect_index;
|
||||
// const addr = try self.updateDeclCode(decl_index, code);
|
||||
const is_threadlocal = switch (macho_file.sections.items(.header[sect_index].type())) {
|
||||
macho.S_THREAD_LOCAL_ZEROFILL, macho.S_THREAD_LOCAL_REGULAR => true,
|
||||
else => false,
|
||||
};
|
||||
if (is_threadlocal) {
|
||||
// TODO: emit TLV
|
||||
@panic("TODO updateDecl for TLS");
|
||||
} else {
|
||||
try self.updateDeclCode(macho_file, decl_index, sym_index, sect_index, code);
|
||||
}
|
||||
|
||||
// if (decl_state) |*ds| {
|
||||
// try self.d_sym.?.dwarf.commitDeclState(
|
||||
@@ -314,6 +322,89 @@ pub fn updateDecl(
|
||||
// try self.updateExports(mod, .{ .decl_index = decl_index }, mod.getDeclExports(decl_index));
|
||||
}
|
||||
|
||||
fn updateDeclCode(
|
||||
self: *ZigObject,
|
||||
macho_file: *MachO,
|
||||
decl_index: Module.Decl.Index,
|
||||
sym_index: Symbol.Index,
|
||||
sect_index: u8,
|
||||
code: []const u8,
|
||||
) !void {
|
||||
const gpa = self.base.comp.gpa;
|
||||
const mod = self.base.comp.module.?;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
|
||||
|
||||
log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });
|
||||
|
||||
const required_alignment = decl.getAlignment(mod);
|
||||
|
||||
const sect = &macho_file.sections.items(.header)[sect_index];
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const nlist = &self.symtab.items(.nlist)[sym.nlist_idx];
|
||||
const size = &self.symtab.items(.size)[sym.nlist_idx];
|
||||
const atom = sym.getAtom(macho_file).?;
|
||||
|
||||
sym.out_n_sect = sect_index;
|
||||
atom.out_n_sect = sect_index;
|
||||
|
||||
sym.name = try macho_file.strings.insert(gpa, decl_name);
|
||||
atom.flags.alive = true;
|
||||
atom.name = sym.name;
|
||||
nlist.n_strx = sym.name;
|
||||
nlist.n_type = macho.N_SECT;
|
||||
nlist.n_sect = sect_index + 1;
|
||||
size = code.len;
|
||||
|
||||
const old_size = atom.size;
|
||||
const old_vaddr = atom.value;
|
||||
atom.alignment = required_alignment;
|
||||
atom.size = code.len;
|
||||
|
||||
if (old_size > 0) {
|
||||
const capacity = atom.capacity(macho_file);
|
||||
const need_realloc = code.len > capacity or !required_alignment.check(sym.value);
|
||||
|
||||
if (need_realloc) {
|
||||
try atom.grow(macho_file);
|
||||
log.debug("growing {s} from 0x{x} to 0x{x}", .{ decl_name, old_vaddr, atom.value });
|
||||
if (old_vaddr != atom.value) {
|
||||
sym.value = atom.value;
|
||||
nlist.n_value = atom.value;
|
||||
|
||||
if (!macho_file.base.isRelocatable()) {
|
||||
log.debug(" (updating offset table entry)", .{});
|
||||
assert(sym.flags.has_zig_got);
|
||||
const extra = sym.getExtra(macho_file).?;
|
||||
try macho_file.zig_got.writeOne(macho_file, extra.zig_got);
|
||||
}
|
||||
}
|
||||
} else if (code.len < old_size) {
|
||||
atom.shrink(macho_file);
|
||||
} else if (atom.next_index == null) {
|
||||
const needed_size = (sym.value + code.len) - sect.addr;
|
||||
sect.size = needed_size;
|
||||
}
|
||||
} else {
|
||||
try atom.allocate(macho_file);
|
||||
// TODO: freeDeclMetadata in case of error
|
||||
|
||||
sym.value = atom.value;
|
||||
sym.flags.needs_zig_got = true;
|
||||
nlist.n_value = atom.value;
|
||||
|
||||
if (!macho_file.base.isRelocatable()) {
|
||||
const gop = try sym.getOrCreateZigGotEntry(sym_index, macho_file);
|
||||
try macho_file.zig_got.writeOne(macho_file, gop.index);
|
||||
}
|
||||
}
|
||||
|
||||
if (!sect.isZerofill()) {
|
||||
const file_offset = sect.offset + sym.value - sect.addr;
|
||||
try macho_file.base.file.?.pwriteAll(code, file_offset);
|
||||
}
|
||||
}
|
||||
|
||||
fn getDeclOutputSection(
|
||||
self: *ZigObject,
|
||||
macho_file: *MachO,
|
||||
|
||||
Reference in New Issue
Block a user