| ... | ... | @@ -299,7 +299,11 @@ const Check = struct { |
| 299 | 299 | dynamic_symtab, |
| 300 | 300 | archive_symtab, |
| 301 | 301 | dynamic_section, |
| 302 | | dyld_info, |
| 302 | dyld_rebase, |
| 303 | dyld_bind, |
| 304 | dyld_weak_bind, |
| 305 | dyld_lazy_bind, |
| 306 | exports, |
| 303 | 307 | compute_compare, |
| 304 | 308 | }; |
| 305 | 309 | }; |
| ... | ... | @@ -398,15 +402,63 @@ pub fn checkInSymtab(self: *CheckObject) void { |
| 398 | 402 | self.checkExact(label); |
| 399 | 403 | } |
| 400 | 404 | |
| 401 | | /// Creates a new check checking specifically dyld_info_only contents parsed and dumped |
| 405 | /// Creates a new check checking specifically dyld rebase opcodes contents parsed and dumped |
| 402 | 406 | /// from the object file. |
| 403 | 407 | /// This check is target-dependent and applicable to MachO only. |
| 404 | | pub fn checkInDyldInfo(self: *CheckObject) void { |
| 408 | pub fn checkInDyldRebase(self: *CheckObject) void { |
| 405 | 409 | const label = switch (self.obj_format) { |
| 406 | | .macho => MachODumper.dyld_info_label, |
| 410 | .macho => MachODumper.dyld_rebase_label, |
| 407 | 411 | else => @panic("Unsupported target platform"), |
| 408 | 412 | }; |
| 409 | | self.checkStart(.dyld_info); |
| 413 | self.checkStart(.dyld_rebase); |
| 414 | self.checkExact(label); |
| 415 | } |
| 416 | |
| 417 | /// Creates a new check checking specifically dyld bind opcodes contents parsed and dumped |
| 418 | /// from the object file. |
| 419 | /// This check is target-dependent and applicable to MachO only. |
| 420 | pub fn checkInDyldBind(self: *CheckObject) void { |
| 421 | const label = switch (self.obj_format) { |
| 422 | .macho => MachODumper.dyld_bind_label, |
| 423 | else => @panic("Unsupported target platform"), |
| 424 | }; |
| 425 | self.checkStart(.dyld_bind); |
| 426 | self.checkExact(label); |
| 427 | } |
| 428 | |
| 429 | /// Creates a new check checking specifically dyld weak bind opcodes contents parsed and dumped |
| 430 | /// from the object file. |
| 431 | /// This check is target-dependent and applicable to MachO only. |
| 432 | pub fn checkInDyldWeakBind(self: *CheckObject) void { |
| 433 | const label = switch (self.obj_format) { |
| 434 | .macho => MachODumper.dyld_weak_bind_label, |
| 435 | else => @panic("Unsupported target platform"), |
| 436 | }; |
| 437 | self.checkStart(.dyld_weak_bind); |
| 438 | self.checkExact(label); |
| 439 | } |
| 440 | |
| 441 | /// Creates a new check checking specifically dyld lazy bind opcodes contents parsed and dumped |
| 442 | /// from the object file. |
| 443 | /// This check is target-dependent and applicable to MachO only. |
| 444 | pub fn checkInDyldLazyBind(self: *CheckObject) void { |
| 445 | const label = switch (self.obj_format) { |
| 446 | .macho => MachODumper.dyld_lazy_bind_label, |
| 447 | else => @panic("Unsupported target platform"), |
| 448 | }; |
| 449 | self.checkStart(.dyld_lazy_bind); |
| 450 | self.checkExact(label); |
| 451 | } |
| 452 | |
| 453 | /// Creates a new check checking specifically exports info contents parsed and dumped |
| 454 | /// from the object file. |
| 455 | /// This check is target-dependent and applicable to MachO only. |
| 456 | pub fn checkInExports(self: *CheckObject) void { |
| 457 | const label = switch (self.obj_format) { |
| 458 | .macho => MachODumper.exports_label, |
| 459 | else => @panic("Unsupported target platform"), |
| 460 | }; |
| 461 | self.checkStart(.exports); |
| 410 | 462 | self.checkExact(label); |
| 411 | 463 | } |
| 412 | 464 | |
| ... | ... | @@ -585,7 +637,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 585 | 637 | |
| 586 | 638 | const MachODumper = struct { |
| 587 | 639 | const LoadCommandIterator = macho.LoadCommandIterator; |
| 588 | | const dyld_info_label = "dyld info data"; |
| 640 | const dyld_rebase_label = "dyld rebase data"; |
| 641 | const dyld_bind_label = "dyld bind data"; |
| 642 | const dyld_weak_bind_label = "dyld weak bind data"; |
| 643 | const dyld_lazy_bind_label = "dyld lazy bind data"; |
| 644 | const exports_label = "exports data"; |
| 589 | 645 | const symtab_label = "symbol table"; |
| 590 | 646 | const indirect_symtab_label = "indirect symbol table"; |
| 591 | 647 | |
| ... | ... | @@ -696,34 +752,54 @@ const MachODumper = struct { |
| 696 | 752 | try dumpIndirectSymtab(gpa, sections.items, symtab, writer); |
| 697 | 753 | } else return step.fail("no indirect symbol table found", .{}), |
| 698 | 754 | |
| 699 | | .dyld_info => if (dyld_info_lc) |lc| { |
| 700 | | try writer.writeAll(dyld_info_label ++ "\n"); |
| 701 | | if (lc.rebase_size > 0) { |
| 702 | | const data = bytes[lc.rebase_off..][0..lc.rebase_size]; |
| 703 | | try writer.writeAll("rebase info\n"); |
| 704 | | try dumpRebaseInfo(gpa, data, segments.items, writer); |
| 705 | | } |
| 706 | | if (lc.bind_size > 0) { |
| 707 | | const data = bytes[lc.bind_off..][0..lc.bind_size]; |
| 708 | | try writer.writeAll("bind info\n"); |
| 709 | | try dumpBindInfo(gpa, data, segments.items, imports.items, writer); |
| 710 | | } |
| 711 | | if (lc.weak_bind_size > 0) { |
| 712 | | const data = bytes[lc.weak_bind_off..][0..lc.weak_bind_size]; |
| 713 | | try writer.writeAll("weak bind info\n"); |
| 714 | | try dumpBindInfo(gpa, data, segments.items, imports.items, writer); |
| 715 | | } |
| 716 | | if (lc.lazy_bind_size > 0) { |
| 717 | | const data = bytes[lc.lazy_bind_off..][0..lc.lazy_bind_size]; |
| 718 | | try writer.writeAll("lazy bind info\n"); |
| 719 | | try dumpBindInfo(gpa, data, segments.items, imports.items, writer); |
| 755 | .dyld_rebase, |
| 756 | .dyld_bind, |
| 757 | .dyld_weak_bind, |
| 758 | .dyld_lazy_bind, |
| 759 | => { |
| 760 | if (dyld_info_lc == null) return step.fail("no dyld info found", .{}); |
| 761 | const lc = dyld_info_lc.?; |
| 762 | |
| 763 | switch (kind) { |
| 764 | .dyld_rebase => if (lc.rebase_size > 0) { |
| 765 | const data = bytes[lc.rebase_off..][0..lc.rebase_size]; |
| 766 | try writer.writeAll(dyld_rebase_label ++ "\n"); |
| 767 | try dumpRebaseInfo(gpa, data, segments.items, writer); |
| 768 | } else return step.fail("no rebase data found", .{}), |
| 769 | |
| 770 | .dyld_bind => if (lc.bind_size > 0) { |
| 771 | const data = bytes[lc.bind_off..][0..lc.bind_size]; |
| 772 | try writer.writeAll(dyld_bind_label ++ "\n"); |
| 773 | try dumpBindInfo(gpa, data, segments.items, imports.items, writer); |
| 774 | } else return step.fail("no bind data found", .{}), |
| 775 | |
| 776 | .dyld_weak_bind => if (lc.weak_bind_size > 0) { |
| 777 | const data = bytes[lc.weak_bind_off..][0..lc.weak_bind_size]; |
| 778 | try writer.writeAll(dyld_weak_bind_label ++ "\n"); |
| 779 | try dumpBindInfo(gpa, data, segments.items, imports.items, writer); |
| 780 | } else return step.fail("no weak bind data found", .{}), |
| 781 | |
| 782 | .dyld_lazy_bind => if (lc.lazy_bind_size > 0) { |
| 783 | const data = bytes[lc.lazy_bind_off..][0..lc.lazy_bind_size]; |
| 784 | try writer.writeAll(dyld_lazy_bind_label ++ "\n"); |
| 785 | try dumpBindInfo(gpa, data, segments.items, imports.items, writer); |
| 786 | } else return step.fail("no lazy bind data found", .{}), |
| 787 | |
| 788 | else => unreachable, |
| 720 | 789 | } |
| 721 | | if (lc.export_size > 0) { |
| 722 | | const data = bytes[lc.export_off..][0..lc.export_size]; |
| 723 | | try writer.writeAll("exports\n"); |
| 724 | | try dumpExportsTrie(gpa, data, segments.items[text_seg.?], writer); |
| 790 | }, |
| 791 | |
| 792 | .exports => blk: { |
| 793 | if (dyld_info_lc) |lc| { |
| 794 | if (lc.export_size > 0) { |
| 795 | const data = bytes[lc.export_off..][0..lc.export_size]; |
| 796 | try writer.writeAll(exports_label ++ "\n"); |
| 797 | try dumpExportsTrie(gpa, data, segments.items[text_seg.?], writer); |
| 798 | break :blk; |
| 799 | } |
| 725 | 800 | } |
| 726 | | } else return step.fail("no dyld info found", .{}), |
| 801 | return step.fail("no exports data found", .{}); |
| 802 | }, |
| 727 | 803 | |
| 728 | 804 | else => return step.fail("invalid check kind for MachO file format: {s}", .{@tagName(kind)}), |
| 729 | 805 | } |