| author | |
| committer | |
| log | 28bf768883d2411d4cd75582d396d465ab6a54b2 |
| tree | 542fb1bed1e22462938a62b5caf647c366dfc0c2 |
| parent | 74a335c4ccd9eb4cfcc5cc6c01b633584c6bb6ba |
* also fix extern variables with initialiaztion values to generate runtime code
* remove the workaround in example/shared_library/mathtest.zig
* introduce the ability for global variables to have Weak and LinkOnce
linkage
* fix `@export` to work for non-functions. this code needs to be
audited though.
* fix comptime ptrcast not keeping bigger alignment
* fix linker warnings when targeting darwin
closes #190310 files changed, 106 insertions(+), 30 deletions(-)
example/shared_library/mathtest.zig-9| ... | @@ -1,12 +1,3 @@ | ... | @@ -1,12 +1,3 @@ |
| 1 | // TODO Remove this workaround | ||
| 2 | comptime { | ||
| 3 | const builtin = @import("builtin"); | ||
| 4 | if (builtin.os == builtin.Os.macosx) { | ||
| 5 | @export("__mh_execute_header", _mh_execute_header, builtin.GlobalLinkage.Weak); | ||
| 6 | } | ||
| 7 | } | ||
| 8 | var _mh_execute_header = extern struct {x: usize}{.x = 0}; | ||
| 9 | |||
| 10 | export fn add(a: i32, b: i32) i32 { | 1 | export fn add(a: i32, b: i32) i32 { |
| 11 | return a + b; | 2 | return a + b; |
| 12 | } | 3 | } |
src/all_types.hpp+3-1| ... | @@ -1853,7 +1853,9 @@ struct CodeGen { | ... | @@ -1853,7 +1853,9 @@ struct CodeGen { |
| 1853 | 1853 | ||
| 1854 | enum VarLinkage { | 1854 | enum VarLinkage { |
| 1855 | VarLinkageInternal, | 1855 | VarLinkageInternal, |
| 1856 | VarLinkageExport, | 1856 | VarLinkageExportStrong, |
| 1857 | VarLinkageExportWeak, | ||
| 1858 | VarLinkageExportLinkOnce, | ||
| 1857 | VarLinkageExternal, | 1859 | VarLinkageExternal, |
| 1858 | }; | 1860 | }; |
| 1859 | 1861 |
src/analyze.cpp+1-1| ... | @@ -3746,7 +3746,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { | ... | @@ -3746,7 +3746,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { |
| 3746 | 3746 | ||
| 3747 | VarLinkage linkage; | 3747 | VarLinkage linkage; |
| 3748 | if (is_export) { | 3748 | if (is_export) { |
| 3749 | linkage = VarLinkageExport; | 3749 | linkage = VarLinkageExportStrong; |
| 3750 | } else if (is_extern) { | 3750 | } else if (is_extern) { |
| 3751 | linkage = VarLinkageExternal; | 3751 | linkage = VarLinkageExternal; |
| 3752 | } else { | 3752 | } else { |
src/codegen.cpp+19-3| ... | @@ -6421,6 +6421,22 @@ static void set_global_tls(CodeGen *g, ZigVar *var, LLVMValueRef global_value) { | ... | @@ -6421,6 +6421,22 @@ static void set_global_tls(CodeGen *g, ZigVar *var, LLVMValueRef global_value) { |
| 6421 | } | 6421 | } |
| 6422 | } | 6422 | } |
| 6423 | 6423 | ||
| 6424 | static LLVMLinkage var_linkage_to_llvm(VarLinkage var_linkage) { | ||
| 6425 | switch (var_linkage) { | ||
| 6426 | case VarLinkageInternal: | ||
| 6427 | return LLVMInternalLinkage; | ||
| 6428 | case VarLinkageExportStrong: | ||
| 6429 | return LLVMExternalLinkage; | ||
| 6430 | case VarLinkageExportWeak: | ||
| 6431 | return LLVMWeakODRLinkage; | ||
| 6432 | case VarLinkageExportLinkOnce: | ||
| 6433 | return LLVMLinkOnceODRLinkage; | ||
| 6434 | case VarLinkageExternal: | ||
| 6435 | return LLVMExternalLinkage; | ||
| 6436 | } | ||
| 6437 | zig_unreachable(); | ||
| 6438 | } | ||
| 6439 | |||
| 6424 | static void do_code_gen(CodeGen *g) { | 6440 | static void do_code_gen(CodeGen *g) { |
| 6425 | assert(!g->errors.length); | 6441 | assert(!g->errors.length); |
| 6426 | 6442 | ||
| ... | @@ -6501,21 +6517,21 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -6501,21 +6517,21 @@ static void do_code_gen(CodeGen *g) { |
| 6501 | global_value = LLVMAddGlobal(g->module, var->var_type->type_ref, buf_ptr(&var->name)); | 6517 | global_value = LLVMAddGlobal(g->module, var->var_type->type_ref, buf_ptr(&var->name)); |
| 6502 | // TODO debug info for the extern variable | 6518 | // TODO debug info for the extern variable |
| 6503 | 6519 | ||
| 6504 | LLVMSetLinkage(global_value, LLVMExternalLinkage); | 6520 | LLVMSetLinkage(global_value, var_linkage_to_llvm(var->linkage)); |
| 6505 | maybe_import_dll(g, global_value, GlobalLinkageIdStrong); | 6521 | maybe_import_dll(g, global_value, GlobalLinkageIdStrong); |
| 6506 | LLVMSetAlignment(global_value, var->align_bytes); | 6522 | LLVMSetAlignment(global_value, var->align_bytes); |
| 6507 | LLVMSetGlobalConstant(global_value, var->gen_is_const); | 6523 | LLVMSetGlobalConstant(global_value, var->gen_is_const); |
| 6508 | set_global_tls(g, var, global_value); | 6524 | set_global_tls(g, var, global_value); |
| 6509 | } | 6525 | } |
| 6510 | } else { | 6526 | } else { |
| 6511 | bool exported = (var->linkage == VarLinkageExport); | 6527 | bool exported = (var->linkage != VarLinkageInternal); |
| 6512 | const char *mangled_name = buf_ptr(get_mangled_name(g, &var->name, exported)); | 6528 | const char *mangled_name = buf_ptr(get_mangled_name(g, &var->name, exported)); |
| 6513 | render_const_val(g, var->const_value, mangled_name); | 6529 | render_const_val(g, var->const_value, mangled_name); |
| 6514 | render_const_val_global(g, var->const_value, mangled_name); | 6530 | render_const_val_global(g, var->const_value, mangled_name); |
| 6515 | global_value = var->const_value->global_refs->llvm_global; | 6531 | global_value = var->const_value->global_refs->llvm_global; |
| 6516 | 6532 | ||
| 6517 | if (exported) { | 6533 | if (exported) { |
| 6518 | LLVMSetLinkage(global_value, LLVMExternalLinkage); | 6534 | LLVMSetLinkage(global_value, var_linkage_to_llvm(var->linkage)); |
| 6519 | maybe_export_dll(g, global_value, GlobalLinkageIdStrong); | 6535 | maybe_export_dll(g, global_value, GlobalLinkageIdStrong); |
| 6520 | } | 6536 | } |
| 6521 | if (tld_var->section_name) { | 6537 | if (tld_var->section_name) { |
src/ir.cpp+53-11| ... | @@ -13133,6 +13133,20 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -13133,6 +13133,20 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 13133 | return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, casted_init_value); | 13133 | return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, casted_init_value); |
| 13134 | } | 13134 | } |
| 13135 | 13135 | ||
| 13136 | static VarLinkage global_linkage_to_var_linkage(GlobalLinkageId id) { | ||
| 13137 | switch (id) { | ||
| 13138 | case GlobalLinkageIdStrong: | ||
| 13139 | return VarLinkageExportStrong; | ||
| 13140 | case GlobalLinkageIdWeak: | ||
| 13141 | return VarLinkageExportWeak; | ||
| 13142 | case GlobalLinkageIdLinkOnce: | ||
| 13143 | return VarLinkageExportLinkOnce; | ||
| 13144 | case GlobalLinkageIdInternal: | ||
| 13145 | return VarLinkageInternal; | ||
| 13146 | } | ||
| 13147 | zig_unreachable(); | ||
| 13148 | } | ||
| 13149 | |||
| 13136 | static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) { | 13150 | static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) { |
| 13137 | IrInstruction *name = instruction->name->child; | 13151 | IrInstruction *name = instruction->name->child; |
| 13138 | Buf *symbol_name = ir_resolve_str(ira, name); | 13152 | Buf *symbol_name = ir_resolve_str(ira, name); |
| ... | @@ -13161,6 +13175,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio | ... | @@ -13161,6 +13175,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio |
| 13161 | add_error_note(ira->codegen, msg, other_export_node, buf_sprintf("other symbol is here")); | 13175 | add_error_note(ira->codegen, msg, other_export_node, buf_sprintf("other symbol is here")); |
| 13162 | } | 13176 | } |
| 13163 | 13177 | ||
| 13178 | bool want_var_export = false; | ||
| 13164 | switch (target->value.type->id) { | 13179 | switch (target->value.type->id) { |
| 13165 | case ZigTypeIdInvalid: | 13180 | case ZigTypeIdInvalid: |
| 13166 | case ZigTypeIdUnreachable: | 13181 | case ZigTypeIdUnreachable: |
| ... | @@ -13196,6 +13211,8 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio | ... | @@ -13196,6 +13211,8 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio |
| 13196 | ErrorMsg *msg = ir_add_error(ira, target, | 13211 | ErrorMsg *msg = ir_add_error(ira, target, |
| 13197 | buf_sprintf("exported struct value must be declared extern")); | 13212 | buf_sprintf("exported struct value must be declared extern")); |
| 13198 | add_error_note(ira->codegen, msg, target->value.type->data.structure.decl_node, buf_sprintf("declared here")); | 13213 | add_error_note(ira->codegen, msg, target->value.type->data.structure.decl_node, buf_sprintf("declared here")); |
| 13214 | } else { | ||
| 13215 | want_var_export = true; | ||
| 13199 | } | 13216 | } |
| 13200 | break; | 13217 | break; |
| 13201 | case ZigTypeIdUnion: | 13218 | case ZigTypeIdUnion: |
| ... | @@ -13203,6 +13220,8 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio | ... | @@ -13203,6 +13220,8 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio |
| 13203 | ErrorMsg *msg = ir_add_error(ira, target, | 13220 | ErrorMsg *msg = ir_add_error(ira, target, |
| 13204 | buf_sprintf("exported union value must be declared extern")); | 13221 | buf_sprintf("exported union value must be declared extern")); |
| 13205 | add_error_note(ira->codegen, msg, target->value.type->data.unionation.decl_node, buf_sprintf("declared here")); | 13222 | add_error_note(ira->codegen, msg, target->value.type->data.unionation.decl_node, buf_sprintf("declared here")); |
| 13223 | } else { | ||
| 13224 | want_var_export = true; | ||
| 13206 | } | 13225 | } |
| 13207 | break; | 13226 | break; |
| 13208 | case ZigTypeIdEnum: | 13227 | case ZigTypeIdEnum: |
| ... | @@ -13210,6 +13229,8 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio | ... | @@ -13210,6 +13229,8 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio |
| 13210 | ErrorMsg *msg = ir_add_error(ira, target, | 13229 | ErrorMsg *msg = ir_add_error(ira, target, |
| 13211 | buf_sprintf("exported enum value must be declared extern")); | 13230 | buf_sprintf("exported enum value must be declared extern")); |
| 13212 | add_error_note(ira->codegen, msg, target->value.type->data.enumeration.decl_node, buf_sprintf("declared here")); | 13231 | add_error_note(ira->codegen, msg, target->value.type->data.enumeration.decl_node, buf_sprintf("declared here")); |
| 13232 | } else { | ||
| 13233 | want_var_export = true; | ||
| 13213 | } | 13234 | } |
| 13214 | break; | 13235 | break; |
| 13215 | case ZigTypeIdMetaType: { | 13236 | case ZigTypeIdMetaType: { |
| ... | @@ -13299,6 +13320,16 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio | ... | @@ -13299,6 +13320,16 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio |
| 13299 | break; | 13320 | break; |
| 13300 | } | 13321 | } |
| 13301 | 13322 | ||
| 13323 | // TODO audit the various ways to use @export | ||
| 13324 | if (want_var_export && target->id == IrInstructionIdLoadPtr) { | ||
| 13325 | IrInstructionLoadPtr *load_ptr = reinterpret_cast<IrInstructionLoadPtr *>(target); | ||
| 13326 | if (load_ptr->ptr->id == IrInstructionIdVarPtr) { | ||
| 13327 | IrInstructionVarPtr *var_ptr = reinterpret_cast<IrInstructionVarPtr *>(load_ptr->ptr); | ||
| 13328 | ZigVar *var = var_ptr->var; | ||
| 13329 | var->linkage = global_linkage_to_var_linkage(global_linkage_id); | ||
| 13330 | } | ||
| 13331 | } | ||
| 13332 | |||
| 13302 | return ir_const_void(ira, &instruction->base); | 13333 | return ir_const_void(ira, &instruction->base); |
| 13303 | } | 13334 | } |
| 13304 | 13335 | ||
| ... | @@ -13586,9 +13617,16 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, | ... | @@ -13586,9 +13617,16 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 13586 | if (var->var_type == nullptr || type_is_invalid(var->var_type)) | 13617 | if (var->var_type == nullptr || type_is_invalid(var->var_type)) |
| 13587 | return ira->codegen->invalid_instruction; | 13618 | return ira->codegen->invalid_instruction; |
| 13588 | 13619 | ||
| 13620 | ConstExprValue *mem_slot = nullptr; | ||
| 13621 | |||
| 13589 | bool comptime_var_mem = ir_get_var_is_comptime(var); | 13622 | bool comptime_var_mem = ir_get_var_is_comptime(var); |
| 13623 | bool linkage_makes_it_runtime = var->linkage == VarLinkageExternal; | ||
| 13624 | bool is_const = var->src_is_const; | ||
| 13625 | bool is_volatile = false; | ||
| 13626 | |||
| 13627 | if (linkage_makes_it_runtime) | ||
| 13628 | goto no_mem_slot; | ||
| 13590 | 13629 | ||
| 13591 | ConstExprValue *mem_slot = nullptr; | ||
| 13592 | if (var->const_value->special == ConstValSpecialStatic) { | 13630 | if (var->const_value->special == ConstValSpecialStatic) { |
| 13593 | mem_slot = var->const_value; | 13631 | mem_slot = var->const_value; |
| 13594 | } else { | 13632 | } else { |
| ... | @@ -13602,8 +13640,6 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, | ... | @@ -13602,8 +13640,6 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 13602 | } | 13640 | } |
| 13603 | } | 13641 | } |
| 13604 | 13642 | ||
| 13605 | bool is_const = var->src_is_const; | ||
| 13606 | bool is_volatile = false; | ||
| 13607 | if (mem_slot != nullptr) { | 13643 | if (mem_slot != nullptr) { |
| 13608 | switch (mem_slot->special) { | 13644 | switch (mem_slot->special) { |
| 13609 | case ConstValSpecialRuntime: | 13645 | case ConstValSpecialRuntime: |
| ... | @@ -20679,6 +20715,13 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -20679,6 +20715,13 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ |
| 20679 | ir_add_error(ira, source_instr, buf_sprintf("cast discards const qualifier")); | 20715 | ir_add_error(ira, source_instr, buf_sprintf("cast discards const qualifier")); |
| 20680 | return ira->codegen->invalid_instruction; | 20716 | return ira->codegen->invalid_instruction; |
| 20681 | } | 20717 | } |
| 20718 | uint32_t src_align_bytes; | ||
| 20719 | if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes))) | ||
| 20720 | return ira->codegen->invalid_instruction; | ||
| 20721 | |||
| 20722 | uint32_t dest_align_bytes; | ||
| 20723 | if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes))) | ||
| 20724 | return ira->codegen->invalid_instruction; | ||
| 20682 | 20725 | ||
| 20683 | if (instr_is_comptime(ptr)) { | 20726 | if (instr_is_comptime(ptr)) { |
| 20684 | bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type); | 20727 | bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type); |
| ... | @@ -20701,16 +20744,15 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -20701,16 +20744,15 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ |
| 20701 | IrInstruction *result = ir_const(ira, source_instr, dest_type); | 20744 | IrInstruction *result = ir_const(ira, source_instr, dest_type); |
| 20702 | copy_const_val(&result->value, val, false); | 20745 | copy_const_val(&result->value, val, false); |
| 20703 | result->value.type = dest_type; | 20746 | result->value.type = dest_type; |
| 20704 | return result; | ||
| 20705 | } | ||
| 20706 | 20747 | ||
| 20707 | uint32_t src_align_bytes; | 20748 | // Keep the bigger alignment, it can only help- |
| 20708 | if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes))) | 20749 | // unless the target is zero bits. |
| 20709 | return ira->codegen->invalid_instruction; | 20750 | if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { |
| 20751 | result = ir_align_cast(ira, result, src_align_bytes, false); | ||
| 20752 | } | ||
| 20710 | 20753 | ||
| 20711 | uint32_t dest_align_bytes; | 20754 | return result; |
| 20712 | if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes))) | 20755 | } |
| 20713 | return ira->codegen->invalid_instruction; | ||
| 20714 | 20756 | ||
| 20715 | if (dest_align_bytes > src_align_bytes) { | 20757 | if (dest_align_bytes > src_align_bytes) { |
| 20716 | ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); | 20758 | ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); |
src/link.cpp+8-2| ... | @@ -899,7 +899,11 @@ static void construct_linker_job_macho(LinkJob *lj) { | ... | @@ -899,7 +899,11 @@ static void construct_linker_job_macho(LinkJob *lj) { |
| 899 | lj->args.append("-ios_simulator_version_min"); | 899 | lj->args.append("-ios_simulator_version_min"); |
| 900 | break; | 900 | break; |
| 901 | } | 901 | } |
| 902 | lj->args.append(buf_ptr(buf_sprintf("%d.%d.%d", platform.major, platform.minor, platform.micro))); | 902 | Buf *version_string = buf_sprintf("%d.%d.%d", platform.major, platform.minor, platform.micro); |
| 903 | lj->args.append(buf_ptr(version_string)); | ||
| 904 | |||
| 905 | lj->args.append("-sdk_version"); | ||
| 906 | lj->args.append(buf_ptr(version_string)); | ||
| 903 | 907 | ||
| 904 | 908 | ||
| 905 | if (g->out_type == OutTypeExe) { | 909 | if (g->out_type == OutTypeExe) { |
| ... | @@ -920,7 +924,9 @@ static void construct_linker_job_macho(LinkJob *lj) { | ... | @@ -920,7 +924,9 @@ static void construct_linker_job_macho(LinkJob *lj) { |
| 920 | add_rpath(lj, &g->output_file_path); | 924 | add_rpath(lj, &g->output_file_path); |
| 921 | 925 | ||
| 922 | if (shared) { | 926 | if (shared) { |
| 923 | lj->args.append("-headerpad_max_install_names"); | 927 | if (g->system_linker_hack) { |
| 928 | lj->args.append("-headerpad_max_install_names"); | ||
| 929 | } | ||
| 924 | } else if (g->is_static) { | 930 | } else if (g->is_static) { |
| 925 | lj->args.append("-lcrt0.o"); | 931 | lj->args.append("-lcrt0.o"); |
| 926 | } else { | 932 | } else { |
std/c/darwin.zig+10-1| ... | @@ -36,11 +36,20 @@ pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usi | ... | @@ -36,11 +36,20 @@ pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usi |
| 36 | pub extern "c" fn bind(socket: c_int, address: ?*const sockaddr, address_len: socklen_t) c_int; | 36 | pub extern "c" fn bind(socket: c_int, address: ?*const sockaddr, address_len: socklen_t) c_int; |
| 37 | pub extern "c" fn socket(domain: c_int, type: c_int, protocol: c_int) c_int; | 37 | pub extern "c" fn socket(domain: c_int, type: c_int, protocol: c_int) c_int; |
| 38 | 38 | ||
| 39 | const mach_hdr = if (@sizeOf(usize) == 8) mach_header_64 else mach_header; | ||
| 40 | |||
| 39 | /// The value of the link editor defined symbol _MH_EXECUTE_SYM is the address | 41 | /// The value of the link editor defined symbol _MH_EXECUTE_SYM is the address |
| 40 | /// of the mach header in a Mach-O executable file type. It does not appear in | 42 | /// of the mach header in a Mach-O executable file type. It does not appear in |
| 41 | /// any file type other than a MH_EXECUTE file type. The type of the symbol is | 43 | /// any file type other than a MH_EXECUTE file type. The type of the symbol is |
| 42 | /// absolute as the header is not part of any section. | 44 | /// absolute as the header is not part of any section. |
| 43 | pub extern "c" var _mh_execute_header: if (@sizeOf(usize) == 8) mach_header_64 else mach_header; | 45 | /// This symbol is populated when linking the system's libc, which is guaranteed |
| 46 | /// on this operating system. However when building object files or libraries, | ||
| 47 | /// the system libc won't be linked until the final executable. So we | ||
| 48 | /// export a weak symbol here, to be overridden by the real one. | ||
| 49 | pub extern "c" var _mh_execute_header: mach_hdr = undefined; | ||
| 50 | comptime { | ||
| 51 | @export("__mh_execute_header", _mh_execute_header, @import("builtin").GlobalLinkage.Weak); | ||
| 52 | } | ||
| 44 | 53 | ||
| 45 | pub const mach_header_64 = macho.mach_header_64; | 54 | pub const mach_header_64 = macho.mach_header_64; |
| 46 | pub const mach_header = macho.mach_header; | 55 | pub const mach_header = macho.mach_header; |
std/debug/index.zig+1-1| ... | @@ -574,7 +574,7 @@ fn machoSearchSymbols(symbols: []const MachoSymbol, address: usize) ?*const Mach | ... | @@ -574,7 +574,7 @@ fn machoSearchSymbols(symbols: []const MachoSymbol, address: usize) ?*const Mach |
| 574 | } | 574 | } |
| 575 | 575 | ||
| 576 | fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void { | 576 | fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void { |
| 577 | const base_addr = @ptrToInt(&std.c._mh_execute_header); | 577 | const base_addr = std.os.getBaseAddress(); |
| 578 | const adjusted_addr = 0x100000000 + (address - base_addr); | 578 | const adjusted_addr = 0x100000000 + (address - base_addr); |
| 579 | 579 | ||
| 580 | const symbol = machoSearchSymbols(di.symbols, adjusted_addr) orelse { | 580 | const symbol = machoSearchSymbols(di.symbols, adjusted_addr) orelse { |
std/os/index.zig+3-1| ... | @@ -701,7 +701,9 @@ pub fn getBaseAddress() usize { | ... | @@ -701,7 +701,9 @@ pub fn getBaseAddress() usize { |
| 701 | const phdr = linuxGetAuxVal(std.elf.AT_PHDR); | 701 | const phdr = linuxGetAuxVal(std.elf.AT_PHDR); |
| 702 | return phdr - @sizeOf(std.elf.Ehdr); | 702 | return phdr - @sizeOf(std.elf.Ehdr); |
| 703 | }, | 703 | }, |
| 704 | builtin.Os.macosx, builtin.Os.freebsd, builtin.Os.netbsd => return @ptrToInt(&std.c._mh_execute_header), | 704 | builtin.Os.macosx, builtin.Os.freebsd, builtin.Os.netbsd => { |
| 705 | return @ptrToInt(&std.c._mh_execute_header); | ||
| 706 | }, | ||
| 705 | builtin.Os.windows => return @ptrToInt(windows.GetModuleHandleW(null)), | 707 | builtin.Os.windows => return @ptrToInt(windows.GetModuleHandleW(null)), |
| 706 | else => @compileError("Unsupported OS"), | 708 | else => @compileError("Unsupported OS"), |
| 707 | } | 709 | } |
test/stage1/behavior/ptrcast.zig+8| ... | @@ -50,3 +50,11 @@ const Bytes = struct { | ... | @@ -50,3 +50,11 @@ const Bytes = struct { |
| 50 | return res; | 50 | return res; |
| 51 | } | 51 | } |
| 52 | }; | 52 | }; |
| 53 | |||
| 54 | test "comptime ptrcast keeps larger alignment" { | ||
| 55 | comptime { | ||
| 56 | const a: u32 = 1234; | ||
| 57 | const p = @ptrCast([*]const u8, &a); | ||
| 58 | std.debug.assert(@typeOf(p) == [*]align(@alignOf(u32)) const u8); | ||
| 59 | } | ||
| 60 | } |