feature. See also
. The project being documented here (as the example) is the Zig library itself.
objdump.main
pub fn main(init: std.process.Init) !void
File
Code
pub fn main(init: std.process.Init) !void {
const io = init.io;
const args = try init.minimal.args.toSlice(init.arena.allocator());
const arena = init.arena.allocator();
var i: usize = 1;
var opt_exports: ?bool = null;
var opt_exports_sort: ?bool = null;
var opt_file_headers: ?bool = null;
var opt_imports: ?bool = null;
var opt_input_path: ?[]const u8 = null;
var opt_linker_member: ?std.coff.ArchiveMemberHeader.Kind = null;
var opt_member_headers: ?bool = null;
var any_elements = false;
var elements: ?@FieldType(Options, "elements") = null;
var redact: @FieldType(Options, "redact") = .initFill(false);
var opt_relocs: ?bool = null;
var opt_section_headers: ?bool = null;
var opt_strings: ?bool = null;
var opt_symbols: ?bool = null;
var opt_tls: ?bool = null;
var section_filters: std.ArrayList([]const u8) = .empty;
var symbol_filters: std.ArrayList([]const u8) = .empty;
var member_filters: std.ArrayList([]const u8) = .empty;
while (i < args.len) : (i += 1) {
const arg = args[i];
if (mem.startsWith(u8, arg, "-")) {
if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
return Io.File.stdout().writeStreamingAll(io, usage);
} else if (mem.eql(u8, arg, "--all-headers")) {
opt_file_headers = true;
opt_linker_member = .second_linker;
opt_member_headers = true;
opt_section_headers = true;
opt_symbols = true;
opt_relocs = true;
} else if (mem.startsWith(u8, arg, "--exports")) {
opt_exports = true;
opt_linker_member = .second_linker;
if (mem.eql(u8, arg["--exports".len..], "=sort"))
opt_exports_sort = true;
} else if (mem.eql(u8, arg, "--file-headers")) {
opt_file_headers = true;
} else if (mem.eql(u8, arg, "--imports")) {
opt_imports = true;
} else if (mem.startsWith(u8, arg, "--linker-member")) {
if (mem.eql(u8, arg["--linker-member".len..], "=1"))
opt_linker_member = .first_linker
else if (mem.eql(u8, arg["--linker-member".len..], "=longnames"))
opt_linker_member = .longnames
else
opt_linker_member = .second_linker;
} else if (mem.eql(u8, arg, "--member-headers")) {
opt_member_headers = true;
} else if (mem.startsWith(u8, arg, "--elements=")) {
any_elements = true;
var split = std.mem.splitScalar(u8, arg["--elements=".len..], ',');
while (split.next()) |element| {
const kind, const add = if (element.len > 0 and element[0] == '-')
.{ element[1..], false }
else
.{ element, true };
if (elements == null) elements = .initFill(false);
if (std.meta.stringToEnum(Element, kind)) |format_kind| {
elements.?.set(format_kind, add);
} else if (std.mem.eql(u8, kind, "all")) {
elements.? = .initFill(add);
} else {
fatal("unrecognized element: '{s}'", .{kind});
}
}
} else if (mem.startsWith(u8, arg, "--only-member=")) {
(try member_filters.addOne(arena)).* = try arena.dupe(u8, arg["--only-member=".len..]);
} else if (mem.startsWith(u8, arg, "--only-section=")) {
(try section_filters.addOne(arena)).* = try arena.dupe(u8, arg["--only-section=".len..]);
} else if (mem.startsWith(u8, arg, "--only-symbol=")) {
(try symbol_filters.addOne(arena)).* = try arena.dupe(u8, arg["--only-symbol=".len..]);
} else if (mem.startsWith(u8, arg, "--redact=")) {
const kind = arg["--redact=".len..];
if (std.meta.stringToEnum(FieldKind, kind)) |field_kind| {
redact.set(field_kind, true);
} else if (std.mem.eql(u8, kind, "all")) {
redact = .initFill(true);
} else {
fatal("unrecognized redaction kind: {s}", .{kind});
}
} else if (mem.eql(u8, arg, "--relocs")) {
opt_relocs = true;
} else if (mem.eql(u8, arg, "--section-headers")) {
opt_section_headers = true;
} else if (mem.eql(u8, arg, "-s") or mem.eql(u8, arg, "--snapshot")) {
elements = .initFill(false);
redact = .initFill(true);
} else if (mem.eql(u8, arg, "--strings")) {
opt_strings = true;
} else if (mem.eql(u8, arg, "--symbols")) {
opt_symbols = true;
} else if (mem.eql(u8, arg, "--tls")) {
opt_tls = true;
} else {
fatal("unrecognized argument: {s}", .{arg});
}
} else if (opt_input_path == null) {
opt_input_path = arg;
} else {
fatal("unexpected positional: {s}", .{arg});
}
}
const opts: Options = .{
.input_path = opt_input_path orelse fatal("missing input file path positional argument", .{}),
.exports = opt_exports orelse false,
.exports_sort = opt_exports_sort orelse false,
.file_headers = opt_file_headers orelse false,
.imports = opt_imports orelse false,
.linker_member = opt_linker_member,
.member_filters = member_filters.items,
.member_headers = opt_member_headers orelse false,
.elements = elements orelse .initFill(true),
.redact = redact,
.relocs = opt_relocs orelse false,
.section_filters = section_filters.items,
.section_headers = opt_section_headers orelse false,
.strings = opt_strings orelse false,
.symbol_filters = symbol_filters.items,
.symbols = opt_symbols orelse false,
.tls = opt_tls orelse false,
};
var file = std.Io.Dir.cwd().openFile(io, opts.input_path, .{}) catch |err|
fatal("failed to open {s}: {t}", .{ opts.input_path, err });
defer file.close(io);
var buffer: [4096]u8 = undefined;
var file_reader = file.reader(io, &buffer);
var stdout_writer = std.Io.File.stdout().writerStreaming(io, &stdout_buffer);
const ctx: DumpContext = .{
.gpa = init.gpa,
.opts = &opts,
.fr = &file_reader,
.w = &stdout_writer.interface,
};
dump(&ctx) catch |err| switch (err) {
error.ReadFailed => return file_reader.err.?,
error.WriteFailed => return stdout_writer.err.?,
error.UnknownFile => fatal("unrecognized file: {s}", .{opts.input_path}),
error.ParseFailure => {},
else => |e| return e,
};
try stdout_writer.flush();
}