authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-12 15:56:26+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-18 09:13:08+02:00
log853ca403c4164a67f32773a069b8f5f5579c4542
treee5dd4a5ca3a14f6c9a11c7fa0847e984cf849341
parentcba04ff24403ea5d134524eee318424599f068a6

macho: bring back relocatable mode for ZigObject


2 files changed, 64 insertions(+), 10 deletions(-)

src/link/MachO/ZigObject.zig+41-2
...@@ -437,9 +437,48 @@ pub fn calcNumRelocs(self: *ZigObject, macho_file: *MachO) void {...@@ -437,9 +437,48 @@ pub fn calcNumRelocs(self: *ZigObject, macho_file: *MachO) void {
437 for (self.getAtoms()) |atom_index| {437 for (self.getAtoms()) |atom_index| {
438 const atom = self.getAtom(atom_index) orelse continue;438 const atom = self.getAtom(atom_index) orelse continue;
439 if (!atom.flags.alive) continue;439 if (!atom.flags.alive) continue;
440 if (!macho_file.isZigSection(atom.out_n_sect) and !macho_file.isDebugSection(atom.out_n_sect)) continue;
441 const header = &macho_file.sections.items(.header)[atom.out_n_sect];440 const header = &macho_file.sections.items(.header)[atom.out_n_sect];
442 header.nreloc += atom.calcNumRelocs(macho_file);441 if (header.isZerofill()) continue;
442 if (!macho_file.isZigSection(atom.out_n_sect) and !macho_file.isDebugSection(atom.out_n_sect)) continue;
443 const nreloc = atom.calcNumRelocs(macho_file);
444 atom.addExtra(.{ .rel_out_index = header.nreloc, .rel_out_count = nreloc }, macho_file);
445 header.nreloc += nreloc;
446 }
447}
448
449pub fn writeRelocs(self: *ZigObject, macho_file: *MachO) !void {
450 const gpa = macho_file.base.comp.gpa;
451
452 for (self.getAtoms()) |atom_index| {
453 const atom = self.getAtom(atom_index) orelse continue;
454 if (!atom.flags.alive) continue;
455 const header = macho_file.sections.items(.header)[atom.out_n_sect];
456 const relocs = macho_file.sections.items(.relocs)[atom.out_n_sect].items;
457 if (header.isZerofill()) continue;
458 if (!macho_file.isZigSection(atom.out_n_sect) and !macho_file.isDebugSection(atom.out_n_sect)) continue;
459 if (atom.getRelocs(macho_file).len == 0) continue;
460 const extra = atom.getExtra(macho_file);
461 const atom_size = std.math.cast(usize, atom.size) orelse return error.Overflow;
462 const code = try gpa.alloc(u8, atom_size);
463 defer gpa.free(code);
464 self.getAtomData(macho_file, atom.*, code) catch |err| switch (err) {
465 error.InputOutput => {
466 try macho_file.reportUnexpectedError("fetching code for '{s}' failed", .{
467 atom.getName(macho_file),
468 });
469 return error.FlushFailure;
470 },
471 else => |e| {
472 try macho_file.reportUnexpectedError("unexpected error while fetching code for '{s}': {s}", .{
473 atom.getName(macho_file),
474 @errorName(e),
475 });
476 return error.FlushFailure;
477 },
478 };
479 const file_offset = header.offset + atom.value;
480 try atom.writeRelocs(macho_file, code, relocs[extra.rel_out_index..][0..extra.rel_out_count]);
481 try macho_file.base.file.?.pwriteAll(code, file_offset);
443 }482 }
444}483}
445484
src/link/MachO/relocatable.zig+23-8
...@@ -372,6 +372,7 @@ fn calcSectionSizes(macho_file: *MachO) !void {...@@ -372,6 +372,7 @@ fn calcSectionSizes(macho_file: *MachO) !void {
372 if (macho_file.getZigObject()) |zo| {372 if (macho_file.getZigObject()) |zo| {
373 // TODO this will create a race373 // TODO this will create a race
374 zo.calcNumRelocs(macho_file);374 zo.calcNumRelocs(macho_file);
375 zo.calcSymtabSize(macho_file);
375 }376 }
376377
377 if (macho_file.eh_frame_sect_index) |_| {378 if (macho_file.eh_frame_sect_index) |_| {
...@@ -390,7 +391,7 @@ fn calcSectionSizes(macho_file: *MachO) !void {...@@ -390,7 +391,7 @@ fn calcSectionSizes(macho_file: *MachO) !void {
390 if (macho_file.unwind_info_sect_index) |_| {391 if (macho_file.unwind_info_sect_index) |_| {
391 calcCompactUnwindSize(macho_file);392 calcCompactUnwindSize(macho_file);
392 }393 }
393 calcSymtabSize(macho_file);394 try calcSymtabSize(macho_file);
394}395}
395396
396fn calcSectionSize(macho_file: *MachO, sect_id: u8) void {397fn calcSectionSize(macho_file: *MachO, sect_id: u8) void {
...@@ -445,19 +446,27 @@ fn calcCompactUnwindSize(macho_file: *MachO) void {...@@ -445,19 +446,27 @@ fn calcCompactUnwindSize(macho_file: *MachO) void {
445 sect.@"align" = 3;446 sect.@"align" = 3;
446}447}
447448
448fn calcSymtabSize(macho_file: *MachO) void {449fn calcSymtabSize(macho_file: *MachO) error{OutOfMemory}!void {
449 const tracy = trace(@src());450 const tracy = trace(@src());
450 defer tracy.end();451 defer tracy.end();
451452
453 const gpa = macho_file.base.comp.gpa;
454
452 var nlocals: u32 = 0;455 var nlocals: u32 = 0;
453 var nstabs: u32 = 0;456 var nstabs: u32 = 0;
454 var nexports: u32 = 0;457 var nexports: u32 = 0;
455 var nimports: u32 = 0;458 var nimports: u32 = 0;
456 var strsize: u32 = 1;459 var strsize: u32 = 1;
457460
458 for (macho_file.objects.items) |index| {461 var objects = try std.ArrayList(File.Index).initCapacity(gpa, macho_file.objects.items.len + 1);
459 const object = macho_file.getFile(index).?.object;462 defer objects.deinit();
460 const ctx = &object.output_symtab_ctx;463 if (macho_file.getZigObject()) |zo| objects.appendAssumeCapacity(zo.index);
464 objects.appendSliceAssumeCapacity(macho_file.objects.items);
465
466 for (objects.items) |index| {
467 const ctx = switch (macho_file.getFile(index).?) {
468 inline else => |x| &x.output_symtab_ctx,
469 };
461 ctx.ilocal = nlocals;470 ctx.ilocal = nlocals;
462 ctx.istab = nstabs;471 ctx.istab = nstabs;
463 ctx.iexport = nexports;472 ctx.iexport = nexports;
...@@ -470,9 +479,10 @@ fn calcSymtabSize(macho_file: *MachO) void {...@@ -470,9 +479,10 @@ fn calcSymtabSize(macho_file: *MachO) void {
470 strsize += ctx.strsize;479 strsize += ctx.strsize;
471 }480 }
472481
473 for (macho_file.objects.items) |index| {482 for (objects.items) |index| {
474 const object = macho_file.getFile(index).?.object;483 const ctx = switch (macho_file.getFile(index).?) {
475 const ctx = &object.output_symtab_ctx;484 inline else => |x| &x.output_symtab_ctx,
485 };
476 ctx.istab += nlocals;486 ctx.istab += nlocals;
477 ctx.iexport += nlocals + nstabs;487 ctx.iexport += nlocals + nstabs;
478 ctx.iimport += nlocals + nstabs + nexports;488 ctx.iimport += nlocals + nstabs + nexports;
...@@ -645,6 +655,11 @@ fn writeSections(macho_file: *MachO) !void {...@@ -645,6 +655,11 @@ fn writeSections(macho_file: *MachO) !void {
645 macho_file.getFile(index).?.writeSymtab(macho_file, macho_file);655 macho_file.getFile(index).?.writeSymtab(macho_file, macho_file);
646 }656 }
647657
658 if (macho_file.getZigObject()) |zo| {
659 try zo.writeRelocs(macho_file);
660 zo.writeSymtab(macho_file, macho_file);
661 }
662
648 if (macho_file.eh_frame_sect_index) |_| {663 if (macho_file.eh_frame_sect_index) |_| {
649 try writeEhFrame(macho_file);664 try writeEhFrame(macho_file);
650 }665 }