Merge pull request #6046 from heidezomp/std-log-scoped-part2
std.log: (breaking) remove scope parameter from logging functions
This commit is contained in:
commit
624e643872
@ -325,7 +325,7 @@ pub fn main() !void {
|
|||||||
represents writing data to a file. When the disk is full, a write to the file will fail.
|
represents writing data to a file. When the disk is full, a write to the file will fail.
|
||||||
However, we typically do not expect writing text to the standard output to fail. To avoid having
|
However, we typically do not expect writing text to the standard output to fail. To avoid having
|
||||||
to handle the failure case of printing to standard output, you can use alternate functions: the
|
to handle the failure case of printing to standard output, you can use alternate functions: the
|
||||||
<code>std.log</code> function for proper logging or the <code>std.debug.print</code> function.
|
functions in <code>std.log</code> for proper logging or the <code>std.debug.print</code> function.
|
||||||
This documentation will use the latter option to print to standard error (stderr) and silently return
|
This documentation will use the latter option to print to standard error (stderr) and silently return
|
||||||
on failure. The next code sample, <code>hello_again.zig</code> demonstrates the use of
|
on failure. The next code sample, <code>hello_again.zig</code> demonstrates the use of
|
||||||
<code>std.debug.print</code>.
|
<code>std.debug.print</code>.
|
||||||
|
@ -93,6 +93,7 @@
|
|||||||
//! in a `std.HashMap` using the backing allocator.
|
//! in a `std.HashMap` using the backing allocator.
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const log = std.log.scoped(.std);
|
||||||
const math = std.math;
|
const math = std.math;
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
@ -288,7 +289,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
|
|||||||
if (is_used) {
|
if (is_used) {
|
||||||
const slot_index = @intCast(SlotIndex, used_bits_byte * 8 + bit_index);
|
const slot_index = @intCast(SlotIndex, used_bits_byte * 8 + bit_index);
|
||||||
const stack_trace = bucketStackTrace(bucket, size_class, slot_index, .alloc);
|
const stack_trace = bucketStackTrace(bucket, size_class, slot_index, .alloc);
|
||||||
std.log.err(.std, "Memory leak detected: {}", .{stack_trace});
|
log.err("Memory leak detected: {}", .{stack_trace});
|
||||||
leaks = true;
|
leaks = true;
|
||||||
}
|
}
|
||||||
if (bit_index == math.maxInt(u3))
|
if (bit_index == math.maxInt(u3))
|
||||||
@ -315,7 +316,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (self.large_allocations.items()) |*large_alloc| {
|
for (self.large_allocations.items()) |*large_alloc| {
|
||||||
std.log.err(.std, "Memory leak detected: {}", .{large_alloc.value.getStackTrace()});
|
log.err("Memory leak detected: {}", .{large_alloc.value.getStackTrace()});
|
||||||
leaks = true;
|
leaks = true;
|
||||||
}
|
}
|
||||||
return leaks;
|
return leaks;
|
||||||
@ -450,7 +451,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
|
|||||||
.index = 0,
|
.index = 0,
|
||||||
};
|
};
|
||||||
std.debug.captureStackTrace(ret_addr, &free_stack_trace);
|
std.debug.captureStackTrace(ret_addr, &free_stack_trace);
|
||||||
std.log.err(.std, "Allocation size {} bytes does not match free size {}. Allocation: {} Free: {}", .{
|
log.err("Allocation size {} bytes does not match free size {}. Allocation: {} Free: {}", .{
|
||||||
entry.value.bytes.len,
|
entry.value.bytes.len,
|
||||||
old_mem.len,
|
old_mem.len,
|
||||||
entry.value.getStackTrace(),
|
entry.value.getStackTrace(),
|
||||||
@ -533,7 +534,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
|
|||||||
.index = 0,
|
.index = 0,
|
||||||
};
|
};
|
||||||
std.debug.captureStackTrace(ret_addr, &second_free_stack_trace);
|
std.debug.captureStackTrace(ret_addr, &second_free_stack_trace);
|
||||||
std.log.err(.std, "Double free detected. Allocation: {} First free: {} Second free: {}", .{
|
log.err("Double free detected. Allocation: {} First free: {} Second free: {}", .{
|
||||||
alloc_stack_trace,
|
alloc_stack_trace,
|
||||||
free_stack_trace,
|
free_stack_trace,
|
||||||
second_free_stack_trace,
|
second_free_stack_trace,
|
||||||
|
169
lib/std/log.zig
169
lib/std/log.zig
@ -6,12 +6,16 @@ const root = @import("root");
|
|||||||
//! of programs and libraries using this interface to be formatted and filtered
|
//! of programs and libraries using this interface to be formatted and filtered
|
||||||
//! by the implementer of the root.log function.
|
//! by the implementer of the root.log function.
|
||||||
//!
|
//!
|
||||||
//! The scope parameter should be used to give context to the logging. For
|
//! Each log message has an associated scope enum, which can be used to give
|
||||||
//! example, a library called 'libfoo' might use .libfoo as its scope.
|
//! context to the logging. The logging functions in std.log implicitly use a
|
||||||
//! This parameter can either be passed explicitly to the logging functions
|
//! scope of .default.
|
||||||
//! provided here, or a scoped logging namespace can be created
|
//!
|
||||||
//! using the `log.scoped` function. If logging scopes are not relevant for
|
//! A logging namespace using a custom scope can be created using the
|
||||||
//! your use case, the `log.default` scope namespace can be used.
|
//! std.log.scoped function, passing the scope as an argument; the logging
|
||||||
|
//! functions in the resulting struct use the provided scope parameter.
|
||||||
|
//! For example, a library called 'libfoo' might use
|
||||||
|
//! `const log = std.log.scoped(.libfoo);` to use .libfoo as the scope of its
|
||||||
|
//! log messages.
|
||||||
//!
|
//!
|
||||||
//! An example root.log might look something like this:
|
//! An example root.log might look something like this:
|
||||||
//!
|
//!
|
||||||
@ -29,9 +33,9 @@ const root = @import("root");
|
|||||||
//! args: anytype,
|
//! args: anytype,
|
||||||
//! ) void {
|
//! ) void {
|
||||||
//! // Ignore all non-critical logging from sources other than
|
//! // Ignore all non-critical logging from sources other than
|
||||||
//! // .my_project and .nice_library
|
//! // .my_project, .nice_library and .default
|
||||||
//! const scope_prefix = "(" ++ switch (scope) {
|
//! const scope_prefix = "(" ++ switch (scope) {
|
||||||
//! .my_project, .nice_library => @tagName(scope),
|
//! .my_project, .nice_library, .default => @tagName(scope),
|
||||||
//! else => if (@enumToInt(level) <= @enumToInt(std.log.Level.crit))
|
//! else => if (@enumToInt(level) <= @enumToInt(std.log.Level.crit))
|
||||||
//! @tagName(scope)
|
//! @tagName(scope)
|
||||||
//! else
|
//! else
|
||||||
@ -48,26 +52,24 @@ const root = @import("root");
|
|||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! pub fn main() void {
|
//! pub fn main() void {
|
||||||
//! // Using explicit scopes:
|
//! // Using the default scope:
|
||||||
//! // Won't be printed as log_level is .warn
|
//! std.log.info("Just a simple informational log message", .{}); // Won't be printed as log_level is .warn
|
||||||
//! std.log.info(.my_project, "Starting up.", .{});
|
//! std.log.warn("Flux capacitor is starting to overheat", .{});
|
||||||
//! std.log.err(.nice_library, "Something went very wrong, sorry.", .{});
|
|
||||||
//! // Won't be printed as it gets filtered out by our log function
|
|
||||||
//! std.log.err(.lib_that_logs_too_much, "Added 1 + 1", .{});
|
|
||||||
//!
|
//!
|
||||||
//! // Using a scoped logging namespace:
|
//! // Using scoped logging:
|
||||||
//! const scoped_log = std.log.scoped(.my_project);
|
//! const my_project_log = std.log.scoped(.my_project);
|
||||||
//! scoped_log.alert("The scope for this message is implicitly .my_project", .{});
|
//! const nice_library_log = std.log.scoped(.nice_library);
|
||||||
|
//! const verbose_lib_log = std.log.scoped(.verbose_lib);
|
||||||
//!
|
//!
|
||||||
//! // Using the default namespace:
|
//! my_project_log.info("Starting up", .{}); // Won't be printed as log_level is .warn
|
||||||
//! // Won't be printed as log_level is .warn
|
//! nice_library_log.err("Something went very wrong, sorry", .{});
|
||||||
//! std.log.default.info("I don't care about my namespace", .{});
|
//! verbose_lib_log.err("Added 1 + 1: {}", .{1 + 1}); // Won't be printed as it gets filtered out by our log function
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//! Which produces the following output:
|
//! Which produces the following output:
|
||||||
//! ```
|
//! ```
|
||||||
//! [err] (nice_library): Something went very wrong, sorry.
|
//! [warn] (default): Flux capacitor is starting to overheat
|
||||||
//! [alert] (my_project): The scope for this message is implicitly .my_project
|
//! [err] (nice_library): Something went very wrong, sorry
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
pub const Level = enum {
|
pub const Level = enum {
|
||||||
@ -129,92 +131,6 @@ fn log(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Log an emergency message. This log level is intended to be used
|
|
||||||
/// for conditions that cannot be handled and is usually followed by a panic.
|
|
||||||
pub fn emerg(
|
|
||||||
comptime scope: @Type(.EnumLiteral),
|
|
||||||
comptime format: []const u8,
|
|
||||||
args: anytype,
|
|
||||||
) void {
|
|
||||||
@setCold(true);
|
|
||||||
log(.emerg, scope, format, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Log an alert message. This log level is intended to be used for
|
|
||||||
/// conditions that should be corrected immediately (e.g. database corruption).
|
|
||||||
pub fn alert(
|
|
||||||
comptime scope: @Type(.EnumLiteral),
|
|
||||||
comptime format: []const u8,
|
|
||||||
args: anytype,
|
|
||||||
) void {
|
|
||||||
@setCold(true);
|
|
||||||
log(.alert, scope, format, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Log a critical message. This log level is intended to be used
|
|
||||||
/// when a bug has been detected or something has gone wrong and it will have
|
|
||||||
/// an effect on the operation of the program.
|
|
||||||
pub fn crit(
|
|
||||||
comptime scope: @Type(.EnumLiteral),
|
|
||||||
comptime format: []const u8,
|
|
||||||
args: anytype,
|
|
||||||
) void {
|
|
||||||
@setCold(true);
|
|
||||||
log(.crit, scope, format, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Log an error message. This log level is intended to be used when
|
|
||||||
/// a bug has been detected or something has gone wrong but it is recoverable.
|
|
||||||
pub fn err(
|
|
||||||
comptime scope: @Type(.EnumLiteral),
|
|
||||||
comptime format: []const u8,
|
|
||||||
args: anytype,
|
|
||||||
) void {
|
|
||||||
@setCold(true);
|
|
||||||
log(.err, scope, format, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Log a warning message. This log level is intended to be used if
|
|
||||||
/// it is uncertain whether something has gone wrong or not, but the
|
|
||||||
/// circumstances would be worth investigating.
|
|
||||||
pub fn warn(
|
|
||||||
comptime scope: @Type(.EnumLiteral),
|
|
||||||
comptime format: []const u8,
|
|
||||||
args: anytype,
|
|
||||||
) void {
|
|
||||||
log(.warn, scope, format, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Log a notice message. This log level is intended to be used for
|
|
||||||
/// non-error but significant conditions.
|
|
||||||
pub fn notice(
|
|
||||||
comptime scope: @Type(.EnumLiteral),
|
|
||||||
comptime format: []const u8,
|
|
||||||
args: anytype,
|
|
||||||
) void {
|
|
||||||
log(.notice, scope, format, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Log an info message. This log level is intended to be used for
|
|
||||||
/// general messages about the state of the program.
|
|
||||||
pub fn info(
|
|
||||||
comptime scope: @Type(.EnumLiteral),
|
|
||||||
comptime format: []const u8,
|
|
||||||
args: anytype,
|
|
||||||
) void {
|
|
||||||
log(.info, scope, format, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Log a debug message. This log level is intended to be used for
|
|
||||||
/// messages which are only useful for debugging.
|
|
||||||
pub fn debug(
|
|
||||||
comptime scope: @Type(.EnumLiteral),
|
|
||||||
comptime format: []const u8,
|
|
||||||
args: anytype,
|
|
||||||
) void {
|
|
||||||
log(.debug, scope, format, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a scoped logging namespace that logs all messages using the scope
|
/// Returns a scoped logging namespace that logs all messages using the scope
|
||||||
/// provided here.
|
/// provided here.
|
||||||
pub fn scoped(comptime scope: @Type(.EnumLiteral)) type {
|
pub fn scoped(comptime scope: @Type(.EnumLiteral)) type {
|
||||||
@ -301,3 +217,40 @@ pub fn scoped(comptime scope: @Type(.EnumLiteral)) type {
|
|||||||
|
|
||||||
/// The default scoped logging namespace.
|
/// The default scoped logging namespace.
|
||||||
pub const default = scoped(.default);
|
pub const default = scoped(.default);
|
||||||
|
|
||||||
|
/// Log an emergency message using the default scope. This log level is
|
||||||
|
/// intended to be used for conditions that cannot be handled and is usually
|
||||||
|
/// followed by a panic.
|
||||||
|
pub const emerg = default.emerg;
|
||||||
|
|
||||||
|
/// Log an alert message using the default scope. This log level is intended to
|
||||||
|
/// be used for conditions that should be corrected immediately (e.g. database
|
||||||
|
/// corruption).
|
||||||
|
pub const alert = default.alert;
|
||||||
|
|
||||||
|
/// Log a critical message using the default scope. This log level is intended
|
||||||
|
/// to be used when a bug has been detected or something has gone wrong and it
|
||||||
|
/// will have an effect on the operation of the program.
|
||||||
|
pub const crit = default.crit;
|
||||||
|
|
||||||
|
/// Log an error message using the default scope. This log level is intended to
|
||||||
|
/// be used when a bug has been detected or something has gone wrong but it is
|
||||||
|
/// recoverable.
|
||||||
|
pub const err = default.err;
|
||||||
|
|
||||||
|
/// Log a warning message using the default scope. This log level is intended
|
||||||
|
/// to be used if it is uncertain whether something has gone wrong or not, but
|
||||||
|
/// the circumstances would be worth investigating.
|
||||||
|
pub const warn = default.warn;
|
||||||
|
|
||||||
|
/// Log a notice message using the default scope. This log level is intended to
|
||||||
|
/// be used for non-error but significant conditions.
|
||||||
|
pub const notice = default.notice;
|
||||||
|
|
||||||
|
/// Log an info message using the default scope. This log level is intended to
|
||||||
|
/// be used for general messages about the state of the program.
|
||||||
|
pub const info = default.info;
|
||||||
|
|
||||||
|
/// Log a debug message using the default scope. This log level is intended to
|
||||||
|
/// be used for messages which are only useful for debugging.
|
||||||
|
pub const debug = default.debug;
|
||||||
|
@ -6,7 +6,7 @@ const Value = @import("value.zig").Value;
|
|||||||
const Type = @import("type.zig").Type;
|
const Type = @import("type.zig").Type;
|
||||||
const TypedValue = @import("TypedValue.zig");
|
const TypedValue = @import("TypedValue.zig");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const log = std.log;
|
const log = std.log.scoped(.module);
|
||||||
const BigIntConst = std.math.big.int.Const;
|
const BigIntConst = std.math.big.int.Const;
|
||||||
const BigIntMutable = std.math.big.int.Mutable;
|
const BigIntMutable = std.math.big.int.Mutable;
|
||||||
const Target = std.Target;
|
const Target = std.Target;
|
||||||
@ -1079,7 +1079,7 @@ pub fn performAllTheWork(self: *Module) error{OutOfMemory}!void {
|
|||||||
// lifetime annotations in the ZIR.
|
// lifetime annotations in the ZIR.
|
||||||
var decl_arena = decl.typed_value.most_recent.arena.?.promote(self.gpa);
|
var decl_arena = decl.typed_value.most_recent.arena.?.promote(self.gpa);
|
||||||
defer decl.typed_value.most_recent.arena.?.* = decl_arena.state;
|
defer decl.typed_value.most_recent.arena.?.* = decl_arena.state;
|
||||||
std.log.debug(.module, "analyze liveness of {}\n", .{decl.name});
|
log.debug("analyze liveness of {}\n", .{decl.name});
|
||||||
try liveness.analyze(self.gpa, &decl_arena.allocator, payload.func.analysis.success);
|
try liveness.analyze(self.gpa, &decl_arena.allocator, payload.func.analysis.success);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1141,7 +1141,7 @@ pub fn ensureDeclAnalyzed(self: *Module, decl: *Decl) InnerError!void {
|
|||||||
.complete => return,
|
.complete => return,
|
||||||
|
|
||||||
.outdated => blk: {
|
.outdated => blk: {
|
||||||
log.debug(.module, "re-analyzing {}\n", .{decl.name});
|
log.debug("re-analyzing {}\n", .{decl.name});
|
||||||
|
|
||||||
// The exports this Decl performs will be re-discovered, so we remove them here
|
// The exports this Decl performs will be re-discovered, so we remove them here
|
||||||
// prior to re-analysis.
|
// prior to re-analysis.
|
||||||
@ -1592,7 +1592,7 @@ fn analyzeRootSrcFile(self: *Module, root_scope: *Scope.File) !void {
|
|||||||
// Handle explicitly deleted decls from the source code. Not to be confused
|
// Handle explicitly deleted decls from the source code. Not to be confused
|
||||||
// with when we delete decls because they are no longer referenced.
|
// with when we delete decls because they are no longer referenced.
|
||||||
for (deleted_decls.items()) |entry| {
|
for (deleted_decls.items()) |entry| {
|
||||||
log.debug(.module, "noticed '{}' deleted from source\n", .{entry.key.name});
|
log.debug("noticed '{}' deleted from source\n", .{entry.key.name});
|
||||||
try self.deleteDecl(entry.key);
|
try self.deleteDecl(entry.key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1645,7 +1645,7 @@ fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void {
|
|||||||
// Handle explicitly deleted decls from the source code. Not to be confused
|
// Handle explicitly deleted decls from the source code. Not to be confused
|
||||||
// with when we delete decls because they are no longer referenced.
|
// with when we delete decls because they are no longer referenced.
|
||||||
for (deleted_decls.items()) |entry| {
|
for (deleted_decls.items()) |entry| {
|
||||||
log.debug(.module, "noticed '{}' deleted from source\n", .{entry.key.name});
|
log.debug("noticed '{}' deleted from source\n", .{entry.key.name});
|
||||||
try self.deleteDecl(entry.key);
|
try self.deleteDecl(entry.key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1657,7 +1657,7 @@ fn deleteDecl(self: *Module, decl: *Decl) !void {
|
|||||||
// not be present in the set, and this does nothing.
|
// not be present in the set, and this does nothing.
|
||||||
decl.scope.removeDecl(decl);
|
decl.scope.removeDecl(decl);
|
||||||
|
|
||||||
log.debug(.module, "deleting decl '{}'\n", .{decl.name});
|
log.debug("deleting decl '{}'\n", .{decl.name});
|
||||||
const name_hash = decl.fullyQualifiedNameHash();
|
const name_hash = decl.fullyQualifiedNameHash();
|
||||||
self.decl_table.removeAssertDiscard(name_hash);
|
self.decl_table.removeAssertDiscard(name_hash);
|
||||||
// Remove itself from its dependencies, because we are about to destroy the decl pointer.
|
// Remove itself from its dependencies, because we are about to destroy the decl pointer.
|
||||||
@ -1744,17 +1744,17 @@ fn analyzeFnBody(self: *Module, decl: *Decl, func: *Fn) !void {
|
|||||||
const fn_zir = func.analysis.queued;
|
const fn_zir = func.analysis.queued;
|
||||||
defer fn_zir.arena.promote(self.gpa).deinit();
|
defer fn_zir.arena.promote(self.gpa).deinit();
|
||||||
func.analysis = .{ .in_progress = {} };
|
func.analysis = .{ .in_progress = {} };
|
||||||
log.debug(.module, "set {} to in_progress\n", .{decl.name});
|
log.debug("set {} to in_progress\n", .{decl.name});
|
||||||
|
|
||||||
try zir_sema.analyzeBody(self, &inner_block.base, fn_zir.body);
|
try zir_sema.analyzeBody(self, &inner_block.base, fn_zir.body);
|
||||||
|
|
||||||
const instructions = try arena.allocator.dupe(*Inst, inner_block.instructions.items);
|
const instructions = try arena.allocator.dupe(*Inst, inner_block.instructions.items);
|
||||||
func.analysis = .{ .success = .{ .instructions = instructions } };
|
func.analysis = .{ .success = .{ .instructions = instructions } };
|
||||||
log.debug(.module, "set {} to success\n", .{decl.name});
|
log.debug("set {} to success\n", .{decl.name});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn markOutdatedDecl(self: *Module, decl: *Decl) !void {
|
fn markOutdatedDecl(self: *Module, decl: *Decl) !void {
|
||||||
log.debug(.module, "mark {} outdated\n", .{decl.name});
|
log.debug("mark {} outdated\n", .{decl.name});
|
||||||
try self.work_queue.writeItem(.{ .analyze_decl = decl });
|
try self.work_queue.writeItem(.{ .analyze_decl = decl });
|
||||||
if (self.failed_decls.remove(decl)) |entry| {
|
if (self.failed_decls.remove(decl)) |entry| {
|
||||||
entry.value.destroy(self.gpa);
|
entry.value.destroy(self.gpa);
|
||||||
|
@ -8,7 +8,7 @@ const fs = std.fs;
|
|||||||
const elf = std.elf;
|
const elf = std.elf;
|
||||||
const codegen = @import("codegen.zig");
|
const codegen = @import("codegen.zig");
|
||||||
const c_codegen = @import("codegen/c.zig");
|
const c_codegen = @import("codegen/c.zig");
|
||||||
const log = std.log;
|
const log = std.log.scoped(.link);
|
||||||
const DW = std.dwarf;
|
const DW = std.dwarf;
|
||||||
const trace = @import("tracy.zig").trace;
|
const trace = @import("tracy.zig").trace;
|
||||||
const leb128 = std.debug.leb;
|
const leb128 = std.debug.leb;
|
||||||
@ -746,7 +746,7 @@ pub const File = struct {
|
|||||||
const file_size = self.base.options.program_code_size_hint;
|
const file_size = self.base.options.program_code_size_hint;
|
||||||
const p_align = 0x1000;
|
const p_align = 0x1000;
|
||||||
const off = self.findFreeSpace(file_size, p_align);
|
const off = self.findFreeSpace(file_size, p_align);
|
||||||
log.debug(.link, "found PT_LOAD free space 0x{x} to 0x{x}\n", .{ off, off + file_size });
|
log.debug("found PT_LOAD free space 0x{x} to 0x{x}\n", .{ off, off + file_size });
|
||||||
try self.program_headers.append(self.base.allocator, .{
|
try self.program_headers.append(self.base.allocator, .{
|
||||||
.p_type = elf.PT_LOAD,
|
.p_type = elf.PT_LOAD,
|
||||||
.p_offset = off,
|
.p_offset = off,
|
||||||
@ -767,7 +767,7 @@ pub const File = struct {
|
|||||||
// page align.
|
// page align.
|
||||||
const p_align = if (self.base.options.target.os.tag == .linux) 0x1000 else @as(u16, ptr_size);
|
const p_align = if (self.base.options.target.os.tag == .linux) 0x1000 else @as(u16, ptr_size);
|
||||||
const off = self.findFreeSpace(file_size, p_align);
|
const off = self.findFreeSpace(file_size, p_align);
|
||||||
log.debug(.link, "found PT_LOAD free space 0x{x} to 0x{x}\n", .{ off, off + file_size });
|
log.debug("found PT_LOAD free space 0x{x} to 0x{x}\n", .{ off, off + file_size });
|
||||||
// TODO instead of hard coding the vaddr, make a function to find a vaddr to put things at.
|
// TODO instead of hard coding the vaddr, make a function to find a vaddr to put things at.
|
||||||
// we'll need to re-use that function anyway, in case the GOT grows and overlaps something
|
// we'll need to re-use that function anyway, in case the GOT grows and overlaps something
|
||||||
// else in virtual memory.
|
// else in virtual memory.
|
||||||
@ -789,7 +789,7 @@ pub const File = struct {
|
|||||||
assert(self.shstrtab.items.len == 0);
|
assert(self.shstrtab.items.len == 0);
|
||||||
try self.shstrtab.append(self.base.allocator, 0); // need a 0 at position 0
|
try self.shstrtab.append(self.base.allocator, 0); // need a 0 at position 0
|
||||||
const off = self.findFreeSpace(self.shstrtab.items.len, 1);
|
const off = self.findFreeSpace(self.shstrtab.items.len, 1);
|
||||||
log.debug(.link, "found shstrtab free space 0x{x} to 0x{x}\n", .{ off, off + self.shstrtab.items.len });
|
log.debug("found shstrtab free space 0x{x} to 0x{x}\n", .{ off, off + self.shstrtab.items.len });
|
||||||
try self.sections.append(self.base.allocator, .{
|
try self.sections.append(self.base.allocator, .{
|
||||||
.sh_name = try self.makeString(".shstrtab"),
|
.sh_name = try self.makeString(".shstrtab"),
|
||||||
.sh_type = elf.SHT_STRTAB,
|
.sh_type = elf.SHT_STRTAB,
|
||||||
@ -847,7 +847,7 @@ pub const File = struct {
|
|||||||
const each_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Sym) else @sizeOf(elf.Elf64_Sym);
|
const each_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Sym) else @sizeOf(elf.Elf64_Sym);
|
||||||
const file_size = self.base.options.symbol_count_hint * each_size;
|
const file_size = self.base.options.symbol_count_hint * each_size;
|
||||||
const off = self.findFreeSpace(file_size, min_align);
|
const off = self.findFreeSpace(file_size, min_align);
|
||||||
log.debug(.link, "found symtab free space 0x{x} to 0x{x}\n", .{ off, off + file_size });
|
log.debug("found symtab free space 0x{x} to 0x{x}\n", .{ off, off + file_size });
|
||||||
|
|
||||||
try self.sections.append(self.base.allocator, .{
|
try self.sections.append(self.base.allocator, .{
|
||||||
.sh_name = try self.makeString(".symtab"),
|
.sh_name = try self.makeString(".symtab"),
|
||||||
@ -889,7 +889,7 @@ pub const File = struct {
|
|||||||
const file_size_hint = 200;
|
const file_size_hint = 200;
|
||||||
const p_align = 1;
|
const p_align = 1;
|
||||||
const off = self.findFreeSpace(file_size_hint, p_align);
|
const off = self.findFreeSpace(file_size_hint, p_align);
|
||||||
log.debug(.link, "found .debug_info free space 0x{x} to 0x{x}\n", .{
|
log.debug("found .debug_info free space 0x{x} to 0x{x}\n", .{
|
||||||
off,
|
off,
|
||||||
off + file_size_hint,
|
off + file_size_hint,
|
||||||
});
|
});
|
||||||
@ -914,7 +914,7 @@ pub const File = struct {
|
|||||||
const file_size_hint = 128;
|
const file_size_hint = 128;
|
||||||
const p_align = 1;
|
const p_align = 1;
|
||||||
const off = self.findFreeSpace(file_size_hint, p_align);
|
const off = self.findFreeSpace(file_size_hint, p_align);
|
||||||
log.debug(.link, "found .debug_abbrev free space 0x{x} to 0x{x}\n", .{
|
log.debug("found .debug_abbrev free space 0x{x} to 0x{x}\n", .{
|
||||||
off,
|
off,
|
||||||
off + file_size_hint,
|
off + file_size_hint,
|
||||||
});
|
});
|
||||||
@ -939,7 +939,7 @@ pub const File = struct {
|
|||||||
const file_size_hint = 160;
|
const file_size_hint = 160;
|
||||||
const p_align = 16;
|
const p_align = 16;
|
||||||
const off = self.findFreeSpace(file_size_hint, p_align);
|
const off = self.findFreeSpace(file_size_hint, p_align);
|
||||||
log.debug(.link, "found .debug_aranges free space 0x{x} to 0x{x}\n", .{
|
log.debug("found .debug_aranges free space 0x{x} to 0x{x}\n", .{
|
||||||
off,
|
off,
|
||||||
off + file_size_hint,
|
off + file_size_hint,
|
||||||
});
|
});
|
||||||
@ -964,7 +964,7 @@ pub const File = struct {
|
|||||||
const file_size_hint = 250;
|
const file_size_hint = 250;
|
||||||
const p_align = 1;
|
const p_align = 1;
|
||||||
const off = self.findFreeSpace(file_size_hint, p_align);
|
const off = self.findFreeSpace(file_size_hint, p_align);
|
||||||
log.debug(.link, "found .debug_line free space 0x{x} to 0x{x}\n", .{
|
log.debug("found .debug_line free space 0x{x} to 0x{x}\n", .{
|
||||||
off,
|
off,
|
||||||
off + file_size_hint,
|
off + file_size_hint,
|
||||||
});
|
});
|
||||||
@ -1090,7 +1090,7 @@ pub const File = struct {
|
|||||||
debug_abbrev_sect.sh_offset = self.findFreeSpace(needed_size, 1);
|
debug_abbrev_sect.sh_offset = self.findFreeSpace(needed_size, 1);
|
||||||
}
|
}
|
||||||
debug_abbrev_sect.sh_size = needed_size;
|
debug_abbrev_sect.sh_size = needed_size;
|
||||||
log.debug(.link, ".debug_abbrev start=0x{x} end=0x{x}\n", .{
|
log.debug(".debug_abbrev start=0x{x} end=0x{x}\n", .{
|
||||||
debug_abbrev_sect.sh_offset,
|
debug_abbrev_sect.sh_offset,
|
||||||
debug_abbrev_sect.sh_offset + needed_size,
|
debug_abbrev_sect.sh_offset + needed_size,
|
||||||
});
|
});
|
||||||
@ -1237,7 +1237,7 @@ pub const File = struct {
|
|||||||
debug_aranges_sect.sh_offset = self.findFreeSpace(needed_size, 16);
|
debug_aranges_sect.sh_offset = self.findFreeSpace(needed_size, 16);
|
||||||
}
|
}
|
||||||
debug_aranges_sect.sh_size = needed_size;
|
debug_aranges_sect.sh_size = needed_size;
|
||||||
log.debug(.link, ".debug_aranges start=0x{x} end=0x{x}\n", .{
|
log.debug(".debug_aranges start=0x{x} end=0x{x}\n", .{
|
||||||
debug_aranges_sect.sh_offset,
|
debug_aranges_sect.sh_offset,
|
||||||
debug_aranges_sect.sh_offset + needed_size,
|
debug_aranges_sect.sh_offset + needed_size,
|
||||||
});
|
});
|
||||||
@ -1405,7 +1405,7 @@ pub const File = struct {
|
|||||||
shstrtab_sect.sh_offset = self.findFreeSpace(needed_size, 1);
|
shstrtab_sect.sh_offset = self.findFreeSpace(needed_size, 1);
|
||||||
}
|
}
|
||||||
shstrtab_sect.sh_size = needed_size;
|
shstrtab_sect.sh_size = needed_size;
|
||||||
log.debug(.link, "writing shstrtab start=0x{x} end=0x{x}\n", .{ shstrtab_sect.sh_offset, shstrtab_sect.sh_offset + needed_size });
|
log.debug("writing shstrtab start=0x{x} end=0x{x}\n", .{ shstrtab_sect.sh_offset, shstrtab_sect.sh_offset + needed_size });
|
||||||
|
|
||||||
try self.base.file.?.pwriteAll(self.shstrtab.items, shstrtab_sect.sh_offset);
|
try self.base.file.?.pwriteAll(self.shstrtab.items, shstrtab_sect.sh_offset);
|
||||||
if (!self.shdr_table_dirty) {
|
if (!self.shdr_table_dirty) {
|
||||||
@ -1426,7 +1426,7 @@ pub const File = struct {
|
|||||||
debug_strtab_sect.sh_offset = self.findFreeSpace(needed_size, 1);
|
debug_strtab_sect.sh_offset = self.findFreeSpace(needed_size, 1);
|
||||||
}
|
}
|
||||||
debug_strtab_sect.sh_size = needed_size;
|
debug_strtab_sect.sh_size = needed_size;
|
||||||
log.debug(.link, "debug_strtab start=0x{x} end=0x{x}\n", .{ debug_strtab_sect.sh_offset, debug_strtab_sect.sh_offset + needed_size });
|
log.debug("debug_strtab start=0x{x} end=0x{x}\n", .{ debug_strtab_sect.sh_offset, debug_strtab_sect.sh_offset + needed_size });
|
||||||
|
|
||||||
try self.base.file.?.pwriteAll(self.debug_strtab.items, debug_strtab_sect.sh_offset);
|
try self.base.file.?.pwriteAll(self.debug_strtab.items, debug_strtab_sect.sh_offset);
|
||||||
if (!self.shdr_table_dirty) {
|
if (!self.shdr_table_dirty) {
|
||||||
@ -1460,7 +1460,7 @@ pub const File = struct {
|
|||||||
|
|
||||||
for (buf) |*shdr, i| {
|
for (buf) |*shdr, i| {
|
||||||
shdr.* = sectHeaderTo32(self.sections.items[i]);
|
shdr.* = sectHeaderTo32(self.sections.items[i]);
|
||||||
std.log.debug(.link, "writing section {}\n", .{shdr.*});
|
log.debug("writing section {}\n", .{shdr.*});
|
||||||
if (foreign_endian) {
|
if (foreign_endian) {
|
||||||
bswapAllFields(elf.Elf32_Shdr, shdr);
|
bswapAllFields(elf.Elf32_Shdr, shdr);
|
||||||
}
|
}
|
||||||
@ -1473,7 +1473,7 @@ pub const File = struct {
|
|||||||
|
|
||||||
for (buf) |*shdr, i| {
|
for (buf) |*shdr, i| {
|
||||||
shdr.* = self.sections.items[i];
|
shdr.* = self.sections.items[i];
|
||||||
log.debug(.link, "writing section {}\n", .{shdr.*});
|
log.debug("writing section {}\n", .{shdr.*});
|
||||||
if (foreign_endian) {
|
if (foreign_endian) {
|
||||||
bswapAllFields(elf.Elf64_Shdr, shdr);
|
bswapAllFields(elf.Elf64_Shdr, shdr);
|
||||||
}
|
}
|
||||||
@ -1484,10 +1484,10 @@ pub const File = struct {
|
|||||||
self.shdr_table_dirty = false;
|
self.shdr_table_dirty = false;
|
||||||
}
|
}
|
||||||
if (self.entry_addr == null and self.base.options.output_mode == .Exe) {
|
if (self.entry_addr == null and self.base.options.output_mode == .Exe) {
|
||||||
log.debug(.link, "flushing. no_entry_point_found = true\n", .{});
|
log.debug("flushing. no_entry_point_found = true\n", .{});
|
||||||
self.error_flags.no_entry_point_found = true;
|
self.error_flags.no_entry_point_found = true;
|
||||||
} else {
|
} else {
|
||||||
log.debug(.link, "flushing. no_entry_point_found = false\n", .{});
|
log.debug("flushing. no_entry_point_found = false\n", .{});
|
||||||
self.error_flags.no_entry_point_found = false;
|
self.error_flags.no_entry_point_found = false;
|
||||||
try self.writeElfHeader();
|
try self.writeElfHeader();
|
||||||
}
|
}
|
||||||
@ -1816,10 +1816,10 @@ pub const File = struct {
|
|||||||
try self.offset_table.ensureCapacity(self.base.allocator, self.offset_table.items.len + 1);
|
try self.offset_table.ensureCapacity(self.base.allocator, self.offset_table.items.len + 1);
|
||||||
|
|
||||||
if (self.local_symbol_free_list.popOrNull()) |i| {
|
if (self.local_symbol_free_list.popOrNull()) |i| {
|
||||||
log.debug(.link, "reusing symbol index {} for {}\n", .{ i, decl.name });
|
log.debug("reusing symbol index {} for {}\n", .{ i, decl.name });
|
||||||
decl.link.elf.local_sym_index = i;
|
decl.link.elf.local_sym_index = i;
|
||||||
} else {
|
} else {
|
||||||
log.debug(.link, "allocating symbol index {} for {}\n", .{ self.local_symbols.items.len, decl.name });
|
log.debug("allocating symbol index {} for {}\n", .{ self.local_symbols.items.len, decl.name });
|
||||||
decl.link.elf.local_sym_index = @intCast(u32, self.local_symbols.items.len);
|
decl.link.elf.local_sym_index = @intCast(u32, self.local_symbols.items.len);
|
||||||
_ = self.local_symbols.addOneAssumeCapacity();
|
_ = self.local_symbols.addOneAssumeCapacity();
|
||||||
}
|
}
|
||||||
@ -2016,11 +2016,11 @@ pub const File = struct {
|
|||||||
!mem.isAlignedGeneric(u64, local_sym.st_value, required_alignment);
|
!mem.isAlignedGeneric(u64, local_sym.st_value, required_alignment);
|
||||||
if (need_realloc) {
|
if (need_realloc) {
|
||||||
const vaddr = try self.growTextBlock(&decl.link.elf, code.len, required_alignment);
|
const vaddr = try self.growTextBlock(&decl.link.elf, code.len, required_alignment);
|
||||||
log.debug(.link, "growing {} from 0x{x} to 0x{x}\n", .{ decl.name, local_sym.st_value, vaddr });
|
log.debug("growing {} from 0x{x} to 0x{x}\n", .{ decl.name, local_sym.st_value, vaddr });
|
||||||
if (vaddr != local_sym.st_value) {
|
if (vaddr != local_sym.st_value) {
|
||||||
local_sym.st_value = vaddr;
|
local_sym.st_value = vaddr;
|
||||||
|
|
||||||
log.debug(.link, " (writing new offset table entry)\n", .{});
|
log.debug(" (writing new offset table entry)\n", .{});
|
||||||
self.offset_table.items[decl.link.elf.offset_table_index] = vaddr;
|
self.offset_table.items[decl.link.elf.offset_table_index] = vaddr;
|
||||||
try self.writeOffsetTableEntry(decl.link.elf.offset_table_index);
|
try self.writeOffsetTableEntry(decl.link.elf.offset_table_index);
|
||||||
}
|
}
|
||||||
@ -2038,7 +2038,7 @@ pub const File = struct {
|
|||||||
const decl_name = mem.spanZ(decl.name);
|
const decl_name = mem.spanZ(decl.name);
|
||||||
const name_str_index = try self.makeString(decl_name);
|
const name_str_index = try self.makeString(decl_name);
|
||||||
const vaddr = try self.allocateTextBlock(&decl.link.elf, code.len, required_alignment);
|
const vaddr = try self.allocateTextBlock(&decl.link.elf, code.len, required_alignment);
|
||||||
log.debug(.link, "allocated text block for {} at 0x{x}\n", .{ decl_name, vaddr });
|
log.debug("allocated text block for {} at 0x{x}\n", .{ decl_name, vaddr });
|
||||||
errdefer self.freeTextBlock(&decl.link.elf);
|
errdefer self.freeTextBlock(&decl.link.elf);
|
||||||
|
|
||||||
local_sym.* = .{
|
local_sym.* = .{
|
||||||
@ -2148,7 +2148,7 @@ pub const File = struct {
|
|||||||
if (needed_size > self.allocatedSize(debug_line_sect.sh_offset)) {
|
if (needed_size > self.allocatedSize(debug_line_sect.sh_offset)) {
|
||||||
const new_offset = self.findFreeSpace(needed_size, 1);
|
const new_offset = self.findFreeSpace(needed_size, 1);
|
||||||
const existing_size = last_src_fn.off;
|
const existing_size = last_src_fn.off;
|
||||||
log.debug(.link, "moving .debug_line section: {} bytes from 0x{x} to 0x{x}\n", .{
|
log.debug("moving .debug_line section: {} bytes from 0x{x} to 0x{x}\n", .{
|
||||||
existing_size,
|
existing_size,
|
||||||
debug_line_sect.sh_offset,
|
debug_line_sect.sh_offset,
|
||||||
new_offset,
|
new_offset,
|
||||||
@ -2227,7 +2227,7 @@ pub const File = struct {
|
|||||||
try dbg_info_buffer.writer().print("{}\x00", .{ty});
|
try dbg_info_buffer.writer().print("{}\x00", .{ty});
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
log.err(.compiler, "TODO implement .debug_info for type '{}'", .{ty});
|
std.log.scoped(.compiler).err("TODO implement .debug_info for type '{}'", .{ty});
|
||||||
try dbg_info_buffer.append(abbrev_pad1);
|
try dbg_info_buffer.append(abbrev_pad1);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -2299,7 +2299,7 @@ pub const File = struct {
|
|||||||
if (needed_size > self.allocatedSize(debug_info_sect.sh_offset)) {
|
if (needed_size > self.allocatedSize(debug_info_sect.sh_offset)) {
|
||||||
const new_offset = self.findFreeSpace(needed_size, 1);
|
const new_offset = self.findFreeSpace(needed_size, 1);
|
||||||
const existing_size = last_decl.dbg_info_off;
|
const existing_size = last_decl.dbg_info_off;
|
||||||
log.debug(.link, "moving .debug_info section: {} bytes from 0x{x} to 0x{x}\n", .{
|
log.debug("moving .debug_info section: {} bytes from 0x{x} to 0x{x}\n", .{
|
||||||
existing_size,
|
existing_size,
|
||||||
debug_info_sect.sh_offset,
|
debug_info_sect.sh_offset,
|
||||||
new_offset,
|
new_offset,
|
||||||
|
@ -151,5 +151,5 @@ fn analyzeInst(
|
|||||||
@panic("Handle liveness analysis for instructions with many parameters");
|
@panic("Handle liveness analysis for instructions with many parameters");
|
||||||
}
|
}
|
||||||
|
|
||||||
std.log.debug(.liveness, "analyze {}: 0b{b}\n", .{ base.tag, base.deaths });
|
std.log.scoped(.liveness).debug("analyze {}: 0b{b}\n", .{ base.tag, base.deaths });
|
||||||
}
|
}
|
||||||
|
@ -557,7 +557,7 @@ fn updateModule(gpa: *Allocator, module: *Module, zir_out_path: ?[]const u8) !vo
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std.log.info(.compiler, "Update completed in {} ms\n", .{update_nanos / std.time.ns_per_ms});
|
std.log.scoped(.compiler).info("Update completed in {} ms\n", .{update_nanos / std.time.ns_per_ms});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zir_out_path) |zop| {
|
if (zir_out_path) |zop| {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user