authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-04-12 10:38:19+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-04-12 10:38:19+02:00
logedfc4727e24b1c75f49aa42f1b84c7fc59176a32
treeaa4ec52e6a5fdd20e730781c2615378f28de4d65
parent8da2f93bd0d11cb1cd5e7380230226df1c45b950
parentf7dabba5612eb20766a52087043ef78fa310bba9

Merge pull request 'init objdump subcommand' (#31827) from objdump into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31827

2 files changed, 101 insertions(+), 2 deletions(-)

lib/compiler/objdump.zig created+93
...@@ -0,0 +1,93 @@
1const std = @import("std");
2const Io = std.Io;
3const fatal = std.process.fatal;
4const mem = std.mem;
5const assert = std.debug.assert;
6
7var stdout_buffer: [4000]u8 = undefined;
8
9pub fn main(init: std.process.Init) !void {
10 const io = init.io;
11 const args = try init.minimal.args.toSlice(init.arena.allocator());
12
13 var opt_input_path: ?[]const u8 = null;
14 var i: usize = 1;
15 while (i < args.len) : (i += 1) {
16 const arg = args[i];
17 if (mem.startsWith(u8, arg, "-")) {
18 if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
19 return Io.File.stdout().writeStreamingAll(io, usage);
20 } else {
21 fatal("unrecognized argument: {s}", .{arg});
22 }
23 } else if (opt_input_path == null) {
24 opt_input_path = arg;
25 } else {
26 fatal("unexpected positional: {s}", .{arg});
27 }
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();
46}
47
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
87const usage =
88 \\Usage: zig objdump [options] file
89 \\
90 \\Options:
91 \\ -h, --help Print this help and exit
92 \\
93;
src/main.zig+8-2
...@@ -95,13 +95,14 @@ const normal_usage =...@@ -95,13 +95,14 @@ const normal_usage =
95 \\ reduce Minimize a bug report95 \\ reduce Minimize a bug report
96 \\ translate-c Convert C code to Zig code96 \\ translate-c Convert C code to Zig code
97 \\97 \\
98 \\ ar Use Zig as a drop-in archiver98 \\ ar Combine object files into static archive
99 \\ cc Use Zig as a drop-in C compiler99 \\ cc Use Zig as a drop-in C compiler
100 \\ c++ Use Zig as a drop-in C++ compiler100 \\ c++ Use Zig as a drop-in C++ compiler
101 \\ dlltool Use Zig as a drop-in dlltool.exe101 \\ dlltool Use Zig as a drop-in dlltool.exe
102 \\ lib Use Zig as a drop-in lib.exe102 \\ lib Use Zig as a drop-in lib.exe
103 \\ objcopy Manipulate executables and relocatables
104 \\ objdump Print information about executables and relocatables
103 \\ ranlib Use Zig as a drop-in ranlib105 \\ ranlib Use Zig as a drop-in ranlib
104 \\ objcopy Use Zig as a drop-in objcopy
105 \\ rc Use Zig as a drop-in rc.exe106 \\ rc Use Zig as a drop-in rc.exe
106 \\107 \\
107 \\ env Print lib path, std path, cache directory, and version108 \\ env Print lib path, std path, cache directory, and version
...@@ -342,6 +343,11 @@ fn mainArgs(...@@ -342,6 +343,11 @@ fn mainArgs(
342 .cmd_name = "objcopy",343 .cmd_name = "objcopy",
343 .root_src_path = "objcopy.zig",344 .root_src_path = "objcopy.zig",
344 });345 });
346 } else if (mem.eql(u8, cmd, "objdump")) {
347 return jitCmd(gpa, arena, io, cmd_args, environ_map, .{
348 .cmd_name = "objdump",
349 .root_src_path = "objdump.zig",
350 });
345 } else if (mem.eql(u8, cmd, "fetch")) {351 } else if (mem.eql(u8, cmd, "fetch")) {
346 return cmdFetch(gpa, arena, io, cmd_args, environ_map);352 return cmdFetch(gpa, arena, io, cmd_args, environ_map);
347 } else if (mem.eql(u8, cmd, "libc")) {353 } else if (mem.eql(u8, cmd, "libc")) {