| ... | ... | @@ -32,13 +32,23 @@ pub fn build(b: *Builder) void { |
| 32 | 32 | check_exe.checkNext("exportoff {exportoff}"); |
| 33 | 33 | check_exe.checkNext("exportsize {exportsize}"); |
| 34 | 34 | |
| 35 | check_exe.checkStart("cmd FUNCTION_STARTS"); |
| 36 | check_exe.checkNext("dataoff {fstartoff}"); |
| 37 | check_exe.checkNext("datasize {fstartsize}"); |
| 38 | |
| 39 | check_exe.checkStart("cmd DATA_IN_CODE"); |
| 40 | check_exe.checkNext("dataoff {diceoff}"); |
| 41 | check_exe.checkNext("datasize {dicesize}"); |
| 42 | |
| 35 | 43 | check_exe.checkStart("cmd SYMTAB"); |
| 36 | 44 | check_exe.checkNext("symoff {symoff}"); |
| 45 | check_exe.checkNext("nsyms {symnsyms}"); |
| 37 | 46 | check_exe.checkNext("stroff {stroff}"); |
| 38 | 47 | check_exe.checkNext("strsize {strsize}"); |
| 39 | 48 | |
| 40 | 49 | check_exe.checkStart("cmd DYSYMTAB"); |
| 41 | 50 | check_exe.checkNext("indirectsymoff {dysymoff}"); |
| 51 | check_exe.checkNext("nindirectsyms {dysymnsyms}"); |
| 42 | 52 | |
| 43 | 53 | switch (builtin.cpu.arch) { |
| 44 | 54 | .aarch64 => { |
| ... | ... | @@ -50,42 +60,51 @@ pub fn build(b: *Builder) void { |
| 50 | 60 | else => unreachable, |
| 51 | 61 | } |
| 52 | 62 | |
| 53 | | // Next check: DYLD_INFO_ONLY subsections are in order: rebase < bind < lazy < export |
| 54 | | check_exe.checkComputeCompare("rebaseoff ", .{ .op = .lt, .value = .{ .variable = "bindoff" } }); |
| 55 | | check_exe.checkComputeCompare("bindoff", .{ .op = .lt, .value = .{ .variable = "lazybindoff" } }); |
| 56 | | check_exe.checkComputeCompare("lazybindoff", .{ .op = .lt, .value = .{ .variable = "exportoff" } }); |
| 63 | // DYLD_INFO_ONLY subsections are in order: rebase < bind < lazy < export, |
| 64 | // and there are no gaps between them |
| 65 | check_exe.checkComputeCompare("rebaseoff rebasesize +", .{ .op = .eq, .value = .{ .variable = "bindoff" } }); |
| 66 | check_exe.checkComputeCompare("bindoff bindsize +", .{ .op = .eq, .value = .{ .variable = "lazybindoff" } }); |
| 67 | check_exe.checkComputeCompare("lazybindoff lazybindsize +", .{ .op = .eq, .value = .{ .variable = "exportoff" } }); |
| 68 | |
| 69 | // FUNCTION_STARTS directly follows DYLD_INFO_ONLY (no gap) |
| 70 | check_exe.checkComputeCompare("exportoff exportsize +", .{ .op = .eq, .value = .{ .variable = "fstartoff" } }); |
| 71 | |
| 72 | // DATA_IN_CODE directly follows FUNCTION_STARTS (no gap) |
| 73 | check_exe.checkComputeCompare("fstartoff fstartsize +", .{ .op = .eq, .value = .{ .variable = "diceoff" } }); |
| 74 | |
| 75 | // SYMTAB directly follows DATA_IN_CODE (no gap) |
| 76 | check_exe.checkComputeCompare("diceoff dicesize +", .{ .op = .eq, .value = .{ .variable = "symoff" } }); |
| 57 | 77 | |
| 58 | | // Next check: DYLD_INFO_ONLY subsections do not overlap |
| 59 | | check_exe.checkComputeCompare("rebaseoff rebasesize +", .{ .op = .lte, .value = .{ .variable = "bindoff" } }); |
| 60 | | check_exe.checkComputeCompare("bindoff bindsize +", .{ .op = .lte, .value = .{ .variable = "lazybindoff" } }); |
| 61 | | check_exe.checkComputeCompare("lazybindoff lazybindsize +", .{ .op = .lte, .value = .{ .variable = "exportoff" } }); |
| 78 | // DYSYMTAB directly follows SYMTAB (no gap) |
| 79 | check_exe.checkComputeCompare("symnsyms 16 symoff * +", .{ .op = .eq, .value = .{ .variable = "dysymoff" } }); |
| 62 | 80 | |
| 63 | | // Next check: we maintain order: symtab < dysymtab < strtab |
| 64 | | check_exe.checkComputeCompare("symoff", .{ .op = .lt, .value = .{ .variable = "dysymoff" } }); |
| 65 | | check_exe.checkComputeCompare("dysymoff", .{ .op = .lt, .value = .{ .variable = "stroff" } }); |
| 81 | // STRTAB follows DYSYMTAB with possible gap |
| 82 | check_exe.checkComputeCompare("dysymnsyms 4 dysymoff * +", .{ .op = .lte, .value = .{ .variable = "stroff" } }); |
| 66 | 83 | |
| 67 | | // Next check: all LINKEDIT sections apart from CODE_SIGNATURE are 8-bytes aligned |
| 84 | // all LINKEDIT sections apart from CODE_SIGNATURE are 8-bytes aligned |
| 68 | 85 | check_exe.checkComputeCompare("rebaseoff 8 %", .{ .op = .eq, .value = .{ .literal = 0 } }); |
| 69 | 86 | check_exe.checkComputeCompare("bindoff 8 %", .{ .op = .eq, .value = .{ .literal = 0 } }); |
| 70 | 87 | check_exe.checkComputeCompare("lazybindoff 8 %", .{ .op = .eq, .value = .{ .literal = 0 } }); |
| 71 | 88 | check_exe.checkComputeCompare("exportoff 8 %", .{ .op = .eq, .value = .{ .literal = 0 } }); |
| 89 | check_exe.checkComputeCompare("fstartoff 8 %", .{ .op = .eq, .value = .{ .literal = 0 } }); |
| 90 | check_exe.checkComputeCompare("diceoff 8 %", .{ .op = .eq, .value = .{ .literal = 0 } }); |
| 72 | 91 | check_exe.checkComputeCompare("symoff 8 %", .{ .op = .eq, .value = .{ .literal = 0 } }); |
| 73 | 92 | check_exe.checkComputeCompare("stroff 8 %", .{ .op = .eq, .value = .{ .literal = 0 } }); |
| 74 | 93 | check_exe.checkComputeCompare("dysymoff 8 %", .{ .op = .eq, .value = .{ .literal = 0 } }); |
| 75 | 94 | |
| 76 | 95 | switch (builtin.cpu.arch) { |
| 77 | 96 | .aarch64 => { |
| 78 | | // Next check: LINKEDIT segment does not extend beyond, or does not include, CODE_SIGNATURE data |
| 97 | // LINKEDIT segment does not extend beyond, or does not include, CODE_SIGNATURE data |
| 79 | 98 | check_exe.checkComputeCompare("fileoff filesz codesigoff codesigsize + - -", .{ |
| 80 | 99 | .op = .eq, |
| 81 | 100 | .value = .{ .literal = 0 }, |
| 82 | 101 | }); |
| 83 | 102 | |
| 84 | | // Next check: CODE_SIGNATURE data offset is 16-bytes aligned |
| 103 | // CODE_SIGNATURE data offset is 16-bytes aligned |
| 85 | 104 | check_exe.checkComputeCompare("codesigoff 16 %", .{ .op = .eq, .value = .{ .literal = 0 } }); |
| 86 | 105 | }, |
| 87 | 106 | .x86_64 => { |
| 88 | | // Next check: LINKEDIT segment does not extend beyond, or does not include, strtab data |
| 107 | // LINKEDIT segment does not extend beyond, or does not include, strtab data |
| 89 | 108 | check_exe.checkComputeCompare("fileoff filesz stroff strsize + - -", .{ |
| 90 | 109 | .op = .eq, |
| 91 | 110 | .value = .{ .literal = 0 }, |