| ... | @@ -299,7 +299,11 @@ const Check = struct { | ... | @@ -299,7 +299,11 @@ const Check = struct { |
| 299 | dynamic_symtab, | 299 | dynamic_symtab, |
| 300 | archive_symtab, | 300 | archive_symtab, |
| 301 | dynamic_section, | 301 | dynamic_section, |
| 302 | dyld_info, | 302 | dyld_rebase, |
| | 303 | dyld_bind, |
| | 304 | dyld_weak_bind, |
| | 305 | dyld_lazy_bind, |
| | 306 | exports, |
| 303 | compute_compare, | 307 | compute_compare, |
| 304 | }; | 308 | }; |
| 305 | }; | 309 | }; |
| ... | @@ -398,15 +402,63 @@ pub fn checkInSymtab(self: *CheckObject) void { | ... | @@ -398,15 +402,63 @@ pub fn checkInSymtab(self: *CheckObject) void { |
| 398 | self.checkExact(label); | 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 | /// from the object file. | 406 | /// from the object file. |
| 403 | /// This check is target-dependent and applicable to MachO only. | 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 | const label = switch (self.obj_format) { | 409 | const label = switch (self.obj_format) { |
| 406 | .macho => MachODumper.dyld_info_label, | 410 | .macho => MachODumper.dyld_rebase_label, |
| 407 | else => @panic("Unsupported target platform"), | 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 | self.checkExact(label); | 462 | self.checkExact(label); |
| 411 | } | 463 | } |
| 412 | | 464 | |
| ... | @@ -585,7 +637,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { | ... | @@ -585,7 +637,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 585 | | 637 | |
| 586 | const MachODumper = struct { | 638 | const MachODumper = struct { |
| 587 | const LoadCommandIterator = macho.LoadCommandIterator; | 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 | const symtab_label = "symbol table"; | 645 | const symtab_label = "symbol table"; |
| 590 | const indirect_symtab_label = "indirect symbol table"; | 646 | const indirect_symtab_label = "indirect symbol table"; |
| 591 | | 647 | |
| ... | @@ -696,34 +752,54 @@ const MachODumper = struct { | ... | @@ -696,34 +752,54 @@ const MachODumper = struct { |
| 696 | try dumpIndirectSymtab(gpa, sections.items, symtab, writer); | 752 | try dumpIndirectSymtab(gpa, sections.items, symtab, writer); |
| 697 | } else return step.fail("no indirect symbol table found", .{}), | 753 | } else return step.fail("no indirect symbol table found", .{}), |
| 698 | | 754 | |
| 699 | .dyld_info => if (dyld_info_lc) |lc| { | 755 | .dyld_rebase, |
| 700 | try writer.writeAll(dyld_info_label ++ "\n"); | 756 | .dyld_bind, |
| 701 | if (lc.rebase_size > 0) { | 757 | .dyld_weak_bind, |
| 702 | const data = bytes[lc.rebase_off..][0..lc.rebase_size]; | 758 | .dyld_lazy_bind, |
| 703 | try writer.writeAll("rebase info\n"); | 759 | => { |
| 704 | try dumpRebaseInfo(gpa, data, segments.items, writer); | 760 | if (dyld_info_lc == null) return step.fail("no dyld info found", .{}); |
| 705 | } | 761 | const lc = dyld_info_lc.?; |
| 706 | if (lc.bind_size > 0) { | 762 | |
| 707 | const data = bytes[lc.bind_off..][0..lc.bind_size]; | 763 | switch (kind) { |
| 708 | try writer.writeAll("bind info\n"); | 764 | .dyld_rebase => if (lc.rebase_size > 0) { |
| 709 | try dumpBindInfo(gpa, data, segments.items, imports.items, writer); | 765 | const data = bytes[lc.rebase_off..][0..lc.rebase_size]; |
| 710 | } | 766 | try writer.writeAll(dyld_rebase_label ++ "\n"); |
| 711 | if (lc.weak_bind_size > 0) { | 767 | try dumpRebaseInfo(gpa, data, segments.items, writer); |
| 712 | const data = bytes[lc.weak_bind_off..][0..lc.weak_bind_size]; | 768 | } else return step.fail("no rebase data found", .{}), |
| 713 | try writer.writeAll("weak bind info\n"); | 769 | |
| 714 | try dumpBindInfo(gpa, data, segments.items, imports.items, writer); | 770 | .dyld_bind => if (lc.bind_size > 0) { |
| 715 | } | 771 | const data = bytes[lc.bind_off..][0..lc.bind_size]; |
| 716 | if (lc.lazy_bind_size > 0) { | 772 | try writer.writeAll(dyld_bind_label ++ "\n"); |
| 717 | const data = bytes[lc.lazy_bind_off..][0..lc.lazy_bind_size]; | 773 | try dumpBindInfo(gpa, data, segments.items, imports.items, writer); |
| 718 | try writer.writeAll("lazy bind info\n"); | 774 | } else return step.fail("no bind data found", .{}), |
| 719 | try dumpBindInfo(gpa, data, segments.items, imports.items, writer); | 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) { | 790 | }, |
| 722 | const data = bytes[lc.export_off..][0..lc.export_size]; | 791 | |
| 723 | try writer.writeAll("exports\n"); | 792 | .exports => blk: { |
| 724 | try dumpExportsTrie(gpa, data, segments.items[text_seg.?], writer); | 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 | else => return step.fail("invalid check kind for MachO file format: {s}", .{@tagName(kind)}), | 804 | else => return step.fail("invalid check kind for MachO file format: {s}", .{@tagName(kind)}), |
| 729 | } | 805 | } |