mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
fix a round of compile errors caused by this branch
This commit is contained in:
parent
f54471b54c
commit
c49957dbe8
@ -884,12 +884,32 @@ const CacheUse = union(CacheMode) {
|
||||
docs_sub_path: ?[]u8,
|
||||
lf_open_opts: link.File.OpenOptions,
|
||||
tmp_artifact_directory: ?Cache.Directory,
|
||||
/// Prevents other processes from clobbering files in the output directory.
|
||||
lock: ?Cache.Lock,
|
||||
|
||||
fn releaseLock(whole: *Whole) void {
|
||||
if (whole.lock) |*lock| {
|
||||
lock.release();
|
||||
whole.lock = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const Incremental = struct {
|
||||
/// Where build artifacts and incremental compilation metadata serialization go.
|
||||
artifact_directory: Compilation.Directory,
|
||||
};
|
||||
|
||||
fn deinit(cu: CacheUse) void {
|
||||
switch (cu) {
|
||||
.incremental => |incremental| {
|
||||
incremental.artifact_directory.handle.close();
|
||||
},
|
||||
.whole => |whole| {
|
||||
whole.releaseLock();
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub const LinkObject = struct {
|
||||
@ -916,7 +936,7 @@ pub const InitOptions = struct {
|
||||
/// Normally, `main_mod` and `root_mod` are the same. The exception is `zig
|
||||
/// test`, in which `root_mod` is the test runner, and `main_mod` is the
|
||||
/// user's source file which has the tests.
|
||||
main_mod: ?*Package.Module,
|
||||
main_mod: ?*Package.Module = null,
|
||||
/// This is provided so that the API user has a chance to tweak the
|
||||
/// per-module settings of the standard library.
|
||||
std_mod: *Package.Module,
|
||||
@ -1615,6 +1635,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
|
||||
.implib_sub_path = try prepareWholeEmitSubPath(arena, options.emit_implib),
|
||||
.docs_sub_path = try prepareWholeEmitSubPath(arena, options.emit_docs),
|
||||
.tmp_artifact_directory = null,
|
||||
.lock = null,
|
||||
};
|
||||
comp.cache_use = .{ .whole = whole };
|
||||
},
|
||||
@ -1822,13 +1843,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
|
||||
pub fn destroy(self: *Compilation) void {
|
||||
if (self.bin_file) |lf| lf.destroy();
|
||||
if (self.module) |zcu| zcu.deinit();
|
||||
switch (self.cache_use) {
|
||||
.incremental => |incremental| {
|
||||
incremental.artifact_directory.handle.close();
|
||||
},
|
||||
.whole => {},
|
||||
}
|
||||
|
||||
self.cache_use.deinit();
|
||||
self.work_queue.deinit();
|
||||
self.anon_work_queue.deinit();
|
||||
self.c_object_work_queue.deinit();
|
||||
@ -1922,11 +1937,17 @@ pub fn getTarget(self: Compilation) Target {
|
||||
return self.root_mod.resolved_target.result;
|
||||
}
|
||||
|
||||
pub fn hotCodeSwap(comp: *Compilation, prog_node: *std.Progress.Node, pid: std.ChildProcess.Id) !void {
|
||||
comp.bin_file.child_pid = pid;
|
||||
try comp.makeBinFileWritable();
|
||||
/// Only legal to call when cache mode is incremental and a link file is present.
|
||||
pub fn hotCodeSwap(
|
||||
comp: *Compilation,
|
||||
prog_node: *std.Progress.Node,
|
||||
pid: std.ChildProcess.Id,
|
||||
) !void {
|
||||
const lf = comp.bin_file.?;
|
||||
lf.child_pid = pid;
|
||||
try lf.makeWritable();
|
||||
try comp.update(prog_node);
|
||||
try comp.makeBinFileExecutable();
|
||||
try lf.makeExecutable();
|
||||
}
|
||||
|
||||
fn cleanupAfterUpdate(comp: *Compilation) void {
|
||||
@ -1941,7 +1962,7 @@ fn cleanupAfterUpdate(comp: *Compilation) void {
|
||||
lf.destroy();
|
||||
comp.bin_file = null;
|
||||
}
|
||||
if (whole.tmp_artifact_directory) |directory| {
|
||||
if (whole.tmp_artifact_directory) |*directory| {
|
||||
directory.handle.close();
|
||||
if (directory.path) |p| comp.gpa.free(p);
|
||||
whole.tmp_artifact_directory = null;
|
||||
@ -1967,8 +1988,9 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
|
||||
// C source files.
|
||||
switch (comp.cache_use) {
|
||||
.whole => |whole| {
|
||||
// We are about to obtain this lock, so here we give other processes a chance first.
|
||||
assert(comp.bin_file == null);
|
||||
// We are about to obtain this lock, so here we give other processes a chance first.
|
||||
whole.releaseLock();
|
||||
|
||||
man = comp.cache_parent.obtain();
|
||||
whole.cache_manifest = &man;
|
||||
@ -1989,8 +2011,8 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
|
||||
|
||||
comp.wholeCacheModeSetBinFilePath(whole, &digest);
|
||||
|
||||
assert(comp.bin_file.lock == null);
|
||||
comp.bin_file.lock = man.toOwnedLock();
|
||||
assert(whole.lock == null);
|
||||
whole.lock = man.toOwnedLock();
|
||||
return;
|
||||
}
|
||||
log.debug("CacheMode.whole cache miss for {s}", .{comp.root_name});
|
||||
@ -2158,7 +2180,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
|
||||
|
||||
// Rename the temporary directory into place.
|
||||
// Close tmp dir and link.File to avoid open handle during rename.
|
||||
if (whole.tmp_artifact_directory) |tmp_directory| {
|
||||
if (whole.tmp_artifact_directory) |*tmp_directory| {
|
||||
tmp_directory.handle.close();
|
||||
if (tmp_directory.path) |p| comp.gpa.free(p);
|
||||
whole.tmp_artifact_directory = null;
|
||||
@ -2181,8 +2203,8 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
|
||||
log.warn("failed to write cache manifest: {s}", .{@errorName(err)});
|
||||
};
|
||||
|
||||
assert(comp.bin_file.lock == null);
|
||||
comp.bin_file.lock = man.toOwnedLock();
|
||||
assert(whole.lock == null);
|
||||
whole.lock = man.toOwnedLock();
|
||||
},
|
||||
.incremental => {},
|
||||
}
|
||||
@ -2263,13 +2285,15 @@ fn maybeGenerateAutodocs(comp: *Compilation, prog_node: *std.Progress.Node) !voi
|
||||
}
|
||||
|
||||
fn flush(comp: *Compilation, prog_node: *std.Progress.Node) !void {
|
||||
// This is needed before reading the error flags.
|
||||
comp.bin_file.flush(comp, prog_node) catch |err| switch (err) {
|
||||
error.FlushFailure => {}, // error reported through link_error_flags
|
||||
error.LLDReportedFailure => {}, // error reported via lockAndParseLldStderr
|
||||
else => |e| return e,
|
||||
};
|
||||
comp.link_error_flags = comp.bin_file.errorFlags();
|
||||
if (comp.bin_file) |lf| {
|
||||
// This is needed before reading the error flags.
|
||||
lf.flush(comp, prog_node) catch |err| switch (err) {
|
||||
error.FlushFailure => {}, // error reported through link_error_flags
|
||||
error.LLDReportedFailure => {}, // error reported via lockAndParseLldStderr
|
||||
else => |e| return e,
|
||||
};
|
||||
comp.link_error_flags = lf.error_flags;
|
||||
}
|
||||
|
||||
if (comp.module) |module| {
|
||||
try link.File.C.flushEmitH(module);
|
||||
@ -2445,9 +2469,9 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
|
||||
.wasm => {
|
||||
const wasm = lf.cast(link.File.Wasm).?;
|
||||
man.hash.add(wasm.rdynamic);
|
||||
man.hash.add(wasm.initial_memory);
|
||||
man.hash.add(wasm.max_memory);
|
||||
man.hash.add(wasm.global_base);
|
||||
man.hash.addOptional(wasm.initial_memory);
|
||||
man.hash.addOptional(wasm.max_memory);
|
||||
man.hash.addOptional(wasm.global_base);
|
||||
},
|
||||
.macho => {
|
||||
const macho = lf.cast(link.File.MachO).?;
|
||||
@ -2626,12 +2650,14 @@ fn reportMultiModuleErrors(mod: *Module) !void {
|
||||
/// binary is concerned. This will remove the write flag, or close the file,
|
||||
/// or whatever is needed so that it can be executed.
|
||||
/// After this, one must call` makeFileWritable` before calling `update`.
|
||||
pub fn makeBinFileExecutable(self: *Compilation) !void {
|
||||
return self.bin_file.makeExecutable();
|
||||
pub fn makeBinFileExecutable(comp: *Compilation) !void {
|
||||
const lf = comp.bin_file orelse return;
|
||||
return lf.makeExecutable();
|
||||
}
|
||||
|
||||
pub fn makeBinFileWritable(self: *Compilation) !void {
|
||||
return self.bin_file.makeWritable();
|
||||
pub fn makeBinFileWritable(comp: *Compilation) !void {
|
||||
const lf = comp.bin_file orelse return;
|
||||
return lf.makeWritable();
|
||||
}
|
||||
|
||||
const Header = extern struct {
|
||||
@ -2764,8 +2790,9 @@ pub fn totalErrorCount(self: *Compilation) u32 {
|
||||
}
|
||||
total += @intFromBool(self.link_error_flags.missing_libc);
|
||||
|
||||
// Misc linker errors
|
||||
total += self.bin_file.miscErrors().len;
|
||||
if (self.bin_file) |lf| {
|
||||
total += lf.misc_errors.items.len;
|
||||
}
|
||||
|
||||
// Compile log errors only count if there are no other errors.
|
||||
if (total == 0) {
|
||||
@ -2914,7 +2941,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
|
||||
}));
|
||||
}
|
||||
|
||||
for (self.bin_file.miscErrors()) |link_err| {
|
||||
if (self.bin_file) |lf| for (lf.misc_errors.items) |link_err| {
|
||||
try bundle.addRootErrorMessage(.{
|
||||
.msg = try bundle.addString(link_err.msg),
|
||||
.notes_len = @intCast(link_err.notes.len),
|
||||
@ -2925,7 +2952,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
|
||||
.msg = try bundle.addString(note.msg),
|
||||
}));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (self.module) |module| {
|
||||
if (bundle.root_list.items.len == 0 and module.compile_log_decls.count() != 0) {
|
||||
@ -3246,12 +3273,12 @@ pub fn performAllTheWork(
|
||||
// TODO put all the modules in a flat array to make them easy to iterate.
|
||||
var seen: std.AutoArrayHashMapUnmanaged(*Package.Module, void) = .{};
|
||||
defer seen.deinit(comp.gpa);
|
||||
try seen.put(comp.gpa, comp.root_mod);
|
||||
try seen.put(comp.gpa, comp.root_mod, {});
|
||||
var i: usize = 0;
|
||||
while (i < seen.count()) : (i += 1) {
|
||||
const mod = seen.keys()[i];
|
||||
for (mod.deps.values()) |dep|
|
||||
try seen.put(comp.gpa, dep);
|
||||
try seen.put(comp.gpa, dep, {});
|
||||
|
||||
const file = mod.builtin_file orelse continue;
|
||||
|
||||
@ -3459,7 +3486,8 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v
|
||||
const gpa = comp.gpa;
|
||||
const module = comp.module.?;
|
||||
const decl = module.declPtr(decl_index);
|
||||
comp.bin_file.updateDeclLineNumber(module, decl_index) catch |err| {
|
||||
const lf = comp.bin_file.?;
|
||||
lf.updateDeclLineNumber(module, decl_index) catch |err| {
|
||||
try module.failed_decls.ensureUnusedCapacity(gpa, 1);
|
||||
module.failed_decls.putAssumeCapacityNoClobber(decl_index, try Module.ErrorMsg.create(
|
||||
gpa,
|
||||
@ -3782,7 +3810,7 @@ pub fn obtainCObjectCacheManifest(
|
||||
// that apply both to @cImport and compiling C objects. No linking stuff here!
|
||||
// Also nothing that applies only to compiling .zig code.
|
||||
man.hash.add(owner_mod.sanitize_c);
|
||||
man.hash.addListOfBytes(owner_mod.clang_argv);
|
||||
man.hash.addListOfBytes(owner_mod.cc_argv);
|
||||
man.hash.add(comp.config.link_libcpp);
|
||||
|
||||
// When libc_installation is null it means that Zig generated this dir list
|
||||
@ -6099,7 +6127,8 @@ fn buildOutputFromZig(
|
||||
const tracy_trace = trace(@src());
|
||||
defer tracy_trace.end();
|
||||
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
|
||||
const gpa = comp.gpa;
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(gpa);
|
||||
defer arena_allocator.deinit();
|
||||
const arena = arena_allocator.allocator();
|
||||
|
||||
@ -6110,6 +6139,7 @@ fn buildOutputFromZig(
|
||||
|
||||
const config = try Config.resolve(.{
|
||||
.output_mode = output_mode,
|
||||
.link_mode = .Static,
|
||||
.resolved_target = comp.root_mod.resolved_target,
|
||||
.is_test = false,
|
||||
.have_zcu = true,
|
||||
@ -6120,7 +6150,8 @@ fn buildOutputFromZig(
|
||||
.any_unwind_tables = unwind_tables,
|
||||
});
|
||||
|
||||
const root_mod = Package.Module.create(.{
|
||||
const root_mod = try Package.Module.create(arena, .{
|
||||
.global_cache_directory = comp.global_cache_directory,
|
||||
.paths = .{
|
||||
.root = .{ .root_dir = comp.zig_lib_directory },
|
||||
.root_src_path = src_basename,
|
||||
@ -6139,6 +6170,8 @@ fn buildOutputFromZig(
|
||||
},
|
||||
.global = config,
|
||||
.cc_argv = &.{},
|
||||
.parent = null,
|
||||
.builtin_mod = null,
|
||||
});
|
||||
const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len];
|
||||
const target = comp.getTarget();
|
||||
@ -6148,23 +6181,21 @@ fn buildOutputFromZig(
|
||||
.output_mode = output_mode,
|
||||
});
|
||||
|
||||
const emit_bin = Compilation.EmitLoc{
|
||||
.directory = null, // Put it in the cache directory.
|
||||
.basename = bin_basename,
|
||||
};
|
||||
const sub_compilation = try Compilation.create(comp.gpa, .{
|
||||
const sub_compilation = try Compilation.create(gpa, .{
|
||||
.global_cache_directory = comp.global_cache_directory,
|
||||
.local_cache_directory = comp.global_cache_directory,
|
||||
.zig_lib_directory = comp.zig_lib_directory,
|
||||
.self_exe_path = comp.self_exe_path,
|
||||
.resolved = config,
|
||||
.config = config,
|
||||
.root_mod = root_mod,
|
||||
.cache_mode = .whole,
|
||||
.root_name = root_name,
|
||||
.thread_pool = comp.thread_pool,
|
||||
.libc_installation = comp.libc_installation,
|
||||
.emit_bin = emit_bin,
|
||||
.link_mode = .Static,
|
||||
.emit_bin = .{
|
||||
.directory = null, // Put it in the cache directory.
|
||||
.basename = bin_basename,
|
||||
},
|
||||
.function_sections = true,
|
||||
.data_sections = true,
|
||||
.no_builtin = true,
|
||||
@ -6186,8 +6217,8 @@ fn buildOutputFromZig(
|
||||
try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node);
|
||||
|
||||
assert(out.* == null);
|
||||
out.* = Compilation.CRTFile{
|
||||
.full_object_path = try sub_compilation.bin_file.?.emit.directory.join(comp.gpa, &[_][]const u8{
|
||||
out.* = .{
|
||||
.full_object_path = try sub_compilation.bin_file.?.emit.directory.join(gpa, &.{
|
||||
sub_compilation.bin_file.?.emit.sub_path,
|
||||
}),
|
||||
.lock = sub_compilation.bin_file.toOwnedLock(),
|
||||
@ -6206,12 +6237,15 @@ pub fn build_crt_file(
|
||||
defer tracy_trace.end();
|
||||
|
||||
const gpa = comp.gpa;
|
||||
const basename = try std.zig.binNameAlloc(gpa, .{
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(gpa);
|
||||
defer arena_allocator.deinit();
|
||||
const arena = arena_allocator.allocator();
|
||||
|
||||
const basename = try std.zig.binNameAlloc(arena, .{
|
||||
.root_name = root_name,
|
||||
.target = comp.root_mod.resolved_target.result,
|
||||
.output_mode = output_mode,
|
||||
});
|
||||
errdefer gpa.free(basename);
|
||||
|
||||
const config = try Config.resolve(.{
|
||||
.output_mode = output_mode,
|
||||
@ -6227,7 +6261,8 @@ pub fn build_crt_file(
|
||||
.Obj, .Exe => false,
|
||||
},
|
||||
});
|
||||
const root_mod = Package.Module.create(.{
|
||||
const root_mod = try Package.Module.create(arena, .{
|
||||
.global_cache_directory = comp.global_cache_directory,
|
||||
.paths = .{
|
||||
.root = .{ .root_dir = comp.zig_lib_directory },
|
||||
.root_src_path = "",
|
||||
@ -6249,6 +6284,8 @@ pub fn build_crt_file(
|
||||
},
|
||||
.global = config,
|
||||
.cc_argv = &.{},
|
||||
.parent = null,
|
||||
.builtin_mod = null,
|
||||
});
|
||||
|
||||
const sub_compilation = try Compilation.create(gpa, .{
|
||||
@ -6257,7 +6294,7 @@ pub fn build_crt_file(
|
||||
.zig_lib_directory = comp.zig_lib_directory,
|
||||
.self_exe_path = comp.self_exe_path,
|
||||
.cache_mode = .whole,
|
||||
.resolved = config,
|
||||
.config = config,
|
||||
.root_mod = root_mod,
|
||||
.root_name = root_name,
|
||||
.thread_pool = comp.thread_pool,
|
||||
@ -6287,7 +6324,7 @@ pub fn build_crt_file(
|
||||
try comp.crt_files.ensureUnusedCapacity(gpa, 1);
|
||||
|
||||
comp.crt_files.putAssumeCapacityNoClobber(basename, .{
|
||||
.full_object_path = try sub_compilation.bin_file.?.emit.directory.join(gpa, &[_][]const u8{
|
||||
.full_object_path = try sub_compilation.bin_file.?.emit.directory.join(gpa, &.{
|
||||
sub_compilation.bin_file.?.emit.sub_path,
|
||||
}),
|
||||
.lock = sub_compilation.bin_file.toOwnedLock(),
|
||||
|
||||
127
src/Module.zig
127
src/Module.zig
@ -619,7 +619,7 @@ pub const Decl = struct {
|
||||
// Sanitize the name for nvptx which is more restrictive.
|
||||
// TODO This should be handled by the backend, not the frontend. Have a
|
||||
// look at how the C backend does it for inspiration.
|
||||
const cpu_arch = mod.root_mod.resolved_target.cpu.arch;
|
||||
const cpu_arch = mod.root_mod.resolved_target.result.cpu.arch;
|
||||
if (cpu_arch.isNvptx()) {
|
||||
for (ip.string_bytes.items[start..]) |*byte| switch (byte.*) {
|
||||
'{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',
|
||||
@ -3313,7 +3313,8 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func_index: InternPool.Index) SemaEr
|
||||
|
||||
if (no_bin_file and !dump_llvm_ir) return;
|
||||
|
||||
comp.bin_file.updateFunc(mod, func_index, air, liveness) catch |err| switch (err) {
|
||||
const lf = comp.bin_file.?;
|
||||
lf.updateFunc(mod, func_index, air, liveness) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.AnalysisFail => {
|
||||
decl.analysis = .codegen_failure;
|
||||
@ -3488,25 +3489,29 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
|
||||
new_decl.owns_tv = true;
|
||||
new_decl.analysis = .complete;
|
||||
|
||||
if (mod.comp.whole_cache_manifest) |whole_cache_manifest| {
|
||||
const source = file.getSource(gpa) catch |err| {
|
||||
try reportRetryableFileError(mod, file, "unable to load source: {s}", .{@errorName(err)});
|
||||
return error.AnalysisFail;
|
||||
};
|
||||
const comp = mod.comp;
|
||||
switch (comp.cache_use) {
|
||||
.whole => |whole| if (whole.cache_manifest) |man| {
|
||||
const source = file.getSource(gpa) catch |err| {
|
||||
try reportRetryableFileError(mod, file, "unable to load source: {s}", .{@errorName(err)});
|
||||
return error.AnalysisFail;
|
||||
};
|
||||
|
||||
const resolved_path = std.fs.path.resolve(gpa, &.{
|
||||
file.mod.root.root_dir.path orelse ".",
|
||||
file.mod.root.sub_path,
|
||||
file.sub_file_path,
|
||||
}) catch |err| {
|
||||
try reportRetryableFileError(mod, file, "unable to resolve path: {s}", .{@errorName(err)});
|
||||
return error.AnalysisFail;
|
||||
};
|
||||
errdefer gpa.free(resolved_path);
|
||||
const resolved_path = std.fs.path.resolve(gpa, &.{
|
||||
file.mod.root.root_dir.path orelse ".",
|
||||
file.mod.root.sub_path,
|
||||
file.sub_file_path,
|
||||
}) catch |err| {
|
||||
try reportRetryableFileError(mod, file, "unable to resolve path: {s}", .{@errorName(err)});
|
||||
return error.AnalysisFail;
|
||||
};
|
||||
errdefer gpa.free(resolved_path);
|
||||
|
||||
mod.comp.whole_cache_manifest_mutex.lock();
|
||||
defer mod.comp.whole_cache_manifest_mutex.unlock();
|
||||
try whole_cache_manifest.addFilePostContents(resolved_path, source.bytes, source.stat);
|
||||
whole.cache_manifest_mutex.lock();
|
||||
defer whole.cache_manifest_mutex.unlock();
|
||||
try man.addFilePostContents(resolved_path, source.bytes, source.stat);
|
||||
},
|
||||
.incremental => {},
|
||||
}
|
||||
}
|
||||
|
||||
@ -4045,12 +4050,16 @@ fn newEmbedFile(
|
||||
const actual_read = try file.readAll(ptr);
|
||||
if (actual_read != size) return error.UnexpectedEndOfFile;
|
||||
|
||||
if (mod.comp.whole_cache_manifest) |whole_cache_manifest| {
|
||||
const copied_resolved_path = try gpa.dupe(u8, resolved_path);
|
||||
errdefer gpa.free(copied_resolved_path);
|
||||
mod.comp.whole_cache_manifest_mutex.lock();
|
||||
defer mod.comp.whole_cache_manifest_mutex.unlock();
|
||||
try whole_cache_manifest.addFilePostContents(copied_resolved_path, ptr, stat);
|
||||
const comp = mod.comp;
|
||||
switch (comp.cache_use) {
|
||||
.whole => |whole| if (whole.cache_manifest) |man| {
|
||||
const copied_resolved_path = try gpa.dupe(u8, resolved_path);
|
||||
errdefer gpa.free(copied_resolved_path);
|
||||
whole.cache_manifest_mutex.lock();
|
||||
defer whole.cache_manifest_mutex.unlock();
|
||||
try man.addFilePostContents(copied_resolved_path, ptr, stat);
|
||||
},
|
||||
.incremental => {},
|
||||
}
|
||||
|
||||
const array_ty = try ip.get(gpa, .{ .array_type = .{
|
||||
@ -4393,7 +4402,9 @@ fn deleteDeclExports(mod: *Module, decl_index: Decl.Index) Allocator.Error!void
|
||||
}
|
||||
},
|
||||
}
|
||||
try mod.comp.bin_file.deleteDeclExport(decl_index, exp.opts.name);
|
||||
if (mod.comp.bin_file) |lf| {
|
||||
try lf.deleteDeclExport(decl_index, exp.opts.name);
|
||||
}
|
||||
if (mod.failed_exports.fetchSwapRemove(exp)) |failed_kv| {
|
||||
failed_kv.value.destroy(mod.gpa);
|
||||
}
|
||||
@ -5247,7 +5258,8 @@ fn processExportsInner(
|
||||
gop.value_ptr.* = new_export;
|
||||
}
|
||||
}
|
||||
mod.comp.bin_file.updateExports(mod, exported, exports) catch |err| switch (err) {
|
||||
const lf = mod.comp.bin_file orelse return;
|
||||
lf.updateExports(mod, exported, exports) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
else => {
|
||||
const new_export = exports[0];
|
||||
@ -5403,36 +5415,39 @@ pub fn populateTestFunctions(
|
||||
pub fn linkerUpdateDecl(mod: *Module, decl_index: Decl.Index) !void {
|
||||
const comp = mod.comp;
|
||||
|
||||
const no_bin_file = (comp.bin_file == null and
|
||||
comp.emit_asm == null and
|
||||
comp.emit_llvm_ir == null and
|
||||
comp.emit_llvm_bc == null);
|
||||
if (comp.bin_file) |lf| {
|
||||
const decl = mod.declPtr(decl_index);
|
||||
lf.updateDecl(mod, decl_index) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.AnalysisFail => {
|
||||
decl.analysis = .codegen_failure;
|
||||
return;
|
||||
},
|
||||
else => {
|
||||
const gpa = mod.gpa;
|
||||
try mod.failed_decls.ensureUnusedCapacity(gpa, 1);
|
||||
mod.failed_decls.putAssumeCapacityNoClobber(decl_index, try ErrorMsg.create(
|
||||
gpa,
|
||||
decl.srcLoc(mod),
|
||||
"unable to codegen: {s}",
|
||||
.{@errorName(err)},
|
||||
));
|
||||
decl.analysis = .codegen_failure_retryable;
|
||||
return;
|
||||
},
|
||||
};
|
||||
} else {
|
||||
const dump_llvm_ir = builtin.mode == .Debug and
|
||||
(comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null);
|
||||
|
||||
const dump_llvm_ir = builtin.mode == .Debug and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null);
|
||||
|
||||
if (no_bin_file and !dump_llvm_ir) return;
|
||||
|
||||
const decl = mod.declPtr(decl_index);
|
||||
|
||||
comp.bin_file.updateDecl(mod, decl_index) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.AnalysisFail => {
|
||||
decl.analysis = .codegen_failure;
|
||||
return;
|
||||
},
|
||||
else => {
|
||||
const gpa = mod.gpa;
|
||||
try mod.failed_decls.ensureUnusedCapacity(gpa, 1);
|
||||
mod.failed_decls.putAssumeCapacityNoClobber(decl_index, try ErrorMsg.create(
|
||||
gpa,
|
||||
decl.srcLoc(mod),
|
||||
"unable to codegen: {s}",
|
||||
.{@errorName(err)},
|
||||
));
|
||||
decl.analysis = .codegen_failure_retryable;
|
||||
return;
|
||||
},
|
||||
};
|
||||
if (comp.emit_asm != null or
|
||||
comp.emit_llvm_ir != null or
|
||||
comp.emit_llvm_bc != null or
|
||||
dump_llvm_ir)
|
||||
{
|
||||
@panic("TODO handle emit_asm, emit_llvm_ir, and emit_llvm_bc along with -fno-emit-bin");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn reportRetryableFileError(
|
||||
|
||||
@ -344,7 +344,7 @@ pub fn generate(
|
||||
assert(fn_owner_decl.has_tv);
|
||||
const fn_type = fn_owner_decl.ty;
|
||||
const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
|
||||
const target = &namespace.file_scope.mod.target;
|
||||
const target = &namespace.file_scope.mod.resolved_target.result;
|
||||
|
||||
var branch_stack = std.ArrayList(Branch).init(gpa);
|
||||
defer {
|
||||
@ -6343,14 +6343,14 @@ fn wantSafety(self: *Self) bool {
|
||||
fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
|
||||
@setCold(true);
|
||||
assert(self.err_msg == null);
|
||||
self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args);
|
||||
self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args);
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError {
|
||||
@setCold(true);
|
||||
assert(self.err_msg == null);
|
||||
self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args);
|
||||
self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args);
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
|
||||
@ -218,14 +218,16 @@ pub fn emitMir(
|
||||
}
|
||||
|
||||
pub fn deinit(emit: *Emit) void {
|
||||
const comp = emit.bin_file.comp;
|
||||
const gpa = comp.gpa;
|
||||
var iter = emit.branch_forward_origins.valueIterator();
|
||||
while (iter.next()) |origin_list| {
|
||||
origin_list.deinit(emit.bin_file.allocator);
|
||||
origin_list.deinit(gpa);
|
||||
}
|
||||
|
||||
emit.branch_types.deinit(emit.bin_file.allocator);
|
||||
emit.branch_forward_origins.deinit(emit.bin_file.allocator);
|
||||
emit.code_offset_mapping.deinit(emit.bin_file.allocator);
|
||||
emit.branch_types.deinit(gpa);
|
||||
emit.branch_forward_origins.deinit(gpa);
|
||||
emit.code_offset_mapping.deinit(gpa);
|
||||
emit.* = undefined;
|
||||
}
|
||||
|
||||
@ -314,8 +316,9 @@ fn branchTarget(emit: *Emit, inst: Mir.Inst.Index) Mir.Inst.Index {
|
||||
}
|
||||
|
||||
fn lowerBranches(emit: *Emit) !void {
|
||||
const comp = emit.bin_file.comp;
|
||||
const gpa = comp.gpa;
|
||||
const mir_tags = emit.mir.instructions.items(.tag);
|
||||
const allocator = emit.bin_file.allocator;
|
||||
|
||||
// First pass: Note down all branches and their target
|
||||
// instructions, i.e. populate branch_types,
|
||||
@ -329,7 +332,7 @@ fn lowerBranches(emit: *Emit) !void {
|
||||
const target_inst = emit.branchTarget(inst);
|
||||
|
||||
// Remember this branch instruction
|
||||
try emit.branch_types.put(allocator, inst, BranchType.default(tag));
|
||||
try emit.branch_types.put(gpa, inst, BranchType.default(tag));
|
||||
|
||||
// Forward branches require some extra stuff: We only
|
||||
// know their offset once we arrive at the target
|
||||
@ -339,14 +342,14 @@ fn lowerBranches(emit: *Emit) !void {
|
||||
// etc.
|
||||
if (target_inst > inst) {
|
||||
// Remember the branch instruction index
|
||||
try emit.code_offset_mapping.put(allocator, inst, 0);
|
||||
try emit.code_offset_mapping.put(gpa, inst, 0);
|
||||
|
||||
if (emit.branch_forward_origins.getPtr(target_inst)) |origin_list| {
|
||||
try origin_list.append(allocator, inst);
|
||||
try origin_list.append(gpa, inst);
|
||||
} else {
|
||||
var origin_list: std.ArrayListUnmanaged(Mir.Inst.Index) = .{};
|
||||
try origin_list.append(allocator, inst);
|
||||
try emit.branch_forward_origins.put(allocator, target_inst, origin_list);
|
||||
try origin_list.append(gpa, inst);
|
||||
try emit.branch_forward_origins.put(gpa, target_inst, origin_list);
|
||||
}
|
||||
}
|
||||
|
||||
@ -356,7 +359,7 @@ fn lowerBranches(emit: *Emit) !void {
|
||||
// putNoClobber may not be used as the put operation
|
||||
// may clobber the entry when multiple branches branch
|
||||
// to the same target instruction
|
||||
try emit.code_offset_mapping.put(allocator, target_inst, 0);
|
||||
try emit.code_offset_mapping.put(gpa, target_inst, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -429,7 +432,9 @@ fn writeInstruction(emit: *Emit, instruction: Instruction) !void {
|
||||
fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
|
||||
@setCold(true);
|
||||
assert(emit.err_msg == null);
|
||||
emit.err_msg = try ErrorMsg.create(emit.bin_file.allocator, emit.src_loc, format, args);
|
||||
const comp = emit.bin_file.comp;
|
||||
const gpa = comp.gpa;
|
||||
emit.err_msg = try ErrorMsg.create(gpa, emit.src_loc, format, args);
|
||||
return error.EmitFail;
|
||||
}
|
||||
|
||||
|
||||
@ -351,7 +351,7 @@ pub fn generate(
|
||||
assert(fn_owner_decl.has_tv);
|
||||
const fn_type = fn_owner_decl.ty;
|
||||
const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
|
||||
const target = &namespace.file_scope.mod.target;
|
||||
const target = &namespace.file_scope.mod.resolved_target.result;
|
||||
|
||||
var branch_stack = std.ArrayList(Branch).init(gpa);
|
||||
defer {
|
||||
@ -6292,14 +6292,16 @@ fn wantSafety(self: *Self) bool {
|
||||
fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
|
||||
@setCold(true);
|
||||
assert(self.err_msg == null);
|
||||
self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args);
|
||||
const gpa = self.gpa;
|
||||
self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError {
|
||||
@setCold(true);
|
||||
assert(self.err_msg == null);
|
||||
self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args);
|
||||
const gpa = self.gpa;
|
||||
self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
|
||||
@ -152,14 +152,17 @@ pub fn emitMir(
|
||||
}
|
||||
|
||||
pub fn deinit(emit: *Emit) void {
|
||||
const comp = emit.bin_file.comp;
|
||||
const gpa = comp.gpa;
|
||||
|
||||
var iter = emit.branch_forward_origins.valueIterator();
|
||||
while (iter.next()) |origin_list| {
|
||||
origin_list.deinit(emit.bin_file.allocator);
|
||||
origin_list.deinit(gpa);
|
||||
}
|
||||
|
||||
emit.branch_types.deinit(emit.bin_file.allocator);
|
||||
emit.branch_forward_origins.deinit(emit.bin_file.allocator);
|
||||
emit.code_offset_mapping.deinit(emit.bin_file.allocator);
|
||||
emit.branch_types.deinit(gpa);
|
||||
emit.branch_forward_origins.deinit(gpa);
|
||||
emit.code_offset_mapping.deinit(gpa);
|
||||
emit.* = undefined;
|
||||
}
|
||||
|
||||
@ -231,8 +234,9 @@ fn branchTarget(emit: *Emit, inst: Mir.Inst.Index) Mir.Inst.Index {
|
||||
}
|
||||
|
||||
fn lowerBranches(emit: *Emit) !void {
|
||||
const comp = emit.bin_file.comp;
|
||||
const gpa = comp.gpa;
|
||||
const mir_tags = emit.mir.instructions.items(.tag);
|
||||
const allocator = emit.bin_file.allocator;
|
||||
|
||||
// First pass: Note down all branches and their target
|
||||
// instructions, i.e. populate branch_types,
|
||||
@ -246,7 +250,7 @@ fn lowerBranches(emit: *Emit) !void {
|
||||
const target_inst = emit.branchTarget(inst);
|
||||
|
||||
// Remember this branch instruction
|
||||
try emit.branch_types.put(allocator, inst, BranchType.default(tag));
|
||||
try emit.branch_types.put(gpa, inst, BranchType.default(tag));
|
||||
|
||||
// Forward branches require some extra stuff: We only
|
||||
// know their offset once we arrive at the target
|
||||
@ -256,14 +260,14 @@ fn lowerBranches(emit: *Emit) !void {
|
||||
// etc.
|
||||
if (target_inst > inst) {
|
||||
// Remember the branch instruction index
|
||||
try emit.code_offset_mapping.put(allocator, inst, 0);
|
||||
try emit.code_offset_mapping.put(gpa, inst, 0);
|
||||
|
||||
if (emit.branch_forward_origins.getPtr(target_inst)) |origin_list| {
|
||||
try origin_list.append(allocator, inst);
|
||||
try origin_list.append(gpa, inst);
|
||||
} else {
|
||||
var origin_list: std.ArrayListUnmanaged(Mir.Inst.Index) = .{};
|
||||
try origin_list.append(allocator, inst);
|
||||
try emit.branch_forward_origins.put(allocator, target_inst, origin_list);
|
||||
try origin_list.append(gpa, inst);
|
||||
try emit.branch_forward_origins.put(gpa, target_inst, origin_list);
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,7 +277,7 @@ fn lowerBranches(emit: *Emit) !void {
|
||||
// putNoClobber may not be used as the put operation
|
||||
// may clobber the entry when multiple branches branch
|
||||
// to the same target instruction
|
||||
try emit.code_offset_mapping.put(allocator, target_inst, 0);
|
||||
try emit.code_offset_mapping.put(gpa, target_inst, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -346,7 +350,9 @@ fn writeInstruction(emit: *Emit, instruction: Instruction) !void {
|
||||
fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
|
||||
@setCold(true);
|
||||
assert(emit.err_msg == null);
|
||||
emit.err_msg = try ErrorMsg.create(emit.bin_file.allocator, emit.src_loc, format, args);
|
||||
const comp = emit.bin_file.comp;
|
||||
const gpa = comp.gpa;
|
||||
emit.err_msg = try ErrorMsg.create(gpa, emit.src_loc, format, args);
|
||||
return error.EmitFail;
|
||||
}
|
||||
|
||||
|
||||
@ -232,7 +232,7 @@ pub fn generate(
|
||||
assert(fn_owner_decl.has_tv);
|
||||
const fn_type = fn_owner_decl.ty;
|
||||
const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
|
||||
const target = &namespace.file_scope.mod.target;
|
||||
const target = &namespace.file_scope.mod.resolved_target.result;
|
||||
|
||||
var branch_stack = std.ArrayList(Branch).init(gpa);
|
||||
defer {
|
||||
@ -2719,14 +2719,14 @@ fn wantSafety(self: *Self) bool {
|
||||
fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
|
||||
@setCold(true);
|
||||
assert(self.err_msg == null);
|
||||
self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args);
|
||||
self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args);
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError {
|
||||
@setCold(true);
|
||||
assert(self.err_msg == null);
|
||||
self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args);
|
||||
self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args);
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
|
||||
@ -80,7 +80,9 @@ fn writeInstruction(emit: *Emit, instruction: Instruction) !void {
|
||||
fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
|
||||
@setCold(true);
|
||||
assert(emit.err_msg == null);
|
||||
emit.err_msg = try ErrorMsg.create(emit.bin_file.allocator, emit.src_loc, format, args);
|
||||
const comp = emit.bin_file.comp;
|
||||
const gpa = comp.gpa;
|
||||
emit.err_msg = try ErrorMsg.create(gpa, emit.src_loc, format, args);
|
||||
return error.EmitFail;
|
||||
}
|
||||
|
||||
|
||||
@ -275,7 +275,7 @@ pub fn generate(
|
||||
assert(fn_owner_decl.has_tv);
|
||||
const fn_type = fn_owner_decl.ty;
|
||||
const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
|
||||
const target = &namespace.file_scope.mod.target;
|
||||
const target = &namespace.file_scope.mod.resolved_target.result;
|
||||
|
||||
var branch_stack = std.ArrayList(Branch).init(gpa);
|
||||
defer {
|
||||
@ -3546,7 +3546,8 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type)
|
||||
fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
|
||||
@setCold(true);
|
||||
assert(self.err_msg == null);
|
||||
self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args);
|
||||
const gpa = self.gpa;
|
||||
self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
|
||||
@ -152,14 +152,16 @@ pub fn emitMir(
|
||||
}
|
||||
|
||||
pub fn deinit(emit: *Emit) void {
|
||||
const comp = emit.bin_file.comp;
|
||||
const gpa = comp.gpa;
|
||||
var iter = emit.branch_forward_origins.valueIterator();
|
||||
while (iter.next()) |origin_list| {
|
||||
origin_list.deinit(emit.bin_file.allocator);
|
||||
origin_list.deinit(gpa);
|
||||
}
|
||||
|
||||
emit.branch_types.deinit(emit.bin_file.allocator);
|
||||
emit.branch_forward_origins.deinit(emit.bin_file.allocator);
|
||||
emit.code_offset_mapping.deinit(emit.bin_file.allocator);
|
||||
emit.branch_types.deinit(gpa);
|
||||
emit.branch_forward_origins.deinit(gpa);
|
||||
emit.code_offset_mapping.deinit(gpa);
|
||||
emit.* = undefined;
|
||||
}
|
||||
|
||||
@ -511,7 +513,9 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) !void {
|
||||
fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
|
||||
@setCold(true);
|
||||
assert(emit.err_msg == null);
|
||||
emit.err_msg = try ErrorMsg.create(emit.bin_file.allocator, emit.src_loc, format, args);
|
||||
const comp = emit.bin_file.comp;
|
||||
const gpa = comp.gpa;
|
||||
emit.err_msg = try ErrorMsg.create(gpa, emit.src_loc, format, args);
|
||||
return error.EmitFail;
|
||||
}
|
||||
|
||||
@ -537,8 +541,9 @@ fn isBranch(tag: Mir.Inst.Tag) bool {
|
||||
}
|
||||
|
||||
fn lowerBranches(emit: *Emit) !void {
|
||||
const comp = emit.bin_file.comp;
|
||||
const gpa = comp.gpa;
|
||||
const mir_tags = emit.mir.instructions.items(.tag);
|
||||
const allocator = emit.bin_file.allocator;
|
||||
|
||||
// First pass: Note down all branches and their target
|
||||
// instructions, i.e. populate branch_types,
|
||||
@ -552,7 +557,7 @@ fn lowerBranches(emit: *Emit) !void {
|
||||
const target_inst = emit.branchTarget(inst);
|
||||
|
||||
// Remember this branch instruction
|
||||
try emit.branch_types.put(allocator, inst, BranchType.default(tag));
|
||||
try emit.branch_types.put(gpa, inst, BranchType.default(tag));
|
||||
|
||||
// Forward branches require some extra stuff: We only
|
||||
// know their offset once we arrive at the target
|
||||
@ -562,14 +567,14 @@ fn lowerBranches(emit: *Emit) !void {
|
||||
// etc.
|
||||
if (target_inst > inst) {
|
||||
// Remember the branch instruction index
|
||||
try emit.code_offset_mapping.put(allocator, inst, 0);
|
||||
try emit.code_offset_mapping.put(gpa, inst, 0);
|
||||
|
||||
if (emit.branch_forward_origins.getPtr(target_inst)) |origin_list| {
|
||||
try origin_list.append(allocator, inst);
|
||||
try origin_list.append(gpa, inst);
|
||||
} else {
|
||||
var origin_list: std.ArrayListUnmanaged(Mir.Inst.Index) = .{};
|
||||
try origin_list.append(allocator, inst);
|
||||
try emit.branch_forward_origins.put(allocator, target_inst, origin_list);
|
||||
try origin_list.append(gpa, inst);
|
||||
try emit.branch_forward_origins.put(gpa, target_inst, origin_list);
|
||||
}
|
||||
}
|
||||
|
||||
@ -579,7 +584,7 @@ fn lowerBranches(emit: *Emit) !void {
|
||||
// putNoClobber may not be used as the put operation
|
||||
// may clobber the entry when multiple branches branch
|
||||
// to the same target instruction
|
||||
try emit.code_offset_mapping.put(allocator, target_inst, 0);
|
||||
try emit.code_offset_mapping.put(gpa, target_inst, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1210,13 +1210,15 @@ pub fn generate(
|
||||
debug_output: codegen.DebugInfoOutput,
|
||||
) codegen.CodeGenError!codegen.Result {
|
||||
_ = src_loc;
|
||||
const mod = bin_file.comp.module.?;
|
||||
const comp = bin_file.comp;
|
||||
const gpa = comp.gpa;
|
||||
const mod = comp.module.?;
|
||||
const func = mod.funcInfo(func_index);
|
||||
const decl = mod.declPtr(func.owner_decl);
|
||||
const namespace = mod.namespacePtr(decl.src_namespace);
|
||||
const target = namespace.file_scope.mod.target;
|
||||
const target = namespace.file_scope.mod.resolved_target.result;
|
||||
var code_gen: CodeGen = .{
|
||||
.gpa = bin_file.allocator,
|
||||
.gpa = gpa,
|
||||
.air = air,
|
||||
.liveness = liveness,
|
||||
.code = code,
|
||||
@ -7731,7 +7733,7 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
||||
// Only when the atomic feature is enabled, and we're not building
|
||||
// for a single-threaded build, can we emit the `fence` instruction.
|
||||
// In all other cases, we emit no instructions for a fence.
|
||||
const func_namespace = zcu.namespacePtr(zcu.declPtr(func.decl).namespace);
|
||||
const func_namespace = zcu.namespacePtr(func.decl.src_namespace);
|
||||
const single_threaded = func_namespace.file_scope.mod.single_threaded;
|
||||
if (func.useAtomicFeature() and !single_threaded) {
|
||||
try func.addAtomicTag(.atomic_fence);
|
||||
|
||||
@ -254,8 +254,10 @@ fn offset(self: Emit) u32 {
|
||||
fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
|
||||
@setCold(true);
|
||||
std.debug.assert(emit.error_msg == null);
|
||||
const mod = emit.bin_file.base.comp.module.?;
|
||||
emit.error_msg = try Module.ErrorMsg.create(emit.bin_file.base.allocator, mod.declPtr(emit.decl_index).srcLoc(mod), format, args);
|
||||
const comp = emit.bin_file.base.comp;
|
||||
const zcu = comp.module.?;
|
||||
const gpa = comp.gpa;
|
||||
emit.error_msg = try Module.ErrorMsg.create(gpa, zcu.declPtr(emit.decl_index).srcLoc(zcu), format, args);
|
||||
return error.EmitFail;
|
||||
}
|
||||
|
||||
@ -299,6 +301,8 @@ fn emitLabel(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) !void {
|
||||
}
|
||||
|
||||
fn emitGlobal(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) !void {
|
||||
const comp = emit.bin_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const label = emit.mir.instructions.items(.data)[inst].label;
|
||||
try emit.code.append(@intFromEnum(tag));
|
||||
var buf: [5]u8 = undefined;
|
||||
@ -308,7 +312,7 @@ fn emitGlobal(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) !void {
|
||||
|
||||
const atom_index = emit.bin_file.decls.get(emit.decl_index).?;
|
||||
const atom = emit.bin_file.getAtomPtr(atom_index);
|
||||
try atom.relocs.append(emit.bin_file.base.allocator, .{
|
||||
try atom.relocs.append(gpa, .{
|
||||
.index = label,
|
||||
.offset = global_offset,
|
||||
.relocation_type = .R_WASM_GLOBAL_INDEX_LEB,
|
||||
@ -356,6 +360,8 @@ fn encodeMemArg(mem_arg: Mir.MemArg, writer: anytype) !void {
|
||||
}
|
||||
|
||||
fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
const comp = emit.bin_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const label = emit.mir.instructions.items(.data)[inst].label;
|
||||
try emit.code.append(std.wasm.opcode(.call));
|
||||
const call_offset = emit.offset();
|
||||
@ -366,7 +372,7 @@ fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
if (label != 0) {
|
||||
const atom_index = emit.bin_file.decls.get(emit.decl_index).?;
|
||||
const atom = emit.bin_file.getAtomPtr(atom_index);
|
||||
try atom.relocs.append(emit.bin_file.base.allocator, .{
|
||||
try atom.relocs.append(gpa, .{
|
||||
.offset = call_offset,
|
||||
.index = label,
|
||||
.relocation_type = .R_WASM_FUNCTION_INDEX_LEB,
|
||||
@ -384,6 +390,8 @@ fn emitCallIndirect(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
}
|
||||
|
||||
fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
const comp = emit.bin_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const symbol_index = emit.mir.instructions.items(.data)[inst].label;
|
||||
try emit.code.append(std.wasm.opcode(.i32_const));
|
||||
const index_offset = emit.offset();
|
||||
@ -394,7 +402,7 @@ fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
if (symbol_index != 0) {
|
||||
const atom_index = emit.bin_file.decls.get(emit.decl_index).?;
|
||||
const atom = emit.bin_file.getAtomPtr(atom_index);
|
||||
try atom.relocs.append(emit.bin_file.base.allocator, .{
|
||||
try atom.relocs.append(gpa, .{
|
||||
.offset = index_offset,
|
||||
.index = symbol_index,
|
||||
.relocation_type = .R_WASM_TABLE_INDEX_SLEB,
|
||||
@ -406,7 +414,9 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
const extra_index = emit.mir.instructions.items(.data)[inst].payload;
|
||||
const mem = emit.mir.extraData(Mir.Memory, extra_index).data;
|
||||
const mem_offset = emit.offset() + 1;
|
||||
const target = emit.bin_file.comp.root_mod.resolved_target.result;
|
||||
const comp = emit.bin_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const target = comp.root_mod.resolved_target.result;
|
||||
const is_wasm32 = target.cpu.arch == .wasm32;
|
||||
if (is_wasm32) {
|
||||
try emit.code.append(std.wasm.opcode(.i32_const));
|
||||
@ -423,7 +433,7 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
if (mem.pointer != 0) {
|
||||
const atom_index = emit.bin_file.decls.get(emit.decl_index).?;
|
||||
const atom = emit.bin_file.getAtomPtr(atom_index);
|
||||
try atom.relocs.append(emit.bin_file.base.allocator, .{
|
||||
try atom.relocs.append(gpa, .{
|
||||
.offset = mem_offset,
|
||||
.index = mem.pointer,
|
||||
.relocation_type = if (is_wasm32) .R_WASM_MEMORY_ADDR_LEB else .R_WASM_MEMORY_ADDR_LEB64,
|
||||
|
||||
@ -795,15 +795,16 @@ pub fn generate(
|
||||
code: *std.ArrayList(u8),
|
||||
debug_output: DebugInfoOutput,
|
||||
) CodeGenError!Result {
|
||||
const mod = bin_file.comp.module.?;
|
||||
const comp = bin_file.comp;
|
||||
const gpa = comp.gpa;
|
||||
const mod = comp.module.?;
|
||||
const func = mod.funcInfo(func_index);
|
||||
const fn_owner_decl = mod.declPtr(func.owner_decl);
|
||||
assert(fn_owner_decl.has_tv);
|
||||
const fn_type = fn_owner_decl.ty;
|
||||
const namespace = mod.namespacePtr(fn_owner_decl.src_namespace);
|
||||
const target = namespace.file_scope.mod.target;
|
||||
const target = namespace.file_scope.mod.resolved_target.result;
|
||||
|
||||
const gpa = bin_file.allocator;
|
||||
var function = Self{
|
||||
.gpa = gpa,
|
||||
.air = air,
|
||||
@ -860,7 +861,7 @@ pub fn generate(
|
||||
error.CodegenFail => return Result{ .fail = function.err_msg.? },
|
||||
error.OutOfRegisters => return Result{
|
||||
.fail = try ErrorMsg.create(
|
||||
bin_file.allocator,
|
||||
gpa,
|
||||
src_loc,
|
||||
"CodeGen ran out of registers. This is a bug in the Zig compiler.",
|
||||
.{},
|
||||
@ -904,22 +905,22 @@ pub fn generate(
|
||||
function.gen() catch |err| switch (err) {
|
||||
error.CodegenFail => return Result{ .fail = function.err_msg.? },
|
||||
error.OutOfRegisters => return Result{
|
||||
.fail = try ErrorMsg.create(bin_file.allocator, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
|
||||
.fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
|
||||
},
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
var mir = Mir{
|
||||
.instructions = function.mir_instructions.toOwnedSlice(),
|
||||
.extra = try function.mir_extra.toOwnedSlice(bin_file.allocator),
|
||||
.extra = try function.mir_extra.toOwnedSlice(gpa),
|
||||
.frame_locs = function.frame_locs.toOwnedSlice(),
|
||||
};
|
||||
defer mir.deinit(bin_file.allocator);
|
||||
defer mir.deinit(gpa);
|
||||
|
||||
var emit = Emit{
|
||||
.lower = .{
|
||||
.bin_file = bin_file,
|
||||
.allocator = bin_file.allocator,
|
||||
.allocator = gpa,
|
||||
.mir = mir,
|
||||
.cc = cc,
|
||||
.src_loc = src_loc,
|
||||
@ -940,7 +941,7 @@ pub fn generate(
|
||||
};
|
||||
return Result{
|
||||
.fail = try ErrorMsg.create(
|
||||
bin_file.allocator,
|
||||
gpa,
|
||||
src_loc,
|
||||
"{s} This is a bug in the Zig compiler.",
|
||||
.{msg},
|
||||
@ -964,12 +965,13 @@ pub fn generateLazy(
|
||||
code: *std.ArrayList(u8),
|
||||
debug_output: DebugInfoOutput,
|
||||
) CodeGenError!Result {
|
||||
const gpa = bin_file.allocator;
|
||||
const zcu = bin_file.comp.module.?;
|
||||
const comp = bin_file.comp;
|
||||
const gpa = comp.gpa;
|
||||
const zcu = comp.module.?;
|
||||
const decl_index = lazy_sym.ty.getOwnerDecl(zcu);
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
const namespace = zcu.namespacePtr(decl.src_namespace);
|
||||
const target = namespace.file_scope.mod.target;
|
||||
const target = namespace.file_scope.mod.resolved_target.result;
|
||||
var function = Self{
|
||||
.gpa = gpa,
|
||||
.air = undefined,
|
||||
@ -996,22 +998,22 @@ pub fn generateLazy(
|
||||
function.genLazy(lazy_sym) catch |err| switch (err) {
|
||||
error.CodegenFail => return Result{ .fail = function.err_msg.? },
|
||||
error.OutOfRegisters => return Result{
|
||||
.fail = try ErrorMsg.create(bin_file.allocator, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
|
||||
.fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
|
||||
},
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
var mir = Mir{
|
||||
.instructions = function.mir_instructions.toOwnedSlice(),
|
||||
.extra = try function.mir_extra.toOwnedSlice(bin_file.allocator),
|
||||
.extra = try function.mir_extra.toOwnedSlice(gpa),
|
||||
.frame_locs = function.frame_locs.toOwnedSlice(),
|
||||
};
|
||||
defer mir.deinit(bin_file.allocator);
|
||||
defer mir.deinit(gpa);
|
||||
|
||||
var emit = Emit{
|
||||
.lower = .{
|
||||
.bin_file = bin_file,
|
||||
.allocator = bin_file.allocator,
|
||||
.allocator = gpa,
|
||||
.mir = mir,
|
||||
.cc = abi.resolveCallingConvention(.Unspecified, function.target.*),
|
||||
.src_loc = src_loc,
|
||||
@ -1032,7 +1034,7 @@ pub fn generateLazy(
|
||||
};
|
||||
return Result{
|
||||
.fail = try ErrorMsg.create(
|
||||
bin_file.allocator,
|
||||
gpa,
|
||||
src_loc,
|
||||
"{s} This is a bug in the Zig compiler.",
|
||||
.{msg},
|
||||
@ -16416,14 +16418,16 @@ fn resolveCallingConventionValues(
|
||||
fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
|
||||
@setCold(true);
|
||||
assert(self.err_msg == null);
|
||||
self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args);
|
||||
const gpa = self.gpa;
|
||||
self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError {
|
||||
@setCold(true);
|
||||
assert(self.err_msg == null);
|
||||
self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args);
|
||||
const gpa = self.gpa;
|
||||
self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
|
||||
@ -57,7 +57,7 @@ pub fn generateFunction(
|
||||
const func = zcu.funcInfo(func_index);
|
||||
const decl = zcu.declPtr(func.owner_decl);
|
||||
const namespace = zcu.namespacePtr(decl.src_namespace);
|
||||
const target = namespace.file_scope.mod.target;
|
||||
const target = namespace.file_scope.mod.resolved_target.result;
|
||||
switch (target.cpu.arch) {
|
||||
.arm,
|
||||
.armeb,
|
||||
@ -87,7 +87,7 @@ pub fn generateLazyFunction(
|
||||
const decl_index = lazy_sym.ty.getOwnerDecl(zcu);
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
const namespace = zcu.namespacePtr(decl.src_namespace);
|
||||
const target = namespace.file_scope.mod.target;
|
||||
const target = namespace.file_scope.mod.resolved_target.result;
|
||||
switch (target.cpu.arch) {
|
||||
.x86_64 => return @import("arch/x86_64/CodeGen.zig").generateLazy(lf, src_loc, lazy_sym, code, debug_output),
|
||||
else => unreachable,
|
||||
@ -117,12 +117,14 @@ pub fn generateLazySymbol(
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const zcu = bin_file.comp.module.?;
|
||||
const comp = bin_file.comp;
|
||||
const zcu = comp.module.?;
|
||||
const decl_index = lazy_sym.ty.getOwnerDecl(zcu);
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
const namespace = zcu.namespacePtr(decl.src_namespace);
|
||||
const target = namespace.file_scope.mod.target;
|
||||
const target = namespace.file_scope.mod.resolved_target.result;
|
||||
const endian = target.cpu.arch.endian();
|
||||
const gpa = comp.gpa;
|
||||
|
||||
log.debug("generateLazySymbol: kind = {s}, ty = {}", .{
|
||||
@tagName(lazy_sym.kind),
|
||||
@ -160,7 +162,7 @@ pub fn generateLazySymbol(
|
||||
}
|
||||
return Result.ok;
|
||||
} else return .{ .fail = try ErrorMsg.create(
|
||||
bin_file.allocator,
|
||||
gpa,
|
||||
src_loc,
|
||||
"TODO implement generateLazySymbol for {s} {}",
|
||||
.{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(zcu) },
|
||||
@ -827,7 +829,7 @@ fn lowerDeclRef(
|
||||
const zcu = lf.comp.module.?;
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
const namespace = zcu.namespacePtr(decl.src_namespace);
|
||||
const target = namespace.file_scope.mod.target;
|
||||
const target = namespace.file_scope.mod.resolved_target.result;
|
||||
|
||||
const ptr_width = target.ptrBitWidth();
|
||||
const is_fn_body = decl.ty.zigTypeTag(zcu) == .Fn;
|
||||
@ -921,7 +923,7 @@ fn genDeclRef(
|
||||
|
||||
const ptr_decl = zcu.declPtr(ptr_decl_index);
|
||||
const namespace = zcu.namespacePtr(ptr_decl.src_namespace);
|
||||
const target = namespace.file_scope.mod.target;
|
||||
const target = namespace.file_scope.mod.resolved_target.result;
|
||||
|
||||
const ptr_bits = target.ptrBitWidth();
|
||||
const ptr_bytes: u64 = @divExact(ptr_bits, 8);
|
||||
@ -944,6 +946,9 @@ fn genDeclRef(
|
||||
return GenResult.mcv(.{ .immediate = imm });
|
||||
}
|
||||
|
||||
const comp = lf.comp;
|
||||
const gpa = comp.gpa;
|
||||
|
||||
// TODO this feels clunky. Perhaps we should check for it in `genTypedValue`?
|
||||
if (tv.ty.castPtrToFn(zcu)) |fn_ty| {
|
||||
if (zcu.typeToFunc(fn_ty).?.is_generic) {
|
||||
@ -958,8 +963,8 @@ fn genDeclRef(
|
||||
|
||||
try zcu.markDeclAlive(decl);
|
||||
|
||||
const decl_namespace = zcu.namespacePtr(decl.namespace_index);
|
||||
const single_threaded = decl_namespace.file_scope.zcu.single_threaded;
|
||||
const decl_namespace = zcu.namespacePtr(decl.src_namespace);
|
||||
const single_threaded = decl_namespace.file_scope.mod.single_threaded;
|
||||
const is_threadlocal = tv.val.isPtrToThreadLocal(zcu) and !single_threaded;
|
||||
const is_extern = decl.isExtern(zcu);
|
||||
|
||||
@ -985,8 +990,8 @@ fn genDeclRef(
|
||||
if (is_extern) {
|
||||
// TODO make this part of getGlobalSymbol
|
||||
const name = zcu.intern_pool.stringToSlice(decl.name);
|
||||
const sym_name = try std.fmt.allocPrint(lf.allocator, "_{s}", .{name});
|
||||
defer lf.allocator.free(sym_name);
|
||||
const sym_name = try std.fmt.allocPrint(gpa, "_{s}", .{name});
|
||||
defer gpa.free(sym_name);
|
||||
const global_index = try macho_file.addUndefined(sym_name, .{ .add_got = true });
|
||||
return GenResult.mcv(.{ .load_got = link.File.MachO.global_symbol_bit | global_index });
|
||||
}
|
||||
@ -1005,7 +1010,7 @@ fn genDeclRef(
|
||||
else
|
||||
null;
|
||||
const global_index = try coff_file.getGlobalSymbol(name, lib_name);
|
||||
try coff_file.need_got_table.put(lf.allocator, global_index, {}); // needs GOT
|
||||
try coff_file.need_got_table.put(gpa, global_index, {}); // needs GOT
|
||||
return GenResult.mcv(.{ .load_got = link.File.Coff.global_symbol_bit | global_index });
|
||||
}
|
||||
const atom_index = try coff_file.getOrCreateAtomForDecl(decl_index);
|
||||
@ -1016,7 +1021,7 @@ fn genDeclRef(
|
||||
const atom = p9.getAtom(atom_index);
|
||||
return GenResult.mcv(.{ .memory = atom.getOffsetTableAddress(p9) });
|
||||
} else {
|
||||
return GenResult.fail(lf.allocator, src_loc, "TODO genDeclRef for target {}", .{target});
|
||||
return GenResult.fail(gpa, src_loc, "TODO genDeclRef for target {}", .{target});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1073,7 +1078,7 @@ pub fn genTypedValue(
|
||||
|
||||
const owner_decl = zcu.declPtr(owner_decl_index);
|
||||
const namespace = zcu.namespacePtr(owner_decl.src_namespace);
|
||||
const target = namespace.file_scope.mod.target;
|
||||
const target = namespace.file_scope.mod.resolved_target.result;
|
||||
const ptr_bits = target.ptrBitWidth();
|
||||
|
||||
if (!typed_value.ty.isSlice(zcu)) switch (zcu.intern_pool.indexToKey(typed_value.val.toIntern())) {
|
||||
|
||||
@ -1785,7 +1785,7 @@ pub const Object = struct {
|
||||
if (wantDllExports(mod)) global_index.setDllStorageClass(.default, &self.builder);
|
||||
global_index.setUnnamedAddr(.unnamed_addr, &self.builder);
|
||||
if (decl.val.getVariable(mod)) |decl_var| {
|
||||
const decl_namespace = mod.namespacePtr(decl.namespace_index);
|
||||
const decl_namespace = mod.namespacePtr(decl.src_namespace);
|
||||
const single_threaded = decl_namespace.file_scope.mod.single_threaded;
|
||||
global_index.ptrConst(&self.builder).kind.variable.setThreadLocal(
|
||||
if (decl_var.is_threadlocal and !single_threaded)
|
||||
@ -3173,7 +3173,7 @@ pub const Object = struct {
|
||||
variable_index.setLinkage(.external, &o.builder);
|
||||
variable_index.setUnnamedAddr(.default, &o.builder);
|
||||
if (decl.val.getVariable(mod)) |decl_var| {
|
||||
const decl_namespace = mod.namespacePtr(decl.namespace_index);
|
||||
const decl_namespace = mod.namespacePtr(decl.src_namespace);
|
||||
const single_threaded = decl_namespace.file_scope.mod.single_threaded;
|
||||
variable_index.setThreadLocal(
|
||||
if (decl_var.is_threadlocal and !single_threaded) .generaldynamic else .default,
|
||||
|
||||
@ -123,7 +123,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: *std.Progress.Node) !void {
|
||||
.local_cache_directory = comp.global_cache_directory,
|
||||
.global_cache_directory = comp.global_cache_directory,
|
||||
.zig_lib_directory = comp.zig_lib_directory,
|
||||
.resolved = config,
|
||||
.config = config,
|
||||
.root_mod = root_mod,
|
||||
.cache_mode = .whole,
|
||||
.root_name = root_name,
|
||||
|
||||
63
src/link.zig
63
src/link.zig
@ -69,10 +69,12 @@ pub const File = struct {
|
||||
allow_shlib_undefined: bool,
|
||||
stack_size: u64,
|
||||
|
||||
error_flags: ErrorFlags = .{},
|
||||
misc_errors: std.ArrayListUnmanaged(ErrorMsg) = .{},
|
||||
|
||||
/// Prevents other processes from clobbering files in the output directory
|
||||
/// of this linking operation.
|
||||
lock: ?Cache.Lock = null,
|
||||
|
||||
child_pid: ?std.ChildProcess.Id = null,
|
||||
|
||||
pub const OpenOptions = struct {
|
||||
@ -210,6 +212,8 @@ pub const File = struct {
|
||||
}
|
||||
|
||||
pub fn makeWritable(base: *File) !void {
|
||||
const comp = base.comp;
|
||||
const gpa = comp.gpa;
|
||||
switch (base.tag) {
|
||||
.coff, .elf, .macho, .plan9, .wasm => {
|
||||
if (build_options.only_c) unreachable;
|
||||
@ -225,9 +229,10 @@ pub const File = struct {
|
||||
// it will return ETXTBSY. So instead, we copy the file, atomically rename it
|
||||
// over top of the exe path, and then proceed normally. This changes the inode,
|
||||
// avoiding the error.
|
||||
const tmp_sub_path = try std.fmt.allocPrint(base.allocator, "{s}-{x}", .{
|
||||
const tmp_sub_path = try std.fmt.allocPrint(gpa, "{s}-{x}", .{
|
||||
emit.sub_path, std.crypto.random.int(u32),
|
||||
});
|
||||
defer gpa.free(tmp_sub_path);
|
||||
try emit.directory.handle.copyFile(emit.sub_path, emit.directory.handle, tmp_sub_path, .{});
|
||||
try emit.directory.handle.rename(tmp_sub_path, emit.sub_path);
|
||||
switch (builtin.os.tag) {
|
||||
@ -242,9 +247,9 @@ pub const File = struct {
|
||||
}
|
||||
}
|
||||
}
|
||||
const use_lld = build_options.have_llvm and base.comp.config.use_lld;
|
||||
const output_mode = base.comp.config.output_mode;
|
||||
const link_mode = base.comp.config.link_mode;
|
||||
const use_lld = build_options.have_llvm and comp.config.use_lld;
|
||||
const output_mode = comp.config.output_mode;
|
||||
const link_mode = comp.config.link_mode;
|
||||
base.file = try emit.directory.handle.createFile(emit.sub_path, .{
|
||||
.truncate = false,
|
||||
.read = true,
|
||||
@ -256,9 +261,10 @@ pub const File = struct {
|
||||
}
|
||||
|
||||
pub fn makeExecutable(base: *File) !void {
|
||||
const output_mode = base.comp.config.output_mode;
|
||||
const link_mode = base.comp.config.link_mode;
|
||||
const use_lld = build_options.have_llvm and base.comp.config.use_lld;
|
||||
const comp = base.comp;
|
||||
const output_mode = comp.config.output_mode;
|
||||
const link_mode = comp.config.link_mode;
|
||||
const use_lld = build_options.have_llvm and comp.config.use_lld;
|
||||
|
||||
switch (output_mode) {
|
||||
.Obj => return,
|
||||
@ -464,8 +470,13 @@ pub const File = struct {
|
||||
}
|
||||
|
||||
pub fn destroy(base: *File) void {
|
||||
const gpa = base.comp.gpa;
|
||||
base.releaseLock();
|
||||
if (base.file) |f| f.close();
|
||||
{
|
||||
for (base.misc_errors.items) |*item| item.deinit(gpa);
|
||||
base.misc_errors.deinit(gpa);
|
||||
}
|
||||
switch (base.tag) {
|
||||
.coff => {
|
||||
if (build_options.only_c) unreachable;
|
||||
@ -602,9 +613,9 @@ pub const File = struct {
|
||||
return;
|
||||
}
|
||||
|
||||
const use_lld = build_options.have_llvm and base.comp.config.use_lld;
|
||||
const output_mode = base.comp.config.output_mode;
|
||||
const link_mode = base.comp.config.link_mode;
|
||||
const use_lld = build_options.have_llvm and comp.config.use_lld;
|
||||
const output_mode = comp.config.output_mode;
|
||||
const link_mode = comp.config.link_mode;
|
||||
if (use_lld and output_mode == .Lib and link_mode == .Static) {
|
||||
return base.linkAsArchive(comp, prog_node);
|
||||
}
|
||||
@ -657,25 +668,6 @@ pub const File = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn errorFlags(base: *File) ErrorFlags {
|
||||
switch (base.tag) {
|
||||
.coff => return @fieldParentPtr(Coff, "base", base).error_flags,
|
||||
.elf => return @fieldParentPtr(Elf, "base", base).error_flags,
|
||||
.macho => return @fieldParentPtr(MachO, "base", base).error_flags,
|
||||
.plan9 => return @fieldParentPtr(Plan9, "base", base).error_flags,
|
||||
.c => return .{ .no_entry_point_found = false },
|
||||
.wasm, .spirv, .nvptx => return ErrorFlags{},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn miscErrors(base: *File) []const ErrorMsg {
|
||||
switch (base.tag) {
|
||||
.elf => return @fieldParentPtr(Elf, "base", base).misc_errors.items,
|
||||
.macho => return @fieldParentPtr(MachO, "base", base).misc_errors.items,
|
||||
else => return &.{},
|
||||
}
|
||||
}
|
||||
|
||||
pub const UpdateExportsError = error{
|
||||
OutOfMemory,
|
||||
AnalysisFail,
|
||||
@ -781,14 +773,15 @@ pub const File = struct {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(base.allocator);
|
||||
const gpa = comp.gpa;
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(gpa);
|
||||
defer arena_allocator.deinit();
|
||||
const arena = arena_allocator.allocator();
|
||||
|
||||
const directory = base.emit.directory; // Just an alias to make it shorter to type.
|
||||
const full_out_path = try directory.join(arena, &[_][]const u8{base.emit.sub_path});
|
||||
const full_out_path_z = try arena.dupeZ(u8, full_out_path);
|
||||
const opt_zcu = base.comp.module;
|
||||
const opt_zcu = comp.module;
|
||||
|
||||
// If there is no Zig code to compile, then we should skip flushing the output file
|
||||
// because it will not be part of the linker line anyway.
|
||||
@ -801,7 +794,7 @@ pub const File = struct {
|
||||
|
||||
log.debug("zcu_obj_path={s}", .{if (zcu_obj_path) |s| s else "(null)"});
|
||||
|
||||
const compiler_rt_path: ?[]const u8 = if (base.comp.include_compiler_rt)
|
||||
const compiler_rt_path: ?[]const u8 = if (comp.include_compiler_rt)
|
||||
comp.compiler_rt_obj.?.full_object_path
|
||||
else
|
||||
null;
|
||||
@ -815,7 +808,7 @@ pub const File = struct {
|
||||
var man: Cache.Manifest = undefined;
|
||||
defer if (!base.disable_lld_caching) man.deinit();
|
||||
|
||||
const objects = base.comp.objects;
|
||||
const objects = comp.objects;
|
||||
|
||||
var digest: [Cache.hex_digest_len]u8 = undefined;
|
||||
|
||||
@ -869,7 +862,7 @@ pub const File = struct {
|
||||
|
||||
const win32_resource_table_len = if (build_options.only_core_functionality) 0 else comp.win32_resource_table.count();
|
||||
const num_object_files = objects.len + comp.c_object_table.count() + win32_resource_table_len + 2;
|
||||
var object_files = try std.ArrayList([*:0]const u8).initCapacity(base.allocator, num_object_files);
|
||||
var object_files = try std.ArrayList([*:0]const u8).initCapacity(gpa, num_object_files);
|
||||
defer object_files.deinit();
|
||||
|
||||
for (objects) |obj| {
|
||||
|
||||
@ -84,7 +84,8 @@ pub fn getString(this: C, s: String) []const u8 {
|
||||
}
|
||||
|
||||
pub fn addString(this: *C, s: []const u8) Allocator.Error!String {
|
||||
const gpa = this.base.allocator;
|
||||
const comp = this.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
try this.string_bytes.appendSlice(gpa, s);
|
||||
return .{
|
||||
.start = @intCast(this.string_bytes.items.len - s.len),
|
||||
@ -97,6 +98,15 @@ pub fn open(
|
||||
comp: *Compilation,
|
||||
emit: Compilation.Emit,
|
||||
options: link.File.OpenOptions,
|
||||
) !*C {
|
||||
return createEmpty(arena, comp, emit, options);
|
||||
}
|
||||
|
||||
pub fn createEmpty(
|
||||
arena: Allocator,
|
||||
comp: *Compilation,
|
||||
emit: Compilation.Emit,
|
||||
options: link.File.OpenOptions,
|
||||
) !*C {
|
||||
const target = comp.root_mod.resolved_target.result;
|
||||
assert(target.ofmt == .c);
|
||||
|
||||
@ -8,7 +8,6 @@ llvm_object: ?*LlvmObject = null,
|
||||
|
||||
base: link.File,
|
||||
image_base: u64,
|
||||
error_flags: link.File.ErrorFlags = .{},
|
||||
dll_export_fns: bool,
|
||||
subsystem: ?std.Target.SubSystem,
|
||||
tsaware: bool,
|
||||
@ -1825,10 +1824,10 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
|
||||
|
||||
if (self.entry_addr == null and self.base.comp.config.output_mode == .Exe) {
|
||||
log.debug("flushing. no_entry_point_found = true\n", .{});
|
||||
self.error_flags.no_entry_point_found = true;
|
||||
self.base.error_flags.no_entry_point_found = true;
|
||||
} else {
|
||||
log.debug("flushing. no_entry_point_found = false\n", .{});
|
||||
self.error_flags.no_entry_point_found = false;
|
||||
self.base.error_flags.no_entry_point_found = false;
|
||||
try self.writeHeader();
|
||||
}
|
||||
|
||||
|
||||
@ -94,7 +94,8 @@ pub fn freeListEligible(self: Atom, coff_file: *const Coff) bool {
|
||||
}
|
||||
|
||||
pub fn addRelocation(coff_file: *Coff, atom_index: Index, reloc: Relocation) !void {
|
||||
const gpa = coff_file.base.allocator;
|
||||
const comp = coff_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
log.debug(" (adding reloc of type {s} to target %{d})", .{ @tagName(reloc.type), reloc.target.sym_index });
|
||||
const gop = try coff_file.relocs.getOrPut(gpa, atom_index);
|
||||
if (!gop.found_existing) {
|
||||
@ -104,7 +105,8 @@ pub fn addRelocation(coff_file: *Coff, atom_index: Index, reloc: Relocation) !vo
|
||||
}
|
||||
|
||||
pub fn addBaseRelocation(coff_file: *Coff, atom_index: Index, offset: u32) !void {
|
||||
const gpa = coff_file.base.allocator;
|
||||
const comp = coff_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
log.debug(" (adding base relocation at offset 0x{x} in %{d})", .{
|
||||
offset,
|
||||
coff_file.getAtom(atom_index).getSymbolIndex().?,
|
||||
@ -117,7 +119,8 @@ pub fn addBaseRelocation(coff_file: *Coff, atom_index: Index, offset: u32) !void
|
||||
}
|
||||
|
||||
pub fn freeRelocations(coff_file: *Coff, atom_index: Index) void {
|
||||
const gpa = coff_file.base.allocator;
|
||||
const comp = coff_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
var removed_relocs = coff_file.relocs.fetchOrderedRemove(atom_index);
|
||||
if (removed_relocs) |*relocs| relocs.value.deinit(gpa);
|
||||
var removed_base_relocs = coff_file.base_relocs.fetchOrderedRemove(atom_index);
|
||||
|
||||
@ -1205,7 +1205,7 @@ pub fn commitDeclState(
|
||||
const decl = zcu.declPtr(decl_index);
|
||||
const ip = &zcu.intern_pool;
|
||||
const namespace = zcu.namespacePtr(decl.src_namespace);
|
||||
const target = namespace.file_scope.mod.target;
|
||||
const target = namespace.file_scope.mod.resolved_target.result;
|
||||
const target_endian = target.cpu.arch.endian();
|
||||
|
||||
var dbg_line_buffer = &decl_state.dbg_line;
|
||||
|
||||
@ -196,9 +196,6 @@ resolver: std.AutoArrayHashMapUnmanaged(u32, Symbol.Index) = .{},
|
||||
has_text_reloc: bool = false,
|
||||
num_ifunc_dynrelocs: usize = 0,
|
||||
|
||||
error_flags: link.File.ErrorFlags = link.File.ErrorFlags{},
|
||||
misc_errors: std.ArrayListUnmanaged(link.File.ErrorMsg) = .{},
|
||||
|
||||
/// List of atoms that are owned directly by the linker.
|
||||
atoms: std.ArrayListUnmanaged(Atom) = .{},
|
||||
|
||||
@ -477,7 +474,6 @@ pub fn deinit(self: *Elf) void {
|
||||
}
|
||||
self.last_atom_and_free_list_table.deinit(gpa);
|
||||
|
||||
self.misc_errors.deinit(gpa);
|
||||
self.comdat_groups.deinit(gpa);
|
||||
self.comdat_groups_owners.deinit(gpa);
|
||||
self.comdat_groups_table.deinit(gpa);
|
||||
@ -1168,7 +1164,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
}
|
||||
|
||||
// libc dep
|
||||
self.error_flags.missing_libc = false;
|
||||
self.base.error_flags.missing_libc = false;
|
||||
if (self.base.comp.config.link_libc) {
|
||||
if (self.base.comp.libc_installation) |lc| {
|
||||
const flags = target_util.libcFullLinkFlags(target);
|
||||
@ -1219,7 +1215,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
});
|
||||
try system_libs.append(.{ .path = path });
|
||||
} else {
|
||||
self.error_flags.missing_libc = true;
|
||||
self.base.error_flags.missing_libc = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1257,7 +1253,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
};
|
||||
}
|
||||
|
||||
if (self.misc_errors.items.len > 0) return error.FlushFailure;
|
||||
if (self.base.misc_errors.items.len > 0) return error.FlushFailure;
|
||||
|
||||
// Init all objects
|
||||
for (self.objects.items) |index| {
|
||||
@ -1267,7 +1263,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
try self.file(index).?.shared_object.init(self);
|
||||
}
|
||||
|
||||
if (self.misc_errors.items.len > 0) return error.FlushFailure;
|
||||
if (self.base.misc_errors.items.len > 0) return error.FlushFailure;
|
||||
|
||||
// Dedup shared objects
|
||||
{
|
||||
@ -1389,14 +1385,14 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
|
||||
if (self.entry_index == null and self.base.isExe()) {
|
||||
log.debug("flushing. no_entry_point_found = true", .{});
|
||||
self.error_flags.no_entry_point_found = true;
|
||||
self.base.error_flags.no_entry_point_found = true;
|
||||
} else {
|
||||
log.debug("flushing. no_entry_point_found = false", .{});
|
||||
self.error_flags.no_entry_point_found = false;
|
||||
self.base.error_flags.no_entry_point_found = false;
|
||||
try self.writeElfHeader();
|
||||
}
|
||||
|
||||
if (self.misc_errors.items.len > 0) return error.FlushFailure;
|
||||
if (self.base.misc_errors.items.len > 0) return error.FlushFailure;
|
||||
}
|
||||
|
||||
pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void {
|
||||
@ -1428,7 +1424,7 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const
|
||||
};
|
||||
}
|
||||
|
||||
if (self.misc_errors.items.len > 0) return error.FlushFailure;
|
||||
if (self.base.misc_errors.items.len > 0) return error.FlushFailure;
|
||||
|
||||
// First, we flush relocatable object file generated with our backends.
|
||||
if (self.zigObjectPtr()) |zig_object| {
|
||||
@ -1540,7 +1536,7 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const
|
||||
try self.base.file.?.setEndPos(total_size);
|
||||
try self.base.file.?.pwriteAll(buffer.items, 0);
|
||||
|
||||
if (self.misc_errors.items.len > 0) return error.FlushFailure;
|
||||
if (self.base.misc_errors.items.len > 0) return error.FlushFailure;
|
||||
}
|
||||
|
||||
pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void {
|
||||
@ -1571,14 +1567,14 @@ pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8)
|
||||
};
|
||||
}
|
||||
|
||||
if (self.misc_errors.items.len > 0) return error.FlushFailure;
|
||||
if (self.base.misc_errors.items.len > 0) return error.FlushFailure;
|
||||
|
||||
// Init all objects
|
||||
for (self.objects.items) |index| {
|
||||
try self.file(index).?.object.init(self);
|
||||
}
|
||||
|
||||
if (self.misc_errors.items.len > 0) return error.FlushFailure;
|
||||
if (self.base.misc_errors.items.len > 0) return error.FlushFailure;
|
||||
|
||||
// Now, we are ready to resolve the symbols across all input files.
|
||||
// We will first resolve the files in the ZigObject, next in the parsed
|
||||
@ -1612,7 +1608,7 @@ pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8)
|
||||
try self.writeShdrTable();
|
||||
try self.writeElfHeader();
|
||||
|
||||
if (self.misc_errors.items.len > 0) return error.FlushFailure;
|
||||
if (self.base.misc_errors.items.len > 0) return error.FlushFailure;
|
||||
}
|
||||
|
||||
/// --verbose-link output
|
||||
@ -2891,7 +2887,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
|
||||
}
|
||||
|
||||
// libc dep
|
||||
self.error_flags.missing_libc = false;
|
||||
self.base.error_flags.missing_libc = false;
|
||||
if (comp.config.link_libc) {
|
||||
if (self.base.comp.libc_installation != null) {
|
||||
const needs_grouping = link_mode == .Static;
|
||||
@ -2912,7 +2908,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
|
||||
.Dynamic => "libc.so",
|
||||
}));
|
||||
} else {
|
||||
self.error_flags.missing_libc = true;
|
||||
self.base.error_flags.missing_libc = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3135,7 +3131,7 @@ fn writePhdrTable(self: *Elf) !void {
|
||||
}
|
||||
|
||||
fn writeElfHeader(self: *Elf) !void {
|
||||
if (self.misc_errors.items.len > 0) return; // We had errors, so skip flushing to render the output unusable
|
||||
if (self.base.misc_errors.items.len > 0) return; // We had errors, so skip flushing to render the output unusable
|
||||
|
||||
var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 = undefined;
|
||||
|
||||
@ -6067,8 +6063,9 @@ const ErrorWithNotes = struct {
|
||||
comptime format: []const u8,
|
||||
args: anytype,
|
||||
) error{OutOfMemory}!void {
|
||||
const gpa = elf_file.base.allocator;
|
||||
const err_msg = &elf_file.misc_errors.items[err.index];
|
||||
const comp = elf_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const err_msg = &elf_file.base.misc_errors.items[err.index];
|
||||
err_msg.msg = try std.fmt.allocPrint(gpa, format, args);
|
||||
}
|
||||
|
||||
@ -6078,8 +6075,9 @@ const ErrorWithNotes = struct {
|
||||
comptime format: []const u8,
|
||||
args: anytype,
|
||||
) error{OutOfMemory}!void {
|
||||
const gpa = elf_file.base.allocator;
|
||||
const err_msg = &elf_file.misc_errors.items[err.index];
|
||||
const comp = elf_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const err_msg = &elf_file.base.misc_errors.items[err.index];
|
||||
assert(err.note_slot < err_msg.notes.len);
|
||||
err_msg.notes[err.note_slot] = .{ .msg = try std.fmt.allocPrint(gpa, format, args) };
|
||||
err.note_slot += 1;
|
||||
@ -6088,14 +6086,14 @@ const ErrorWithNotes = struct {
|
||||
|
||||
pub fn addErrorWithNotes(self: *Elf, note_count: usize) error{OutOfMemory}!ErrorWithNotes {
|
||||
const gpa = self.base.comp.gpa;
|
||||
try self.misc_errors.ensureUnusedCapacity(gpa, 1);
|
||||
try self.base.misc_errors.ensureUnusedCapacity(gpa, 1);
|
||||
return self.addErrorWithNotesAssumeCapacity(note_count);
|
||||
}
|
||||
|
||||
fn addErrorWithNotesAssumeCapacity(self: *Elf, note_count: usize) error{OutOfMemory}!ErrorWithNotes {
|
||||
const gpa = self.base.comp.gpa;
|
||||
const index = self.misc_errors.items.len;
|
||||
const err = self.misc_errors.addOneAssumeCapacity();
|
||||
const index = self.base.misc_errors.items.len;
|
||||
const err = self.base.misc_errors.addOneAssumeCapacity();
|
||||
err.* = .{ .msg = undefined, .notes = try gpa.alloc(link.File.ErrorMsg, note_count) };
|
||||
return .{ .index = index };
|
||||
}
|
||||
@ -6130,7 +6128,7 @@ fn reportUndefinedSymbols(self: *Elf, undefs: anytype) !void {
|
||||
const gpa = self.base.comp.gpa;
|
||||
const max_notes = 4;
|
||||
|
||||
try self.misc_errors.ensureUnusedCapacity(gpa, undefs.count());
|
||||
try self.base.misc_errors.ensureUnusedCapacity(gpa, undefs.count());
|
||||
|
||||
var it = undefs.iterator();
|
||||
while (it.next()) |entry| {
|
||||
|
||||
@ -227,7 +227,8 @@ pub fn grow(self: *Atom, elf_file: *Elf) !void {
|
||||
pub fn free(self: *Atom, elf_file: *Elf) void {
|
||||
log.debug("freeAtom {d} ({s})", .{ self.atom_index, self.name(elf_file) });
|
||||
|
||||
const gpa = elf_file.base.allocator;
|
||||
const comp = elf_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const shndx = self.outputShndx().?;
|
||||
const meta = elf_file.last_atom_and_free_list_table.getPtr(shndx).?;
|
||||
const free_list = &meta.free_list;
|
||||
@ -352,7 +353,8 @@ pub fn markFdesDead(self: Atom, elf_file: *Elf) void {
|
||||
}
|
||||
|
||||
pub fn addReloc(self: Atom, elf_file: *Elf, reloc: elf.Elf64_Rela) !void {
|
||||
const gpa = elf_file.base.allocator;
|
||||
const comp = elf_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const file_ptr = self.file(elf_file).?;
|
||||
assert(file_ptr == .zig_object);
|
||||
const zig_object = file_ptr.zig_object;
|
||||
@ -747,6 +749,8 @@ fn reportUndefined(
|
||||
rel: elf.Elf64_Rela,
|
||||
undefs: anytype,
|
||||
) !void {
|
||||
const comp = elf_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const rel_esym = switch (self.file(elf_file).?) {
|
||||
.zig_object => |x| x.elfSym(rel.r_sym()).*,
|
||||
.object => |x| x.symtab.items[rel.r_sym()],
|
||||
@ -761,7 +765,7 @@ fn reportUndefined(
|
||||
{
|
||||
const gop = try undefs.getOrPut(sym_index);
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = std.ArrayList(Atom.Index).init(elf_file.base.allocator);
|
||||
gop.value_ptr.* = std.ArrayList(Atom.Index).init(gpa);
|
||||
}
|
||||
try gop.value_ptr.append(self.atom_index);
|
||||
}
|
||||
@ -957,6 +961,8 @@ fn resolveDynAbsReloc(
|
||||
elf_file: *Elf,
|
||||
writer: anytype,
|
||||
) !void {
|
||||
const comp = elf_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const P = self.value + rel.r_offset;
|
||||
const A = rel.r_addend;
|
||||
const S = @as(i64, @intCast(target.address(.{}, elf_file)));
|
||||
@ -967,7 +973,7 @@ fn resolveDynAbsReloc(
|
||||
.shared_object => unreachable,
|
||||
inline else => |x| x.num_dynrelocs,
|
||||
};
|
||||
try elf_file.rela_dyn.ensureUnusedCapacity(elf_file.base.allocator, num_dynrelocs);
|
||||
try elf_file.rela_dyn.ensureUnusedCapacity(gpa, num_dynrelocs);
|
||||
|
||||
switch (action) {
|
||||
.@"error",
|
||||
|
||||
@ -67,9 +67,6 @@ tlv_ptr_table: TableSection(SymbolWithLoc) = .{},
|
||||
thunk_table: std.AutoHashMapUnmanaged(Atom.Index, thunks.Thunk.Index) = .{},
|
||||
thunks: std.ArrayListUnmanaged(thunks.Thunk) = .{},
|
||||
|
||||
error_flags: File.ErrorFlags = File.ErrorFlags{},
|
||||
misc_errors: std.ArrayListUnmanaged(File.ErrorMsg) = .{},
|
||||
|
||||
segment_table_dirty: bool = false,
|
||||
got_table_count_dirty: bool = false,
|
||||
got_table_contents_dirty: bool = false,
|
||||
@ -337,8 +334,8 @@ pub fn flush(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) li
|
||||
if (build_options.have_llvm) {
|
||||
return self.base.linkAsArchive(comp, prog_node);
|
||||
} else {
|
||||
try self.misc_errors.ensureUnusedCapacity(gpa, 1);
|
||||
self.misc_errors.appendAssumeCapacity(.{
|
||||
try self.base.misc_errors.ensureUnusedCapacity(gpa, 1);
|
||||
self.base.misc_errors.appendAssumeCapacity(.{
|
||||
.msg = try gpa.dupe(u8, "TODO: non-LLVM archiver for MachO object files"),
|
||||
});
|
||||
return error.FlushFailure;
|
||||
@ -492,7 +489,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
|
||||
try self.resolveSymbols();
|
||||
|
||||
if (self.getEntryPoint() == null) {
|
||||
self.error_flags.no_entry_point_found = true;
|
||||
self.base.error_flags.no_entry_point_found = true;
|
||||
}
|
||||
if (self.unresolved.count() > 0) {
|
||||
try self.reportUndefined();
|
||||
@ -2097,11 +2094,6 @@ pub fn deinit(self: *MachO) void {
|
||||
bindings.deinit(gpa);
|
||||
}
|
||||
self.bindings.deinit(gpa);
|
||||
|
||||
for (self.misc_errors.items) |*err| {
|
||||
err.deinit(gpa);
|
||||
}
|
||||
self.misc_errors.deinit(gpa);
|
||||
}
|
||||
|
||||
fn freeAtom(self: *MachO, atom_index: Atom.Index) void {
|
||||
@ -5341,13 +5333,13 @@ fn reportMissingLibraryError(
|
||||
args: anytype,
|
||||
) error{OutOfMemory}!void {
|
||||
const gpa = self.base.comp.gpa;
|
||||
try self.misc_errors.ensureUnusedCapacity(gpa, 1);
|
||||
try self.base.misc_errors.ensureUnusedCapacity(gpa, 1);
|
||||
const notes = try gpa.alloc(File.ErrorMsg, checked_paths.len);
|
||||
errdefer gpa.free(notes);
|
||||
for (checked_paths, notes) |path, *note| {
|
||||
note.* = .{ .msg = try std.fmt.allocPrint(gpa, "tried {s}", .{path}) };
|
||||
}
|
||||
self.misc_errors.appendAssumeCapacity(.{
|
||||
self.base.misc_errors.appendAssumeCapacity(.{
|
||||
.msg = try std.fmt.allocPrint(gpa, format, args),
|
||||
.notes = notes,
|
||||
});
|
||||
@ -5361,14 +5353,14 @@ fn reportDependencyError(
|
||||
args: anytype,
|
||||
) error{OutOfMemory}!void {
|
||||
const gpa = self.base.comp.gpa;
|
||||
try self.misc_errors.ensureUnusedCapacity(gpa, 1);
|
||||
try self.base.misc_errors.ensureUnusedCapacity(gpa, 1);
|
||||
var notes = try std.ArrayList(File.ErrorMsg).initCapacity(gpa, 2);
|
||||
defer notes.deinit();
|
||||
if (path) |p| {
|
||||
notes.appendAssumeCapacity(.{ .msg = try std.fmt.allocPrint(gpa, "while parsing {s}", .{p}) });
|
||||
}
|
||||
notes.appendAssumeCapacity(.{ .msg = try std.fmt.allocPrint(gpa, "a dependency of {s}", .{parent}) });
|
||||
self.misc_errors.appendAssumeCapacity(.{
|
||||
self.base.misc_errors.appendAssumeCapacity(.{
|
||||
.msg = try std.fmt.allocPrint(gpa, format, args),
|
||||
.notes = try notes.toOwnedSlice(),
|
||||
});
|
||||
@ -5381,11 +5373,11 @@ pub fn reportParseError(
|
||||
args: anytype,
|
||||
) error{OutOfMemory}!void {
|
||||
const gpa = self.base.comp.gpa;
|
||||
try self.misc_errors.ensureUnusedCapacity(gpa, 1);
|
||||
try self.base.misc_errors.ensureUnusedCapacity(gpa, 1);
|
||||
var notes = try gpa.alloc(File.ErrorMsg, 1);
|
||||
errdefer gpa.free(notes);
|
||||
notes[0] = .{ .msg = try std.fmt.allocPrint(gpa, "while parsing {s}", .{path}) };
|
||||
self.misc_errors.appendAssumeCapacity(.{
|
||||
self.base.misc_errors.appendAssumeCapacity(.{
|
||||
.msg = try std.fmt.allocPrint(gpa, format, args),
|
||||
.notes = notes,
|
||||
});
|
||||
@ -5398,11 +5390,11 @@ pub fn reportUnresolvedBoundarySymbol(
|
||||
args: anytype,
|
||||
) error{OutOfMemory}!void {
|
||||
const gpa = self.base.comp.gpa;
|
||||
try self.misc_errors.ensureUnusedCapacity(gpa, 1);
|
||||
try self.base.misc_errors.ensureUnusedCapacity(gpa, 1);
|
||||
var notes = try gpa.alloc(File.ErrorMsg, 1);
|
||||
errdefer gpa.free(notes);
|
||||
notes[0] = .{ .msg = try std.fmt.allocPrint(gpa, "while resolving {s}", .{sym_name}) };
|
||||
self.misc_errors.appendAssumeCapacity(.{
|
||||
self.base.misc_errors.appendAssumeCapacity(.{
|
||||
.msg = try std.fmt.allocPrint(gpa, format, args),
|
||||
.notes = notes,
|
||||
});
|
||||
@ -5411,7 +5403,7 @@ pub fn reportUnresolvedBoundarySymbol(
|
||||
pub fn reportUndefined(self: *MachO) error{OutOfMemory}!void {
|
||||
const gpa = self.base.comp.gpa;
|
||||
const count = self.unresolved.count();
|
||||
try self.misc_errors.ensureUnusedCapacity(gpa, count);
|
||||
try self.base.misc_errors.ensureUnusedCapacity(gpa, count);
|
||||
|
||||
for (self.unresolved.keys()) |global_index| {
|
||||
const global = self.globals.items[global_index];
|
||||
@ -5432,7 +5424,7 @@ pub fn reportUndefined(self: *MachO) error{OutOfMemory}!void {
|
||||
};
|
||||
err_msg.notes = try notes.toOwnedSlice();
|
||||
|
||||
self.misc_errors.appendAssumeCapacity(err_msg);
|
||||
self.base.misc_errors.appendAssumeCapacity(err_msg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5442,7 +5434,7 @@ fn reportSymbolCollision(
|
||||
other: SymbolWithLoc,
|
||||
) error{OutOfMemory}!void {
|
||||
const gpa = self.base.comp.gpa;
|
||||
try self.misc_errors.ensureUnusedCapacity(gpa, 1);
|
||||
try self.base.misc_errors.ensureUnusedCapacity(gpa, 1);
|
||||
|
||||
var notes = try std.ArrayList(File.ErrorMsg).initCapacity(gpa, 2);
|
||||
defer notes.deinit();
|
||||
@ -5465,12 +5457,12 @@ fn reportSymbolCollision(
|
||||
}) };
|
||||
err_msg.notes = try notes.toOwnedSlice();
|
||||
|
||||
self.misc_errors.appendAssumeCapacity(err_msg);
|
||||
self.base.misc_errors.appendAssumeCapacity(err_msg);
|
||||
}
|
||||
|
||||
fn reportUnhandledSymbolType(self: *MachO, sym_with_loc: SymbolWithLoc) error{OutOfMemory}!void {
|
||||
const gpa = self.base.comp.gpa;
|
||||
try self.misc_errors.ensureUnusedCapacity(gpa, 1);
|
||||
try self.base.misc_errors.ensureUnusedCapacity(gpa, 1);
|
||||
|
||||
const notes = try gpa.alloc(File.ErrorMsg, 1);
|
||||
errdefer gpa.free(notes);
|
||||
@ -5488,7 +5480,7 @@ fn reportUnhandledSymbolType(self: *MachO, sym_with_loc: SymbolWithLoc) error{Ou
|
||||
else
|
||||
unreachable;
|
||||
|
||||
self.misc_errors.appendAssumeCapacity(.{
|
||||
self.base.misc_errors.appendAssumeCapacity(.{
|
||||
.msg = try std.fmt.allocPrint(gpa, "unhandled symbol type: '{s}' has type {s}", .{
|
||||
self.getSymbolName(sym_with_loc),
|
||||
sym_type,
|
||||
|
||||
@ -253,7 +253,8 @@ pub fn addRelocation(macho_file: *MachO, atom_index: Index, reloc: Relocation) !
|
||||
}
|
||||
|
||||
pub fn addRelocations(macho_file: *MachO, atom_index: Index, relocs: []const Relocation) !void {
|
||||
const gpa = macho_file.base.allocator;
|
||||
const comp = macho_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const gop = try macho_file.relocs.getOrPut(gpa, atom_index);
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = .{};
|
||||
@ -269,7 +270,8 @@ pub fn addRelocations(macho_file: *MachO, atom_index: Index, relocs: []const Rel
|
||||
}
|
||||
|
||||
pub fn addRebase(macho_file: *MachO, atom_index: Index, offset: u32) !void {
|
||||
const gpa = macho_file.base.allocator;
|
||||
const comp = macho_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const atom = macho_file.getAtom(atom_index);
|
||||
log.debug(" (adding rebase at offset 0x{x} in %{?d})", .{ offset, atom.getSymbolIndex() });
|
||||
const gop = try macho_file.rebases.getOrPut(gpa, atom_index);
|
||||
@ -280,7 +282,8 @@ pub fn addRebase(macho_file: *MachO, atom_index: Index, offset: u32) !void {
|
||||
}
|
||||
|
||||
pub fn addBinding(macho_file: *MachO, atom_index: Index, binding: Binding) !void {
|
||||
const gpa = macho_file.base.allocator;
|
||||
const comp = macho_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const atom = macho_file.getAtom(atom_index);
|
||||
log.debug(" (adding binding to symbol {s} at offset 0x{x} in %{?d})", .{
|
||||
macho_file.getSymbolName(binding.target),
|
||||
@ -307,7 +310,8 @@ pub fn resolveRelocations(
|
||||
}
|
||||
|
||||
pub fn freeRelocations(macho_file: *MachO, atom_index: Index) void {
|
||||
const gpa = macho_file.base.allocator;
|
||||
const comp = macho_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
var removed_relocs = macho_file.relocs.fetchOrderedRemove(atom_index);
|
||||
if (removed_relocs) |*relocs| relocs.value.deinit(gpa);
|
||||
var removed_rebases = macho_file.rebases.fetchOrderedRemove(atom_index);
|
||||
|
||||
@ -28,7 +28,6 @@ pub const base_tag = .plan9;
|
||||
|
||||
base: link.File,
|
||||
sixtyfour_bit: bool,
|
||||
error_flags: File.ErrorFlags = File.ErrorFlags{},
|
||||
bases: Bases,
|
||||
|
||||
/// A symbol's value is just casted down when compiling
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user