| author | |
| committer | |
| log | 4574dea13a4b1d38c97fe73c257d895f605b78ca |
| tree | 0a1af823ce5c7c2ff0546c32f37cfe45b1f5ea6f |
| parent | a38af5f542199378483aba9f4598634ebf012b7b |
| parent | 5d12622469db5c53fe4857dfd95be033c16b4056 |
| signature |
lib/std/Build/CheckObject: introduce scoped checks29 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 | }; |
| 247 | 247 | ||
| 248 | const Check = struct { | 248 | const Check = struct { |
| 249 | kind: Kind, | ||
| 249 | actions: std.ArrayList(Action), | 250 | actions: std.ArrayList(Action), |
| 250 | 251 | ||
| 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 | }; |
| 293 | 310 | ||
| 294 | /// Creates a new empty sequence of actions. | 311 | /// Creates a new empty sequence of actions. |
| 295 | pub fn checkStart(self: *CheckObject) void { | 312 | fn 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 | } |
| 299 | 316 | ||
| 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. |
| 301 | pub fn checkExact(self: *CheckObject, phrase: []const u8) void { | 318 | pub 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 | } |
| 316 | 333 | ||
| 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. |
| 318 | pub fn checkContains(self: *CheckObject, phrase: []const u8) void { | 335 | pub 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 | } |
| 333 | 350 | ||
| 334 | /// Adds an exact match phrase with variable extractor to the latest created Check | 351 | /// Adds an exact match phrase with variable extractor to the latest created Check. |
| 335 | /// with `CheckObject.checkStart()`. | ||
| 336 | pub fn checkExtract(self: *CheckObject, phrase: []const u8) void { | 352 | pub 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 | } |
| 351 | 367 | ||
| 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. |
| 354 | pub fn checkNotPresent(self: *CheckObject, phrase: []const u8) void { | 370 | pub 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 | } |
| 369 | 385 | ||
| 386 | /// Creates a new check checking in the file headers (section, program headers, etc.). | ||
| 387 | pub 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 object | 391 | /// Creates a new check checking specifically symbol table parsed and dumped from the object |
| 371 | /// file. | 392 | /// file. |
| 372 | pub fn checkInSymtab(self: *CheckObject) void { | 393 | pub 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. | ||
| 408 | pub 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. | ||
| 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); | ||
| 381 | self.checkExact(label); | 438 | self.checkExact(label); |
| 382 | } | 439 | } |
| 383 | 440 | ||
| 384 | /// Creates a new check checking specifically dyld_info_only contents parsed and dumped | 441 | /// 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. |
| 387 | pub fn checkInDyldInfo(self: *CheckObject) void { | 444 | pub 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. | ||
| 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); | ||
| 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. | ||
| 468 | pub 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 | } |
| 395 | 476 | ||
| ... | @@ -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 | } |
| 407 | 488 | ||
| ... | @@ -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 | } |
| 419 | 500 | ||
| ... | @@ -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 | } |
| 430 | 511 | ||
| ... | @@ -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) }); |
| 459 | 540 | ||
| 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 { |
| 555 | 637 | ||
| 556 | const MachODumper = struct { | 638 | const 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"; | ||
| 560 | 647 | ||
| 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 | }; |
| 565 | 658 | ||
| 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(); |
| 578 | 671 | ||
| 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; |
| 588 | 681 | ||
| 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 | } | ||
| 590 | 725 | ||
| 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 | } | ||
| 627 | 729 | ||
| 628 | try dumpLoadCommand(cmd, i, writer); | 730 | switch (kind) { |
| 629 | try writer.writeByte('\n'); | 731 | .headers => { |
| 732 | try dumpHeader(hdr, writer); | ||
| 630 | 733 | ||
| 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'); | ||
| 633 | 742 | ||
| 634 | if (symtab) |stab| { | 743 | i += 1; |
| 635 | try dumpSymtab(sections.items, imports.items, stab, writer); | 744 | } |
| 636 | } | 745 | }, |
| 637 | 746 | ||
| 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 | } |
| 666 | 806 | ||
| 667 | return output.toOwnedSlice(); | 807 | return output.toOwnedSlice(); |
| ... | @@ -971,7 +1111,7 @@ const MachODumper = struct { | ... | @@ -971,7 +1111,7 @@ const MachODumper = struct { |
| 971 | 1111 | ||
| 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 | } |
| 1023 | 1163 | ||
| 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"; |
| 1445 | 1631 | ||
| 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 | } |
| 1453 | 1638 | ||
| 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(); |
| 1457 | 1643 | ||
| ... | @@ -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(); |
| 1514 | 1700 | ||
| 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 | } | ||
| 1517 | 1710 | ||
| 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 | } |
| 1556 | 1749 | ||
| 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 | } |
| 1592 | 1783 | ||
| 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 | }; |
| 1613 | 1804 | ||
| 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(); |
| 1617 | 1809 | ||
| ... | @@ -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(); |
| 1665 | 1857 | ||
| 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 | } | ||
| 1672 | 1879 | ||
| 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 = .{}, |
| 1685 | 1892 | ||
| 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 | } |
| 1747 | 1954 | ||
| 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 | }; |
| 1892 | 2098 | ||
| 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 | }; |
| 1987 | 2193 | ||
| 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{}, |
| 1991 | 2197 | ||
| 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 { |
| 2090 | const WasmDumper = struct { | 2296 | const WasmDumper = struct { |
| 2091 | const symtab_label = "symbols"; | 2297 | const symtab_label = "symbols"; |
| 2092 | 2298 | ||
| 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(); |
| 2109 | 2315 | ||
| 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 | }, | ||
| 2114 | 2328 | ||
| 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 | ||
| 2119 | 2331 | ||
| 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); |
| 507 | 507 | ||
| 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); |
| 526 | 526 | ||
| 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); |
| 545 | 545 | ||
| 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" }; |
| 816 | 816 | ||
| 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" }; |
| 832 | 832 | ||
| 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); |
| 1461 | 1461 | ||
| 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); |
| 1495 | 1495 | ||
| 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; |
| 1508 | 1508 | ||
| 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); |
| 1938 | 1938 | ||
| 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); |
| 1968 | 1968 | ||
| 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); |
| 2056 | 2056 | ||
| 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(); |
| 2076 | 2076 | ||
| 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); |
| 2104 | 2104 | ||
| 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); |
| 2327 | 2327 | ||
| 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); |
| 2333 | 2333 | ||
| 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); |
| 2370 | 2370 | ||
| 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 CheckObject | 2375 | // 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); |
| 2391 | 2391 | ||
| 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 CheckObject | 2396 | // // 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(); |
| 2423 | 2423 | ||
| 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(); |
| 2436 | 2436 | ||
| 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(); |
| 3522 | 3522 | ||
| 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"); |
| 20 | 20 | ||
| 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"); |
| 25 | 25 | ||
| 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"); |
| 29 | 29 |
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(); |
| 26 | 26 | ||
| 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(); |
| 47 | 47 | ||
| 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"); |
| 55 | 55 | ||
| 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 |
| 24 | 24 | ||
| 25 | const check_exe = exe.checkObject(); | 25 | const check_exe = exe.checkObject(); |
| 26 | 26 | ||
| 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}"); |
| 30 | 30 | ||
| 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}"); |
| 34 | 34 |
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"); |
| 35 | 35 | ||
| 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}"); |
| 40 | 40 | ||
| 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}"); |
| 44 | 44 | ||
| 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}"); |
| 48 | 48 |
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; |
| 22 | 22 | ||
| 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}"); |
| 27 | 27 | ||
| ... | @@ -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; |
| 48 | 48 | ||
| 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; |
| 66 | 66 | ||
| 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; |
| 84 | 84 | ||
| 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}"); |
| 89 | 89 |
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; |
| 27 | 27 | ||
| 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; |
| 40 | 40 | ||
| 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; |
| 21 | 21 | ||
| 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"); |
| 28 | 28 | ||
| 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"); |
| 32 | 32 | ||
| ... | @@ -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; |
| 45 | 45 | ||
| 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); |
| 21 | 21 | ||
| 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; |
| 26 | 26 | ||
| 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 |
| 26 | 26 | ||
| 27 | const check_exe = exe.checkObject(); | 27 | const check_exe = exe.checkObject(); |
| 28 | 28 | ||
| 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}"); |
| 34 | 34 | ||
| 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}"); |
| 45 | 45 | ||
| 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}"); |
| 50 | 50 | ||
| 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}"); |
| 55 | 55 | ||
| 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}"); |
| 62 | 62 | ||
| 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}"); |
| 67 | 67 | ||
| 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; |
| 33 | 33 | ||
| 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"); |
| 24 | 24 | ||
| 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()); |
| 38 | 38 | ||
| 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"); |
| 43 | 43 |
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; |
| 28 | 28 | ||
| 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 resolved | 32 | check.checkExact("name __trunch"); // Ensure it was imported and resolved |
| 33 | 33 |
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 { |
| 21 | 21 | ||
| 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(); |
| 32 | 32 | ||
| 33 | // since we import memory, make sure it exists with the correct naming | 33 | // 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 specification | 38 | check_lib.checkExact("name memory"); // as per linker specification |
| 39 | 39 | ||
| 40 | // since we are importing memory, ensure it's not exported | 40 | // 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"); |
| 43 | 43 | ||
| 44 | // validate the name of the stack pointer | 44 | // 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; |
| 78 | 78 | ||
| 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 { |
| 22 | 22 | ||
| 23 | const check_lib = lib.checkObject(); | 23 | const check_lib = lib.checkObject(); |
| 24 | 24 | ||
| 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 fields | 28 | 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 } }); |
| 37 | 37 | ||
| 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; |
| 47 | 47 | ||
| 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"); |
| 54 | 54 | ||
| 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"); |
| 61 | 61 | ||
| 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` |
| 23 | 23 | ||
| 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.hello | 27 | 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(); |
| 54 | 54 | ||
| 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 max | 63 | check_import.checkNotPresent("max"); // when importing, we do not provide a max |
| 64 | check_import.checkNotPresent("Section table"); // we're importing it | 64 | check_import.checkNotPresent("Section table"); // we're importing it |
| 65 | 65 | ||
| 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 specification | 69 | check_export.checkExact("name __indirect_function_table"); // as per linker specification |
| 70 | check_export.checkExact("kind table"); | 70 | check_export.checkExact("kind table"); |
| 71 | 71 | ||
| 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"); |
| 78 | 78 | ||
| 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 { |
| 34 | 34 | ||
| 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; |
| 30 | 30 | ||
| 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); |
| 28 | 28 | ||
| 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 memory | 32 | check_lib.checkExact("entries 2"); // rodata & data, no bss because we're exporting memory |
| 33 | 33 | ||
| 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 section | 37 | 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(); |
| 31 | 31 | ||
| 32 | // ensure global exists and its initial value is equal to explitic stack size | 32 | // 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 i32 | 36 | 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.? } }); |
| 40 | 40 | ||
| 41 | // validate memory section starts after virtual stack | 41 | // 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" } }); |
| 46 | 46 | ||
| 47 | // validate the name of the stack pointer | 47 | // 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); |
| 27 | 27 | ||
| 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 signature | 32 | // 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(); |
| 31 | 31 | ||
| 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); |