link-tests: rename check() to checkStart()

Do not hardcode the symtab label; instead allow each parser to define
its own.

Check for missing extractor value in the matcher when matching `{}`.
This commit is contained in:
Jakub Konka 2022-06-23 12:56:28 +02:00
parent 6e04c2faab
commit 03ddb42b8b
6 changed files with 22 additions and 15 deletions

View File

@ -83,6 +83,7 @@ const MatchAction = struct {
if (closing_brace != needle_tok.len - 1) return error.ClosingBraceNotLast;
const name = needle_tok[1..closing_brace];
if (name.len == 0) return error.MissingBraceValue;
const value = try std.fmt.parseInt(u64, hay_tok, 16);
try global_vars.putNoClobber(name, value);
} else {
@ -135,13 +136,13 @@ const Check = struct {
};
/// Creates a new sequence of actions with `phrase` as the first anchor searched phrase.
pub fn check(self: *CheckObjectStep, phrase: []const u8) void {
pub fn checkStart(self: *CheckObjectStep, phrase: []const u8) void {
var new_check = Check.create(self.builder);
new_check.match(phrase);
self.checks.append(new_check) catch unreachable;
}
/// Adds another searched phrase to the latest created Check with `CheckObjectStep.check(...)`.
/// Adds another searched phrase to the latest created Check with `CheckObjectStep.checkStart(...)`.
/// Asserts at least one check already exists.
pub fn checkNext(self: *CheckObjectStep, phrase: []const u8) void {
assert(self.checks.items.len > 0);
@ -154,7 +155,11 @@ pub fn checkNext(self: *CheckObjectStep, phrase: []const u8) void {
/// Issuing this check will force parsing and dumping of the symbol table.
pub fn checkInSymtab(self: *CheckObjectStep) void {
self.dump_symtab = true;
self.check("symtab");
const symtab_label = switch (self.obj_format) {
.macho => MachODumper.symtab_label,
else => @panic("TODO other parsers"),
};
self.checkStart(symtab_label);
}
/// Creates a new standalone, singular check which allows running simple binary operations
@ -274,6 +279,8 @@ const Opts = struct {
};
const MachODumper = struct {
const symtab_label = "symtab";
fn parseAndDump(bytes: []const u8, opts: Opts) ![]const u8 {
const gpa = opts.gpa orelse unreachable; // MachO dumper requires an allocator
var stream = std.io.fixedBufferStream(bytes);
@ -301,7 +308,7 @@ const MachODumper = struct {
}
if (symtab_cmd) |cmd| {
try writer.writeAll("symtab\n");
try writer.writeAll(symtab_label ++ "\n");
const strtab = bytes[cmd.stroff..][0..cmd.strsize];
const raw_symtab = bytes[cmd.symoff..][0 .. cmd.nsyms * @sizeOf(macho.nlist_64)];
const symtab = mem.bytesAsSlice(macho.nlist_64, raw_symtab);

View File

@ -14,7 +14,7 @@ pub fn build(b: *Builder) void {
dylib.install();
const check_dylib = dylib.checkObject(.macho);
check_dylib.check("cmd ID_DYLIB");
check_dylib.checkStart("cmd ID_DYLIB");
check_dylib.checkNext("name @rpath/liba.dylib");
check_dylib.checkNext("timestamp 2");
check_dylib.checkNext("current version 10000");
@ -31,13 +31,13 @@ pub fn build(b: *Builder) void {
exe.addRPath(b.pathFromRoot("zig-out/lib"));
const check_exe = exe.checkObject(.macho);
check_exe.check("cmd LOAD_DYLIB");
check_exe.checkStart("cmd LOAD_DYLIB");
check_exe.checkNext("name @rpath/liba.dylib");
check_exe.checkNext("timestamp 2");
check_exe.checkNext("current version 10000");
check_exe.checkNext("compatibility version 10000");
check_exe.check("cmd RPATH");
check_exe.checkStart("cmd RPATH");
check_exe.checkNext(std.fmt.allocPrint(b.allocator, "path {s}", .{b.pathFromRoot("zig-out/lib")}) catch unreachable);
test_step.dependOn(&check_exe.step);

View File

@ -15,10 +15,10 @@ pub fn build(b: *Builder) void {
const check_exe = exe.checkObject(.macho);
check_exe.check("segname __TEXT");
check_exe.checkStart("segname __TEXT");
check_exe.checkNext("vmaddr {vmaddr}");
check_exe.check("cmd MAIN");
check_exe.checkStart("cmd MAIN");
check_exe.checkNext("entryoff {entryoff}");
check_exe.checkInSymtab();

View File

@ -14,12 +14,12 @@ pub fn build(b: *Builder) void {
exe.linkFramework("Cocoa");
const check = exe.checkObject(.macho);
check.check("cmd LOAD_DYLIB");
check.checkStart("cmd LOAD_DYLIB");
check.checkNext("name {*}Cocoa");
switch (mode) {
.Debug, .ReleaseSafe => {
check.check("cmd LOAD_DYLIB");
check.checkStart("cmd LOAD_DYLIB");
check.checkNext("name {*}libobjc{*}.dylib");
},
else => {},

View File

@ -15,12 +15,12 @@ pub fn build(b: *Builder) void {
exe.pagezero_size = 0x4000;
const check = exe.checkObject(.macho);
check.check("LC 0");
check.checkStart("LC 0");
check.checkNext("segname __PAGEZERO");
check.checkNext("vmaddr 0");
check.checkNext("vmsize 4000");
check.check("segname __TEXT");
check.checkStart("segname __TEXT");
check.checkNext("vmaddr 4000");
test_step.dependOn(&check.step);
@ -34,7 +34,7 @@ pub fn build(b: *Builder) void {
exe.pagezero_size = 0;
const check = exe.checkObject(.macho);
check.check("LC 0");
check.checkStart("LC 0");
check.checkNext("segname __TEXT");
check.checkNext("vmaddr 0");

View File

@ -14,7 +14,7 @@ pub fn build(b: *Builder) void {
exe.stack_size = 0x100000000;
const check_exe = exe.checkObject(.macho);
check_exe.check("cmd MAIN");
check_exe.checkStart("cmd MAIN");
check_exe.checkNext("stacksize 100000000");
test_step.dependOn(&check_exe.step);