mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-08 02:44:43 +01:00
Merge pull request #20767 from ziglang/emit-options
add "trace pc guard" as optional additional coverage instrumentation
This commit is contained in:
commit
75cf7fca90
11 changed files with 233 additions and 100 deletions
|
|
@ -217,6 +217,14 @@ no_builtin: bool = false,
|
|||
/// Managed by the build runner, not user build script.
|
||||
zig_process: ?*Step.ZigProcess,
|
||||
|
||||
/// Enables deprecated coverage instrumentation that is only useful if you
|
||||
/// are using third party fuzzers that depend on it. Otherwise, slows down
|
||||
/// the instrumented binary with unnecessary function calls.
|
||||
///
|
||||
/// To enable fuzz testing instrumentation on a compilation, see the `fuzz`
|
||||
/// flag in `Module`.
|
||||
sanitize_coverage_trace_pc_guard: ?bool = null,
|
||||
|
||||
pub const ExpectedCompileErrors = union(enum) {
|
||||
contains: []const u8,
|
||||
exact: []const []const u8,
|
||||
|
|
@ -1656,6 +1664,7 @@ fn getZigArgs(compile: *Compile) ![][]const u8 {
|
|||
|
||||
try addFlag(&zig_args, "PIE", compile.pie);
|
||||
try addFlag(&zig_args, "lto", compile.want_lto);
|
||||
try addFlag(&zig_args, "sanitize-coverage-trace-pc-guard", compile.sanitize_coverage_trace_pc_guard);
|
||||
|
||||
if (compile.subsystem) |subsystem| {
|
||||
try zig_args.append("--subsystem");
|
||||
|
|
|
|||
|
|
@ -1412,6 +1412,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
|
|||
cache_helpers.addOptionalEmitLoc(&cache.hash, options.emit_docs);
|
||||
cache.hash.addBytes(options.root_name);
|
||||
cache.hash.add(options.config.wasi_exec_model);
|
||||
cache.hash.add(options.config.san_cov_trace_pc_guard);
|
||||
// TODO audit this and make sure everything is in it
|
||||
|
||||
const main_mod = options.main_mod orelse options.root_mod;
|
||||
|
|
@ -5652,6 +5653,10 @@ pub fn addCCArgs(
|
|||
// function was called.
|
||||
try argv.append("-fno-sanitize=function");
|
||||
}
|
||||
|
||||
if (comp.config.san_cov_trace_pc_guard) {
|
||||
try argv.appendSlice(&.{ "-Xclang", "-fsanitize-coverage-trace-pc-guard" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ root_strip: bool,
|
|||
root_error_tracing: bool,
|
||||
dll_export_fns: bool,
|
||||
rdynamic: bool,
|
||||
san_cov_trace_pc_guard: bool,
|
||||
|
||||
pub const CFrontend = enum { clang, aro };
|
||||
|
||||
|
|
@ -108,6 +109,7 @@ pub const Options = struct {
|
|||
debug_format: ?DebugFormat = null,
|
||||
dll_export_fns: ?bool = null,
|
||||
rdynamic: ?bool = null,
|
||||
san_cov_trace_pc_guard: bool = false,
|
||||
};
|
||||
|
||||
pub const ResolveError = error{
|
||||
|
|
@ -489,6 +491,7 @@ pub fn resolve(options: Options) ResolveError!Config {
|
|||
.any_error_tracing = any_error_tracing,
|
||||
.any_sanitize_thread = options.any_sanitize_thread,
|
||||
.any_fuzz = options.any_fuzz,
|
||||
.san_cov_trace_pc_guard = options.san_cov_trace_pc_guard,
|
||||
.root_error_tracing = root_error_tracing,
|
||||
.pie = pie,
|
||||
.lto = lto,
|
||||
|
|
|
|||
|
|
@ -3825,7 +3825,14 @@ flagpd1("fsanitize-coverage-trace-div"),
|
|||
flagpd1("fsanitize-coverage-trace-gep"),
|
||||
flagpd1("fsanitize-coverage-trace-loads"),
|
||||
flagpd1("fsanitize-coverage-trace-pc"),
|
||||
flagpd1("fsanitize-coverage-trace-pc-guard"),
|
||||
.{
|
||||
.name = "fsanitize-coverage-trace-pc-guard",
|
||||
.syntax = .flag,
|
||||
.zig_equivalent = .san_cov_trace_pc_guard,
|
||||
.pd1 = true,
|
||||
.pd2 = false,
|
||||
.psl = false,
|
||||
},
|
||||
flagpd1("fsanitize-coverage-trace-stores"),
|
||||
flagpd1("fsanitize-hwaddress-experimental-aliasing"),
|
||||
flagpd1("fsanitize-link-c++-runtime"),
|
||||
|
|
@ -6012,7 +6019,7 @@ joinpd1("fmodules-ignore-macro="),
|
|||
.{
|
||||
.name = "fno-sanitize-coverage=",
|
||||
.syntax = .comma_joined,
|
||||
.zig_equivalent = .other,
|
||||
.zig_equivalent = .no_san_cov,
|
||||
.pd1 = true,
|
||||
.pd2 = false,
|
||||
.psl = false,
|
||||
|
|
@ -6149,7 +6156,7 @@ joinpd1("fprofile-instr-use="),
|
|||
.{
|
||||
.name = "fsanitize-coverage=",
|
||||
.syntax = .comma_joined,
|
||||
.zig_equivalent = .other,
|
||||
.zig_equivalent = .san_cov,
|
||||
.pd1 = true,
|
||||
.pd2 = false,
|
||||
.psl = false,
|
||||
|
|
|
|||
|
|
@ -1278,50 +1278,52 @@ pub const Object = struct {
|
|||
// Unfortunately, LLVM shits the bed when we ask for both binary and assembly.
|
||||
// So we call the entire pipeline multiple times if this is requested.
|
||||
// var error_message: [*:0]const u8 = undefined;
|
||||
var emit_bin_path = options.bin_path;
|
||||
var post_ir_path = options.post_ir_path;
|
||||
var lowered_options: llvm.TargetMachine.EmitOptions = .{
|
||||
.is_debug = options.is_debug,
|
||||
.is_small = options.is_small,
|
||||
.time_report = options.time_report,
|
||||
.tsan = options.sanitize_thread,
|
||||
.sancov = options.fuzz,
|
||||
.lto = options.lto,
|
||||
.asm_filename = null,
|
||||
.bin_filename = options.bin_path,
|
||||
.llvm_ir_filename = options.post_ir_path,
|
||||
.bitcode_filename = null,
|
||||
.coverage = .{
|
||||
.CoverageType = .Edge,
|
||||
.IndirectCalls = true,
|
||||
.TraceBB = false,
|
||||
.TraceCmp = true,
|
||||
.TraceDiv = false,
|
||||
.TraceGep = false,
|
||||
.Use8bitCounters = false,
|
||||
.TracePC = false,
|
||||
.TracePCGuard = comp.config.san_cov_trace_pc_guard,
|
||||
.Inline8bitCounters = true,
|
||||
.InlineBoolFlag = false,
|
||||
.PCTable = true,
|
||||
.NoPrune = false,
|
||||
.StackDepth = true,
|
||||
.TraceLoads = false,
|
||||
.TraceStores = false,
|
||||
.CollectControlFlow = false,
|
||||
},
|
||||
};
|
||||
if (options.asm_path != null and options.bin_path != null) {
|
||||
if (target_machine.emitToFile(
|
||||
module,
|
||||
&error_message,
|
||||
options.is_debug,
|
||||
options.is_small,
|
||||
options.time_report,
|
||||
options.sanitize_thread,
|
||||
options.fuzz,
|
||||
options.lto,
|
||||
null,
|
||||
emit_bin_path,
|
||||
post_ir_path,
|
||||
null,
|
||||
)) {
|
||||
if (target_machine.emitToFile(module, &error_message, lowered_options)) {
|
||||
defer llvm.disposeMessage(error_message);
|
||||
|
||||
log.err("LLVM failed to emit bin={s} ir={s}: {s}", .{
|
||||
emit_bin_msg, post_llvm_ir_msg, error_message,
|
||||
});
|
||||
return error.FailedToEmit;
|
||||
}
|
||||
emit_bin_path = null;
|
||||
post_ir_path = null;
|
||||
lowered_options.bin_filename = null;
|
||||
lowered_options.llvm_ir_filename = null;
|
||||
}
|
||||
|
||||
if (target_machine.emitToFile(
|
||||
module,
|
||||
&error_message,
|
||||
options.is_debug,
|
||||
options.is_small,
|
||||
options.time_report,
|
||||
options.sanitize_thread,
|
||||
options.fuzz,
|
||||
options.lto,
|
||||
options.asm_path,
|
||||
emit_bin_path,
|
||||
post_ir_path,
|
||||
null,
|
||||
)) {
|
||||
lowered_options.asm_filename = options.asm_path;
|
||||
if (target_machine.emitToFile(module, &error_message, lowered_options)) {
|
||||
defer llvm.disposeMessage(error_message);
|
||||
|
||||
log.err("LLVM failed to emit asm={s} bin={s} ir={s} bc={s}: {s}", .{
|
||||
emit_asm_msg, emit_bin_msg, post_llvm_ir_msg, post_llvm_bc_msg,
|
||||
error_message,
|
||||
|
|
|
|||
|
|
@ -84,11 +84,7 @@ pub const TargetMachine = opaque {
|
|||
pub const dispose = LLVMDisposeTargetMachine;
|
||||
extern fn LLVMDisposeTargetMachine(T: *TargetMachine) void;
|
||||
|
||||
pub const emitToFile = ZigLLVMTargetMachineEmitToFile;
|
||||
extern fn ZigLLVMTargetMachineEmitToFile(
|
||||
T: *TargetMachine,
|
||||
M: *Module,
|
||||
ErrorMessage: *[*:0]const u8,
|
||||
pub const EmitOptions = extern struct {
|
||||
is_debug: bool,
|
||||
is_small: bool,
|
||||
time_report: bool,
|
||||
|
|
@ -99,6 +95,42 @@ pub const TargetMachine = opaque {
|
|||
bin_filename: ?[*:0]const u8,
|
||||
llvm_ir_filename: ?[*:0]const u8,
|
||||
bitcode_filename: ?[*:0]const u8,
|
||||
coverage: Coverage,
|
||||
|
||||
pub const Coverage = extern struct {
|
||||
CoverageType: Coverage.Type,
|
||||
IndirectCalls: bool,
|
||||
TraceBB: bool,
|
||||
TraceCmp: bool,
|
||||
TraceDiv: bool,
|
||||
TraceGep: bool,
|
||||
Use8bitCounters: bool,
|
||||
TracePC: bool,
|
||||
TracePCGuard: bool,
|
||||
Inline8bitCounters: bool,
|
||||
InlineBoolFlag: bool,
|
||||
PCTable: bool,
|
||||
NoPrune: bool,
|
||||
StackDepth: bool,
|
||||
TraceLoads: bool,
|
||||
TraceStores: bool,
|
||||
CollectControlFlow: bool,
|
||||
|
||||
pub const Type = enum(c_uint) {
|
||||
None = 0,
|
||||
Function,
|
||||
BB,
|
||||
Edge,
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
pub const emitToFile = ZigLLVMTargetMachineEmitToFile;
|
||||
extern fn ZigLLVMTargetMachineEmitToFile(
|
||||
T: *TargetMachine,
|
||||
M: *Module,
|
||||
ErrorMessage: *[*:0]const u8,
|
||||
options: EmitOptions,
|
||||
) bool;
|
||||
|
||||
pub const createTargetDataLayout = LLVMCreateTargetDataLayout;
|
||||
|
|
|
|||
|
|
@ -2673,12 +2673,14 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s
|
|||
try argv.append(p);
|
||||
}
|
||||
|
||||
if (comp.config.any_sanitize_thread) {
|
||||
try argv.append(comp.tsan_lib.?.full_object_path);
|
||||
if (comp.tsan_lib) |lib| {
|
||||
assert(comp.config.any_sanitize_thread);
|
||||
try argv.append(lib.full_object_path);
|
||||
}
|
||||
|
||||
if (comp.config.any_fuzz) {
|
||||
try argv.append(comp.fuzzer_lib.?.full_object_path);
|
||||
if (comp.fuzzer_lib) |lib| {
|
||||
assert(comp.config.any_fuzz);
|
||||
try argv.append(lib.full_object_path);
|
||||
}
|
||||
|
||||
// libc
|
||||
|
|
|
|||
26
src/main.zig
26
src/main.zig
|
|
@ -1454,6 +1454,10 @@ fn buildOutputType(
|
|||
create_module.opts.use_clang = true;
|
||||
} else if (mem.eql(u8, arg, "-fno-clang")) {
|
||||
create_module.opts.use_clang = false;
|
||||
} else if (mem.eql(u8, arg, "-fsanitize-coverage-trace-pc-guard")) {
|
||||
create_module.opts.san_cov_trace_pc_guard = true;
|
||||
} else if (mem.eql(u8, arg, "-fno-sanitize-coverage-trace-pc-guard")) {
|
||||
create_module.opts.san_cov_trace_pc_guard = false;
|
||||
} else if (mem.eql(u8, arg, "-freference-trace")) {
|
||||
reference_trace = 256;
|
||||
} else if (mem.startsWith(u8, arg, "-freference-trace=")) {
|
||||
|
|
@ -2025,6 +2029,25 @@ fn buildOutputType(
|
|||
}
|
||||
}
|
||||
},
|
||||
.san_cov_trace_pc_guard => create_module.opts.san_cov_trace_pc_guard = true,
|
||||
.san_cov => {
|
||||
var split_it = mem.splitScalar(u8, it.only_arg, ',');
|
||||
while (split_it.next()) |san_arg| {
|
||||
if (std.mem.eql(u8, san_arg, "trace-pc-guard")) {
|
||||
create_module.opts.san_cov_trace_pc_guard = true;
|
||||
}
|
||||
}
|
||||
try cc_argv.appendSlice(arena, it.other_args);
|
||||
},
|
||||
.no_san_cov => {
|
||||
var split_it = mem.splitScalar(u8, it.only_arg, ',');
|
||||
while (split_it.next()) |san_arg| {
|
||||
if (std.mem.eql(u8, san_arg, "trace-pc-guard")) {
|
||||
create_module.opts.san_cov_trace_pc_guard = false;
|
||||
}
|
||||
}
|
||||
try cc_argv.appendSlice(arena, it.other_args);
|
||||
},
|
||||
.optimize => {
|
||||
// Alright, what release mode do they want?
|
||||
const level = if (it.only_arg.len >= 1 and it.only_arg[0] == 'O') it.only_arg[1..] else it.only_arg;
|
||||
|
|
@ -5803,6 +5826,9 @@ pub const ClangArgIterator = struct {
|
|||
undefined,
|
||||
force_load_objc,
|
||||
mingw_unicode_entry_point,
|
||||
san_cov_trace_pc_guard,
|
||||
san_cov,
|
||||
no_san_cov,
|
||||
};
|
||||
|
||||
const Args = struct {
|
||||
|
|
|
|||
|
|
@ -189,59 +189,56 @@ struct TimeTracerRAII {
|
|||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
static SanitizerCoverageOptions getSanCovOptions(void) {
|
||||
static SanitizerCoverageOptions getSanCovOptions(ZigLLVMCoverageOptions z) {
|
||||
SanitizerCoverageOptions o;
|
||||
o.CoverageType = SanitizerCoverageOptions::SCK_Edge;
|
||||
o.IndirectCalls = true;
|
||||
o.TraceBB = false;
|
||||
o.TraceCmp = true;
|
||||
o.TraceDiv = false;
|
||||
o.TraceGep = false;
|
||||
o.Use8bitCounters = false;
|
||||
o.TracePC = false;
|
||||
o.TracePCGuard = false;
|
||||
o.Inline8bitCounters = true;
|
||||
o.InlineBoolFlag = false;
|
||||
o.PCTable = true;
|
||||
o.NoPrune = false;
|
||||
o.StackDepth = true;
|
||||
o.TraceLoads = false;
|
||||
o.TraceStores = false;
|
||||
o.CollectControlFlow = false;
|
||||
o.CoverageType = (SanitizerCoverageOptions::Type)z.CoverageType;
|
||||
o.IndirectCalls = z.IndirectCalls;
|
||||
o.TraceBB = z.TraceBB;
|
||||
o.TraceCmp = z.TraceCmp;
|
||||
o.TraceDiv = z.TraceDiv;
|
||||
o.TraceGep = z.TraceGep;
|
||||
o.Use8bitCounters = z.Use8bitCounters;
|
||||
o.TracePC = z.TracePC;
|
||||
o.TracePCGuard = z.TracePCGuard;
|
||||
o.Inline8bitCounters = z.Inline8bitCounters;
|
||||
o.InlineBoolFlag = z.InlineBoolFlag;
|
||||
o.PCTable = z.PCTable;
|
||||
o.NoPrune = z.NoPrune;
|
||||
o.StackDepth = z.StackDepth;
|
||||
o.TraceLoads = z.TraceLoads;
|
||||
o.TraceStores = z.TraceStores;
|
||||
o.CollectControlFlow = z.CollectControlFlow;
|
||||
return o;
|
||||
}
|
||||
|
||||
bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
|
||||
char **error_message, bool is_debug,
|
||||
bool is_small, bool time_report, bool tsan, bool sancov, bool lto,
|
||||
const char *asm_filename, const char *bin_filename,
|
||||
const char *llvm_ir_filename, const char *bitcode_filename)
|
||||
ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
|
||||
char **error_message, struct ZigLLVMEmitOptions options)
|
||||
{
|
||||
TimePassesIsEnabled = time_report;
|
||||
TimePassesIsEnabled = options.time_report;
|
||||
|
||||
raw_fd_ostream *dest_asm_ptr = nullptr;
|
||||
raw_fd_ostream *dest_bin_ptr = nullptr;
|
||||
raw_fd_ostream *dest_bitcode_ptr = nullptr;
|
||||
|
||||
if (asm_filename) {
|
||||
if (options.asm_filename) {
|
||||
std::error_code EC;
|
||||
dest_asm_ptr = new(std::nothrow) raw_fd_ostream(asm_filename, EC, sys::fs::OF_None);
|
||||
dest_asm_ptr = new(std::nothrow) raw_fd_ostream(options.asm_filename, EC, sys::fs::OF_None);
|
||||
if (EC) {
|
||||
*error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (bin_filename) {
|
||||
if (options.bin_filename) {
|
||||
std::error_code EC;
|
||||
dest_bin_ptr = new(std::nothrow) raw_fd_ostream(bin_filename, EC, sys::fs::OF_None);
|
||||
dest_bin_ptr = new(std::nothrow) raw_fd_ostream(options.bin_filename, EC, sys::fs::OF_None);
|
||||
if (EC) {
|
||||
*error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (bitcode_filename) {
|
||||
if (options.bitcode_filename) {
|
||||
std::error_code EC;
|
||||
dest_bitcode_ptr = new(std::nothrow) raw_fd_ostream(bitcode_filename, EC, sys::fs::OF_None);
|
||||
dest_bitcode_ptr = new(std::nothrow) raw_fd_ostream(options.bitcode_filename, EC, sys::fs::OF_None);
|
||||
if (EC) {
|
||||
*error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
|
||||
return true;
|
||||
|
|
@ -257,7 +254,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
|
|||
std::string ProcName = "zig-";
|
||||
ProcName += std::to_string(PID);
|
||||
TimeTracerRAII TimeTracer(ProcName,
|
||||
bin_filename? bin_filename : asm_filename);
|
||||
options.bin_filename? options.bin_filename : options.asm_filename);
|
||||
|
||||
TargetMachine &target_machine = *reinterpret_cast<TargetMachine*>(targ_machine_ref);
|
||||
target_machine.setO0WantsFastISel(true);
|
||||
|
|
@ -266,11 +263,11 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
|
|||
|
||||
// Pipeline configurations
|
||||
PipelineTuningOptions pipeline_opts;
|
||||
pipeline_opts.LoopUnrolling = !is_debug;
|
||||
pipeline_opts.SLPVectorization = !is_debug;
|
||||
pipeline_opts.LoopVectorization = !is_debug;
|
||||
pipeline_opts.LoopInterleaving = !is_debug;
|
||||
pipeline_opts.MergeFunctions = !is_debug;
|
||||
pipeline_opts.LoopUnrolling = !options.is_debug;
|
||||
pipeline_opts.SLPVectorization = !options.is_debug;
|
||||
pipeline_opts.LoopVectorization = !options.is_debug;
|
||||
pipeline_opts.LoopInterleaving = !options.is_debug;
|
||||
pipeline_opts.MergeFunctions = !options.is_debug;
|
||||
|
||||
// Instrumentations
|
||||
PassInstrumentationCallbacks instr_callbacks;
|
||||
|
|
@ -308,19 +305,19 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
|
|||
module_pm.addPass(VerifierPass());
|
||||
}
|
||||
|
||||
if (!is_debug) {
|
||||
if (!options.is_debug) {
|
||||
module_pm.addPass(createModuleToFunctionPassAdaptor(AddDiscriminatorsPass()));
|
||||
}
|
||||
});
|
||||
|
||||
pass_builder.registerOptimizerEarlyEPCallback([&](ModulePassManager &module_pm, OptimizationLevel OL) {
|
||||
// Code coverage instrumentation.
|
||||
if (sancov) {
|
||||
module_pm.addPass(SanitizerCoveragePass(getSanCovOptions()));
|
||||
if (options.sancov) {
|
||||
module_pm.addPass(SanitizerCoveragePass(getSanCovOptions(options.coverage)));
|
||||
}
|
||||
|
||||
// Thread sanitizer
|
||||
if (tsan) {
|
||||
if (options.tsan) {
|
||||
module_pm.addPass(ModuleThreadSanitizerPass());
|
||||
module_pm.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
|
||||
}
|
||||
|
|
@ -336,17 +333,17 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
|
|||
ModulePassManager module_pm;
|
||||
OptimizationLevel opt_level;
|
||||
// Setting up the optimization level
|
||||
if (is_debug)
|
||||
if (options.is_debug)
|
||||
opt_level = OptimizationLevel::O0;
|
||||
else if (is_small)
|
||||
else if (options.is_small)
|
||||
opt_level = OptimizationLevel::Oz;
|
||||
else
|
||||
opt_level = OptimizationLevel::O3;
|
||||
|
||||
// Initialize the PassManager
|
||||
if (opt_level == OptimizationLevel::O0) {
|
||||
module_pm = pass_builder.buildO0DefaultPipeline(opt_level, lto);
|
||||
} else if (lto) {
|
||||
module_pm = pass_builder.buildO0DefaultPipeline(opt_level, options.lto);
|
||||
} else if (options.lto) {
|
||||
module_pm = pass_builder.buildLTOPreLinkDefaultPipeline(opt_level);
|
||||
} else {
|
||||
module_pm = pass_builder.buildPerModuleDefaultPipeline(opt_level);
|
||||
|
|
@ -357,7 +354,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
|
|||
codegen_pm.add(
|
||||
createTargetTransformInfoWrapperPass(target_machine.getTargetIRAnalysis()));
|
||||
|
||||
if (dest_bin && !lto) {
|
||||
if (dest_bin && !options.lto) {
|
||||
if (target_machine.addPassesToEmitFile(codegen_pm, *dest_bin, nullptr, CodeGenFileType::ObjectFile)) {
|
||||
*error_message = strdup("TargetMachine can't emit an object file");
|
||||
return true;
|
||||
|
|
@ -376,20 +373,20 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
|
|||
// Code generation phase
|
||||
codegen_pm.run(llvm_module);
|
||||
|
||||
if (llvm_ir_filename) {
|
||||
if (LLVMPrintModuleToFile(module_ref, llvm_ir_filename, error_message)) {
|
||||
if (options.llvm_ir_filename) {
|
||||
if (LLVMPrintModuleToFile(module_ref, options.llvm_ir_filename, error_message)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dest_bin && lto) {
|
||||
if (dest_bin && options.lto) {
|
||||
WriteBitcodeToFile(llvm_module, *dest_bin);
|
||||
}
|
||||
if (dest_bitcode) {
|
||||
WriteBitcodeToFile(llvm_module, *dest_bitcode);
|
||||
}
|
||||
|
||||
if (time_report) {
|
||||
if (options.time_report) {
|
||||
TimerGroup::printAll(errs());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,12 +24,50 @@
|
|||
// ATTENTION: If you modify this file, be sure to update the corresponding
|
||||
// extern function declarations in the self-hosted compiler.
|
||||
|
||||
ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
|
||||
char **error_message, bool is_debug,
|
||||
bool is_small, bool time_report, bool tsan, bool sancov, bool lto,
|
||||
const char *asm_filename, const char *bin_filename,
|
||||
const char *llvm_ir_filename, const char *bitcode_filename);
|
||||
|
||||
enum ZigLLVMCoverageType {
|
||||
ZigLLVMCoverageType_None = 0,
|
||||
ZigLLVMCoverageType_Function,
|
||||
ZigLLVMCoverageType_BB,
|
||||
ZigLLVMCoverageType_Edge
|
||||
};
|
||||
|
||||
struct ZigLLVMCoverageOptions {
|
||||
ZigLLVMCoverageType CoverageType;
|
||||
bool IndirectCalls;
|
||||
bool TraceBB;
|
||||
bool TraceCmp;
|
||||
bool TraceDiv;
|
||||
bool TraceGep;
|
||||
bool Use8bitCounters;
|
||||
bool TracePC;
|
||||
bool TracePCGuard;
|
||||
bool Inline8bitCounters;
|
||||
bool InlineBoolFlag;
|
||||
bool PCTable;
|
||||
bool NoPrune;
|
||||
bool StackDepth;
|
||||
bool TraceLoads;
|
||||
bool TraceStores;
|
||||
bool CollectControlFlow;
|
||||
};
|
||||
|
||||
struct ZigLLVMEmitOptions {
|
||||
bool is_debug;
|
||||
bool is_small;
|
||||
bool time_report;
|
||||
bool tsan;
|
||||
bool sancov;
|
||||
bool lto;
|
||||
const char *asm_filename;
|
||||
const char *bin_filename;
|
||||
const char *llvm_ir_filename;
|
||||
const char *bitcode_filename;
|
||||
ZigLLVMCoverageOptions coverage;
|
||||
};
|
||||
|
||||
ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
|
||||
char **error_message, struct ZigLLVMEmitOptions options);
|
||||
|
||||
enum ZigLLVMABIType {
|
||||
ZigLLVMABITypeDefault, // Target-specific (either soft or hard depending on triple, etc).
|
||||
|
|
|
|||
|
|
@ -536,6 +536,18 @@ const known_options = [_]KnownOpt{
|
|||
.name = "municode",
|
||||
.ident = "mingw_unicode_entry_point",
|
||||
},
|
||||
.{
|
||||
.name = "fsanitize-coverage-trace-pc-guard",
|
||||
.ident = "san_cov_trace_pc_guard",
|
||||
},
|
||||
.{
|
||||
.name = "fsanitize-coverage",
|
||||
.ident = "san_cov",
|
||||
},
|
||||
.{
|
||||
.name = "fno-sanitize-coverage",
|
||||
.ident = "no_san_cov",
|
||||
},
|
||||
};
|
||||
|
||||
const blacklisted_options = [_][]const u8{};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue