| 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,47 +567,10 @@ pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_n |
| 567 | try self.resizeSections(); | 567 | try self.resizeSections(); |
| 568 | 568 | ||
| 569 | if (self.getZigObject()) |zo| { | 569 | if (self.getZigObject()) |zo| { |
| 570 | var has_resolve_error = false; | 570 | zo.resolveRelocs(self) catch |err| switch (err) { |
| 571 | 571 | error.ResolveFailed => return error.FlushFailure, | |
| 572 | for (zo.getAtoms()) |atom_index| { | 572 | else => |e| return e, |
| 573 | const atom = zo.getAtom(atom_index) orelse continue; | 573 | }; |
| 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; | ||
| 611 | } | 574 | } |
| 612 | self.writeSectionsAndUpdateLinkeditSizes() catch |err| { | 575 | self.writeSectionsAndUpdateLinkeditSizes() catch |err| { |
| 613 | switch (err) { | 576 | switch (err) { |
src/link/MachO/ZigObject.zig+49| ... | @@ -383,6 +383,55 @@ pub fn scanRelocs(self: *ZigObject, macho_file: *MachO) !void { | ... | @@ -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 | pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) void { | 435 | pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) void { |
| 387 | const tracy = trace(@src()); | 436 | const tracy = trace(@src()); |
| 388 | defer tracy.end(); | 437 | defer tracy.end(); |