authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-12-13 18:47:09+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-12-13 18:47:09+01:00
log4574dea13a4b1d38c97fe73c257d895f605b78ca
tree0a1af823ce5c7c2ff0546c32f37cfe45b1f5ea6f
parenta38af5f542199378483aba9f4598634ebf012b7b
parent5d12622469db5c53fe4857dfd95be033c16b4056
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #18271 from ziglang/check-object-scoped-checks

lib/std/Build/CheckObject: introduce scoped checks

29 files changed, 454 insertions(+), 242 deletions(-)

lib/std/Build/Step/CheckObject.zig+370-158
...@@ -246,10 +246,12 @@ const ComputeCompareExpected = struct {...@@ -246,10 +246,12 @@ const ComputeCompareExpected = struct {
246};246};
247247
248const Check = struct {248const Check = struct {
249 kind: Kind,
249 actions: std.ArrayList(Action),250 actions: std.ArrayList(Action),
250251
251 fn create(allocator: Allocator) Check {252 fn create(allocator: Allocator, kind: Kind) Check {
252 return .{253 return .{
254 .kind = kind,
253 .actions = std.ArrayList(Action).init(allocator),255 .actions = std.ArrayList(Action).init(allocator),
254 };256 };
255 }257 }
...@@ -289,15 +291,30 @@ const Check = struct {...@@ -289,15 +291,30 @@ const Check = struct {
289 .expected = expected,291 .expected = expected,
290 }) catch @panic("OOM");292 }) catch @panic("OOM");
291 }293 }
294
295 const Kind = enum {
296 headers,
297 symtab,
298 indirect_symtab,
299 dynamic_symtab,
300 archive_symtab,
301 dynamic_section,
302 dyld_rebase,
303 dyld_bind,
304 dyld_weak_bind,
305 dyld_lazy_bind,
306 exports,
307 compute_compare,
308 };
292};309};
293310
294/// Creates a new empty sequence of actions.311/// Creates a new empty sequence of actions.
295pub fn checkStart(self: *CheckObject) void {312fn checkStart(self: *CheckObject, kind: Check.Kind) void {
296 const new_check = Check.create(self.step.owner.allocator);313 const new_check = Check.create(self.step.owner.allocator, kind);
297 self.checks.append(new_check) catch @panic("OOM");314 self.checks.append(new_check) catch @panic("OOM");
298}315}
299316
300/// Adds an exact match phrase to the latest created Check with `CheckObject.checkStart()`.317/// Adds an exact match phrase to the latest created Check.
301pub fn checkExact(self: *CheckObject, phrase: []const u8) void {318pub fn checkExact(self: *CheckObject, phrase: []const u8) void {
302 self.checkExactInner(phrase, null);319 self.checkExactInner(phrase, null);
303}320}
...@@ -314,7 +331,7 @@ fn checkExactInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Bui...@@ -314,7 +331,7 @@ fn checkExactInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Bui
314 last.exact(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source });331 last.exact(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source });
315}332}
316333
317/// Adds a fuzzy match phrase to the latest created Check with `CheckObject.checkStart()`.334/// Adds a fuzzy match phrase to the latest created Check.
318pub fn checkContains(self: *CheckObject, phrase: []const u8) void {335pub fn checkContains(self: *CheckObject, phrase: []const u8) void {
319 self.checkContainsInner(phrase, null);336 self.checkContainsInner(phrase, null);
320}337}
...@@ -331,8 +348,7 @@ fn checkContainsInner(self: *CheckObject, phrase: []const u8, file_source: ?std....@@ -331,8 +348,7 @@ fn checkContainsInner(self: *CheckObject, phrase: []const u8, file_source: ?std.
331 last.contains(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source });348 last.contains(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source });
332}349}
333350
334/// Adds an exact match phrase with variable extractor to the latest created Check351/// Adds an exact match phrase with variable extractor to the latest created Check.
335/// with `CheckObject.checkStart()`.
336pub fn checkExtract(self: *CheckObject, phrase: []const u8) void {352pub fn checkExtract(self: *CheckObject, phrase: []const u8) void {
337 self.checkExtractInner(phrase, null);353 self.checkExtractInner(phrase, null);
338}354}
...@@ -349,7 +365,7 @@ fn checkExtractInner(self: *CheckObject, phrase: []const u8, file_source: ?std.B...@@ -349,7 +365,7 @@ fn checkExtractInner(self: *CheckObject, phrase: []const u8, file_source: ?std.B
349 last.extract(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source });365 last.extract(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source });
350}366}
351367
352/// Adds another searched phrase to the latest created Check with `CheckObject.checkStart(...)`368/// Adds another searched phrase to the latest created Check
353/// however ensures there is no matching phrase in the output.369/// however ensures there is no matching phrase in the output.
354pub fn checkNotPresent(self: *CheckObject, phrase: []const u8) void {370pub fn checkNotPresent(self: *CheckObject, phrase: []const u8) void {
355 self.checkNotPresentInner(phrase, null);371 self.checkNotPresentInner(phrase, null);
...@@ -367,6 +383,11 @@ fn checkNotPresentInner(self: *CheckObject, phrase: []const u8, file_source: ?st...@@ -367,6 +383,11 @@ fn checkNotPresentInner(self: *CheckObject, phrase: []const u8, file_source: ?st
367 last.notPresent(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source });383 last.notPresent(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source });
368}384}
369385
386/// Creates a new check checking in the file headers (section, program headers, etc.).
387pub fn checkInHeaders(self: *CheckObject) void {
388 self.checkStart(.headers);
389}
390
370/// Creates a new check checking specifically symbol table parsed and dumped from the object391/// Creates a new check checking specifically symbol table parsed and dumped from the object
371/// file.392/// file.
372pub fn checkInSymtab(self: *CheckObject) void {393pub fn checkInSymtab(self: *CheckObject) void {
...@@ -377,19 +398,79 @@ pub fn checkInSymtab(self: *CheckObject) void {...@@ -377,19 +398,79 @@ pub fn checkInSymtab(self: *CheckObject) void {
377 .coff => @panic("TODO symtab for coff"),398 .coff => @panic("TODO symtab for coff"),
378 else => @panic("TODO other file formats"),399 else => @panic("TODO other file formats"),
379 };400 };
380 self.checkStart();401 self.checkStart(.symtab);
402 self.checkExact(label);
403}
404
405/// Creates a new check checking specifically dyld rebase opcodes contents parsed and dumped
406/// from the object file.
407/// This check is target-dependent and applicable to MachO only.
408pub fn checkInDyldRebase(self: *CheckObject) void {
409 const label = switch (self.obj_format) {
410 .macho => MachODumper.dyld_rebase_label,
411 else => @panic("Unsupported target platform"),
412 };
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.
420pub 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.
432pub 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);
381 self.checkExact(label);438 self.checkExact(label);
382}439}
383440
384/// Creates a new check checking specifically dyld_info_only contents parsed and dumped441/// Creates a new check checking specifically dyld lazy bind opcodes contents parsed and dumped
385/// from the object file.442/// from the object file.
386/// This check is target-dependent and applicable to MachO only.443/// This check is target-dependent and applicable to MachO only.
387pub fn checkInDyldInfo(self: *CheckObject) void {444pub fn checkInDyldLazyBind(self: *CheckObject) void {
388 const label = switch (self.obj_format) {445 const label = switch (self.obj_format) {
389 .macho => MachODumper.dyld_info_label,446 .macho => MachODumper.dyld_lazy_bind_label,
390 else => @panic("Unsupported target platform"),447 else => @panic("Unsupported target platform"),
391 };448 };
392 self.checkStart();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.
456pub 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);
462 self.checkExact(label);
463}
464
465/// Creates a new check checking specifically indirect symbol table parsed and dumped
466/// from the object file.
467/// This check is target-dependent and applicable to MachO only.
468pub fn checkInIndirectSymtab(self: *CheckObject) void {
469 const label = switch (self.obj_format) {
470 .macho => MachODumper.indirect_symtab_label,
471 else => @panic("Unsupported target platform"),
472 };
473 self.checkStart(.indirect_symtab);
393 self.checkExact(label);474 self.checkExact(label);
394}475}
395476
...@@ -401,7 +482,7 @@ pub fn checkInDynamicSymtab(self: *CheckObject) void {...@@ -401,7 +482,7 @@ pub fn checkInDynamicSymtab(self: *CheckObject) void {
401 .elf => ElfDumper.dynamic_symtab_label,482 .elf => ElfDumper.dynamic_symtab_label,
402 else => @panic("Unsupported target platform"),483 else => @panic("Unsupported target platform"),
403 };484 };
404 self.checkStart();485 self.checkStart(.dynamic_symtab);
405 self.checkExact(label);486 self.checkExact(label);
406}487}
407488
...@@ -413,7 +494,7 @@ pub fn checkInDynamicSection(self: *CheckObject) void {...@@ -413,7 +494,7 @@ pub fn checkInDynamicSection(self: *CheckObject) void {
413 .elf => ElfDumper.dynamic_section_label,494 .elf => ElfDumper.dynamic_section_label,
414 else => @panic("Unsupported target platform"),495 else => @panic("Unsupported target platform"),
415 };496 };
416 self.checkStart();497 self.checkStart(.dynamic_section);
417 self.checkExact(label);498 self.checkExact(label);
418}499}
419500
...@@ -424,7 +505,7 @@ pub fn checkInArchiveSymtab(self: *CheckObject) void {...@@ -424,7 +505,7 @@ pub fn checkInArchiveSymtab(self: *CheckObject) void {
424 .elf => ElfDumper.archive_symtab_label,505 .elf => ElfDumper.archive_symtab_label,
425 else => @panic("TODO other file formats"),506 else => @panic("TODO other file formats"),
426 };507 };
427 self.checkStart();508 self.checkStart(.archive_symtab);
428 self.checkExact(label);509 self.checkExact(label);
429}510}
430511
...@@ -436,7 +517,7 @@ pub fn checkComputeCompare(...@@ -436,7 +517,7 @@ pub fn checkComputeCompare(
436 program: []const u8,517 program: []const u8,
437 expected: ComputeCompareExpected,518 expected: ComputeCompareExpected,
438) void {519) void {
439 var new_check = Check.create(self.step.owner.allocator);520 var new_check = Check.create(self.step.owner.allocator, .compute_compare);
440 new_check.computeCmp(.{ .string = self.step.owner.dupe(program) }, expected);521 new_check.computeCmp(.{ .string = self.step.owner.dupe(program) }, expected);
441 self.checks.append(new_check) catch @panic("OOM");522 self.checks.append(new_check) catch @panic("OOM");
442}523}
...@@ -457,17 +538,35 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -457,17 +538,35 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
457 null,538 null,
458 ) catch |err| return step.fail("unable to read '{s}': {s}", .{ src_path, @errorName(err) });539 ) catch |err| return step.fail("unable to read '{s}': {s}", .{ src_path, @errorName(err) });
459540
460 const output = switch (self.obj_format) {
461 .macho => try MachODumper.parseAndDump(step, contents),
462 .elf => try ElfDumper.parseAndDump(step, contents),
463 .coff => @panic("TODO coff parser"),
464 .wasm => try WasmDumper.parseAndDump(step, contents),
465 else => unreachable,
466 };
467
468 var vars = std.StringHashMap(u64).init(gpa);541 var vars = std.StringHashMap(u64).init(gpa);
469
470 for (self.checks.items) |chk| {542 for (self.checks.items) |chk| {
543 if (chk.kind == .compute_compare) {
544 assert(chk.actions.items.len == 1);
545 const act = chk.actions.items[0];
546 assert(act.tag == .compute_cmp);
547 const res = act.computeCmp(b, step, vars) catch |err| switch (err) {
548 error.UnknownVariable => return step.fail("Unknown variable", .{}),
549 else => |e| return e,
550 };
551 if (!res) {
552 return step.fail(
553 \\
554 \\========= comparison failed for action: ===========
555 \\{s} {}
556 \\===================================================
557 , .{ act.phrase.resolve(b, step), act.expected.? });
558 }
559 continue;
560 }
561
562 const output = switch (self.obj_format) {
563 .macho => try MachODumper.parseAndDump(step, chk.kind, contents),
564 .elf => try ElfDumper.parseAndDump(step, chk.kind, contents),
565 .coff => return step.fail("TODO coff parser", .{}),
566 .wasm => try WasmDumper.parseAndDump(step, chk.kind, contents),
567 else => unreachable,
568 };
569
471 var it = mem.tokenizeAny(u8, output, "\r\n");570 var it = mem.tokenizeAny(u8, output, "\r\n");
472 for (chk.actions.items) |act| {571 for (chk.actions.items) |act| {
473 switch (act.tag) {572 switch (act.tag) {
...@@ -485,6 +584,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -485,6 +584,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
485 , .{ act.phrase.resolve(b, step), output });584 , .{ act.phrase.resolve(b, step), output });
486 }585 }
487 },586 },
587
488 .contains => {588 .contains => {
489 while (it.next()) |line| {589 while (it.next()) |line| {
490 if (act.contains(b, step, line)) break;590 if (act.contains(b, step, line)) break;
...@@ -499,6 +599,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -499,6 +599,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
499 , .{ act.phrase.resolve(b, step), output });599 , .{ act.phrase.resolve(b, step), output });
500 }600 }
501 },601 },
602
502 .not_present => {603 .not_present => {
503 while (it.next()) |line| {604 while (it.next()) |line| {
504 if (act.notPresent(b, step, line)) continue;605 if (act.notPresent(b, step, line)) continue;
...@@ -512,6 +613,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -512,6 +613,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
512 , .{ act.phrase.resolve(b, step), output });613 , .{ act.phrase.resolve(b, step), output });
513 }614 }
514 },615 },
616
515 .extract => {617 .extract => {
516 while (it.next()) |line| {618 while (it.next()) |line| {
517 if (try act.extract(b, step, line, &vars)) break;619 if (try act.extract(b, step, line, &vars)) break;
...@@ -526,28 +628,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -526,28 +628,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
526 , .{ act.phrase.resolve(b, step), output });628 , .{ act.phrase.resolve(b, step), output });
527 }629 }
528 },630 },
529 .compute_cmp => {631
530 const res = act.computeCmp(b, step, vars) catch |err| switch (err) {632 .compute_cmp => unreachable,
531 error.UnknownVariable => {
532 return step.fail(
533 \\========= from parsed file: =====================
534 \\{s}
535 \\=================================================
536 , .{output});
537 },
538 else => |e| return e,
539 };
540 if (!res) {
541 return step.fail(
542 \\
543 \\========= comparison failed for action: ===========
544 \\{s} {}
545 \\========= from parsed file: =======================
546 \\{s}
547 \\===================================================
548 , .{ act.phrase.resolve(b, step), act.expected.?, output });
549 }
550 },
551 }633 }
552 }634 }
553 }635 }
...@@ -555,15 +637,26 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -555,15 +637,26 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
555637
556const MachODumper = struct {638const MachODumper = struct {
557 const LoadCommandIterator = macho.LoadCommandIterator;639 const LoadCommandIterator = macho.LoadCommandIterator;
558 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";
559 const symtab_label = "symbol table";645 const symtab_label = "symbol table";
646 const indirect_symtab_label = "indirect symbol table";
560647
561 const Symtab = struct {648 const Symtab = struct {
562 symbols: []align(1) const macho.nlist_64,649 symbols: []align(1) const macho.nlist_64 = &[0]macho.nlist_64{},
563 strings: []const u8,650 strings: []const u8 = &[0]u8{},
651 indirect_symbols: []align(1) const u32 = &[0]u32{},
652
653 fn getString(symtab: Symtab, off: u32) []const u8 {
654 assert(off < symtab.strings.len);
655 return mem.sliceTo(@as([*:0]const u8, @ptrCast(symtab.strings.ptr + off)), 0);
656 }
564 };657 };
565658
566 fn parseAndDump(step: *Step, bytes: []const u8) ![]const u8 {659 fn parseAndDump(step: *Step, kind: Check.Kind, bytes: []const u8) ![]const u8 {
567 const gpa = step.owner.allocator;660 const gpa = step.owner.allocator;
568 var stream = std.io.fixedBufferStream(bytes);661 var stream = std.io.fixedBufferStream(bytes);
569 const reader = stream.reader();662 const reader = stream.reader();
...@@ -576,7 +669,7 @@ const MachODumper = struct {...@@ -576,7 +669,7 @@ const MachODumper = struct {
576 var output = std.ArrayList(u8).init(gpa);669 var output = std.ArrayList(u8).init(gpa);
577 const writer = output.writer();670 const writer = output.writer();
578671
579 var symtab: ?Symtab = null;672 var symtab: Symtab = .{};
580 var segments = std.ArrayList(macho.segment_command_64).init(gpa);673 var segments = std.ArrayList(macho.segment_command_64).init(gpa);
581 defer segments.deinit();674 defer segments.deinit();
582 var sections = std.ArrayList(macho.section_64).init(gpa);675 var sections = std.ArrayList(macho.section_64).init(gpa);
...@@ -586,82 +679,129 @@ const MachODumper = struct {...@@ -586,82 +679,129 @@ const MachODumper = struct {
586 var text_seg: ?u8 = null;679 var text_seg: ?u8 = null;
587 var dyld_info_lc: ?macho.dyld_info_command = null;680 var dyld_info_lc: ?macho.dyld_info_command = null;
588681
589 try dumpHeader(hdr, writer);682 {
683 var it: LoadCommandIterator = .{
684 .ncmds = hdr.ncmds,
685 .buffer = bytes[@sizeOf(macho.mach_header_64)..][0..hdr.sizeofcmds],
686 };
687 var i: usize = 0;
688 while (it.next()) |cmd| {
689 switch (cmd.cmd()) {
690 .SEGMENT_64 => {
691 const seg = cmd.cast(macho.segment_command_64).?;
692 try sections.ensureUnusedCapacity(seg.nsects);
693 for (cmd.getSections()) |sect| {
694 sections.appendAssumeCapacity(sect);
695 }
696 const seg_id: u8 = @intCast(segments.items.len);
697 try segments.append(seg);
698 if (mem.eql(u8, seg.segName(), "__TEXT")) {
699 text_seg = seg_id;
700 }
701 },
702 .SYMTAB => {
703 const lc = cmd.cast(macho.symtab_command).?;
704 const symbols = @as([*]align(1) const macho.nlist_64, @ptrCast(bytes.ptr + lc.symoff))[0..lc.nsyms];
705 const strings = bytes[lc.stroff..][0..lc.strsize];
706 symtab.symbols = symbols;
707 symtab.strings = strings;
708 },
709 .DYSYMTAB => {
710 const lc = cmd.cast(macho.dysymtab_command).?;
711 const indexes = @as([*]align(1) const u32, @ptrCast(bytes.ptr + lc.indirectsymoff))[0..lc.nindirectsyms];
712 symtab.indirect_symbols = indexes;
713 },
714 .LOAD_DYLIB,
715 .LOAD_WEAK_DYLIB,
716 .REEXPORT_DYLIB,
717 => {
718 try imports.append(cmd.getDylibPathName());
719 },
720 .DYLD_INFO_ONLY => {
721 dyld_info_lc = cmd.cast(macho.dyld_info_command).?;
722 },
723 else => {},
724 }
590725
591 var it: LoadCommandIterator = .{726 i += 1;
592 .ncmds = hdr.ncmds,
593 .buffer = bytes[@sizeOf(macho.mach_header_64)..][0..hdr.sizeofcmds],
594 };
595 var i: usize = 0;
596 while (it.next()) |cmd| {
597 switch (cmd.cmd()) {
598 .SEGMENT_64 => {
599 const seg = cmd.cast(macho.segment_command_64).?;
600 try sections.ensureUnusedCapacity(seg.nsects);
601 for (cmd.getSections()) |sect| {
602 sections.appendAssumeCapacity(sect);
603 }
604 const seg_id: u8 = @intCast(segments.items.len);
605 try segments.append(seg);
606 if (mem.eql(u8, seg.segName(), "__TEXT")) {
607 text_seg = seg_id;
608 }
609 },
610 .SYMTAB => {
611 const lc = cmd.cast(macho.symtab_command).?;
612 const symbols = @as([*]align(1) const macho.nlist_64, @ptrCast(bytes.ptr + lc.symoff))[0..lc.nsyms];
613 const strings = bytes[lc.stroff..][0..lc.strsize];
614 symtab = .{ .symbols = symbols, .strings = strings };
615 },
616 .LOAD_DYLIB,
617 .LOAD_WEAK_DYLIB,
618 .REEXPORT_DYLIB,
619 => {
620 try imports.append(cmd.getDylibPathName());
621 },
622 .DYLD_INFO_ONLY => {
623 dyld_info_lc = cmd.cast(macho.dyld_info_command).?;
624 },
625 else => {},
626 }727 }
728 }
627729
628 try dumpLoadCommand(cmd, i, writer);730 switch (kind) {
629 try writer.writeByte('\n');731 .headers => {
732 try dumpHeader(hdr, writer);
630733
631 i += 1;734 var it: LoadCommandIterator = .{
632 }735 .ncmds = hdr.ncmds,
736 .buffer = bytes[@sizeOf(macho.mach_header_64)..][0..hdr.sizeofcmds],
737 };
738 var i: usize = 0;
739 while (it.next()) |cmd| {
740 try dumpLoadCommand(cmd, i, writer);
741 try writer.writeByte('\n');
633742
634 if (symtab) |stab| {743 i += 1;
635 try dumpSymtab(sections.items, imports.items, stab, writer);744 }
636 }745 },
637746
638 if (dyld_info_lc) |lc| {747 .symtab => if (symtab.symbols.len > 0) {
639 try writer.writeAll(dyld_info_label ++ "\n");748 try dumpSymtab(sections.items, imports.items, symtab, writer);
640 if (lc.rebase_size > 0) {749 } else return step.fail("no symbol table found", .{}),
641 const data = bytes[lc.rebase_off..][0..lc.rebase_size];750
642 try writer.writeAll("rebase info\n");751 .indirect_symtab => if (symtab.symbols.len > 0 and symtab.indirect_symbols.len > 0) {
643 try dumpRebaseInfo(gpa, data, segments.items, writer);752 try dumpIndirectSymtab(gpa, sections.items, symtab, writer);
644 }753 } else return step.fail("no indirect symbol table found", .{}),
645 if (lc.bind_size > 0) {754
646 const data = bytes[lc.bind_off..][0..lc.bind_size];755 .dyld_rebase,
647 try writer.writeAll("bind info\n");756 .dyld_bind,
648 try dumpBindInfo(gpa, data, segments.items, imports.items, writer);757 .dyld_weak_bind,
649 }758 .dyld_lazy_bind,
650 if (lc.weak_bind_size > 0) {759 => {
651 const data = bytes[lc.weak_bind_off..][0..lc.weak_bind_size];760 if (dyld_info_lc == null) return step.fail("no dyld info found", .{});
652 try writer.writeAll("weak bind info\n");761 const lc = dyld_info_lc.?;
653 try dumpBindInfo(gpa, data, segments.items, imports.items, writer);762
654 }763 switch (kind) {
655 if (lc.lazy_bind_size > 0) {764 .dyld_rebase => if (lc.rebase_size > 0) {
656 const data = bytes[lc.lazy_bind_off..][0..lc.lazy_bind_size];765 const data = bytes[lc.rebase_off..][0..lc.rebase_size];
657 try writer.writeAll("lazy bind info\n");766 try writer.writeAll(dyld_rebase_label ++ "\n");
658 try dumpBindInfo(gpa, data, segments.items, imports.items, writer);767 try dumpRebaseInfo(gpa, data, segments.items, writer);
659 }768 } else return step.fail("no rebase data found", .{}),
660 if (lc.export_size > 0) {769
661 const data = bytes[lc.export_off..][0..lc.export_size];770 .dyld_bind => if (lc.bind_size > 0) {
662 try writer.writeAll("exports\n");771 const data = bytes[lc.bind_off..][0..lc.bind_size];
663 try dumpExportsTrie(gpa, data, segments.items[text_seg.?], writer);772 try writer.writeAll(dyld_bind_label ++ "\n");
664 }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,
789 }
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 }
800 }
801 return step.fail("no exports data found", .{});
802 },
803
804 else => return step.fail("invalid check kind for MachO file format: {s}", .{@tagName(kind)}),
665 }805 }
666806
667 return output.toOwnedSlice();807 return output.toOwnedSlice();
...@@ -971,7 +1111,7 @@ const MachODumper = struct {...@@ -971,7 +1111,7 @@ const MachODumper = struct {
9711111
972 for (symtab.symbols) |sym| {1112 for (symtab.symbols) |sym| {
973 if (sym.stab()) continue;1113 if (sym.stab()) continue;
974 const sym_name = mem.sliceTo(@as([*:0]const u8, @ptrCast(symtab.strings.ptr + sym.n_strx)), 0);1114 const sym_name = symtab.getString(sym.n_strx);
975 if (sym.sect()) {1115 if (sym.sect()) {
976 const sect = sections[sym.n_sect - 1];1116 const sect = sections[sym.n_sect - 1];
977 try writer.print("{x} ({s},{s})", .{1117 try writer.print("{x} ({s},{s})", .{
...@@ -1021,6 +1161,52 @@ const MachODumper = struct {...@@ -1021,6 +1161,52 @@ const MachODumper = struct {
1021 }1161 }
1022 }1162 }
10231163
1164 fn dumpIndirectSymtab(
1165 gpa: Allocator,
1166 sections: []const macho.section_64,
1167 symtab: Symtab,
1168 writer: anytype,
1169 ) !void {
1170 try writer.writeAll(indirect_symtab_label ++ "\n");
1171
1172 var sects = std.ArrayList(macho.section_64).init(gpa);
1173 defer sects.deinit();
1174 try sects.ensureUnusedCapacity(3);
1175
1176 for (sections) |sect| {
1177 if (mem.eql(u8, sect.sectName(), "__stubs")) sects.appendAssumeCapacity(sect);
1178 if (mem.eql(u8, sect.sectName(), "__got")) sects.appendAssumeCapacity(sect);
1179 if (mem.eql(u8, sect.sectName(), "__la_symbol_ptr")) sects.appendAssumeCapacity(sect);
1180 }
1181
1182 const sortFn = struct {
1183 fn sortFn(ctx: void, lhs: macho.section_64, rhs: macho.section_64) bool {
1184 _ = ctx;
1185 return lhs.reserved1 < rhs.reserved1;
1186 }
1187 }.sortFn;
1188 mem.sort(macho.section_64, sects.items, {}, sortFn);
1189
1190 var i: usize = 0;
1191 while (i < sects.items.len) : (i += 1) {
1192 const sect = sects.items[i];
1193 const start = sect.reserved1;
1194 const end = if (i + 1 >= sects.items.len) symtab.indirect_symbols.len else sects.items[i + 1].reserved1;
1195 const entry_size = blk: {
1196 if (mem.eql(u8, sect.sectName(), "__stubs")) break :blk sect.reserved2;
1197 break :blk @sizeOf(u64);
1198 };
1199
1200 try writer.print("{s},{s}\n", .{ sect.segName(), sect.sectName() });
1201 try writer.print("nentries {d}\n", .{end - start});
1202 for (symtab.indirect_symbols[start..end], 0..) |index, j| {
1203 const sym = symtab.symbols[index];
1204 const addr = sect.addr + entry_size * j;
1205 try writer.print("0x{x} {d} {s}\n", .{ addr, index, symtab.getString(sym.n_strx) });
1206 }
1207 }
1208 }
1209
1024 fn dumpRebaseInfo(1210 fn dumpRebaseInfo(
1025 gpa: Allocator,1211 gpa: Allocator,
1026 data: []const u8,1212 data: []const u8,
...@@ -1443,15 +1629,15 @@ const ElfDumper = struct {...@@ -1443,15 +1629,15 @@ const ElfDumper = struct {
1443 const dynamic_section_label = "dynamic section";1629 const dynamic_section_label = "dynamic section";
1444 const archive_symtab_label = "archive symbol table";1630 const archive_symtab_label = "archive symbol table";
14451631
1446 fn parseAndDump(step: *Step, bytes: []const u8) ![]const u8 {1632 fn parseAndDump(step: *Step, kind: Check.Kind, bytes: []const u8) ![]const u8 {
1447 const gpa = step.owner.allocator;1633 return parseAndDumpArchive(step, kind, bytes) catch |err| switch (err) {
1448 return parseAndDumpArchive(gpa, bytes) catch |err| switch (err) {1634 error.InvalidArchiveMagicNumber => try parseAndDumpObject(step, kind, bytes),
1449 error.InvalidArchiveMagicNumber => try parseAndDumpObject(gpa, bytes),
1450 else => |e| return e,1635 else => |e| return e,
1451 };1636 };
1452 }1637 }
14531638
1454 fn parseAndDumpArchive(gpa: Allocator, bytes: []const u8) ![]const u8 {1639 fn parseAndDumpArchive(step: *Step, kind: Check.Kind, bytes: []const u8) ![]const u8 {
1640 const gpa = step.owner.allocator;
1455 var stream = std.io.fixedBufferStream(bytes);1641 var stream = std.io.fixedBufferStream(bytes);
1456 const reader = stream.reader();1642 const reader = stream.reader();
14571643
...@@ -1512,8 +1698,15 @@ const ElfDumper = struct {...@@ -1512,8 +1698,15 @@ const ElfDumper = struct {
1512 var output = std.ArrayList(u8).init(gpa);1698 var output = std.ArrayList(u8).init(gpa);
1513 const writer = output.writer();1699 const writer = output.writer();
15141700
1515 try ctx.dumpSymtab(writer);1701 switch (kind) {
1516 try ctx.dumpObjects(writer);1702 .archive_symtab => if (ctx.symtab.items.len > 0) {
1703 try ctx.dumpSymtab(writer);
1704 } else return step.fail("no archive symbol table found", .{}),
1705
1706 else => if (ctx.objects.items.len > 0) {
1707 try ctx.dumpObjects(step, kind, writer);
1708 } else return step.fail("empty archive", .{}),
1709 }
15171710
1518 return output.toOwnedSlice();1711 return output.toOwnedSlice();
1519 }1712 }
...@@ -1555,8 +1748,6 @@ const ElfDumper = struct {...@@ -1555,8 +1748,6 @@ const ElfDumper = struct {
1555 }1748 }
15561749
1557 fn dumpSymtab(ctx: ArchiveContext, writer: anytype) !void {1750 fn dumpSymtab(ctx: ArchiveContext, writer: anytype) !void {
1558 if (ctx.symtab.items.len == 0) return;
1559
1560 var files = std.AutoHashMap(usize, []const u8).init(ctx.gpa);1751 var files = std.AutoHashMap(usize, []const u8).init(ctx.gpa);
1561 defer files.deinit();1752 defer files.deinit();
1562 try files.ensureUnusedCapacity(@intCast(ctx.objects.items.len));1753 try files.ensureUnusedCapacity(@intCast(ctx.objects.items.len));
...@@ -1590,10 +1781,10 @@ const ElfDumper = struct {...@@ -1590,10 +1781,10 @@ const ElfDumper = struct {
1590 }1781 }
1591 }1782 }
15921783
1593 fn dumpObjects(ctx: ArchiveContext, writer: anytype) !void {1784 fn dumpObjects(ctx: ArchiveContext, step: *Step, kind: Check.Kind, writer: anytype) !void {
1594 for (ctx.objects.items) |object| {1785 for (ctx.objects.items) |object| {
1595 try writer.print("object {s}\n", .{object.name});1786 try writer.print("object {s}\n", .{object.name});
1596 const output = try parseAndDumpObject(ctx.gpa, ctx.data[object.off..][0..object.len]);1787 const output = try parseAndDumpObject(step, kind, ctx.data[object.off..][0..object.len]);
1597 defer ctx.gpa.free(output);1788 defer ctx.gpa.free(output);
1598 try writer.print("{s}\n", .{output});1789 try writer.print("{s}\n", .{output});
1599 }1790 }
...@@ -1611,7 +1802,8 @@ const ElfDumper = struct {...@@ -1611,7 +1802,8 @@ const ElfDumper = struct {
1611 };1802 };
1612 };1803 };
16131804
1614 fn parseAndDumpObject(gpa: Allocator, bytes: []const u8) ![]const u8 {1805 fn parseAndDumpObject(step: *Step, kind: Check.Kind, bytes: []const u8) ![]const u8 {
1806 const gpa = step.owner.allocator;
1615 var stream = std.io.fixedBufferStream(bytes);1807 var stream = std.io.fixedBufferStream(bytes);
1616 const reader = stream.reader();1808 const reader = stream.reader();
16171809
...@@ -1663,12 +1855,27 @@ const ElfDumper = struct {...@@ -1663,12 +1855,27 @@ const ElfDumper = struct {
1663 var output = std.ArrayList(u8).init(gpa);1855 var output = std.ArrayList(u8).init(gpa);
1664 const writer = output.writer();1856 const writer = output.writer();
16651857
1666 try ctx.dumpHeader(writer);1858 switch (kind) {
1667 try ctx.dumpShdrs(writer);1859 .headers => {
1668 try ctx.dumpPhdrs(writer);1860 try ctx.dumpHeader(writer);
1669 try ctx.dumpDynamicSection(writer);1861 try ctx.dumpShdrs(writer);
1670 try ctx.dumpSymtab(.symtab, writer);1862 try ctx.dumpPhdrs(writer);
1671 try ctx.dumpSymtab(.dysymtab, writer);1863 },
1864
1865 .symtab => if (ctx.symtab.symbols.len > 0) {
1866 try ctx.dumpSymtab(.symtab, writer);
1867 } else return step.fail("no symbol table found", .{}),
1868
1869 .dynamic_symtab => if (ctx.dysymtab.symbols.len > 0) {
1870 try ctx.dumpSymtab(.dysymtab, writer);
1871 } else return step.fail("no dynamic symbol table found", .{}),
1872
1873 .dynamic_section => if (ctx.getSectionByName(".dynamic")) |shndx| {
1874 try ctx.dumpDynamicSection(shndx, writer);
1875 } else return step.fail("no .dynamic section found", .{}),
1876
1877 else => return step.fail("invalid check kind for ELF file format: {s}", .{@tagName(kind)}),
1878 }
16721879
1673 return output.toOwnedSlice();1880 return output.toOwnedSlice();
1674 }1881 }
...@@ -1680,8 +1887,8 @@ const ElfDumper = struct {...@@ -1680,8 +1887,8 @@ const ElfDumper = struct {
1680 shdrs: []align(1) const elf.Elf64_Shdr,1887 shdrs: []align(1) const elf.Elf64_Shdr,
1681 phdrs: []align(1) const elf.Elf64_Phdr,1888 phdrs: []align(1) const elf.Elf64_Phdr,
1682 shstrtab: []const u8,1889 shstrtab: []const u8,
1683 symtab: ?Symtab = null,1890 symtab: Symtab = .{},
1684 dysymtab: ?Symtab = null,1891 dysymtab: Symtab = .{},
16851892
1686 fn dumpHeader(ctx: ObjectContext, writer: anytype) !void {1893 fn dumpHeader(ctx: ObjectContext, writer: anytype) !void {
1687 try writer.writeAll("header\n");1894 try writer.writeAll("header\n");
...@@ -1745,8 +1952,7 @@ const ElfDumper = struct {...@@ -1745,8 +1952,7 @@ const ElfDumper = struct {
1745 }1952 }
1746 }1953 }
17471954
1748 fn dumpDynamicSection(ctx: ObjectContext, writer: anytype) !void {1955 fn dumpDynamicSection(ctx: ObjectContext, shndx: usize, writer: anytype) !void {
1749 const shndx = ctx.getSectionByName(".dynamic") orelse return;
1750 const shdr = ctx.shdrs[shndx];1956 const shdr = ctx.shdrs[shndx];
1751 const strtab = ctx.getSectionContents(shdr.sh_link);1957 const strtab = ctx.getSectionContents(shdr.sh_link);
1752 const data = ctx.getSectionContents(shndx);1958 const data = ctx.getSectionContents(shndx);
...@@ -1888,7 +2094,7 @@ const ElfDumper = struct {...@@ -1888,7 +2094,7 @@ const ElfDumper = struct {
1888 const symtab = switch (@"type") {2094 const symtab = switch (@"type") {
1889 .symtab => ctx.symtab,2095 .symtab => ctx.symtab,
1890 .dysymtab => ctx.dysymtab,2096 .dysymtab => ctx.dysymtab,
1891 } orelse return;2097 };
18922098
1893 try writer.writeAll(switch (@"type") {2099 try writer.writeAll(switch (@"type") {
1894 .symtab => symtab_label,2100 .symtab => symtab_label,
...@@ -1986,8 +2192,8 @@ const ElfDumper = struct {...@@ -1986,8 +2192,8 @@ const ElfDumper = struct {
1986 };2192 };
19872193
1988 const Symtab = struct {2194 const Symtab = struct {
1989 symbols: []align(1) const elf.Elf64_Sym,2195 symbols: []align(1) const elf.Elf64_Sym = &[0]elf.Elf64_Sym{},
1990 strings: []const u8,2196 strings: []const u8 = &[0]u8{},
19912197
1992 fn get(st: Symtab, index: usize) ?elf.Elf64_Sym {2198 fn get(st: Symtab, index: usize) ?elf.Elf64_Sym {
1993 if (index >= st.symbols.len) return null;2199 if (index >= st.symbols.len) return null;
...@@ -2090,7 +2296,7 @@ const ElfDumper = struct {...@@ -2090,7 +2296,7 @@ const ElfDumper = struct {
2090const WasmDumper = struct {2296const WasmDumper = struct {
2091 const symtab_label = "symbols";2297 const symtab_label = "symbols";
20922298
2093 fn parseAndDump(step: *Step, bytes: []const u8) ![]const u8 {2299 fn parseAndDump(step: *Step, kind: Check.Kind, bytes: []const u8) ![]const u8 {
2094 const gpa = step.owner.allocator;2300 const gpa = step.owner.allocator;
2095 var fbs = std.io.fixedBufferStream(bytes);2301 var fbs = std.io.fixedBufferStream(bytes);
2096 const reader = fbs.reader();2302 const reader = fbs.reader();
...@@ -2107,15 +2313,21 @@ const WasmDumper = struct {...@@ -2107,15 +2313,21 @@ const WasmDumper = struct {
2107 errdefer output.deinit();2313 errdefer output.deinit();
2108 const writer = output.writer();2314 const writer = output.writer();
21092315
2110 while (reader.readByte()) |current_byte| {2316 switch (kind) {
2111 const section = std.meta.intToEnum(std.wasm.Section, current_byte) catch {2317 .headers => {
2112 return step.fail("Found invalid section id '{d}'", .{current_byte});2318 while (reader.readByte()) |current_byte| {
2113 };2319 const section = std.meta.intToEnum(std.wasm.Section, current_byte) catch {
2320 return step.fail("Found invalid section id '{d}'", .{current_byte});
2321 };
2322
2323 const section_length = try std.leb.readULEB128(u32, reader);
2324 try parseAndDumpSection(step, section, bytes[fbs.pos..][0..section_length], writer);
2325 fbs.pos += section_length;
2326 } else |_| {} // reached end of stream
2327 },
21142328
2115 const section_length = try std.leb.readULEB128(u32, reader);2329 else => return step.fail("invalid check kind for Wasm file format: {s}", .{@tagName(kind)}),
2116 try parseAndDumpSection(step, section, bytes[fbs.pos..][0..section_length], writer);2330 }
2117 fbs.pos += section_length;
2118 } else |_| {} // reached end of stream
21192331
2120 return output.toOwnedSlice();2332 return output.toOwnedSlice();
2121 }2333 }
test/link/elf.zig+26-26
...@@ -506,7 +506,7 @@ fn testCopyrelAlignment(b: *Build, opts: Options) *Step {...@@ -506,7 +506,7 @@ fn testCopyrelAlignment(b: *Build, opts: Options) *Step {
506 test_step.dependOn(&run.step);506 test_step.dependOn(&run.step);
507507
508 const check = exe.checkObject();508 const check = exe.checkObject();
509 check.checkStart();509 check.checkInHeaders();
510 check.checkExact("section headers");510 check.checkExact("section headers");
511 check.checkExact("name .copyrel");511 check.checkExact("name .copyrel");
512 check.checkExact("addralign 20");512 check.checkExact("addralign 20");
...@@ -525,7 +525,7 @@ fn testCopyrelAlignment(b: *Build, opts: Options) *Step {...@@ -525,7 +525,7 @@ fn testCopyrelAlignment(b: *Build, opts: Options) *Step {
525 test_step.dependOn(&run.step);525 test_step.dependOn(&run.step);
526526
527 const check = exe.checkObject();527 const check = exe.checkObject();
528 check.checkStart();528 check.checkInHeaders();
529 check.checkExact("section headers");529 check.checkExact("section headers");
530 check.checkExact("name .copyrel");530 check.checkExact("name .copyrel");
531 check.checkExact("addralign 8");531 check.checkExact("addralign 8");
...@@ -544,7 +544,7 @@ fn testCopyrelAlignment(b: *Build, opts: Options) *Step {...@@ -544,7 +544,7 @@ fn testCopyrelAlignment(b: *Build, opts: Options) *Step {
544 test_step.dependOn(&run.step);544 test_step.dependOn(&run.step);
545545
546 const check = exe.checkObject();546 const check = exe.checkObject();
547 check.checkStart();547 check.checkInHeaders();
548 check.checkExact("section headers");548 check.checkExact("section headers");
549 check.checkExact("name .copyrel");549 check.checkExact("name .copyrel");
550 check.checkExact("addralign 100");550 check.checkExact("addralign 100");
...@@ -815,7 +815,7 @@ fn testEntryPoint(b: *Build, opts: Options) *Step {...@@ -815,7 +815,7 @@ fn testEntryPoint(b: *Build, opts: Options) *Step {
815 exe.entry = .{ .symbol_name = "foo" };815 exe.entry = .{ .symbol_name = "foo" };
816816
817 const check = exe.checkObject();817 const check = exe.checkObject();
818 check.checkStart();818 check.checkInHeaders();
819 check.checkExact("header");819 check.checkExact("header");
820 check.checkExact("entry 1000");820 check.checkExact("entry 1000");
821 test_step.dependOn(&check.step);821 test_step.dependOn(&check.step);
...@@ -831,7 +831,7 @@ fn testEntryPoint(b: *Build, opts: Options) *Step {...@@ -831,7 +831,7 @@ fn testEntryPoint(b: *Build, opts: Options) *Step {
831 exe.entry = .{ .symbol_name = "bar" };831 exe.entry = .{ .symbol_name = "bar" };
832832
833 const check = exe.checkObject();833 const check = exe.checkObject();
834 check.checkStart();834 check.checkInHeaders();
835 check.checkExact("header");835 check.checkExact("header");
836 check.checkExact("entry 2000");836 check.checkExact("entry 2000");
837 test_step.dependOn(&check.step);837 test_step.dependOn(&check.step);
...@@ -1460,13 +1460,13 @@ fn testIFuncStaticPie(b: *Build, opts: Options) *Step {...@@ -1460,13 +1460,13 @@ fn testIFuncStaticPie(b: *Build, opts: Options) *Step {
1460 test_step.dependOn(&run.step);1460 test_step.dependOn(&run.step);
14611461
1462 const check = exe.checkObject();1462 const check = exe.checkObject();
1463 check.checkStart();1463 check.checkInHeaders();
1464 check.checkExact("header");1464 check.checkExact("header");
1465 check.checkExact("type DYN");1465 check.checkExact("type DYN");
1466 check.checkStart();1466 check.checkInHeaders();
1467 check.checkExact("section headers");1467 check.checkExact("section headers");
1468 check.checkExact("name .dynamic");1468 check.checkExact("name .dynamic");
1469 check.checkStart();1469 check.checkInHeaders();
1470 check.checkExact("section headers");1470 check.checkExact("section headers");
1471 check.checkNotPresent("name .interp");1471 check.checkNotPresent("name .interp");
1472 test_step.dependOn(&check.step);1472 test_step.dependOn(&check.step);
...@@ -1494,7 +1494,7 @@ fn testImageBase(b: *Build, opts: Options) *Step {...@@ -1494,7 +1494,7 @@ fn testImageBase(b: *Build, opts: Options) *Step {
1494 test_step.dependOn(&run.step);1494 test_step.dependOn(&run.step);
14951495
1496 const check = exe.checkObject();1496 const check = exe.checkObject();
1497 check.checkStart();1497 check.checkInHeaders();
1498 check.checkExact("header");1498 check.checkExact("header");
1499 check.checkExtract("entry {addr}");1499 check.checkExtract("entry {addr}");
1500 check.checkComputeCompare("addr", .{ .op = .gte, .value = .{ .literal = 0x8000000 } });1500 check.checkComputeCompare("addr", .{ .op = .gte, .value = .{ .literal = 0x8000000 } });
...@@ -1507,7 +1507,7 @@ fn testImageBase(b: *Build, opts: Options) *Step {...@@ -1507,7 +1507,7 @@ fn testImageBase(b: *Build, opts: Options) *Step {
1507 exe.image_base = 0xffffffff8000000;1507 exe.image_base = 0xffffffff8000000;
15081508
1509 const check = exe.checkObject();1509 const check = exe.checkObject();
1510 check.checkStart();1510 check.checkInHeaders();
1511 check.checkExact("header");1511 check.checkExact("header");
1512 check.checkExtract("entry {addr}");1512 check.checkExtract("entry {addr}");
1513 check.checkComputeCompare("addr", .{ .op = .gte, .value = .{ .literal = 0xffffffff8000000 } });1513 check.checkComputeCompare("addr", .{ .op = .gte, .value = .{ .literal = 0xffffffff8000000 } });
...@@ -1937,10 +1937,10 @@ fn testLinkingC(b: *Build, opts: Options) *Step {...@@ -1937,10 +1937,10 @@ fn testLinkingC(b: *Build, opts: Options) *Step {
1937 test_step.dependOn(&run.step);1937 test_step.dependOn(&run.step);
19381938
1939 const check = exe.checkObject();1939 const check = exe.checkObject();
1940 check.checkStart();1940 check.checkInHeaders();
1941 check.checkExact("header");1941 check.checkExact("header");
1942 check.checkExact("type EXEC");1942 check.checkExact("type EXEC");
1943 check.checkStart();1943 check.checkInHeaders();
1944 check.checkExact("section headers");1944 check.checkExact("section headers");
1945 check.checkNotPresent("name .dynamic");1945 check.checkNotPresent("name .dynamic");
1946 test_step.dependOn(&check.step);1946 test_step.dependOn(&check.step);
...@@ -1967,10 +1967,10 @@ fn testLinkingCpp(b: *Build, opts: Options) *Step {...@@ -1967,10 +1967,10 @@ fn testLinkingCpp(b: *Build, opts: Options) *Step {
1967 test_step.dependOn(&run.step);1967 test_step.dependOn(&run.step);
19681968
1969 const check = exe.checkObject();1969 const check = exe.checkObject();
1970 check.checkStart();1970 check.checkInHeaders();
1971 check.checkExact("header");1971 check.checkExact("header");
1972 check.checkExact("type EXEC");1972 check.checkExact("type EXEC");
1973 check.checkStart();1973 check.checkInHeaders();
1974 check.checkExact("section headers");1974 check.checkExact("section headers");
1975 check.checkNotPresent("name .dynamic");1975 check.checkNotPresent("name .dynamic");
1976 test_step.dependOn(&check.step);1976 test_step.dependOn(&check.step);
...@@ -2055,10 +2055,10 @@ fn testLinkingZig(b: *Build, opts: Options) *Step {...@@ -2055,10 +2055,10 @@ fn testLinkingZig(b: *Build, opts: Options) *Step {
2055 test_step.dependOn(&run.step);2055 test_step.dependOn(&run.step);
20562056
2057 const check = exe.checkObject();2057 const check = exe.checkObject();
2058 check.checkStart();2058 check.checkInHeaders();
2059 check.checkExact("header");2059 check.checkExact("header");
2060 check.checkExact("type EXEC");2060 check.checkExact("type EXEC");
2061 check.checkStart();2061 check.checkInHeaders();
2062 check.checkExact("section headers");2062 check.checkExact("section headers");
2063 check.checkNotPresent("name .dynamic");2063 check.checkNotPresent("name .dynamic");
2064 test_step.dependOn(&check.step);2064 test_step.dependOn(&check.step);
...@@ -2075,7 +2075,7 @@ fn testNoEhFrameHdr(b: *Build, opts: Options) *Step {...@@ -2075,7 +2075,7 @@ fn testNoEhFrameHdr(b: *Build, opts: Options) *Step {
2075 exe.linkLibC();2075 exe.linkLibC();
20762076
2077 const check = exe.checkObject();2077 const check = exe.checkObject();
2078 check.checkStart();2078 check.checkInHeaders();
2079 check.checkExact("section headers");2079 check.checkExact("section headers");
2080 check.checkNotPresent("name .eh_frame_hdr");2080 check.checkNotPresent("name .eh_frame_hdr");
2081 test_step.dependOn(&check.step);2081 test_step.dependOn(&check.step);
...@@ -2103,10 +2103,10 @@ fn testPie(b: *Build, opts: Options) *Step {...@@ -2103,10 +2103,10 @@ fn testPie(b: *Build, opts: Options) *Step {
2103 test_step.dependOn(&run.step);2103 test_step.dependOn(&run.step);
21042104
2105 const check = exe.checkObject();2105 const check = exe.checkObject();
2106 check.checkStart();2106 check.checkInHeaders();
2107 check.checkExact("header");2107 check.checkExact("header");
2108 check.checkExact("type DYN");2108 check.checkExact("type DYN");
2109 check.checkStart();2109 check.checkInHeaders();
2110 check.checkExact("section headers");2110 check.checkExact("section headers");
2111 check.checkExact("name .dynamic");2111 check.checkExact("name .dynamic");
2112 test_step.dependOn(&check.step);2112 test_step.dependOn(&check.step);
...@@ -2326,13 +2326,13 @@ fn testRelocatableNoEhFrame(b: *Build, opts: Options) *Step {...@@ -2326,13 +2326,13 @@ fn testRelocatableNoEhFrame(b: *Build, opts: Options) *Step {
2326 obj2.addObject(obj1);2326 obj2.addObject(obj1);
23272327
2328 const check1 = obj1.checkObject();2328 const check1 = obj1.checkObject();
2329 check1.checkStart();2329 check1.checkInHeaders();
2330 check1.checkExact("section headers");2330 check1.checkExact("section headers");
2331 check1.checkNotPresent(".eh_frame");2331 check1.checkNotPresent(".eh_frame");
2332 test_step.dependOn(&check1.step);2332 test_step.dependOn(&check1.step);
23332333
2334 const check2 = obj2.checkObject();2334 const check2 = obj2.checkObject();
2335 check2.checkStart();2335 check2.checkInHeaders();
2336 check2.checkExact("section headers");2336 check2.checkExact("section headers");
2337 check2.checkNotPresent(".eh_frame");2337 check2.checkNotPresent(".eh_frame");
2338 test_step.dependOn(&check2.step);2338 test_step.dependOn(&check2.step);
...@@ -2369,7 +2369,7 @@ fn testSharedAbsSymbol(b: *Build, opts: Options) *Step {...@@ -2369,7 +2369,7 @@ fn testSharedAbsSymbol(b: *Build, opts: Options) *Step {
2369 test_step.dependOn(&run.step);2369 test_step.dependOn(&run.step);
23702370
2371 const check = exe.checkObject();2371 const check = exe.checkObject();
2372 check.checkStart();2372 check.checkInHeaders();
2373 check.checkExact("header");2373 check.checkExact("header");
2374 check.checkExact("type DYN");2374 check.checkExact("type DYN");
2375 // TODO fix/improve in CheckObject2375 // TODO fix/improve in CheckObject
...@@ -2390,7 +2390,7 @@ fn testSharedAbsSymbol(b: *Build, opts: Options) *Step {...@@ -2390,7 +2390,7 @@ fn testSharedAbsSymbol(b: *Build, opts: Options) *Step {
2390 // test_step.dependOn(&run.step);2390 // test_step.dependOn(&run.step);
23912391
2392 // const check = exe.checkObject();2392 // const check = exe.checkObject();
2393 // check.checkStart();2393 // check.checkInHeaders();
2394 // check.checkExact("header");2394 // check.checkExact("header");
2395 // check.checkExact("type EXEC");2395 // check.checkExact("type EXEC");
2396 // // TODO fix/improve in CheckObject2396 // // TODO fix/improve in CheckObject
...@@ -2422,7 +2422,7 @@ fn testStrip(b: *Build, opts: Options) *Step {...@@ -2422,7 +2422,7 @@ fn testStrip(b: *Build, opts: Options) *Step {
2422 exe.linkLibC();2422 exe.linkLibC();
24232423
2424 const check = exe.checkObject();2424 const check = exe.checkObject();
2425 check.checkStart();2425 check.checkInHeaders();
2426 check.checkExact("section headers");2426 check.checkExact("section headers");
2427 check.checkExact("name .debug_info");2427 check.checkExact("name .debug_info");
2428 test_step.dependOn(&check.step);2428 test_step.dependOn(&check.step);
...@@ -2435,7 +2435,7 @@ fn testStrip(b: *Build, opts: Options) *Step {...@@ -2435,7 +2435,7 @@ fn testStrip(b: *Build, opts: Options) *Step {
2435 exe.linkLibC();2435 exe.linkLibC();
24362436
2437 const check = exe.checkObject();2437 const check = exe.checkObject();
2438 check.checkStart();2438 check.checkInHeaders();
2439 check.checkExact("section headers");2439 check.checkExact("section headers");
2440 check.checkNotPresent("name .debug_info");2440 check.checkNotPresent("name .debug_info");
2441 test_step.dependOn(&check.step);2441 test_step.dependOn(&check.step);
...@@ -3521,7 +3521,7 @@ fn testZStackSize(b: *Build, opts: Options) *Step {...@@ -3521,7 +3521,7 @@ fn testZStackSize(b: *Build, opts: Options) *Step {
3521 exe.linkLibC();3521 exe.linkLibC();
35223522
3523 const check = exe.checkObject();3523 const check = exe.checkObject();
3524 check.checkStart();3524 check.checkInHeaders();
3525 check.checkExact("program headers");3525 check.checkExact("program headers");
3526 check.checkExact("type GNU_STACK");3526 check.checkExact("type GNU_STACK");
3527 check.checkExact("memsz 800000");3527 check.checkExact("memsz 800000");
test/link/macho/dead_strip_dylibs/build.zig+2-2
...@@ -19,11 +19,11 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -19,11 +19,11 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
19 const exe = createScenario(b, optimize, "no-dead-strip");19 const exe = createScenario(b, optimize, "no-dead-strip");
2020
21 const check = exe.checkObject();21 const check = exe.checkObject();
22 check.checkStart();22 check.checkInHeaders();
23 check.checkExact("cmd LOAD_DYLIB");23 check.checkExact("cmd LOAD_DYLIB");
24 check.checkContains("Cocoa");24 check.checkContains("Cocoa");
2525
26 check.checkStart();26 check.checkInHeaders();
27 check.checkExact("cmd LOAD_DYLIB");27 check.checkExact("cmd LOAD_DYLIB");
28 check.checkContains("libobjc");28 check.checkContains("libobjc");
2929
test/link/macho/dylib/build.zig+3-3
...@@ -25,7 +25,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -25,7 +25,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
25 dylib.linkLibC();25 dylib.linkLibC();
2626
27 const check_dylib = dylib.checkObject();27 const check_dylib = dylib.checkObject();
28 check_dylib.checkStart();28 check_dylib.checkInHeaders();
29 check_dylib.checkExact("cmd ID_DYLIB");29 check_dylib.checkExact("cmd ID_DYLIB");
30 check_dylib.checkExact("name @rpath/liba.dylib");30 check_dylib.checkExact("name @rpath/liba.dylib");
31 check_dylib.checkExact("timestamp 2");31 check_dylib.checkExact("timestamp 2");
...@@ -46,14 +46,14 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -46,14 +46,14 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
46 exe.linkLibC();46 exe.linkLibC();
4747
48 const check_exe = exe.checkObject();48 const check_exe = exe.checkObject();
49 check_exe.checkStart();49 check_exe.checkInHeaders();
50 check_exe.checkExact("cmd LOAD_DYLIB");50 check_exe.checkExact("cmd LOAD_DYLIB");
51 check_exe.checkExact("name @rpath/liba.dylib");51 check_exe.checkExact("name @rpath/liba.dylib");
52 check_exe.checkExact("timestamp 2");52 check_exe.checkExact("timestamp 2");
53 check_exe.checkExact("current version 10000");53 check_exe.checkExact("current version 10000");
54 check_exe.checkExact("compatibility version 10000");54 check_exe.checkExact("compatibility version 10000");
5555
56 check_exe.checkStart();56 check_exe.checkInHeaders();
57 check_exe.checkExact("cmd RPATH");57 check_exe.checkExact("cmd RPATH");
58 check_exe.checkExactPath("path", dylib.getOutputDirectorySource());58 check_exe.checkExactPath("path", dylib.getOutputDirectorySource());
59 test_step.dependOn(&check_exe.step);59 test_step.dependOn(&check_exe.step);
test/link/macho/entry/build.zig+2-2
...@@ -24,11 +24,11 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -24,11 +24,11 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
2424
25 const check_exe = exe.checkObject();25 const check_exe = exe.checkObject();
2626
27 check_exe.checkStart();27 check_exe.checkInHeaders();
28 check_exe.checkExact("segname __TEXT");28 check_exe.checkExact("segname __TEXT");
29 check_exe.checkExtract("vmaddr {vmaddr}");29 check_exe.checkExtract("vmaddr {vmaddr}");
3030
31 check_exe.checkStart();31 check_exe.checkInHeaders();
32 check_exe.checkExact("cmd MAIN");32 check_exe.checkExact("cmd MAIN");
33 check_exe.checkExtract("entryoff {entryoff}");33 check_exe.checkExtract("entryoff {entryoff}");
3434
test/link/macho/entry_in_dylib/build.zig+3-3
...@@ -34,15 +34,15 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -34,15 +34,15 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
34 exe.forceUndefinedSymbol("_my_main");34 exe.forceUndefinedSymbol("_my_main");
3535
36 const check_exe = exe.checkObject();36 const check_exe = exe.checkObject();
37 check_exe.checkStart();37 check_exe.checkInHeaders();
38 check_exe.checkExact("segname __TEXT");38 check_exe.checkExact("segname __TEXT");
39 check_exe.checkExtract("vmaddr {text_vmaddr}");39 check_exe.checkExtract("vmaddr {text_vmaddr}");
4040
41 check_exe.checkStart();41 check_exe.checkInHeaders();
42 check_exe.checkExact("sectname __stubs");42 check_exe.checkExact("sectname __stubs");
43 check_exe.checkExtract("addr {stubs_vmaddr}");43 check_exe.checkExtract("addr {stubs_vmaddr}");
4444
45 check_exe.checkStart();45 check_exe.checkInHeaders();
46 check_exe.checkExact("cmd MAIN");46 check_exe.checkExact("cmd MAIN");
47 check_exe.checkExtract("entryoff {entryoff}");47 check_exe.checkExtract("entryoff {entryoff}");
4848
test/link/macho/headerpad/build.zig+4-4
...@@ -21,7 +21,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -21,7 +21,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
21 exe.headerpad_max_install_names = true;21 exe.headerpad_max_install_names = true;
2222
23 const check = exe.checkObject();23 const check = exe.checkObject();
24 check.checkStart();24 check.checkInHeaders();
25 check.checkExact("sectname __text");25 check.checkExact("sectname __text");
26 check.checkExtract("offset {offset}");26 check.checkExtract("offset {offset}");
2727
...@@ -47,7 +47,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -47,7 +47,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
47 exe.headerpad_size = 0x10000;47 exe.headerpad_size = 0x10000;
4848
49 const check = exe.checkObject();49 const check = exe.checkObject();
50 check.checkStart();50 check.checkInHeaders();
51 check.checkExact("sectname __text");51 check.checkExact("sectname __text");
52 check.checkExtract("offset {offset}");52 check.checkExtract("offset {offset}");
53 check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x10000 } });53 check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x10000 } });
...@@ -65,7 +65,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -65,7 +65,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
65 exe.headerpad_size = 0x10000;65 exe.headerpad_size = 0x10000;
6666
67 const check = exe.checkObject();67 const check = exe.checkObject();
68 check.checkStart();68 check.checkInHeaders();
69 check.checkExact("sectname __text");69 check.checkExact("sectname __text");
70 check.checkExtract("offset {offset}");70 check.checkExtract("offset {offset}");
71 check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x10000 } });71 check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x10000 } });
...@@ -83,7 +83,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -83,7 +83,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
83 exe.headerpad_max_install_names = true;83 exe.headerpad_max_install_names = true;
8484
85 const check = exe.checkObject();85 const check = exe.checkObject();
86 check.checkStart();86 check.checkInHeaders();
87 check.checkExact("sectname __text");87 check.checkExact("sectname __text");
88 check.checkExtract("offset {offset}");88 check.checkExtract("offset {offset}");
8989
test/link/macho/needed_framework/build.zig+1-1
...@@ -26,7 +26,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -26,7 +26,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
26 exe.dead_strip_dylibs = true;26 exe.dead_strip_dylibs = true;
2727
28 const check = exe.checkObject();28 const check = exe.checkObject();
29 check.checkStart();29 check.checkInHeaders();
30 check.checkExact("cmd LOAD_DYLIB");30 check.checkExact("cmd LOAD_DYLIB");
31 check.checkContains("Cocoa");31 check.checkContains("Cocoa");
32 test_step.dependOn(&check.step);32 test_step.dependOn(&check.step);
test/link/macho/needed_library/build.zig+1-1
...@@ -39,7 +39,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -39,7 +39,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
39 exe.dead_strip_dylibs = true;39 exe.dead_strip_dylibs = true;
4040
41 const check = exe.checkObject();41 const check = exe.checkObject();
42 check.checkStart();42 check.checkInHeaders();
43 check.checkExact("cmd LOAD_DYLIB");43 check.checkExact("cmd LOAD_DYLIB");
44 check.checkExact("name @rpath/liba.dylib");44 check.checkExact("name @rpath/liba.dylib");
45 test_step.dependOn(&check.step);45 test_step.dependOn(&check.step);
test/link/macho/pagezero/build.zig+3-3
...@@ -20,13 +20,13 @@ pub fn build(b: *std.Build) void {...@@ -20,13 +20,13 @@ pub fn build(b: *std.Build) void {
20 exe.pagezero_size = 0x4000;20 exe.pagezero_size = 0x4000;
2121
22 const check = exe.checkObject();22 const check = exe.checkObject();
23 check.checkStart();23 check.checkInHeaders();
24 check.checkExact("LC 0");24 check.checkExact("LC 0");
25 check.checkExact("segname __PAGEZERO");25 check.checkExact("segname __PAGEZERO");
26 check.checkExact("vmaddr 0");26 check.checkExact("vmaddr 0");
27 check.checkExact("vmsize 4000");27 check.checkExact("vmsize 4000");
2828
29 check.checkStart();29 check.checkInHeaders();
30 check.checkExact("segname __TEXT");30 check.checkExact("segname __TEXT");
31 check.checkExact("vmaddr 4000");31 check.checkExact("vmaddr 4000");
3232
...@@ -44,7 +44,7 @@ pub fn build(b: *std.Build) void {...@@ -44,7 +44,7 @@ pub fn build(b: *std.Build) void {
44 exe.pagezero_size = 0;44 exe.pagezero_size = 0;
4545
46 const check = exe.checkObject();46 const check = exe.checkObject();
47 check.checkStart();47 check.checkInHeaders();
48 check.checkExact("LC 0");48 check.checkExact("LC 0");
49 check.checkExact("segname __TEXT");49 check.checkExact("segname __TEXT");
50 check.checkExact("vmaddr 0");50 check.checkExact("vmaddr 0");
test/link/macho/search_strategy/build.zig+1-1
...@@ -20,7 +20,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -20,7 +20,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
20 const exe = createScenario(b, optimize, target, "search_dylibs_first", .mode_first);20 const exe = createScenario(b, optimize, target, "search_dylibs_first", .mode_first);
2121
22 const check = exe.checkObject();22 const check = exe.checkObject();
23 check.checkStart();23 check.checkInHeaders();
24 check.checkExact("cmd LOAD_DYLIB");24 check.checkExact("cmd LOAD_DYLIB");
25 check.checkExact("name @rpath/libsearch_dylibs_first.dylib");25 check.checkExact("name @rpath/libsearch_dylibs_first.dylib");
26 test_step.dependOn(&check.step);26 test_step.dependOn(&check.step);
test/link/macho/stack_size/build.zig+1-1
...@@ -25,7 +25,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -25,7 +25,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
25 exe.stack_size = 0x100000000;25 exe.stack_size = 0x100000000;
2626
27 const check_exe = exe.checkObject();27 const check_exe = exe.checkObject();
28 check_exe.checkStart();28 check_exe.checkInHeaders();
29 check_exe.checkExact("cmd MAIN");29 check_exe.checkExact("cmd MAIN");
30 check_exe.checkExact("stacksize 100000000");30 check_exe.checkExact("stacksize 100000000");
31 test_step.dependOn(&check_exe.step);31 test_step.dependOn(&check_exe.step);
test/link/macho/strict_validation/build.zig+7-7
...@@ -26,13 +26,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -26,13 +26,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
2626
27 const check_exe = exe.checkObject();27 const check_exe = exe.checkObject();
2828
29 check_exe.checkStart();29 check_exe.checkInHeaders();
30 check_exe.checkExact("cmd SEGMENT_64");30 check_exe.checkExact("cmd SEGMENT_64");
31 check_exe.checkExact("segname __LINKEDIT");31 check_exe.checkExact("segname __LINKEDIT");
32 check_exe.checkExtract("fileoff {fileoff}");32 check_exe.checkExtract("fileoff {fileoff}");
33 check_exe.checkExtract("filesz {filesz}");33 check_exe.checkExtract("filesz {filesz}");
3434
35 check_exe.checkStart();35 check_exe.checkInHeaders();
36 check_exe.checkExact("cmd DYLD_INFO_ONLY");36 check_exe.checkExact("cmd DYLD_INFO_ONLY");
37 check_exe.checkExtract("rebaseoff {rebaseoff}");37 check_exe.checkExtract("rebaseoff {rebaseoff}");
38 check_exe.checkExtract("rebasesize {rebasesize}");38 check_exe.checkExtract("rebasesize {rebasesize}");
...@@ -43,31 +43,31 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -43,31 +43,31 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
43 check_exe.checkExtract("exportoff {exportoff}");43 check_exe.checkExtract("exportoff {exportoff}");
44 check_exe.checkExtract("exportsize {exportsize}");44 check_exe.checkExtract("exportsize {exportsize}");
4545
46 check_exe.checkStart();46 check_exe.checkInHeaders();
47 check_exe.checkExact("cmd FUNCTION_STARTS");47 check_exe.checkExact("cmd FUNCTION_STARTS");
48 check_exe.checkExtract("dataoff {fstartoff}");48 check_exe.checkExtract("dataoff {fstartoff}");
49 check_exe.checkExtract("datasize {fstartsize}");49 check_exe.checkExtract("datasize {fstartsize}");
5050
51 check_exe.checkStart();51 check_exe.checkInHeaders();
52 check_exe.checkExact("cmd DATA_IN_CODE");52 check_exe.checkExact("cmd DATA_IN_CODE");
53 check_exe.checkExtract("dataoff {diceoff}");53 check_exe.checkExtract("dataoff {diceoff}");
54 check_exe.checkExtract("datasize {dicesize}");54 check_exe.checkExtract("datasize {dicesize}");
5555
56 check_exe.checkStart();56 check_exe.checkInHeaders();
57 check_exe.checkExact("cmd SYMTAB");57 check_exe.checkExact("cmd SYMTAB");
58 check_exe.checkExtract("symoff {symoff}");58 check_exe.checkExtract("symoff {symoff}");
59 check_exe.checkExtract("nsyms {symnsyms}");59 check_exe.checkExtract("nsyms {symnsyms}");
60 check_exe.checkExtract("stroff {stroff}");60 check_exe.checkExtract("stroff {stroff}");
61 check_exe.checkExtract("strsize {strsize}");61 check_exe.checkExtract("strsize {strsize}");
6262
63 check_exe.checkStart();63 check_exe.checkInHeaders();
64 check_exe.checkExact("cmd DYSYMTAB");64 check_exe.checkExact("cmd DYSYMTAB");
65 check_exe.checkExtract("indirectsymoff {dysymoff}");65 check_exe.checkExtract("indirectsymoff {dysymoff}");
66 check_exe.checkExtract("nindirectsyms {dysymnsyms}");66 check_exe.checkExtract("nindirectsyms {dysymnsyms}");
6767
68 switch (builtin.cpu.arch) {68 switch (builtin.cpu.arch) {
69 .aarch64 => {69 .aarch64 => {
70 check_exe.checkStart();70 check_exe.checkInHeaders();
71 check_exe.checkExact("cmd CODE_SIGNATURE");71 check_exe.checkExact("cmd CODE_SIGNATURE");
72 check_exe.checkExtract("dataoff {codesigoff}");72 check_exe.checkExtract("dataoff {codesigoff}");
73 check_exe.checkExtract("datasize {codesigsize}");73 check_exe.checkExtract("datasize {codesigsize}");
test/link/macho/unwind_info/build.zig+1-1
...@@ -32,7 +32,7 @@ fn testUnwindInfo(...@@ -32,7 +32,7 @@ fn testUnwindInfo(
32 exe.link_gc_sections = dead_strip;32 exe.link_gc_sections = dead_strip;
3333
34 const check = exe.checkObject();34 const check = exe.checkObject();
35 check.checkStart();35 check.checkInHeaders();
36 check.checkExact("segname __TEXT");36 check.checkExact("segname __TEXT");
37 check.checkExact("sectname __gcc_except_tab");37 check.checkExact("sectname __gcc_except_tab");
38 check.checkExact("sectname __unwind_info");38 check.checkExact("sectname __unwind_info");
test/link/macho/weak_framework/build.zig+1-1
...@@ -23,7 +23,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -23,7 +23,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
23 exe.linkFrameworkWeak("Cocoa");23 exe.linkFrameworkWeak("Cocoa");
2424
25 const check = exe.checkObject();25 const check = exe.checkObject();
26 check.checkStart();26 check.checkInHeaders();
27 check.checkExact("cmd LOAD_WEAK_DYLIB");27 check.checkExact("cmd LOAD_WEAK_DYLIB");
28 check.checkContains("Cocoa");28 check.checkContains("Cocoa");
29 test_step.dependOn(&check.step);29 test_step.dependOn(&check.step);
test/link/macho/weak_library/build.zig+1-1
...@@ -37,7 +37,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -37,7 +37,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
37 exe.addRPath(dylib.getEmittedBinDirectory());37 exe.addRPath(dylib.getEmittedBinDirectory());
3838
39 const check = exe.checkObject();39 const check = exe.checkObject();
40 check.checkStart();40 check.checkInHeaders();
41 check.checkExact("cmd LOAD_WEAK_DYLIB");41 check.checkExact("cmd LOAD_WEAK_DYLIB");
42 check.checkExact("name @rpath/liba.dylib");42 check.checkExact("name @rpath/liba.dylib");
4343
test/link/wasm/archive/build.zig+1-1
...@@ -27,7 +27,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -27,7 +27,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
27 lib.strip = false;27 lib.strip = false;
2828
29 const check = lib.checkObject();29 const check = lib.checkObject();
30 check.checkStart();30 check.checkInHeaders();
31 check.checkExact("Section custom");31 check.checkExact("Section custom");
32 check.checkExact("name __trunch"); // Ensure it was imported and resolved32 check.checkExact("name __trunch"); // Ensure it was imported and resolved
3333
test/link/wasm/basic-features/build.zig+1-1
...@@ -21,7 +21,7 @@ pub fn build(b: *std.Build) void {...@@ -21,7 +21,7 @@ pub fn build(b: *std.Build) void {
2121
22 // Verify the result contains the features explicitly set on the target for the library.22 // Verify the result contains the features explicitly set on the target for the library.
23 const check = lib.checkObject();23 const check = lib.checkObject();
24 check.checkStart();24 check.checkInHeaders();
25 check.checkExact("name target_features");25 check.checkExact("name target_features");
26 check.checkExact("features 1");26 check.checkExact("features 1");
27 check.checkExact("+ atomics");27 check.checkExact("+ atomics");
test/link/wasm/bss/build.zig+4-4
...@@ -31,18 +31,18 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt...@@ -31,18 +31,18 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt
31 const check_lib = lib.checkObject();31 const check_lib = lib.checkObject();
3232
33 // since we import memory, make sure it exists with the correct naming33 // since we import memory, make sure it exists with the correct naming
34 check_lib.checkStart();34 check_lib.checkInHeaders();
35 check_lib.checkExact("Section import");35 check_lib.checkExact("Section import");
36 check_lib.checkExact("entries 1");36 check_lib.checkExact("entries 1");
37 check_lib.checkExact("module env"); // default module name is "env"37 check_lib.checkExact("module env"); // default module name is "env"
38 check_lib.checkExact("name memory"); // as per linker specification38 check_lib.checkExact("name memory"); // as per linker specification
3939
40 // since we are importing memory, ensure it's not exported40 // since we are importing memory, ensure it's not exported
41 check_lib.checkStart();41 check_lib.checkInHeaders();
42 check_lib.checkNotPresent("Section export");42 check_lib.checkNotPresent("Section export");
4343
44 // validate the name of the stack pointer44 // validate the name of the stack pointer
45 check_lib.checkStart();45 check_lib.checkInHeaders();
46 check_lib.checkExact("Section custom");46 check_lib.checkExact("Section custom");
47 check_lib.checkExact("type data_segment");47 check_lib.checkExact("type data_segment");
48 check_lib.checkExact("names 2");48 check_lib.checkExact("names 2");
...@@ -77,7 +77,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt...@@ -77,7 +77,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt
77 lib.link_gc_sections = false;77 lib.link_gc_sections = false;
7878
79 const check_lib = lib.checkObject();79 const check_lib = lib.checkObject();
80 check_lib.checkStart();80 check_lib.checkInHeaders();
81 check_lib.checkExact("Section custom");81 check_lib.checkExact("Section custom");
82 check_lib.checkExact("type data_segment");82 check_lib.checkExact("type data_segment");
83 check_lib.checkExact("names 2");83 check_lib.checkExact("names 2");
test/link/wasm/export-data/build.zig+2-2
...@@ -22,7 +22,7 @@ pub fn build(b: *std.Build) void {...@@ -22,7 +22,7 @@ pub fn build(b: *std.Build) void {
2222
23 const check_lib = lib.checkObject();23 const check_lib = lib.checkObject();
2424
25 check_lib.checkStart();25 check_lib.checkInHeaders();
26 check_lib.checkExact("Section global");26 check_lib.checkExact("Section global");
27 check_lib.checkExact("entries 3");27 check_lib.checkExact("entries 3");
28 check_lib.checkExact("type i32"); // stack pointer so skip other fields28 check_lib.checkExact("type i32"); // stack pointer so skip other fields
...@@ -35,7 +35,7 @@ pub fn build(b: *std.Build) void {...@@ -35,7 +35,7 @@ pub fn build(b: *std.Build) void {
35 check_lib.checkComputeCompare("foo_address", .{ .op = .eq, .value = .{ .literal = 4 } });35 check_lib.checkComputeCompare("foo_address", .{ .op = .eq, .value = .{ .literal = 4 } });
36 check_lib.checkComputeCompare("bar_address", .{ .op = .eq, .value = .{ .literal = 0 } });36 check_lib.checkComputeCompare("bar_address", .{ .op = .eq, .value = .{ .literal = 0 } });
3737
38 check_lib.checkStart();38 check_lib.checkInHeaders();
39 check_lib.checkExact("Section export");39 check_lib.checkExact("Section export");
40 check_lib.checkExact("entries 3");40 check_lib.checkExact("entries 3");
41 check_lib.checkExact("name foo");41 check_lib.checkExact("name foo");
test/link/wasm/export/build.zig+3-3
...@@ -46,21 +46,21 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -46,21 +46,21 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
46 force_export.use_lld = false;46 force_export.use_lld = false;
4747
48 const check_no_export = no_export.checkObject();48 const check_no_export = no_export.checkObject();
49 check_no_export.checkStart();49 check_no_export.checkInHeaders();
50 check_no_export.checkExact("Section export");50 check_no_export.checkExact("Section export");
51 check_no_export.checkExact("entries 1");51 check_no_export.checkExact("entries 1");
52 check_no_export.checkExact("name memory");52 check_no_export.checkExact("name memory");
53 check_no_export.checkExact("kind memory");53 check_no_export.checkExact("kind memory");
5454
55 const check_dynamic_export = dynamic_export.checkObject();55 const check_dynamic_export = dynamic_export.checkObject();
56 check_dynamic_export.checkStart();56 check_dynamic_export.checkInHeaders();
57 check_dynamic_export.checkExact("Section export");57 check_dynamic_export.checkExact("Section export");
58 check_dynamic_export.checkExact("entries 2");58 check_dynamic_export.checkExact("entries 2");
59 check_dynamic_export.checkExact("name foo");59 check_dynamic_export.checkExact("name foo");
60 check_dynamic_export.checkExact("kind function");60 check_dynamic_export.checkExact("kind function");
6161
62 const check_force_export = force_export.checkObject();62 const check_force_export = force_export.checkObject();
63 check_force_export.checkStart();63 check_force_export.checkInHeaders();
64 check_force_export.checkExact("Section export");64 check_force_export.checkExact("Section export");
65 check_force_export.checkExact("entries 2");65 check_force_export.checkExact("entries 2");
66 check_force_export.checkExact("name foo");66 check_force_export.checkExact("name foo");
test/link/wasm/extern-mangle/build.zig+1-1
...@@ -22,7 +22,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -22,7 +22,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
22 lib.rdynamic = true; // export `foo`22 lib.rdynamic = true; // export `foo`
2323
24 const check_lib = lib.checkObject();24 const check_lib = lib.checkObject();
25 check_lib.checkStart();25 check_lib.checkInHeaders();
26 check_lib.checkExact("Section import");26 check_lib.checkExact("Section import");
27 check_lib.checkExact("entries 2"); // a.hello & b.hello27 check_lib.checkExact("entries 2"); // a.hello & b.hello
28 check_lib.checkExact("module a");28 check_lib.checkExact("module a");
test/link/wasm/function-table/build.zig+4-4
...@@ -52,7 +52,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -52,7 +52,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
52 const check_export = export_table.checkObject();52 const check_export = export_table.checkObject();
53 const check_regular = regular_table.checkObject();53 const check_regular = regular_table.checkObject();
5454
55 check_import.checkStart();55 check_import.checkInHeaders();
56 check_import.checkExact("Section import");56 check_import.checkExact("Section import");
57 check_import.checkExact("entries 1");57 check_import.checkExact("entries 1");
58 check_import.checkExact("module env");58 check_import.checkExact("module env");
...@@ -63,20 +63,20 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -63,20 +63,20 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
63 check_import.checkNotPresent("max"); // when importing, we do not provide a max63 check_import.checkNotPresent("max"); // when importing, we do not provide a max
64 check_import.checkNotPresent("Section table"); // we're importing it64 check_import.checkNotPresent("Section table"); // we're importing it
6565
66 check_export.checkStart();66 check_export.checkInHeaders();
67 check_export.checkExact("Section export");67 check_export.checkExact("Section export");
68 check_export.checkExact("entries 2");68 check_export.checkExact("entries 2");
69 check_export.checkExact("name __indirect_function_table"); // as per linker specification69 check_export.checkExact("name __indirect_function_table"); // as per linker specification
70 check_export.checkExact("kind table");70 check_export.checkExact("kind table");
7171
72 check_regular.checkStart();72 check_regular.checkInHeaders();
73 check_regular.checkExact("Section table");73 check_regular.checkExact("Section table");
74 check_regular.checkExact("entries 1");74 check_regular.checkExact("entries 1");
75 check_regular.checkExact("type funcref");75 check_regular.checkExact("type funcref");
76 check_regular.checkExact("min 2"); // index starts at 1 & 1 function pointer = 2.76 check_regular.checkExact("min 2"); // index starts at 1 & 1 function pointer = 2.
77 check_regular.checkExact("max 2");77 check_regular.checkExact("max 2");
7878
79 check_regular.checkStart();79 check_regular.checkInHeaders();
80 check_regular.checkExact("Section element");80 check_regular.checkExact("Section element");
81 check_regular.checkExact("entries 1");81 check_regular.checkExact("entries 1");
82 check_regular.checkExact("table index 0");82 check_regular.checkExact("table index 0");
test/link/wasm/infer-features/build.zig+1-1
...@@ -34,7 +34,7 @@ pub fn build(b: *std.Build) void {...@@ -34,7 +34,7 @@ pub fn build(b: *std.Build) void {
3434
35 // Verify the result contains the features from the C Object file.35 // Verify the result contains the features from the C Object file.
36 const check = lib.checkObject();36 const check = lib.checkObject();
37 check.checkStart();37 check.checkInHeaders();
38 check.checkExact("name target_features");38 check.checkExact("name target_features");
39 check.checkExact("features 7");39 check.checkExact("features 7");
40 check.checkExact("+ atomics");40 check.checkExact("+ atomics");
test/link/wasm/producers/build.zig+1-1
...@@ -29,7 +29,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -29,7 +29,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
29 const version_fmt = "version " ++ builtin.zig_version_string;29 const version_fmt = "version " ++ builtin.zig_version_string;
3030
31 const check_lib = lib.checkObject();31 const check_lib = lib.checkObject();
32 check_lib.checkStart();32 check_lib.checkInHeaders();
33 check_lib.checkExact("name producers");33 check_lib.checkExact("name producers");
34 check_lib.checkExact("fields 2");34 check_lib.checkExact("fields 2");
35 check_lib.checkExact("field_name language");35 check_lib.checkExact("field_name language");
test/link/wasm/segments/build.zig+4-4
...@@ -27,15 +27,15 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -27,15 +27,15 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
27 b.installArtifact(lib);27 b.installArtifact(lib);
2828
29 const check_lib = lib.checkObject();29 const check_lib = lib.checkObject();
30 check_lib.checkStart();30 check_lib.checkInHeaders();
31 check_lib.checkExact("Section data");31 check_lib.checkExact("Section data");
32 check_lib.checkExact("entries 2"); // rodata & data, no bss because we're exporting memory32 check_lib.checkExact("entries 2"); // rodata & data, no bss because we're exporting memory
3333
34 check_lib.checkStart();34 check_lib.checkInHeaders();
35 check_lib.checkExact("Section custom");35 check_lib.checkExact("Section custom");
36 check_lib.checkStart();36 check_lib.checkInHeaders();
37 check_lib.checkExact("name name"); // names custom section37 check_lib.checkExact("name name"); // names custom section
38 check_lib.checkStart();38 check_lib.checkInHeaders();
39 check_lib.checkExact("type data_segment");39 check_lib.checkExact("type data_segment");
40 check_lib.checkExact("names 2");40 check_lib.checkExact("names 2");
41 check_lib.checkExact("index 0");41 check_lib.checkExact("index 0");
test/link/wasm/stack_pointer/build.zig+3-3
...@@ -30,7 +30,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -30,7 +30,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
30 const check_lib = lib.checkObject();30 const check_lib = lib.checkObject();
3131
32 // ensure global exists and its initial value is equal to explitic stack size32 // ensure global exists and its initial value is equal to explitic stack size
33 check_lib.checkStart();33 check_lib.checkInHeaders();
34 check_lib.checkExact("Section global");34 check_lib.checkExact("Section global");
35 check_lib.checkExact("entries 1");35 check_lib.checkExact("entries 1");
36 check_lib.checkExact("type i32"); // on wasm32 the stack pointer must be i3236 check_lib.checkExact("type i32"); // on wasm32 the stack pointer must be i32
...@@ -39,13 +39,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -39,13 +39,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
39 check_lib.checkComputeCompare("stack_pointer", .{ .op = .eq, .value = .{ .literal = lib.stack_size.? } });39 check_lib.checkComputeCompare("stack_pointer", .{ .op = .eq, .value = .{ .literal = lib.stack_size.? } });
4040
41 // validate memory section starts after virtual stack41 // validate memory section starts after virtual stack
42 check_lib.checkStart();42 check_lib.checkInHeaders();
43 check_lib.checkExact("Section data");43 check_lib.checkExact("Section data");
44 check_lib.checkExtract("i32.const {data_start}");44 check_lib.checkExtract("i32.const {data_start}");
45 check_lib.checkComputeCompare("data_start", .{ .op = .eq, .value = .{ .variable = "stack_pointer" } });45 check_lib.checkComputeCompare("data_start", .{ .op = .eq, .value = .{ .variable = "stack_pointer" } });
4646
47 // validate the name of the stack pointer47 // validate the name of the stack pointer
48 check_lib.checkStart();48 check_lib.checkInHeaders();
49 check_lib.checkExact("Section custom");49 check_lib.checkExact("Section custom");
50 check_lib.checkExact("type global");50 check_lib.checkExact("type global");
51 check_lib.checkExact("names 1");51 check_lib.checkExact("names 1");
test/link/wasm/type/build.zig+1-1
...@@ -26,7 +26,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -26,7 +26,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
26 b.installArtifact(lib);26 b.installArtifact(lib);
2727
28 const check_lib = lib.checkObject();28 const check_lib = lib.checkObject();
29 check_lib.checkStart();29 check_lib.checkInHeaders();
30 check_lib.checkExact("Section type");30 check_lib.checkExact("Section type");
31 // only 2 entries, although we have more functions.31 // only 2 entries, although we have more functions.
32 // This is to test functions with the same function signature32 // This is to test functions with the same function signature
test/standalone/ios/build.zig+1-1
...@@ -30,7 +30,7 @@ pub fn build(b: *std.Build) void {...@@ -30,7 +30,7 @@ pub fn build(b: *std.Build) void {
30 exe.linkLibC();30 exe.linkLibC();
3131
32 const check = exe.checkObject();32 const check = exe.checkObject();
33 check.checkStart();33 check.checkInHeaders();
34 check.checkExact("cmd BUILD_VERSION");34 check.checkExact("cmd BUILD_VERSION");
35 check.checkExact("platform IOS");35 check.checkExact("platform IOS");
36 test_step.dependOn(&check.step);36 test_step.dependOn(&check.step);