| author | |
| committer | |
| log | 853ca403c4164a67f32773a069b8f5f5579c4542 |
| tree | e5dd4a5ca3a14f6c9a11c7fa0847e984cf849341 |
| parent | cba04ff24403ea5d134524eee318424599f068a6 |
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 | 437 | for (self.getAtoms()) |atom_index| { |
| 438 | 438 | const atom = self.getAtom(atom_index) orelse continue; |
| 439 | 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 | 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 | ||
| 449 | pub 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 | } |
| 445 | 484 |
src/link/MachO/relocatable.zig+23-8| ... | ... | @@ -372,6 +372,7 @@ fn calcSectionSizes(macho_file: *MachO) !void { |
| 372 | 372 | if (macho_file.getZigObject()) |zo| { |
| 373 | 373 | // TODO this will create a race |
| 374 | 374 | zo.calcNumRelocs(macho_file); |
| 375 | zo.calcSymtabSize(macho_file); | |
| 375 | 376 | } |
| 376 | 377 | |
| 377 | 378 | if (macho_file.eh_frame_sect_index) |_| { |
| ... | ... | @@ -390,7 +391,7 @@ fn calcSectionSizes(macho_file: *MachO) !void { |
| 390 | 391 | if (macho_file.unwind_info_sect_index) |_| { |
| 391 | 392 | calcCompactUnwindSize(macho_file); |
| 392 | 393 | } |
| 393 | calcSymtabSize(macho_file); | |
| 394 | try calcSymtabSize(macho_file); | |
| 394 | 395 | } |
| 395 | 396 | |
| 396 | 397 | fn calcSectionSize(macho_file: *MachO, sect_id: u8) void { |
| ... | ... | @@ -445,19 +446,27 @@ fn calcCompactUnwindSize(macho_file: *MachO) void { |
| 445 | 446 | sect.@"align" = 3; |
| 446 | 447 | } |
| 447 | 448 | |
| 448 | fn calcSymtabSize(macho_file: *MachO) void { | |
| 449 | fn calcSymtabSize(macho_file: *MachO) error{OutOfMemory}!void { | |
| 449 | 450 | const tracy = trace(@src()); |
| 450 | 451 | defer tracy.end(); |
| 451 | 452 | |
| 453 | const gpa = macho_file.base.comp.gpa; | |
| 454 | ||
| 452 | 455 | var nlocals: u32 = 0; |
| 453 | 456 | var nstabs: u32 = 0; |
| 454 | 457 | var nexports: u32 = 0; |
| 455 | 458 | var nimports: u32 = 0; |
| 456 | 459 | var strsize: u32 = 1; |
| 457 | 460 | |
| 458 | for (macho_file.objects.items) |index| { | |
| 459 | const object = macho_file.getFile(index).?.object; | |
| 460 | const ctx = &object.output_symtab_ctx; | |
| 461 | var objects = try std.ArrayList(File.Index).initCapacity(gpa, macho_file.objects.items.len + 1); | |
| 462 | defer objects.deinit(); | |
| 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 | 470 | ctx.ilocal = nlocals; |
| 462 | 471 | ctx.istab = nstabs; |
| 463 | 472 | ctx.iexport = nexports; |
| ... | ... | @@ -470,9 +479,10 @@ fn calcSymtabSize(macho_file: *MachO) void { |
| 470 | 479 | strsize += ctx.strsize; |
| 471 | 480 | } |
| 472 | 481 | |
| 473 | for (macho_file.objects.items) |index| { | |
| 474 | const object = macho_file.getFile(index).?.object; | |
| 475 | const ctx = &object.output_symtab_ctx; | |
| 482 | for (objects.items) |index| { | |
| 483 | const ctx = switch (macho_file.getFile(index).?) { | |
| 484 | inline else => |x| &x.output_symtab_ctx, | |
| 485 | }; | |
| 476 | 486 | ctx.istab += nlocals; |
| 477 | 487 | ctx.iexport += nlocals + nstabs; |
| 478 | 488 | ctx.iimport += nlocals + nstabs + nexports; |
| ... | ... | @@ -645,6 +655,11 @@ fn writeSections(macho_file: *MachO) !void { |
| 645 | 655 | macho_file.getFile(index).?.writeSymtab(macho_file, macho_file); |
| 646 | 656 | } |
| 647 | 657 | |
| 658 | if (macho_file.getZigObject()) |zo| { | |
| 659 | try zo.writeRelocs(macho_file); | |
| 660 | zo.writeSymtab(macho_file, macho_file); | |
| 661 | } | |
| 662 | ||
| 648 | 663 | if (macho_file.eh_frame_sect_index) |_| { |
| 649 | 664 | try writeEhFrame(macho_file); |
| 650 | 665 | } |