authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-17 18:59:24+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:34:41+01:00
logc7de5e511125a738269a802318695b98a88b2791
tree56845e79288dfd23ac21461ea154aaaf55b25850
parent0b2133d4412e8f3c67a1eb6ddbb43afc02196703

macho: re-implement updateDeclCode


1 files changed, 93 insertions(+), 2 deletions(-)

src/link/MachO/ZigObject.zig+93-2
......@@ -296,8 +296,16 @@ pub fn updateDecl(
296296 },
297297 };
298298 const sect_index = try self.getDeclOutputSection(macho_file, decl, code);
299 _ = sect_index;
300 // const addr = try self.updateDeclCode(decl_index, code);
299 const is_threadlocal = switch (macho_file.sections.items(.header[sect_index].type())) {
300 macho.S_THREAD_LOCAL_ZEROFILL, macho.S_THREAD_LOCAL_REGULAR => true,
301 else => false,
302 };
303 if (is_threadlocal) {
304 // TODO: emit TLV
305 @panic("TODO updateDecl for TLS");
306 } else {
307 try self.updateDeclCode(macho_file, decl_index, sym_index, sect_index, code);
308 }
301309
302310 // if (decl_state) |*ds| {
303311 // try self.d_sym.?.dwarf.commitDeclState(
......@@ -314,6 +322,89 @@ pub fn updateDecl(
314322 // try self.updateExports(mod, .{ .decl_index = decl_index }, mod.getDeclExports(decl_index));
315323}
316324
325fn updateDeclCode(
326 self: *ZigObject,
327 macho_file: *MachO,
328 decl_index: Module.Decl.Index,
329 sym_index: Symbol.Index,
330 sect_index: u8,
331 code: []const u8,
332) !void {
333 const gpa = self.base.comp.gpa;
334 const mod = self.base.comp.module.?;
335 const decl = mod.declPtr(decl_index);
336 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
337
338 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });
339
340 const required_alignment = decl.getAlignment(mod);
341
342 const sect = &macho_file.sections.items(.header)[sect_index];
343 const sym = macho_file.getSymbol(sym_index);
344 const nlist = &self.symtab.items(.nlist)[sym.nlist_idx];
345 const size = &self.symtab.items(.size)[sym.nlist_idx];
346 const atom = sym.getAtom(macho_file).?;
347
348 sym.out_n_sect = sect_index;
349 atom.out_n_sect = sect_index;
350
351 sym.name = try macho_file.strings.insert(gpa, decl_name);
352 atom.flags.alive = true;
353 atom.name = sym.name;
354 nlist.n_strx = sym.name;
355 nlist.n_type = macho.N_SECT;
356 nlist.n_sect = sect_index + 1;
357 size = code.len;
358
359 const old_size = atom.size;
360 const old_vaddr = atom.value;
361 atom.alignment = required_alignment;
362 atom.size = code.len;
363
364 if (old_size > 0) {
365 const capacity = atom.capacity(macho_file);
366 const need_realloc = code.len > capacity or !required_alignment.check(sym.value);
367
368 if (need_realloc) {
369 try atom.grow(macho_file);
370 log.debug("growing {s} from 0x{x} to 0x{x}", .{ decl_name, old_vaddr, atom.value });
371 if (old_vaddr != atom.value) {
372 sym.value = atom.value;
373 nlist.n_value = atom.value;
374
375 if (!macho_file.base.isRelocatable()) {
376 log.debug(" (updating offset table entry)", .{});
377 assert(sym.flags.has_zig_got);
378 const extra = sym.getExtra(macho_file).?;
379 try macho_file.zig_got.writeOne(macho_file, extra.zig_got);
380 }
381 }
382 } else if (code.len < old_size) {
383 atom.shrink(macho_file);
384 } else if (atom.next_index == null) {
385 const needed_size = (sym.value + code.len) - sect.addr;
386 sect.size = needed_size;
387 }
388 } else {
389 try atom.allocate(macho_file);
390 // TODO: freeDeclMetadata in case of error
391
392 sym.value = atom.value;
393 sym.flags.needs_zig_got = true;
394 nlist.n_value = atom.value;
395
396 if (!macho_file.base.isRelocatable()) {
397 const gop = try sym.getOrCreateZigGotEntry(sym_index, macho_file);
398 try macho_file.zig_got.writeOne(macho_file, gop.index);
399 }
400 }
401
402 if (!sect.isZerofill()) {
403 const file_offset = sect.offset + sym.value - sect.addr;
404 try macho_file.base.file.?.pwriteAll(code, file_offset);
405 }
406}
407
317408fn getDeclOutputSection(
318409 self: *ZigObject,
319410 macho_file: *MachO,