| author | |
| committer | |
| log | 4aff0ec394cb6ef42db982df86caf8976b558d43 |
| tree | 31b9adeae926a2f2a451196f0286b9e3094d3969 |
| parent | b62281a9c87caab22ff22fb783751a1cd784bcaa |
2 files changed, 53 insertions(+), 41 deletions(-)
src/link/MachO.zig+4-41| ... | ... | @@ -567,47 +567,10 @@ pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_n |
| 567 | 567 | try self.resizeSections(); |
| 568 | 568 | |
| 569 | 569 | if (self.getZigObject()) |zo| { |
| 570 | var has_resolve_error = false; | |
| 571 | ||
| 572 | for (zo.getAtoms()) |atom_index| { | |
| 573 | const atom = zo.getAtom(atom_index) orelse continue; | |
| 574 | if (!atom.flags.alive) continue; | |
| 575 | const sect = &self.sections.items(.header)[atom.out_n_sect]; | |
| 576 | if (sect.isZerofill()) continue; | |
| 577 | if (!self.isZigSection(atom.out_n_sect)) continue; // Non-Zig sections are handled separately | |
| 578 | if (atom.getRelocs(self).len == 0) continue; | |
| 579 | // TODO: we will resolve and write ZigObject's TLS data twice: | |
| 580 | // once here, and once in writeAtoms | |
| 581 | const atom_size = math.cast(usize, atom.size) orelse return error.Overflow; | |
| 582 | const code = try gpa.alloc(u8, atom_size); | |
| 583 | defer gpa.free(code); | |
| 584 | zo.getAtomData(self, atom.*, code) catch |err| switch (err) { | |
| 585 | error.InputOutput => { | |
| 586 | try self.reportUnexpectedError("fetching code for '{s}' failed", .{ | |
| 587 | atom.getName(self), | |
| 588 | }); | |
| 589 | return error.FlushFailure; | |
| 590 | }, | |
| 591 | else => |e| { | |
| 592 | try self.reportUnexpectedError("unexpected error while fetching code for '{s}': {s}", .{ | |
| 593 | atom.getName(self), | |
| 594 | @errorName(e), | |
| 595 | }); | |
| 596 | return error.FlushFailure; | |
| 597 | }, | |
| 598 | }; | |
| 599 | const file_offset = sect.offset + atom.value; | |
| 600 | atom.resolveRelocs(self, code) catch |err| switch (err) { | |
| 601 | error.ResolveFailed => has_resolve_error = true, | |
| 602 | else => |e| { | |
| 603 | try self.reportUnexpectedError("unexpected error while resolving relocations", .{}); | |
| 604 | return e; | |
| 605 | }, | |
| 606 | }; | |
| 607 | try self.base.file.?.pwriteAll(code, file_offset); | |
| 608 | } | |
| 609 | ||
| 610 | if (has_resolve_error) return error.FlushFailure; | |
| 570 | zo.resolveRelocs(self) catch |err| switch (err) { | |
| 571 | error.ResolveFailed => return error.FlushFailure, | |
| 572 | else => |e| return e, | |
| 573 | }; | |
| 611 | 574 | } |
| 612 | 575 | self.writeSectionsAndUpdateLinkeditSizes() catch |err| { |
| 613 | 576 | switch (err) { |
src/link/MachO/ZigObject.zig+49| ... | ... | @@ -383,6 +383,55 @@ pub fn scanRelocs(self: *ZigObject, macho_file: *MachO) !void { |
| 383 | 383 | } |
| 384 | 384 | } |
| 385 | 385 | |
| 386 | pub fn resolveRelocs(self: *ZigObject, macho_file: *MachO) !void { | |
| 387 | const gpa = macho_file.base.comp.gpa; | |
| 388 | var has_error = false; | |
| 389 | for (self.getAtoms()) |atom_index| { | |
| 390 | const atom = self.getAtom(atom_index) orelse continue; | |
| 391 | if (!atom.flags.alive) continue; | |
| 392 | const sect = &macho_file.sections.items(.header)[atom.out_n_sect]; | |
| 393 | if (sect.isZerofill()) continue; | |
| 394 | if (!macho_file.isZigSection(atom.out_n_sect)) continue; // Non-Zig sections are handled separately | |
| 395 | if (atom.getRelocs(macho_file).len == 0) continue; | |
| 396 | // TODO: we will resolve and write ZigObject's TLS data twice: | |
| 397 | // once here, and once in writeAtoms | |
| 398 | const atom_size = std.math.cast(usize, atom.size) orelse return error.Overflow; | |
| 399 | const code = try gpa.alloc(u8, atom_size); | |
| 400 | defer gpa.free(code); | |
| 401 | self.getAtomData(macho_file, atom.*, code) catch |err| { | |
| 402 | switch (err) { | |
| 403 | error.InputOutput => { | |
| 404 | try macho_file.reportUnexpectedError("fetching code for '{s}' failed", .{ | |
| 405 | atom.getName(macho_file), | |
| 406 | }); | |
| 407 | }, | |
| 408 | else => |e| { | |
| 409 | try macho_file.reportUnexpectedError("unexpected error while fetching code for '{s}': {s}", .{ | |
| 410 | atom.getName(macho_file), | |
| 411 | @errorName(e), | |
| 412 | }); | |
| 413 | }, | |
| 414 | } | |
| 415 | has_error = true; | |
| 416 | continue; | |
| 417 | }; | |
| 418 | const file_offset = sect.offset + atom.value; | |
| 419 | atom.resolveRelocs(macho_file, code) catch |err| { | |
| 420 | switch (err) { | |
| 421 | error.ResolveFailed => {}, | |
| 422 | else => |e| { | |
| 423 | try macho_file.reportUnexpectedError("unexpected error while resolving relocations: {s}", .{@errorName(e)}); | |
| 424 | }, | |
| 425 | } | |
| 426 | has_error = true; | |
| 427 | continue; | |
| 428 | }; | |
| 429 | try macho_file.base.file.?.pwriteAll(code, file_offset); | |
| 430 | } | |
| 431 | ||
| 432 | if (has_error) return error.ResolveFailed; | |
| 433 | } | |
| 434 | ||
| 386 | 435 | pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) void { |
| 387 | 436 | const tracy = trace(@src()); |
| 388 | 437 | defer tracy.end(); |