authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-04-11 18:56:22-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-04-11 18:56:51-07:00
logf7dabba5612eb20766a52087043ef78fa310bba9
treec57617d49bf9b064c9527f05dbb2fecb0bd81bf4
parent1809a19c27d4dc5cebdf4c16bae51071019e9f96

objdump: recognize some file types


1 files changed, 66 insertions(+), 6 deletions(-)

lib/compiler/objdump.zig+66-6
...@@ -1,29 +1,89 @@...@@ -1,29 +1,89 @@
1const std = @import("std");1const std = @import("std");
2const Io = std.Io;2const Io = std.Io;
3const fatal = std.process.fatal;3const fatal = std.process.fatal;
4const mem = std.mem;
5const assert = std.debug.assert;
6
7var stdout_buffer: [4000]u8 = undefined;
48
5pub fn main(init: std.process.Init) !void {9pub fn main(init: std.process.Init) !void {
6 const io = init.io;10 const io = init.io;
7 const args = try init.minimal.args.toSlice(init.arena.allocator());11 const args = try init.minimal.args.toSlice(init.arena.allocator());
812
9 var input_path: ?[]const u8 = null;13 var opt_input_path: ?[]const u8 = null;
10 var i: usize = 0;14 var i: usize = 1;
11 while (i < args.len) : (i += 1) {15 while (i < args.len) : (i += 1) {
12 const arg = args[i];16 const arg = args[i];
13 if (std.mem.startsWith(u8, arg, "-")) {17 if (mem.startsWith(u8, arg, "-")) {
14 if (std.mem.eql(u8, arg, "-h") or std.mem.eql(u8, arg, "--help")) {18 if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
15 return Io.File.stdout().writeStreamingAll(io, usage);19 return Io.File.stdout().writeStreamingAll(io, usage);
16 } else {20 } else {
17 fatal("unrecognized argument: {s}", .{arg});21 fatal("unrecognized argument: {s}", .{arg});
18 }22 }
19 } else if (input_path == null) {23 } else if (opt_input_path == null) {
20 input_path = arg;24 opt_input_path = arg;
21 } else {25 } else {
22 fatal("unexpected positional: {s}", .{arg});26 fatal("unexpected positional: {s}", .{arg});
23 }27 }
24 }28 }
29
30 const input_path = opt_input_path orelse fatal("missing input file path positional argument", .{});
31
32 var file = std.Io.Dir.cwd().openFile(io, input_path, .{}) catch |err|
33 fatal("failed to open {s}: {t}", .{ input_path, err });
34 defer file.close(io);
35
36 var buffer: [4000]u8 = undefined;
37 var file_reader = file.reader(io, &buffer);
38 var stdout_writer = std.Io.File.stdout().writerStreaming(io, &stdout_buffer);
39 dump(&file_reader.interface, &stdout_writer.interface) catch |err| switch (err) {
40 error.ReadFailed => return file_reader.err.?,
41 error.WriteFailed => return stdout_writer.err.?,
42 error.UnknownFile => fatal("unrecognized file: {s}", .{input_path}),
43 else => |e| return e,
44 };
45 try stdout_writer.flush();
25}46}
2647
48fn dump(r: *Io.Reader, w: *Io.Writer) !void {
49 try r.fill(4);
50 elf: {
51 if (!mem.eql(u8, r.buffered()[0..4], std.elf.MAGIC)) break :elf;
52 return elf.dump(r, w);
53 }
54 macho: {
55 if (mem.readInt(u32, r.buffered()[0..4], .little) != std.macho.MH_MAGIC_64) break :macho;
56 return macho.dump(r, w);
57 }
58 wasm: {
59 comptime assert(std.wasm.magic.len == 4);
60 if (!mem.eql(u8, r.buffered()[0..4], &std.wasm.magic)) break :wasm;
61 return wasm.dump(r, w);
62 }
63 return error.UnknownFile;
64}
65
66const elf = struct {
67 fn dump(r: *Io.Reader, w: *Io.Writer) !void {
68 _ = r;
69 try w.writeAll("TODO dump elf file\n");
70 }
71};
72
73const macho = struct {
74 fn dump(r: *Io.Reader, w: *Io.Writer) !void {
75 _ = r;
76 try w.writeAll("TODO dump macho file\n");
77 }
78};
79
80const wasm = struct {
81 fn dump(r: *Io.Reader, w: *Io.Writer) !void {
82 _ = r;
83 try w.writeAll("TODO dump wasm file\n");
84 }
85};
86
27const usage =87const usage =
28 \\Usage: zig objdump [options] file88 \\Usage: zig objdump [options] file
29 \\89 \\