mirror of
https://github.com/ziglang/zig.git
synced 2025-12-16 11:13:08 +00:00
zig objcopy: support the compiler protocol
This commit extracts out server code into src/Server.zig and uses it both in the main CLI as well as `zig objcopy`. std.Build.ObjCopyStep now adds `--listen=-` to the CLI for `zig objcopy` and observes the protocol for progress and other kinds of integrations. This fixes the last two test failures of this branch when I run `zig build test` locally.
This commit is contained in:
parent
59f5df3af9
commit
a333bb91ff
@ -623,6 +623,7 @@ set(ZIG_STAGE2_SOURCES
|
|||||||
"${CMAKE_SOURCE_DIR}/src/print_targets.zig"
|
"${CMAKE_SOURCE_DIR}/src/print_targets.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/print_zir.zig"
|
"${CMAKE_SOURCE_DIR}/src/print_zir.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/register_manager.zig"
|
"${CMAKE_SOURCE_DIR}/src/register_manager.zig"
|
||||||
|
"${CMAKE_SOURCE_DIR}/src/Server.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/target.zig"
|
"${CMAKE_SOURCE_DIR}/src/target.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/tracy.zig"
|
"${CMAKE_SOURCE_DIR}/src/tracy.zig"
|
||||||
"${CMAKE_SOURCE_DIR}/src/translate_c.zig"
|
"${CMAKE_SOURCE_DIR}/src/translate_c.zig"
|
||||||
|
|||||||
@ -113,6 +113,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
|
|||||||
};
|
};
|
||||||
|
|
||||||
try argv.appendSlice(&.{ full_src_path, full_dest_path });
|
try argv.appendSlice(&.{ full_src_path, full_dest_path });
|
||||||
|
|
||||||
|
try argv.append("--listen=-");
|
||||||
_ = try step.evalZigProcess(argv.items, prog_node);
|
_ = try step.evalZigProcess(argv.items, prog_node);
|
||||||
|
|
||||||
self.output_file.path = full_dest_path;
|
self.output_file.path = full_dest_path;
|
||||||
|
|||||||
113
src/Server.zig
Normal file
113
src/Server.zig
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
in: std.fs.File,
|
||||||
|
out: std.fs.File,
|
||||||
|
receive_fifo: std.fifo.LinearFifo(u8, .Dynamic),
|
||||||
|
|
||||||
|
pub const Options = struct {
|
||||||
|
gpa: Allocator,
|
||||||
|
in: std.fs.File,
|
||||||
|
out: std.fs.File,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn init(options: Options) !Server {
|
||||||
|
var s: Server = .{
|
||||||
|
.in = options.in,
|
||||||
|
.out = options.out,
|
||||||
|
.receive_fifo = std.fifo.LinearFifo(u8, .Dynamic).init(options.gpa),
|
||||||
|
};
|
||||||
|
try s.serveStringMessage(.zig_version, build_options.version);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(s: *Server) void {
|
||||||
|
s.receive_fifo.deinit();
|
||||||
|
s.* = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn receiveMessage(s: *Server) !InMessage.Header {
|
||||||
|
const Header = InMessage.Header;
|
||||||
|
const fifo = &s.receive_fifo;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const buf = fifo.readableSlice(0);
|
||||||
|
assert(fifo.readableLength() == buf.len);
|
||||||
|
if (buf.len >= @sizeOf(Header)) {
|
||||||
|
const header = @ptrCast(*align(1) const Header, buf[0..@sizeOf(Header)]);
|
||||||
|
if (header.bytes_len != 0)
|
||||||
|
return error.InvalidClientMessage;
|
||||||
|
const result = header.*;
|
||||||
|
fifo.discard(@sizeOf(Header));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const write_buffer = try fifo.writableWithSize(256);
|
||||||
|
const amt = try s.in.read(write_buffer);
|
||||||
|
fifo.update(amt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serveStringMessage(s: *Server, tag: OutMessage.Tag, msg: []const u8) !void {
|
||||||
|
return s.serveMessage(.{
|
||||||
|
.tag = tag,
|
||||||
|
.bytes_len = @intCast(u32, msg.len),
|
||||||
|
}, &.{msg});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serveMessage(
|
||||||
|
s: *const Server,
|
||||||
|
header: OutMessage.Header,
|
||||||
|
bufs: []const []const u8,
|
||||||
|
) !void {
|
||||||
|
var iovecs: [10]std.os.iovec_const = undefined;
|
||||||
|
iovecs[0] = .{
|
||||||
|
.iov_base = @ptrCast([*]const u8, &header),
|
||||||
|
.iov_len = @sizeOf(OutMessage.Header),
|
||||||
|
};
|
||||||
|
for (bufs, iovecs[1 .. bufs.len + 1]) |buf, *iovec| {
|
||||||
|
iovec.* = .{
|
||||||
|
.iov_base = buf.ptr,
|
||||||
|
.iov_len = buf.len,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
try s.out.writevAll(iovecs[0 .. bufs.len + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serveEmitBinPath(
|
||||||
|
s: *Server,
|
||||||
|
fs_path: []const u8,
|
||||||
|
header: std.zig.Server.Message.EmitBinPath,
|
||||||
|
) !void {
|
||||||
|
try s.serveMessage(.{
|
||||||
|
.tag = .emit_bin_path,
|
||||||
|
.bytes_len = @intCast(u32, fs_path.len + @sizeOf(std.zig.Server.Message.EmitBinPath)),
|
||||||
|
}, &.{
|
||||||
|
std.mem.asBytes(&header),
|
||||||
|
fs_path,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serveErrorBundle(s: *Server, error_bundle: std.zig.ErrorBundle) !void {
|
||||||
|
const eb_hdr: std.zig.Server.Message.ErrorBundle = .{
|
||||||
|
.extra_len = @intCast(u32, error_bundle.extra.len),
|
||||||
|
.string_bytes_len = @intCast(u32, error_bundle.string_bytes.len),
|
||||||
|
};
|
||||||
|
const bytes_len = @sizeOf(std.zig.Server.Message.ErrorBundle) +
|
||||||
|
4 * error_bundle.extra.len + error_bundle.string_bytes.len;
|
||||||
|
try s.serveMessage(.{
|
||||||
|
.tag = .error_bundle,
|
||||||
|
.bytes_len = @intCast(u32, bytes_len),
|
||||||
|
}, &.{
|
||||||
|
std.mem.asBytes(&eb_hdr),
|
||||||
|
// TODO: implement @ptrCast between slices changing the length
|
||||||
|
std.mem.sliceAsBytes(error_bundle.extra),
|
||||||
|
error_bundle.string_bytes,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const OutMessage = std.zig.Server.Message;
|
||||||
|
const InMessage = std.zig.Client.Message;
|
||||||
|
|
||||||
|
const Server = @This();
|
||||||
|
const std = @import("std");
|
||||||
|
const build_options = @import("build_options");
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
const assert = std.debug.assert;
|
||||||
111
src/main.zig
111
src/main.zig
@ -26,6 +26,7 @@ const target_util = @import("target.zig");
|
|||||||
const crash_report = @import("crash_report.zig");
|
const crash_report = @import("crash_report.zig");
|
||||||
const Module = @import("Module.zig");
|
const Module = @import("Module.zig");
|
||||||
const AstGen = @import("AstGen.zig");
|
const AstGen = @import("AstGen.zig");
|
||||||
|
const Server = @import("Server.zig");
|
||||||
|
|
||||||
pub const std_options = struct {
|
pub const std_options = struct {
|
||||||
pub const wasiCwd = wasi_cwd;
|
pub const wasiCwd = wasi_cwd;
|
||||||
@ -3540,11 +3541,14 @@ fn serve(
|
|||||||
) !void {
|
) !void {
|
||||||
const gpa = comp.gpa;
|
const gpa = comp.gpa;
|
||||||
|
|
||||||
try serveStringMessage(out, .zig_version, build_options.version);
|
var server = try Server.init(.{
|
||||||
|
.gpa = gpa,
|
||||||
|
.in = in,
|
||||||
|
.out = out,
|
||||||
|
});
|
||||||
|
defer server.deinit();
|
||||||
|
|
||||||
var child_pid: ?std.ChildProcess.Id = null;
|
var child_pid: ?std.ChildProcess.Id = null;
|
||||||
var receive_fifo = std.fifo.LinearFifo(u8, .Dynamic).init(gpa);
|
|
||||||
defer receive_fifo.deinit();
|
|
||||||
|
|
||||||
var progress: std.Progress = .{
|
var progress: std.Progress = .{
|
||||||
.terminal = null,
|
.terminal = null,
|
||||||
@ -3564,7 +3568,7 @@ fn serve(
|
|||||||
main_progress_node.context = &progress;
|
main_progress_node.context = &progress;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const hdr = try receiveMessage(in, &receive_fifo);
|
const hdr = try server.receiveMessage();
|
||||||
|
|
||||||
switch (hdr.tag) {
|
switch (hdr.tag) {
|
||||||
.exit => {
|
.exit => {
|
||||||
@ -3580,7 +3584,7 @@ fn serve(
|
|||||||
const arena = arena_instance.allocator();
|
const arena = arena_instance.allocator();
|
||||||
var output: TranslateCOutput = undefined;
|
var output: TranslateCOutput = undefined;
|
||||||
try cmdTranslateC(comp, arena, &output);
|
try cmdTranslateC(comp, arena, &output);
|
||||||
try serveEmitBinPath(out, output.path, .{
|
try server.serveEmitBinPath(output.path, .{
|
||||||
.flags = .{ .cache_hit = output.cache_hit },
|
.flags = .{ .cache_hit = output.cache_hit },
|
||||||
});
|
});
|
||||||
continue;
|
continue;
|
||||||
@ -3594,7 +3598,7 @@ fn serve(
|
|||||||
var reset: std.Thread.ResetEvent = .{};
|
var reset: std.Thread.ResetEvent = .{};
|
||||||
|
|
||||||
var progress_thread = try std.Thread.spawn(.{}, progressThread, .{
|
var progress_thread = try std.Thread.spawn(.{}, progressThread, .{
|
||||||
&progress, out, &reset,
|
&progress, &server, &reset,
|
||||||
});
|
});
|
||||||
defer {
|
defer {
|
||||||
reset.set();
|
reset.set();
|
||||||
@ -3605,7 +3609,7 @@ fn serve(
|
|||||||
}
|
}
|
||||||
|
|
||||||
try comp.makeBinFileExecutable();
|
try comp.makeBinFileExecutable();
|
||||||
try serveUpdateResults(out, comp);
|
try serveUpdateResults(&server, comp);
|
||||||
},
|
},
|
||||||
.run => {
|
.run => {
|
||||||
if (child_pid != null) {
|
if (child_pid != null) {
|
||||||
@ -3632,14 +3636,14 @@ fn serve(
|
|||||||
assert(main_progress_node.recently_updated_child == null);
|
assert(main_progress_node.recently_updated_child == null);
|
||||||
if (child_pid) |pid| {
|
if (child_pid) |pid| {
|
||||||
try comp.hotCodeSwap(main_progress_node, pid);
|
try comp.hotCodeSwap(main_progress_node, pid);
|
||||||
try serveUpdateResults(out, comp);
|
try serveUpdateResults(&server, comp);
|
||||||
} else {
|
} else {
|
||||||
if (comp.bin_file.options.output_mode == .Exe) {
|
if (comp.bin_file.options.output_mode == .Exe) {
|
||||||
try comp.makeBinFileWritable();
|
try comp.makeBinFileWritable();
|
||||||
}
|
}
|
||||||
try comp.update(main_progress_node);
|
try comp.update(main_progress_node);
|
||||||
try comp.makeBinFileExecutable();
|
try comp.makeBinFileExecutable();
|
||||||
try serveUpdateResults(out, comp);
|
try serveUpdateResults(&server, comp);
|
||||||
|
|
||||||
child_pid = try runOrTestHotSwap(
|
child_pid = try runOrTestHotSwap(
|
||||||
comp,
|
comp,
|
||||||
@ -3659,7 +3663,7 @@ fn serve(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn progressThread(progress: *std.Progress, out: fs.File, reset: *std.Thread.ResetEvent) void {
|
fn progressThread(progress: *std.Progress, server: *const Server, reset: *std.Thread.ResetEvent) void {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (reset.timedWait(500 * std.time.ns_per_ms)) |_| {
|
if (reset.timedWait(500 * std.time.ns_per_ms)) |_| {
|
||||||
// The Compilation update has completed.
|
// The Compilation update has completed.
|
||||||
@ -3705,7 +3709,7 @@ fn progressThread(progress: *std.Progress, out: fs.File, reset: *std.Thread.Rese
|
|||||||
|
|
||||||
const progress_string = buf.slice();
|
const progress_string = buf.slice();
|
||||||
|
|
||||||
serveMessage(out, .{
|
server.serveMessage(.{
|
||||||
.tag = .progress,
|
.tag = .progress,
|
||||||
.bytes_len = @intCast(u32, progress_string.len),
|
.bytes_len = @intCast(u32, progress_string.len),
|
||||||
}, &.{
|
}, &.{
|
||||||
@ -3716,100 +3720,21 @@ fn progressThread(progress: *std.Progress, out: fs.File, reset: *std.Thread.Rese
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serveMessage(
|
fn serveUpdateResults(s: *Server, comp: *Compilation) !void {
|
||||||
out: fs.File,
|
|
||||||
header: std.zig.Server.Message.Header,
|
|
||||||
bufs: []const []const u8,
|
|
||||||
) !void {
|
|
||||||
var iovecs: [10]std.os.iovec_const = undefined;
|
|
||||||
iovecs[0] = .{
|
|
||||||
.iov_base = @ptrCast([*]const u8, &header),
|
|
||||||
.iov_len = @sizeOf(std.zig.Server.Message.Header),
|
|
||||||
};
|
|
||||||
for (bufs, iovecs[1 .. bufs.len + 1]) |buf, *iovec| {
|
|
||||||
iovec.* = .{
|
|
||||||
.iov_base = buf.ptr,
|
|
||||||
.iov_len = buf.len,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
try out.writevAll(iovecs[0 .. bufs.len + 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serveErrorBundle(out: fs.File, error_bundle: std.zig.ErrorBundle) !void {
|
|
||||||
const eb_hdr: std.zig.Server.Message.ErrorBundle = .{
|
|
||||||
.extra_len = @intCast(u32, error_bundle.extra.len),
|
|
||||||
.string_bytes_len = @intCast(u32, error_bundle.string_bytes.len),
|
|
||||||
};
|
|
||||||
const bytes_len = @sizeOf(std.zig.Server.Message.ErrorBundle) +
|
|
||||||
4 * error_bundle.extra.len + error_bundle.string_bytes.len;
|
|
||||||
try serveMessage(out, .{
|
|
||||||
.tag = .error_bundle,
|
|
||||||
.bytes_len = @intCast(u32, bytes_len),
|
|
||||||
}, &.{
|
|
||||||
std.mem.asBytes(&eb_hdr),
|
|
||||||
// TODO: implement @ptrCast between slices changing the length
|
|
||||||
std.mem.sliceAsBytes(error_bundle.extra),
|
|
||||||
error_bundle.string_bytes,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serveUpdateResults(out: fs.File, comp: *Compilation) !void {
|
|
||||||
const gpa = comp.gpa;
|
const gpa = comp.gpa;
|
||||||
var error_bundle = try comp.getAllErrorsAlloc();
|
var error_bundle = try comp.getAllErrorsAlloc();
|
||||||
defer error_bundle.deinit(gpa);
|
defer error_bundle.deinit(gpa);
|
||||||
if (error_bundle.errorMessageCount() > 0) {
|
if (error_bundle.errorMessageCount() > 0) {
|
||||||
try serveErrorBundle(out, error_bundle);
|
try s.serveErrorBundle(error_bundle);
|
||||||
} else if (comp.bin_file.options.emit) |emit| {
|
} else if (comp.bin_file.options.emit) |emit| {
|
||||||
const full_path = try emit.directory.join(gpa, &.{emit.sub_path});
|
const full_path = try emit.directory.join(gpa, &.{emit.sub_path});
|
||||||
defer gpa.free(full_path);
|
defer gpa.free(full_path);
|
||||||
try serveEmitBinPath(out, full_path, .{
|
try s.serveEmitBinPath(full_path, .{
|
||||||
.flags = .{ .cache_hit = comp.last_update_was_cache_hit },
|
.flags = .{ .cache_hit = comp.last_update_was_cache_hit },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serveEmitBinPath(
|
|
||||||
out: fs.File,
|
|
||||||
fs_path: []const u8,
|
|
||||||
header: std.zig.Server.Message.EmitBinPath,
|
|
||||||
) !void {
|
|
||||||
try serveMessage(out, .{
|
|
||||||
.tag = .emit_bin_path,
|
|
||||||
.bytes_len = @intCast(u32, fs_path.len + @sizeOf(std.zig.Server.Message.EmitBinPath)),
|
|
||||||
}, &.{
|
|
||||||
std.mem.asBytes(&header),
|
|
||||||
fs_path,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serveStringMessage(out: fs.File, tag: std.zig.Server.Message.Tag, s: []const u8) !void {
|
|
||||||
try serveMessage(out, .{
|
|
||||||
.tag = tag,
|
|
||||||
.bytes_len = @intCast(u32, s.len),
|
|
||||||
}, &.{s});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn receiveMessage(in: fs.File, fifo: *std.fifo.LinearFifo(u8, .Dynamic)) !std.zig.Client.Message.Header {
|
|
||||||
const Header = std.zig.Client.Message.Header;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
const buf = fifo.readableSlice(0);
|
|
||||||
assert(fifo.readableLength() == buf.len);
|
|
||||||
if (buf.len >= @sizeOf(Header)) {
|
|
||||||
const header = @ptrCast(*align(1) const Header, buf[0..@sizeOf(Header)]);
|
|
||||||
if (header.bytes_len != 0)
|
|
||||||
return error.InvalidClientMessage;
|
|
||||||
const result = header.*;
|
|
||||||
fifo.discard(@sizeOf(Header));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
const write_buffer = try fifo.writableWithSize(256);
|
|
||||||
const amt = try in.read(write_buffer);
|
|
||||||
fifo.update(amt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const ModuleDepIterator = struct {
|
const ModuleDepIterator = struct {
|
||||||
split: mem.SplitIterator(u8),
|
split: mem.SplitIterator(u8),
|
||||||
|
|
||||||
|
|||||||
@ -4,22 +4,25 @@ const fs = std.fs;
|
|||||||
const elf = std.elf;
|
const elf = std.elf;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const File = std.fs.File;
|
const File = std.fs.File;
|
||||||
|
const assert = std.debug.assert;
|
||||||
|
|
||||||
const main = @import("main.zig");
|
const main = @import("main.zig");
|
||||||
const fatal = main.fatal;
|
const fatal = main.fatal;
|
||||||
const cleanExit = main.cleanExit;
|
const cleanExit = main.cleanExit;
|
||||||
|
const Server = @import("Server.zig");
|
||||||
|
|
||||||
pub fn cmdObjCopy(
|
pub fn cmdObjCopy(
|
||||||
gpa: Allocator,
|
gpa: Allocator,
|
||||||
arena: Allocator,
|
arena: Allocator,
|
||||||
args: []const []const u8,
|
args: []const []const u8,
|
||||||
) !void {
|
) !void {
|
||||||
_ = gpa;
|
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
var opt_out_fmt: ?std.Target.ObjectFormat = null;
|
var opt_out_fmt: ?std.Target.ObjectFormat = null;
|
||||||
var opt_input: ?[]const u8 = null;
|
var opt_input: ?[]const u8 = null;
|
||||||
var opt_output: ?[]const u8 = null;
|
var opt_output: ?[]const u8 = null;
|
||||||
var only_section: ?[]const u8 = null;
|
var only_section: ?[]const u8 = null;
|
||||||
var pad_to: ?u64 = null;
|
var pad_to: ?u64 = null;
|
||||||
|
var listen = false;
|
||||||
while (i < args.len) : (i += 1) {
|
while (i < args.len) : (i += 1) {
|
||||||
const arg = args[i];
|
const arg = args[i];
|
||||||
if (!mem.startsWith(u8, arg, "-")) {
|
if (!mem.startsWith(u8, arg, "-")) {
|
||||||
@ -54,6 +57,8 @@ pub fn cmdObjCopy(
|
|||||||
i += 1;
|
i += 1;
|
||||||
if (i >= args.len) fatal("expected another argument after '{s}'", .{arg});
|
if (i >= args.len) fatal("expected another argument after '{s}'", .{arg});
|
||||||
only_section = args[i];
|
only_section = args[i];
|
||||||
|
} else if (mem.eql(u8, arg, "--listen=-")) {
|
||||||
|
listen = true;
|
||||||
} else if (mem.startsWith(u8, arg, "--only-section=")) {
|
} else if (mem.startsWith(u8, arg, "--only-section=")) {
|
||||||
only_section = arg["--output-target=".len..];
|
only_section = arg["--output-target=".len..];
|
||||||
} else if (mem.eql(u8, arg, "--pad-to")) {
|
} else if (mem.eql(u8, arg, "--pad-to")) {
|
||||||
@ -102,10 +107,44 @@ pub fn cmdObjCopy(
|
|||||||
.only_section = only_section,
|
.only_section = only_section,
|
||||||
.pad_to = pad_to,
|
.pad_to = pad_to,
|
||||||
});
|
});
|
||||||
return cleanExit();
|
|
||||||
},
|
},
|
||||||
else => fatal("unsupported output object format: {s}", .{@tagName(out_fmt)}),
|
else => fatal("unsupported output object format: {s}", .{@tagName(out_fmt)}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (listen) {
|
||||||
|
var server = try Server.init(.{
|
||||||
|
.gpa = gpa,
|
||||||
|
.in = std.io.getStdIn(),
|
||||||
|
.out = std.io.getStdOut(),
|
||||||
|
});
|
||||||
|
defer server.deinit();
|
||||||
|
|
||||||
|
var seen_update = false;
|
||||||
|
while (true) {
|
||||||
|
const hdr = try server.receiveMessage();
|
||||||
|
switch (hdr.tag) {
|
||||||
|
.exit => {
|
||||||
|
return cleanExit();
|
||||||
|
},
|
||||||
|
.update => {
|
||||||
|
if (seen_update) {
|
||||||
|
std.debug.print("zig objcopy only supports 1 update for now\n", .{});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
seen_update = true;
|
||||||
|
|
||||||
|
try server.serveEmitBinPath(output, .{
|
||||||
|
.flags = .{ .cache_hit = false },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
std.debug.print("unsupported message: {s}", .{@tagName(hdr.tag)});
|
||||||
|
std.process.exit(1);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
const usage =
|
const usage =
|
||||||
@ -417,7 +456,7 @@ const HexWriter = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn Address(address: u32) Record {
|
fn Address(address: u32) Record {
|
||||||
std.debug.assert(address > 0xFFFF);
|
assert(address > 0xFFFF);
|
||||||
const segment = @intCast(u16, address / 0x10000);
|
const segment = @intCast(u16, address / 0x10000);
|
||||||
if (address > 0xFFFFF) {
|
if (address > 0xFFFFF) {
|
||||||
return Record{
|
return Record{
|
||||||
@ -460,7 +499,7 @@ const HexWriter = struct {
|
|||||||
const BUFSIZE = 1 + (1 + 2 + 1 + MAX_PAYLOAD_LEN + 1) * 2 + linesep.len;
|
const BUFSIZE = 1 + (1 + 2 + 1 + MAX_PAYLOAD_LEN + 1) * 2 + linesep.len;
|
||||||
var outbuf: [BUFSIZE]u8 = undefined;
|
var outbuf: [BUFSIZE]u8 = undefined;
|
||||||
const payload_bytes = self.getPayloadBytes();
|
const payload_bytes = self.getPayloadBytes();
|
||||||
std.debug.assert(payload_bytes.len <= MAX_PAYLOAD_LEN);
|
assert(payload_bytes.len <= MAX_PAYLOAD_LEN);
|
||||||
|
|
||||||
const line = try std.fmt.bufPrint(&outbuf, ":{0X:0>2}{1X:0>4}{2X:0>2}{3s}{4X:0>2}" ++ linesep, .{
|
const line = try std.fmt.bufPrint(&outbuf, ":{0X:0>2}{1X:0>4}{2X:0>2}{3s}{4X:0>2}" ++ linesep, .{
|
||||||
@intCast(u8, payload_bytes.len),
|
@intCast(u8, payload_bytes.len),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user