diff --git a/ci/drone/linux_script_finalize b/ci/drone/linux_script_finalize index 4219bd19ac..43ff5f8f0e 100755 --- a/ci/drone/linux_script_finalize +++ b/ci/drone/linux_script_finalize @@ -19,7 +19,8 @@ pip3 install s3cmd cd build mv ../LICENSE "$INSTALL_PREFIX/" -mv ../zig-cache/langref.html "$INSTALL_PREFIX/" +# https://github.com/ziglang/zig/issues/12689 +# mv ../zig-cache/langref.html "$INSTALL_PREFIX/" mv "$INSTALL_PREFIX/bin/zig" "$INSTALL_PREFIX/" rmdir "$INSTALL_PREFIX/bin" diff --git a/ci/drone/test_linux_behavior b/ci/drone/test_linux_behavior index 53c9d94a1e..7aa9c6dcc0 100755 --- a/ci/drone/test_linux_behavior +++ b/ci/drone/test_linux_behavior @@ -7,8 +7,10 @@ INSTALL_PREFIX="$DRONE_WORKSPACE/stage3-release" ZIG="$INSTALL_PREFIX/bin/zig" export ZIG_GLOBAL_CACHE_DIR="$DRONE_WORKSPACE/zig-cache" +# Tracking issue for the disabled tests: # https://github.com/ziglang/zig/issues/12689 + # $ZIG build test-behavior -Dskip-non-native --zig-lib-dir lib $ZIG build test-compiler-rt -Dskip-non-native --zig-lib-dir lib $ZIG build test-fmt --zig-lib-dir lib -$ZIG build docs --zig-lib-dir lib +# $ZIG build docs --zig-lib-dir lib diff --git a/ci/drone/test_linux_misc b/ci/drone/test_linux_misc index a64edf19b8..ebbeee7576 100755 --- a/ci/drone/test_linux_misc +++ b/ci/drone/test_linux_misc @@ -7,10 +7,12 @@ INSTALL_PREFIX="$DRONE_WORKSPACE/stage3-release" ZIG="$INSTALL_PREFIX/bin/zig" export ZIG_GLOBAL_CACHE_DIR="$DRONE_WORKSPACE/zig-cache" -$ZIG build test-universal-libc -Dskip-non-native --zig-lib-dir lib +# Tracking issue for the disabled tests: # https://github.com/ziglang/zig/issues/12689 + +$ZIG build test-universal-libc -Dskip-non-native --zig-lib-dir lib # $ZIG build test-compare-output -Dskip-non-native --zig-lib-dir lib -$ZIG build test-standalone -Dskip-non-native --zig-lib-dir lib -Dskip-release-safe +# $ZIG build test-standalone -Dskip-non-native --zig-lib-dir lib -Dskip-release-safe $ZIG build test-stack-traces -Dskip-non-native --zig-lib-dir lib $ZIG build test-cli -Dskip-non-native --zig-lib-dir lib $ZIG build test-asm-link -Dskip-non-native --zig-lib-dir lib diff --git a/lib/std/coff.zig b/lib/std/coff.zig index e822416f70..1caec57c4a 100644 --- a/lib/std/coff.zig +++ b/lib/std/coff.zig @@ -310,6 +310,84 @@ pub const ImageDataDirectory = extern struct { size: u32, }; +pub const BaseRelocationDirectoryEntry = extern struct { + /// The image base plus the page RVA is added to each offset to create the VA where the base relocation must be applied. + page_rva: u32, + + /// The total number of bytes in the base relocation block, including the Page RVA and Block Size fields and the Type/Offset fields that follow. + block_size: u32, +}; + +pub const BaseRelocation = packed struct { + /// Stored in the remaining 12 bits of the WORD, an offset from the starting address that was specified in the Page RVA field for the block. + /// This offset specifies where the base relocation is to be applied. + offset: u12, + + /// Stored in the high 4 bits of the WORD, a value that indicates the type of base relocation to be applied. + @"type": BaseRelocationType, +}; + +pub const BaseRelocationType = enum(u4) { + /// The base relocation is skipped. This type can be used to pad a block. + ABSOLUTE = 0, + + /// The base relocation adds the high 16 bits of the difference to the 16-bit field at offset. The 16-bit field represents the high value of a 32-bit word. + HIGH = 1, + + /// The base relocation adds the low 16 bits of the difference to the 16-bit field at offset. The 16-bit field represents the low half of a 32-bit word. + LOW = 2, + + /// The base relocation applies all 32 bits of the difference to the 32-bit field at offset. + HIGHLOW = 3, + + /// The base relocation adds the high 16 bits of the difference to the 16-bit field at offset. + /// The 16-bit field represents the high value of a 32-bit word. + /// The low 16 bits of the 32-bit value are stored in the 16-bit word that follows this base relocation. + /// This means that this base relocation occupies two slots. + HIGHADJ = 4, + + /// When the machine type is MIPS, the base relocation applies to a MIPS jump instruction. + MIPS_JMPADDR = 5, + + /// This relocation is meaningful only when the machine type is ARM or Thumb. + /// The base relocation applies the 32-bit address of a symbol across a consecutive MOVW/MOVT instruction pair. + // ARM_MOV32 = 5, + + /// This relocation is only meaningful when the machine type is RISC-V. + /// The base relocation applies to the high 20 bits of a 32-bit absolute address. + // RISCV_HIGH20 = 5, + + /// Reserved, must be zero. + RESERVED = 6, + + /// This relocation is meaningful only when the machine type is Thumb. + /// The base relocation applies the 32-bit address of a symbol to a consecutive MOVW/MOVT instruction pair. + THUMB_MOV32 = 7, + + /// This relocation is only meaningful when the machine type is RISC-V. + /// The base relocation applies to the low 12 bits of a 32-bit absolute address formed in RISC-V I-type instruction format. + // RISCV_LOW12I = 7, + + /// This relocation is only meaningful when the machine type is RISC-V. + /// The base relocation applies to the low 12 bits of a 32-bit absolute address formed in RISC-V S-type instruction format. + RISCV_LOW12S = 8, + + /// This relocation is only meaningful when the machine type is LoongArch 32-bit. + /// The base relocation applies to a 32-bit absolute address formed in two consecutive instructions. + // LOONGARCH32_MARK_LA = 8, + + /// This relocation is only meaningful when the machine type is LoongArch 64-bit. + /// The base relocation applies to a 64-bit absolute address formed in four consecutive instructions. + // LOONGARCH64_MARK_LA = 8, + + /// The relocation is only meaningful when the machine type is MIPS. + /// The base relocation applies to a MIPS16 jump instruction. + MIPS_JMPADDR16 = 9, + + /// The base relocation applies the difference to the 64-bit field at offset. + DIR64 = 10, +}; + pub const DebugDirectoryEntry = extern struct { characteristics: u32, time_date_stamp: u32, diff --git a/src/Module.zig b/src/Module.zig index 66c36b939b..9410c4ea4a 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -1496,6 +1496,22 @@ pub const Fn = struct { /// active Sema context. Importantly, this value is also updated when an existing /// generic function instantiation is found and called. branch_quota: u32, + + /// If this is not none, this function is a generic function instantiation, and + /// this is the generic function decl from which the instance was derived. + /// This information is redundant with a combination of checking if comptime_args is + /// not null and looking at the first decl dependency of owner_decl. This redundant + /// information is useful for three reasons: + /// 1. Improved perf of monomorphed_funcs when checking the eql() function because it + /// can do two fewer pointer chases by grabbing the info from this field directly + /// instead of accessing the decl and then the dependencies set. + /// 2. While a generic function instantiation is being initialized, we need hash() + /// and eql() to work before the initialization is complete. Completing the + /// insertion into the decl dependency set has more fallible operations than simply + /// setting this field. + /// 3. I forgot what the third thing was while typing up the other two. + generic_owner_decl: Decl.OptionalIndex, + state: Analysis, is_cold: bool = false, is_noinline: bool, diff --git a/src/Sema.zig b/src/Sema.zig index 0626fd30ee..7a96fd51cd 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -5590,11 +5590,10 @@ const GenericCallAdapter = struct { pub fn eql(ctx: @This(), adapted_key: void, other_key: *Module.Fn) bool { _ = adapted_key; - // The generic function Decl is guaranteed to be the first dependency - // of each of its instantiations. - const other_owner_decl = ctx.module.declPtr(other_key.owner_decl); - const generic_owner_decl = other_owner_decl.dependencies.keys()[0]; - if (ctx.generic_fn.owner_decl != generic_owner_decl) return false; + // Checking for equality may happen on an item that has been inserted + // into the map but is not yet fully initialized. In such case, the + // two initialized fields are `hash` and `generic_owner_decl`. + if (ctx.generic_fn.owner_decl != other_key.generic_owner_decl.unwrap().?) return false; const other_comptime_args = other_key.comptime_args.?; for (other_comptime_args[0..ctx.func_ty_info.param_types.len]) |other_arg, i| { @@ -6447,11 +6446,14 @@ fn instantiateGenericCall( const gop = try mod.monomorphed_funcs.getOrPutAdapted(gpa, {}, adapter); const callee = if (!gop.found_existing) callee: { const new_module_func = try gpa.create(Module.Fn); + errdefer gpa.destroy(new_module_func); + // This ensures that we can operate on the hash map before the Module.Fn // struct is fully initialized. new_module_func.hash = precomputed_hash; + new_module_func.generic_owner_decl = module_fn.owner_decl.toOptional(); + new_module_func.comptime_args = null; gop.key_ptr.* = new_module_func; - errdefer gpa.destroy(new_module_func); errdefer assert(mod.monomorphed_funcs.remove(new_module_func)); try namespace.anon_decls.ensureUnusedCapacity(gpa, 1); @@ -8032,11 +8034,13 @@ fn funcCommon( } else null; const hash = new_func.hash; + const generic_owner_decl = if (comptime_args == null) .none else new_func.generic_owner_decl; const fn_payload = try sema.arena.create(Value.Payload.Function); new_func.* = .{ .state = anal_state, .zir_body_inst = func_inst, .owner_decl = sema.owner_decl_index, + .generic_owner_decl = generic_owner_decl, .comptime_args = comptime_args, .hash = hash, .lbrace_line = src_locs.lbrace_line,