| author | |
| committer | |
| log | db74832e40f98960e5dc3e46c8196c59033ee0f9 |
| tree | 95d7e039968d665d0e0001c45c9c9c1f3e2a622d |
| parent | c9fb5240d6305bcef7db5e12b7676ba3d741c11e |
| signature | Commit is signed but in an unrecognized format. |
with this change, when you assign undefined, zig emits a few
assembly instructions to tell valgrind that the memory is undefined
it's on by default for debug builds, and disabled otherwise. only
support for linux, darwin, solaris, mingw on x86_64 is currently
implemented.
--disable-valgrind turns it off even in debug mode.
--enable-valgrind turns it on even in release modes.
It's always disabled for compiler_rt.a and builtin.a.
Adds `@import("builtin").valgrind_support` which lets code know
at comptime whether valgrind client requests are enabled.
See #19896 files changed, 130 insertions(+), 9 deletions(-)
src/all_types.hpp+18-6| ... | @@ -1345,15 +1345,11 @@ struct ZigFn { | ... | @@ -1345,15 +1345,11 @@ struct ZigFn { |
| 1345 | // in the case of async functions this is the implicit return type according to the | 1345 | // in the case of async functions this is the implicit return type according to the |
| 1346 | // zig source code, not according to zig ir | 1346 | // zig source code, not according to zig ir |
| 1347 | ZigType *src_implicit_return_type; | 1347 | ZigType *src_implicit_return_type; |
| 1348 | bool is_test; | ||
| 1349 | FnInline fn_inline; | ||
| 1350 | FnAnalState anal_state; | ||
| 1351 | IrExecutable ir_executable; | 1348 | IrExecutable ir_executable; |
| 1352 | IrExecutable analyzed_executable; | 1349 | IrExecutable analyzed_executable; |
| 1353 | size_t prealloc_bbc; | 1350 | size_t prealloc_bbc; |
| 1354 | AstNode **param_source_nodes; | 1351 | AstNode **param_source_nodes; |
| 1355 | Buf **param_names; | 1352 | Buf **param_names; |
| 1356 | uint32_t align_bytes; | ||
| 1357 | 1353 | ||
| 1358 | AstNode *fn_no_inline_set_node; | 1354 | AstNode *fn_no_inline_set_node; |
| 1359 | AstNode *fn_static_eval_set_node; | 1355 | AstNode *fn_static_eval_set_node; |
| ... | @@ -1363,13 +1359,22 @@ struct ZigFn { | ... | @@ -1363,13 +1359,22 @@ struct ZigFn { |
| 1363 | 1359 | ||
| 1364 | Buf *section_name; | 1360 | Buf *section_name; |
| 1365 | AstNode *set_alignstack_node; | 1361 | AstNode *set_alignstack_node; |
| 1366 | uint32_t alignstack_value; | ||
| 1367 | 1362 | ||
| 1368 | AstNode *set_cold_node; | 1363 | AstNode *set_cold_node; |
| 1369 | bool is_cold; | ||
| 1370 | 1364 | ||
| 1371 | ZigList<FnExport> export_list; | 1365 | ZigList<FnExport> export_list; |
| 1366 | |||
| 1367 | LLVMValueRef valgrind_client_request_array; | ||
| 1368 | |||
| 1369 | FnInline fn_inline; | ||
| 1370 | FnAnalState anal_state; | ||
| 1371 | |||
| 1372 | uint32_t align_bytes; | ||
| 1373 | uint32_t alignstack_value; | ||
| 1374 | |||
| 1372 | bool calls_or_awaits_errorable_fn; | 1375 | bool calls_or_awaits_errorable_fn; |
| 1376 | bool is_cold; | ||
| 1377 | bool is_test; | ||
| 1373 | }; | 1378 | }; |
| 1374 | 1379 | ||
| 1375 | uint32_t fn_table_entry_hash(ZigFn*); | 1380 | uint32_t fn_table_entry_hash(ZigFn*); |
| ... | @@ -1612,6 +1617,12 @@ struct LinkLib { | ... | @@ -1612,6 +1617,12 @@ struct LinkLib { |
| 1612 | bool provided_explicitly; | 1617 | bool provided_explicitly; |
| 1613 | }; | 1618 | }; |
| 1614 | 1619 | ||
| 1620 | enum ValgrindSupport { | ||
| 1621 | ValgrindSupportAuto, | ||
| 1622 | ValgrindSupportDisabled, | ||
| 1623 | ValgrindSupportEnabled, | ||
| 1624 | }; | ||
| 1625 | |||
| 1615 | // When adding fields, check if they should be added to the hash computation in build_with_cache | 1626 | // When adding fields, check if they should be added to the hash computation in build_with_cache |
| 1616 | struct CodeGen { | 1627 | struct CodeGen { |
| 1617 | //////////////////////////// Runtime State | 1628 | //////////////////////////// Runtime State |
| ... | @@ -1813,6 +1824,7 @@ struct CodeGen { | ... | @@ -1813,6 +1824,7 @@ struct CodeGen { |
| 1813 | OutType out_type; | 1824 | OutType out_type; |
| 1814 | ZigTarget zig_target; | 1825 | ZigTarget zig_target; |
| 1815 | TargetSubsystem subsystem; | 1826 | TargetSubsystem subsystem; |
| 1827 | ValgrindSupport valgrind_support; | ||
| 1816 | bool is_static; | 1828 | bool is_static; |
| 1817 | bool strip_debug_symbols; | 1829 | bool strip_debug_symbols; |
| 1818 | bool is_test_build; | 1830 | bool is_test_build; |
src/codegen.cpp+81| ... | @@ -3341,6 +3341,77 @@ static bool value_is_all_undef(ConstExprValue *const_val) { | ... | @@ -3341,6 +3341,77 @@ static bool value_is_all_undef(ConstExprValue *const_val) { |
| 3341 | zig_unreachable(); | 3341 | zig_unreachable(); |
| 3342 | } | 3342 | } |
| 3343 | 3343 | ||
| 3344 | static LLVMValueRef gen_valgrind_client_request(CodeGen *g, LLVMValueRef default_value, LLVMValueRef request, | ||
| 3345 | LLVMValueRef a1, LLVMValueRef a2, LLVMValueRef a3, LLVMValueRef a4, LLVMValueRef a5) | ||
| 3346 | { | ||
| 3347 | if (!target_has_valgrind_support(&g->zig_target)) { | ||
| 3348 | return default_value; | ||
| 3349 | } | ||
| 3350 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->type_ref; | ||
| 3351 | bool asm_has_side_effects = true; | ||
| 3352 | bool asm_is_alignstack = false; | ||
| 3353 | if (g->zig_target.arch.arch == ZigLLVM_x86_64) { | ||
| 3354 | if (g->zig_target.os == OsLinux || target_is_darwin(&g->zig_target) || g->zig_target.os == OsSolaris || | ||
| 3355 | (g->zig_target.os == OsWindows && g->zig_target.env_type != ZigLLVM_MSVC)) | ||
| 3356 | { | ||
| 3357 | if (g->cur_fn->valgrind_client_request_array == nullptr) { | ||
| 3358 | LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder); | ||
| 3359 | LLVMBasicBlockRef entry_block = LLVMGetEntryBasicBlock(g->cur_fn->llvm_value); | ||
| 3360 | LLVMValueRef first_inst = LLVMGetFirstInstruction(entry_block); | ||
| 3361 | LLVMPositionBuilderBefore(g->builder, first_inst); | ||
| 3362 | LLVMTypeRef array_type_ref = LLVMArrayType(usize_type_ref, 6); | ||
| 3363 | g->cur_fn->valgrind_client_request_array = LLVMBuildAlloca(g->builder, array_type_ref, ""); | ||
| 3364 | LLVMPositionBuilderAtEnd(g->builder, prev_block); | ||
| 3365 | } | ||
| 3366 | LLVMValueRef array_ptr = g->cur_fn->valgrind_client_request_array; | ||
| 3367 | LLVMValueRef array_elements[] = {request, a1, a2, a3, a4, a5}; | ||
| 3368 | LLVMValueRef zero = LLVMConstInt(usize_type_ref, 0, false); | ||
| 3369 | for (unsigned i = 0; i < 6; i += 1) { | ||
| 3370 | LLVMValueRef indexes[] = { | ||
| 3371 | zero, | ||
| 3372 | LLVMConstInt(usize_type_ref, i, false), | ||
| 3373 | }; | ||
| 3374 | LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indexes, 2, ""); | ||
| 3375 | LLVMBuildStore(g->builder, array_elements[i], elem_ptr); | ||
| 3376 | } | ||
| 3377 | |||
| 3378 | Buf *asm_template = buf_create_from_str( | ||
| 3379 | "rolq $$3, %rdi ; rolq $$13, %rdi\n" | ||
| 3380 | "rolq $$61, %rdi ; rolq $$51, %rdi\n" | ||
| 3381 | "xchgq %rbx,%rbx\n" | ||
| 3382 | ); | ||
| 3383 | Buf *asm_constraints = buf_create_from_str( | ||
| 3384 | "={rdx},{rax},0,~{cc},~{memory}" | ||
| 3385 | ); | ||
| 3386 | unsigned input_and_output_count = 2; | ||
| 3387 | LLVMValueRef array_ptr_as_usize = LLVMBuildPtrToInt(g->builder, array_ptr, usize_type_ref, ""); | ||
| 3388 | LLVMValueRef param_values[] = { array_ptr_as_usize, default_value }; | ||
| 3389 | LLVMTypeRef param_types[] = {usize_type_ref, usize_type_ref}; | ||
| 3390 | LLVMTypeRef function_type = LLVMFunctionType(usize_type_ref, param_types, | ||
| 3391 | input_and_output_count, false); | ||
| 3392 | LLVMValueRef asm_fn = LLVMGetInlineAsm(function_type, buf_ptr(asm_template), buf_len(asm_template), | ||
| 3393 | buf_ptr(asm_constraints), buf_len(asm_constraints), asm_has_side_effects, asm_is_alignstack, | ||
| 3394 | LLVMInlineAsmDialectATT); | ||
| 3395 | return LLVMBuildCall(g->builder, asm_fn, param_values, input_and_output_count, ""); | ||
| 3396 | } | ||
| 3397 | } | ||
| 3398 | zig_unreachable(); | ||
| 3399 | } | ||
| 3400 | |||
| 3401 | static bool want_valgrind_support(CodeGen *g) { | ||
| 3402 | if (!target_has_valgrind_support(&g->zig_target)) | ||
| 3403 | return false; | ||
| 3404 | switch (g->valgrind_support) { | ||
| 3405 | case ValgrindSupportDisabled: | ||
| 3406 | return false; | ||
| 3407 | case ValgrindSupportEnabled: | ||
| 3408 | return true; | ||
| 3409 | case ValgrindSupportAuto: | ||
| 3410 | return g->build_mode == BuildModeDebug; | ||
| 3411 | } | ||
| 3412 | zig_unreachable(); | ||
| 3413 | } | ||
| 3414 | |||
| 3344 | static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr) { | 3415 | static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr) { |
| 3345 | assert(type_has_bits(value_type)); | 3416 | assert(type_has_bits(value_type)); |
| 3346 | uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, value_type->type_ref); | 3417 | uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, value_type->type_ref); |
| ... | @@ -3353,6 +3424,14 @@ static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_ | ... | @@ -3353,6 +3424,14 @@ static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_ |
| 3353 | ZigType *usize = g->builtin_types.entry_usize; | 3424 | ZigType *usize = g->builtin_types.entry_usize; |
| 3354 | LLVMValueRef byte_count = LLVMConstInt(usize->type_ref, size_bytes, false); | 3425 | LLVMValueRef byte_count = LLVMConstInt(usize->type_ref, size_bytes, false); |
| 3355 | ZigLLVMBuildMemSet(g->builder, dest_ptr, fill_char, byte_count, ptr_align_bytes, false); | 3426 | ZigLLVMBuildMemSet(g->builder, dest_ptr, fill_char, byte_count, ptr_align_bytes, false); |
| 3427 | // then tell valgrind that the memory is undefined even though we just memset it | ||
| 3428 | if (want_valgrind_support(g)) { | ||
| 3429 | static const uint32_t VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545; | ||
| 3430 | LLVMValueRef zero = LLVMConstInt(usize->type_ref, 0, false); | ||
| 3431 | LLVMValueRef req = LLVMConstInt(usize->type_ref, VG_USERREQ__MAKE_MEM_UNDEFINED, false); | ||
| 3432 | LLVMValueRef ptr_as_usize = LLVMBuildPtrToInt(g->builder, dest_ptr, usize->type_ref, ""); | ||
| 3433 | gen_valgrind_client_request(g, zero, req, ptr_as_usize, byte_count, zero, zero, zero); | ||
| 3434 | } | ||
| 3356 | } | 3435 | } |
| 3357 | 3436 | ||
| 3358 | static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) { | 3437 | static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) { |
| ... | @@ -7525,6 +7604,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { | ... | @@ -7525,6 +7604,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { |
| 7525 | buf_appendf(contents, "pub const mode = %s;\n", build_mode_to_str(g->build_mode)); | 7604 | buf_appendf(contents, "pub const mode = %s;\n", build_mode_to_str(g->build_mode)); |
| 7526 | buf_appendf(contents, "pub const link_libc = %s;\n", bool_to_str(g->libc_link_lib != nullptr)); | 7605 | buf_appendf(contents, "pub const link_libc = %s;\n", bool_to_str(g->libc_link_lib != nullptr)); |
| 7527 | buf_appendf(contents, "pub const have_error_return_tracing = %s;\n", bool_to_str(g->have_err_ret_tracing)); | 7606 | buf_appendf(contents, "pub const have_error_return_tracing = %s;\n", bool_to_str(g->have_err_ret_tracing)); |
| 7607 | buf_appendf(contents, "pub const valgrind_support = %s;\n", bool_to_str(want_valgrind_support(g))); | ||
| 7528 | 7608 | ||
| 7529 | buf_appendf(contents, "pub const __zig_test_fn_slice = {}; // overwritten later\n"); | 7609 | buf_appendf(contents, "pub const __zig_test_fn_slice = {}; // overwritten later\n"); |
| 7530 | 7610 | ||
| ... | @@ -8489,6 +8569,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { | ... | @@ -8489,6 +8569,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { |
| 8489 | cache_bool(ch, g->linker_rdynamic); | 8569 | cache_bool(ch, g->linker_rdynamic); |
| 8490 | cache_bool(ch, g->each_lib_rpath); | 8570 | cache_bool(ch, g->each_lib_rpath); |
| 8491 | cache_bool(ch, g->disable_pic); | 8571 | cache_bool(ch, g->disable_pic); |
| 8572 | cache_bool(ch, g->valgrind_support); | ||
| 8492 | cache_buf_opt(ch, g->mmacosx_version_min); | 8573 | cache_buf_opt(ch, g->mmacosx_version_min); |
| 8493 | cache_buf_opt(ch, g->mios_version_min); | 8574 | cache_buf_opt(ch, g->mios_version_min); |
| 8494 | cache_usize(ch, g->version_major); | 8575 | cache_usize(ch, g->version_major); |
src/link.cpp+1| ... | @@ -55,6 +55,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path) | ... | @@ -55,6 +55,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path) |
| 55 | codegen_set_strip(child_gen, parent_gen->strip_debug_symbols); | 55 | codegen_set_strip(child_gen, parent_gen->strip_debug_symbols); |
| 56 | codegen_set_is_static(child_gen, true); | 56 | codegen_set_is_static(child_gen, true); |
| 57 | child_gen->disable_pic = parent_gen->disable_pic; | 57 | child_gen->disable_pic = parent_gen->disable_pic; |
| 58 | child_gen->valgrind_support = ValgrindSupportDisabled; | ||
| 58 | 59 | ||
| 59 | codegen_set_out_name(child_gen, buf_create_from_str(aname)); | 60 | codegen_set_out_name(child_gen, buf_create_from_str(aname)); |
| 60 | 61 |
src/main.cpp+11| ... | @@ -49,6 +49,8 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { | ... | @@ -49,6 +49,8 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { |
| 49 | " --cache [auto|off|on] build in global cache, print out paths to stdout\n" | 49 | " --cache [auto|off|on] build in global cache, print out paths to stdout\n" |
| 50 | " --color [auto|off|on] enable or disable colored error messages\n" | 50 | " --color [auto|off|on] enable or disable colored error messages\n" |
| 51 | " --disable-pic disable Position Independent Code for libraries\n" | 51 | " --disable-pic disable Position Independent Code for libraries\n" |
| 52 | " --disable-valgrind omit valgrind client requests in debug builds\n" | ||
| 53 | " --enable-valgrind include valgrind client requests release builds\n" | ||
| 52 | " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n" | 54 | " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n" |
| 53 | " -ftime-report print timing diagnostics\n" | 55 | " -ftime-report print timing diagnostics\n" |
| 54 | " --libc-include-dir [path] directory where libc stdlib.h resides\n" | 56 | " --libc-include-dir [path] directory where libc stdlib.h resides\n" |
| ... | @@ -396,6 +398,7 @@ int main(int argc, char **argv) { | ... | @@ -396,6 +398,7 @@ int main(int argc, char **argv) { |
| 396 | TargetSubsystem subsystem = TargetSubsystemAuto; | 398 | TargetSubsystem subsystem = TargetSubsystemAuto; |
| 397 | bool is_single_threaded = false; | 399 | bool is_single_threaded = false; |
| 398 | Buf *override_std_dir = nullptr; | 400 | Buf *override_std_dir = nullptr; |
| 401 | ValgrindSupport valgrind_support = ValgrindSupportAuto; | ||
| 399 | 402 | ||
| 400 | if (argc >= 2 && strcmp(argv[1], "build") == 0) { | 403 | if (argc >= 2 && strcmp(argv[1], "build") == 0) { |
| 401 | Buf zig_exe_path_buf = BUF_INIT; | 404 | Buf zig_exe_path_buf = BUF_INIT; |
| ... | @@ -433,6 +436,7 @@ int main(int argc, char **argv) { | ... | @@ -433,6 +436,7 @@ int main(int argc, char **argv) { |
| 433 | 436 | ||
| 434 | CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe, BuildModeDebug, get_zig_lib_dir(), | 437 | CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe, BuildModeDebug, get_zig_lib_dir(), |
| 435 | override_std_dir); | 438 | override_std_dir); |
| 439 | g->valgrind_support = valgrind_support; | ||
| 436 | g->enable_time_report = timing_info; | 440 | g->enable_time_report = timing_info; |
| 437 | buf_init_from_str(&g->cache_dir, cache_dir ? cache_dir : default_zig_cache_name); | 441 | buf_init_from_str(&g->cache_dir, cache_dir ? cache_dir : default_zig_cache_name); |
| 438 | codegen_set_out_name(g, buf_create_from_str("build")); | 442 | codegen_set_out_name(g, buf_create_from_str("build")); |
| ... | @@ -520,6 +524,7 @@ int main(int argc, char **argv) { | ... | @@ -520,6 +524,7 @@ int main(int argc, char **argv) { |
| 520 | os_path_join(get_zig_special_dir(), buf_create_from_str("fmt_runner.zig"), fmt_runner_path); | 524 | os_path_join(get_zig_special_dir(), buf_create_from_str("fmt_runner.zig"), fmt_runner_path); |
| 521 | CodeGen *g = codegen_create(fmt_runner_path, nullptr, OutTypeExe, BuildModeDebug, get_zig_lib_dir(), | 525 | CodeGen *g = codegen_create(fmt_runner_path, nullptr, OutTypeExe, BuildModeDebug, get_zig_lib_dir(), |
| 522 | nullptr); | 526 | nullptr); |
| 527 | g->valgrind_support = valgrind_support; | ||
| 523 | g->is_single_threaded = true; | 528 | g->is_single_threaded = true; |
| 524 | codegen_set_out_name(g, buf_create_from_str("fmt")); | 529 | codegen_set_out_name(g, buf_create_from_str("fmt")); |
| 525 | g->enable_cache = true; | 530 | g->enable_cache = true; |
| ... | @@ -577,6 +582,10 @@ int main(int argc, char **argv) { | ... | @@ -577,6 +582,10 @@ int main(int argc, char **argv) { |
| 577 | timing_info = true; | 582 | timing_info = true; |
| 578 | } else if (strcmp(arg, "--disable-pic") == 0) { | 583 | } else if (strcmp(arg, "--disable-pic") == 0) { |
| 579 | disable_pic = true; | 584 | disable_pic = true; |
| 585 | } else if (strcmp(arg, "--enable-valgrind") == 0) { | ||
| 586 | valgrind_support = ValgrindSupportEnabled; | ||
| 587 | } else if (strcmp(arg, "--disable-valgrind") == 0) { | ||
| 588 | valgrind_support = ValgrindSupportDisabled; | ||
| 580 | } else if (strcmp(arg, "--system-linker-hack") == 0) { | 589 | } else if (strcmp(arg, "--system-linker-hack") == 0) { |
| 581 | system_linker_hack = true; | 590 | system_linker_hack = true; |
| 582 | } else if (strcmp(arg, "--single-threaded") == 0) { | 591 | } else if (strcmp(arg, "--single-threaded") == 0) { |
| ... | @@ -849,6 +858,7 @@ int main(int argc, char **argv) { | ... | @@ -849,6 +858,7 @@ int main(int argc, char **argv) { |
| 849 | switch (cmd) { | 858 | switch (cmd) { |
| 850 | case CmdBuiltin: { | 859 | case CmdBuiltin: { |
| 851 | CodeGen *g = codegen_create(nullptr, target, out_type, build_mode, get_zig_lib_dir(), override_std_dir); | 860 | CodeGen *g = codegen_create(nullptr, target, out_type, build_mode, get_zig_lib_dir(), override_std_dir); |
| 861 | g->valgrind_support = valgrind_support; | ||
| 852 | g->is_single_threaded = is_single_threaded; | 862 | g->is_single_threaded = is_single_threaded; |
| 853 | Buf *builtin_source = codegen_generate_builtin_source(g); | 863 | Buf *builtin_source = codegen_generate_builtin_source(g); |
| 854 | if (fwrite(buf_ptr(builtin_source), 1, buf_len(builtin_source), stdout) != buf_len(builtin_source)) { | 864 | if (fwrite(buf_ptr(builtin_source), 1, buf_len(builtin_source), stdout) != buf_len(builtin_source)) { |
| ... | @@ -909,6 +919,7 @@ int main(int argc, char **argv) { | ... | @@ -909,6 +919,7 @@ int main(int argc, char **argv) { |
| 909 | } | 919 | } |
| 910 | CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode, get_zig_lib_dir(), | 920 | CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode, get_zig_lib_dir(), |
| 911 | override_std_dir); | 921 | override_std_dir); |
| 922 | g->valgrind_support = valgrind_support; | ||
| 912 | g->subsystem = subsystem; | 923 | g->subsystem = subsystem; |
| 913 | 924 | ||
| 914 | if (disable_pic) { | 925 | if (disable_pic) { |
src/target.cpp+17-3| ... | @@ -544,7 +544,7 @@ void get_target_triple(Buf *triple, const ZigTarget *target) { | ... | @@ -544,7 +544,7 @@ void get_target_triple(Buf *triple, const ZigTarget *target) { |
| 544 | } | 544 | } |
| 545 | } | 545 | } |
| 546 | 546 | ||
| 547 | static bool is_os_darwin(ZigTarget *target) { | 547 | bool target_is_darwin(const ZigTarget *target) { |
| 548 | switch (target->os) { | 548 | switch (target->os) { |
| 549 | case OsMacOSX: | 549 | case OsMacOSX: |
| 550 | case OsIOS: | 550 | case OsIOS: |
| ... | @@ -566,7 +566,7 @@ void resolve_target_object_format(ZigTarget *target) { | ... | @@ -566,7 +566,7 @@ void resolve_target_object_format(ZigTarget *target) { |
| 566 | case ZigLLVM_thumb: | 566 | case ZigLLVM_thumb: |
| 567 | case ZigLLVM_x86: | 567 | case ZigLLVM_x86: |
| 568 | case ZigLLVM_x86_64: | 568 | case ZigLLVM_x86_64: |
| 569 | if (is_os_darwin(target)) { | 569 | if (target_is_darwin(target)) { |
| 570 | target->oformat = ZigLLVM_MachO; | 570 | target->oformat = ZigLLVM_MachO; |
| 571 | } else if (target->os == OsWindows) { | 571 | } else if (target->os == OsWindows) { |
| 572 | target->oformat = ZigLLVM_COFF; | 572 | target->oformat = ZigLLVM_COFF; |
| ... | @@ -626,7 +626,7 @@ void resolve_target_object_format(ZigTarget *target) { | ... | @@ -626,7 +626,7 @@ void resolve_target_object_format(ZigTarget *target) { |
| 626 | 626 | ||
| 627 | case ZigLLVM_ppc: | 627 | case ZigLLVM_ppc: |
| 628 | case ZigLLVM_ppc64: | 628 | case ZigLLVM_ppc64: |
| 629 | if (is_os_darwin(target)) { | 629 | if (target_is_darwin(target)) { |
| 630 | target->oformat = ZigLLVM_MachO; | 630 | target->oformat = ZigLLVM_MachO; |
| 631 | } else { | 631 | } else { |
| 632 | target->oformat= ZigLLVM_ELF; | 632 | target->oformat= ZigLLVM_ELF; |
| ... | @@ -1084,3 +1084,17 @@ bool target_is_arm(const ZigTarget *target) { | ... | @@ -1084,3 +1084,17 @@ bool target_is_arm(const ZigTarget *target) { |
| 1084 | } | 1084 | } |
| 1085 | zig_unreachable(); | 1085 | zig_unreachable(); |
| 1086 | } | 1086 | } |
| 1087 | |||
| 1088 | // Valgrind supports more, but Zig does not support them yet. | ||
| 1089 | bool target_has_valgrind_support(const ZigTarget *target) { | ||
| 1090 | switch (target->arch.arch) { | ||
| 1091 | case ZigLLVM_UnknownArch: | ||
| 1092 | zig_unreachable(); | ||
| 1093 | case ZigLLVM_x86_64: | ||
| 1094 | return (target->os == OsLinux || target_is_darwin(target) || target->os == OsSolaris || | ||
| 1095 | (target->os == OsWindows && target->env_type != ZigLLVM_MSVC)); | ||
| 1096 | default: | ||
| 1097 | return false; | ||
| 1098 | } | ||
| 1099 | zig_unreachable(); | ||
| 1100 | } |
src/target.hpp+2| ... | @@ -136,5 +136,7 @@ ZigLLVM_OSType get_llvm_os_type(Os os_type); | ... | @@ -136,5 +136,7 @@ ZigLLVM_OSType get_llvm_os_type(Os os_type); |
| 136 | 136 | ||
| 137 | bool target_is_arm(const ZigTarget *target); | 137 | bool target_is_arm(const ZigTarget *target); |
| 138 | bool target_allows_addr_zero(const ZigTarget *target); | 138 | bool target_allows_addr_zero(const ZigTarget *target); |
| 139 | bool target_has_valgrind_support(const ZigTarget *target); | ||
| 140 | bool target_is_darwin(const ZigTarget *target); | ||
| 139 | 141 | ||
| 140 | #endif | 142 | #endif |