mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
Merge branch 'master' into ambiguous-precedence
This commit is contained in:
commit
aae73cfab2
88 changed files with 453 additions and 2351 deletions
|
|
@ -581,7 +581,6 @@ set(ZIG_STAGE2_SOURCES
|
|||
src/link/Elf/relocation.zig
|
||||
src/link/Elf/synthetic_sections.zig
|
||||
src/link/Elf2.zig
|
||||
src/link/Goff.zig
|
||||
src/link/LdScript.zig
|
||||
src/link/Lld.zig
|
||||
src/link/MachO.zig
|
||||
|
|
@ -617,7 +616,6 @@ set(ZIG_STAGE2_SOURCES
|
|||
src/link/Wasm/Archive.zig
|
||||
src/link/Wasm/Flush.zig
|
||||
src/link/Wasm/Object.zig
|
||||
src/link/Xcoff.zig
|
||||
src/link/aarch64.zig
|
||||
src/link/riscv.zig
|
||||
src/link/table_section.zig
|
||||
|
|
@ -738,17 +736,12 @@ string(TOLOWER "${CMAKE_HOST_SYSTEM_NAME}" ZIG_HOST_TARGET_OS)
|
|||
if(ZIG_HOST_TARGET_OS STREQUAL "darwin")
|
||||
set(ZIG_HOST_TARGET_OS "macos")
|
||||
elseif(ZIG_HOST_TARGET_OS STREQUAL "sunos")
|
||||
check_symbol_exists(__illumos__ "" ZIG_HOST_TARGET_HAS_ILLUMOS_MACRO)
|
||||
if (ZIG_HOST_TARGET_HAS_ILLUMOS_MACRO)
|
||||
set(ZIG_HOST_TARGET_OS "illumos")
|
||||
else()
|
||||
set(ZIG_HOST_TARGET_OS "solaris")
|
||||
endif()
|
||||
set(ZIG_HOST_TARGET_OS "illumos")
|
||||
endif()
|
||||
|
||||
string(TOLOWER "${CMAKE_HOST_SYSTEM_PROCESSOR}" ZIG_HOST_TARGET_ARCH)
|
||||
if(ZIG_HOST_TARGET_ARCH MATCHES "^i[3-9]86$")
|
||||
if (ZIG_HOST_TARGET_OS MATCHES "(solaris|illumos)")
|
||||
if (ZIG_HOST_TARGET_OS STREQUAL "illumos")
|
||||
set(ZIG_HOST_TARGET_ARCH "x86_64")
|
||||
else()
|
||||
set(ZIG_HOST_TARGET_ARCH "x86")
|
||||
|
|
|
|||
|
|
@ -818,7 +818,7 @@ fn addCmakeCfgOptionsToExe(
|
|||
try addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), null, need_cpp_includes);
|
||||
if (static) try addCxxKnownPath(b, cfg, exe, b.fmt("libgcc_eh.{s}", .{lib_suffix}), null, need_cpp_includes);
|
||||
},
|
||||
.solaris, .illumos => {
|
||||
.illumos => {
|
||||
try addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), null, need_cpp_includes);
|
||||
try addCxxKnownPath(b, cfg, exe, b.fmt("libgcc_eh.{s}", .{lib_suffix}), null, need_cpp_includes);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3025,7 +3025,7 @@ or
|
|||
{#syntax#}catch{#endsyntax#} after performing some logic, you
|
||||
can combine {#syntax#}catch{#endsyntax#} with named {#link|Blocks#}:
|
||||
</p>
|
||||
{#code|handle_error_with_catch_block.zig.zig#}
|
||||
{#code|handle_error_with_catch_block.zig#}
|
||||
|
||||
{#header_close#}
|
||||
{#header_open|try#}
|
||||
|
|
|
|||
16
lib/compiler/aro/aro/Compilation.zig
vendored
16
lib/compiler/aro/aro/Compilation.zig
vendored
|
|
@ -337,7 +337,7 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
|
|||
.netbsd => try define(w, "__NetBSD__"),
|
||||
.openbsd => try define(w, "__OpenBSD__"),
|
||||
.dragonfly => try define(w, "__DragonFly__"),
|
||||
.solaris => try defineStd(w, "sun", is_gnu),
|
||||
.illumos => try defineStd(w, "sun", is_gnu),
|
||||
.macos,
|
||||
.tvos,
|
||||
.ios,
|
||||
|
|
@ -361,8 +361,7 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
|
|||
.linux,
|
||||
.haiku,
|
||||
.hurd,
|
||||
.solaris,
|
||||
.aix,
|
||||
.illumos,
|
||||
.emscripten,
|
||||
.ps4,
|
||||
.ps5,
|
||||
|
|
@ -618,7 +617,7 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
|
|||
try defineStd(w, "sparc", is_gnu);
|
||||
try define(w, "__sparc_v9__");
|
||||
try define(w, "__arch64__");
|
||||
if (comp.target.os.tag != .solaris) {
|
||||
if (comp.target.os.tag != .illumos) {
|
||||
try define(w, "__sparc64__");
|
||||
try define(w, "__sparc_v9__");
|
||||
try define(w, "__sparcv9__");
|
||||
|
|
@ -626,7 +625,7 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
|
|||
},
|
||||
.sparc => {
|
||||
try defineStd(w, "sparc", is_gnu);
|
||||
if (comp.target.os.tag == .solaris) {
|
||||
if (comp.target.os.tag == .illumos) {
|
||||
try define(w, "__sparcv8");
|
||||
}
|
||||
},
|
||||
|
|
@ -1006,13 +1005,6 @@ fn writeBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefinesMode
|
|||
\\
|
||||
);
|
||||
},
|
||||
.aix => {
|
||||
try w.writeAll(
|
||||
\\#define __STDC_NO_THREADS__ 1
|
||||
\\#define __STDC_NO_ATOMICS__ 1
|
||||
\\
|
||||
);
|
||||
},
|
||||
else => {},
|
||||
};
|
||||
if (comp.langopts.standard.StdCVersionMacro()) |stdc_version| {
|
||||
|
|
|
|||
2
lib/compiler/aro/aro/Driver.zig
vendored
2
lib/compiler/aro/aro/Driver.zig
vendored
|
|
@ -810,7 +810,7 @@ pub fn parseArgs(
|
|||
if (strip) break :debug .strip;
|
||||
if (debug) |explicit| break :debug explicit;
|
||||
break :debug switch (d.comp.target.ofmt) {
|
||||
.elf, .goff, .macho, .wasm, .xcoff => .{ .dwarf = .@"32" },
|
||||
.elf, .macho, .wasm => .{ .dwarf = .@"32" },
|
||||
.coff => .code_view,
|
||||
.c => switch (d.comp.target.os.tag) {
|
||||
.windows, .uefi => .code_view,
|
||||
|
|
|
|||
18
lib/compiler/aro/aro/Toolchain.zig
vendored
18
lib/compiler/aro/aro/Toolchain.zig
vendored
|
|
@ -369,7 +369,7 @@ fn getUnwindLibKind(tc: *const Toolchain) !UnwindLibKind {
|
|||
switch (tc.getRuntimeLibKind()) {
|
||||
.compiler_rt => {
|
||||
const target = tc.getTarget();
|
||||
if (target.abi.isAndroid() or target.os.tag == .aix) {
|
||||
if (target.abi.isAndroid()) {
|
||||
return .compiler_rt;
|
||||
} else {
|
||||
return .none;
|
||||
|
|
@ -391,8 +391,8 @@ fn getUnwindLibKind(tc: *const Toolchain) !UnwindLibKind {
|
|||
}
|
||||
}
|
||||
|
||||
fn getAsNeededOption(is_solaris: bool, needed: bool) []const u8 {
|
||||
if (is_solaris) {
|
||||
fn getAsNeededOption(is_illumos: bool, needed: bool) []const u8 {
|
||||
if (is_illumos) {
|
||||
return if (needed) "-zignore" else "-zrecord";
|
||||
} else {
|
||||
return if (needed) "--as-needed" else "--no-as-needed";
|
||||
|
|
@ -408,20 +408,16 @@ fn addUnwindLibrary(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !voi
|
|||
unw == .none) return;
|
||||
|
||||
const lgk = tc.getLibGCCKind();
|
||||
const as_needed = lgk == .unspecified and !target.abi.isAndroid() and !target_util.isCygwinMinGW(target) and target.os.tag != .aix;
|
||||
const as_needed = lgk == .unspecified and !target.abi.isAndroid() and !target_util.isCygwinMinGW(target);
|
||||
|
||||
try argv.ensureUnusedCapacity(tc.driver.comp.gpa, 3);
|
||||
if (as_needed) {
|
||||
argv.appendAssumeCapacity(getAsNeededOption(target.os.tag == .solaris, true));
|
||||
argv.appendAssumeCapacity(getAsNeededOption(target.os.tag == .illumos, true));
|
||||
}
|
||||
switch (unw) {
|
||||
.none => return,
|
||||
.libgcc => argv.appendAssumeCapacity(if (lgk == .static) "-lgcc_eh" else "-lgcc_s"),
|
||||
.compiler_rt => if (target.os.tag == .aix) {
|
||||
if (lgk != .static) {
|
||||
argv.appendAssumeCapacity("-lunwind");
|
||||
}
|
||||
} else if (lgk == .static) {
|
||||
.compiler_rt => if (lgk == .static) {
|
||||
argv.appendAssumeCapacity("-l:libunwind.a");
|
||||
} else if (lgk == .shared) {
|
||||
if (target_util.isCygwinMinGW(target)) {
|
||||
|
|
@ -435,7 +431,7 @@ fn addUnwindLibrary(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !voi
|
|||
}
|
||||
|
||||
if (as_needed) {
|
||||
argv.appendAssumeCapacity(getAsNeededOption(target.os.tag == .solaris, false));
|
||||
argv.appendAssumeCapacity(getAsNeededOption(target.os.tag == .illumos, false));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
5
lib/compiler/aro/aro/TypeStore.zig
vendored
5
lib/compiler/aro/aro/TypeStore.zig
vendored
|
|
@ -2099,10 +2099,7 @@ fn generateVaListType(ts: *TypeStore, comp: *Compilation) !QualType {
|
|||
.hexagon_va_list
|
||||
else
|
||||
return .char_pointer,
|
||||
.powerpc, .powerpcle => switch (comp.target.os.tag) {
|
||||
.aix => return .char_pointer,
|
||||
else => .powerpc_va_list,
|
||||
},
|
||||
.powerpc, .powerpcle => .powerpc_va_list,
|
||||
.s390x => .s390x_va_list,
|
||||
.x86_64 => switch (comp.target.os.tag) {
|
||||
.uefi, .windows => return .char_pointer,
|
||||
|
|
|
|||
23
lib/compiler/aro/aro/target.zig
vendored
23
lib/compiler/aro/aro/target.zig
vendored
|
|
@ -252,7 +252,7 @@ pub fn systemCompiler(target: std.Target) LangOpts.Compiler {
|
|||
target.abi.isAndroid() or
|
||||
target.os.tag.isBSD() or
|
||||
target.os.tag == .fuchsia or
|
||||
target.os.tag == .solaris or
|
||||
target.os.tag == .illumos or
|
||||
target.os.tag == .haiku or
|
||||
target.cpu.arch == .hexagon)
|
||||
{
|
||||
|
|
@ -281,7 +281,7 @@ pub fn hasFloat128(target: std.Target) bool {
|
|||
.haiku,
|
||||
.linux,
|
||||
.openbsd,
|
||||
.solaris,
|
||||
.illumos,
|
||||
=> target.cpu.arch.isX86(),
|
||||
else => false,
|
||||
};
|
||||
|
|
@ -403,7 +403,6 @@ pub fn builtinEnabled(target: std.Target, enabled_for: TargetSet) bool {
|
|||
}
|
||||
|
||||
pub fn defaultFpEvalMethod(target: std.Target) LangOpts.FPEvalMethod {
|
||||
if (target.os.tag == .aix) return .double;
|
||||
switch (target.cpu.arch) {
|
||||
.x86, .x86_64 => {
|
||||
if (target.ptrBitWidth() == 32 and target.os.tag == .netbsd) {
|
||||
|
|
@ -654,13 +653,10 @@ pub fn toLLVMTriple(target: std.Target, buf: []u8) []const u8 {
|
|||
.ps3 => "lv2",
|
||||
.netbsd => "netbsd",
|
||||
.openbsd => "openbsd",
|
||||
.solaris => "solaris",
|
||||
.illumos => "illumos",
|
||||
.illumos => "solaris",
|
||||
.windows => "windows",
|
||||
.zos => "zos",
|
||||
.haiku => "haiku",
|
||||
.rtems => "rtems",
|
||||
.aix => "aix",
|
||||
.cuda => "cuda",
|
||||
.nvcl => "nvcl",
|
||||
.amdhsa => "amdhsa",
|
||||
|
|
@ -742,7 +738,6 @@ pub const DefaultPIStatus = enum { yes, no, depends_on_linker };
|
|||
|
||||
pub fn isPIEDefault(target: std.Target) DefaultPIStatus {
|
||||
return switch (target.os.tag) {
|
||||
.aix,
|
||||
.haiku,
|
||||
|
||||
.macos,
|
||||
|
|
@ -755,7 +750,7 @@ pub fn isPIEDefault(target: std.Target) DefaultPIStatus {
|
|||
.dragonfly,
|
||||
.netbsd,
|
||||
.freebsd,
|
||||
.solaris,
|
||||
.illumos,
|
||||
|
||||
.cuda,
|
||||
.amdhsa,
|
||||
|
|
@ -766,7 +761,6 @@ pub fn isPIEDefault(target: std.Target) DefaultPIStatus {
|
|||
.ps5,
|
||||
|
||||
.hurd,
|
||||
.zos,
|
||||
=> .no,
|
||||
|
||||
.openbsd,
|
||||
|
|
@ -811,7 +805,6 @@ pub fn isPIEDefault(target: std.Target) DefaultPIStatus {
|
|||
|
||||
pub fn isPICdefault(target: std.Target) DefaultPIStatus {
|
||||
return switch (target.os.tag) {
|
||||
.aix,
|
||||
.haiku,
|
||||
|
||||
.macos,
|
||||
|
|
@ -831,14 +824,13 @@ pub fn isPICdefault(target: std.Target) DefaultPIStatus {
|
|||
|
||||
.fuchsia,
|
||||
.cuda,
|
||||
.zos,
|
||||
=> .no,
|
||||
|
||||
.dragonfly,
|
||||
.openbsd,
|
||||
.netbsd,
|
||||
.freebsd,
|
||||
.solaris,
|
||||
.illumos,
|
||||
.hurd,
|
||||
=> {
|
||||
return switch (target.cpu.arch) {
|
||||
|
|
@ -890,21 +882,20 @@ pub fn isPICdefault(target: std.Target) DefaultPIStatus {
|
|||
|
||||
pub fn isPICDefaultForced(target: std.Target) DefaultPIStatus {
|
||||
return switch (target.os.tag) {
|
||||
.aix, .amdhsa, .amdpal, .mesa3d => .yes,
|
||||
.amdhsa, .amdpal, .mesa3d => .yes,
|
||||
|
||||
.haiku,
|
||||
.dragonfly,
|
||||
.openbsd,
|
||||
.netbsd,
|
||||
.freebsd,
|
||||
.solaris,
|
||||
.illumos,
|
||||
.cuda,
|
||||
.ps4,
|
||||
.ps5,
|
||||
.hurd,
|
||||
.linux,
|
||||
.fuchsia,
|
||||
.zos,
|
||||
=> .no,
|
||||
|
||||
.windows => {
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, resul
|
|||
const parts = math.frexp(a);
|
||||
const significand_bits_adjusted_to_handle_smin = @as(i32, significand_bits) +
|
||||
@intFromBool(signedness == .signed and parts.exponent == 32 * result.len);
|
||||
const exponent = @max(parts.exponent - significand_bits_adjusted_to_handle_smin, 0);
|
||||
const exponent: usize = @intCast(@max(parts.exponent - significand_bits_adjusted_to_handle_smin, 0));
|
||||
const int: I = @intFromFloat(switch (exponent) {
|
||||
0 => a,
|
||||
else => math.ldexp(parts.significand, significand_bits_adjusted_to_handle_smin),
|
||||
|
|
|
|||
18
lib/include/zos_wrappers/builtins.h
vendored
18
lib/include/zos_wrappers/builtins.h
vendored
|
|
@ -1,18 +0,0 @@
|
|||
/*===---- builtins.h - z/Architecture Builtin Functions --------------------===
|
||||
*
|
||||
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
* See https://llvm.org/LICENSE.txt for license information.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*
|
||||
*===-----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#ifndef __ZOS_WRAPPERS_BUILTINS_H
|
||||
#define __ZOS_WRAPPERS_BUILTINS_H
|
||||
#if defined(__MVS__)
|
||||
#include_next <builtins.h>
|
||||
#if defined(__VEC__)
|
||||
#include <vecintrin.h>
|
||||
#endif
|
||||
#endif /* defined(__MVS__) */
|
||||
#endif /* __ZOS_WRAPPERS_BUILTINS_H */
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
//===-----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_IBM_H
|
||||
#define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_IBM_H
|
||||
|
||||
#if defined(__MVS__)
|
||||
# include <__support/ibm/locale_mgmt_zos.h>
|
||||
#endif // defined(__MVS__)
|
||||
|
||||
#include <locale.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cstdlib"
|
||||
|
||||
#if defined(__MVS__)
|
||||
# include <wctype.h>
|
||||
// POSIX routines
|
||||
# include <__support/xlocale/__posix_l_fallback.h>
|
||||
#endif // defined(__MVS__)
|
||||
|
||||
namespace {
|
||||
|
||||
struct __setAndRestore {
|
||||
explicit __setAndRestore(locale_t locale) {
|
||||
if (locale == (locale_t)0) {
|
||||
__cloc = newlocale(LC_ALL_MASK, "C", /* base */ (locale_t)0);
|
||||
__stored = uselocale(__cloc);
|
||||
} else {
|
||||
__stored = uselocale(locale);
|
||||
}
|
||||
}
|
||||
|
||||
~__setAndRestore() {
|
||||
uselocale(__stored);
|
||||
if (__cloc)
|
||||
freelocale(__cloc);
|
||||
}
|
||||
|
||||
private:
|
||||
locale_t __stored = (locale_t)0;
|
||||
locale_t __cloc = (locale_t)0;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// The following are not POSIX routines. These are quick-and-dirty hacks
|
||||
// to make things pretend to work
|
||||
inline _LIBCPP_HIDE_FROM_ABI long long strtoll_l(const char* __nptr, char** __endptr, int __base, locale_t locale) {
|
||||
__setAndRestore __newloc(locale);
|
||||
return ::strtoll(__nptr, __endptr, __base);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI double strtod_l(const char* __nptr, char** __endptr, locale_t locale) {
|
||||
__setAndRestore __newloc(locale);
|
||||
return ::strtod(__nptr, __endptr);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI float strtof_l(const char* __nptr, char** __endptr, locale_t locale) {
|
||||
__setAndRestore __newloc(locale);
|
||||
return ::strtof(__nptr, __endptr);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI long double strtold_l(const char* __nptr, char** __endptr, locale_t locale) {
|
||||
__setAndRestore __newloc(locale);
|
||||
return ::strtold(__nptr, __endptr);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI unsigned long long
|
||||
strtoull_l(const char* __nptr, char** __endptr, int __base, locale_t locale) {
|
||||
__setAndRestore __newloc(locale);
|
||||
return ::strtoull(__nptr, __endptr, __base);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 2, 0) int vasprintf(char** strp, const char* fmt, va_list ap) {
|
||||
const size_t buff_size = 256;
|
||||
if ((*strp = (char*)malloc(buff_size)) == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
va_list ap_copy;
|
||||
// va_copy may not be provided by the C library in C++03 mode.
|
||||
#if defined(_LIBCPP_CXX03_LANG) && __has_builtin(__builtin_va_copy)
|
||||
__builtin_va_copy(ap_copy, ap);
|
||||
#else
|
||||
va_copy(ap_copy, ap);
|
||||
#endif
|
||||
int str_size = vsnprintf(*strp, buff_size, fmt, ap_copy);
|
||||
va_end(ap_copy);
|
||||
|
||||
if ((size_t)str_size >= buff_size) {
|
||||
if ((*strp = (char*)realloc(*strp, str_size + 1)) == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
str_size = vsnprintf(*strp, str_size + 1, fmt, ap);
|
||||
}
|
||||
return str_size;
|
||||
}
|
||||
|
||||
#endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_IBM_H
|
||||
52
lib/libcxx/include/__support/ibm/gettod_zos.h
vendored
52
lib/libcxx/include/__support/ibm/gettod_zos.h
vendored
|
|
@ -1,52 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___SUPPORT_IBM_GETTOD_ZOS_H
|
||||
#define _LIBCPP___SUPPORT_IBM_GETTOD_ZOS_H
|
||||
|
||||
#include <time.h>
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI int gettimeofdayMonotonic(struct timespec64* Output) {
|
||||
// The POSIX gettimeofday() function is not available on z/OS. Therefore,
|
||||
// we will call stcke and other hardware instructions in implement equivalent.
|
||||
// Note that nanoseconds alone will overflow when reaching new epoch in 2042.
|
||||
|
||||
struct _t {
|
||||
uint64_t Hi;
|
||||
uint64_t Lo;
|
||||
};
|
||||
struct _t Value = {0, 0};
|
||||
uint64_t CC = 0;
|
||||
asm(" stcke %0\n"
|
||||
" ipm %1\n"
|
||||
" srlg %1,%1,28\n"
|
||||
: "=m"(Value), "+r"(CC)::);
|
||||
|
||||
if (CC != 0) {
|
||||
errno = EMVSTODNOTSET;
|
||||
return CC;
|
||||
}
|
||||
uint64_t us = (Value.Hi >> 4);
|
||||
uint64_t ns = ((Value.Hi & 0x0F) << 8) + (Value.Lo >> 56);
|
||||
ns = (ns * 1000) >> 12;
|
||||
us = us - 2208988800000000;
|
||||
|
||||
register uint64_t DivPair0 asm("r0"); // dividend (upper half), remainder
|
||||
DivPair0 = 0;
|
||||
register uint64_t DivPair1 asm("r1"); // dividend (lower half), quotient
|
||||
DivPair1 = us;
|
||||
uint64_t Divisor = 1000000;
|
||||
asm(" dlgr %0,%2" : "+r"(DivPair0), "+r"(DivPair1) : "r"(Divisor) :);
|
||||
|
||||
Output->tv_sec = DivPair1;
|
||||
Output->tv_nsec = DivPair0 * 1000 + ns;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // _LIBCPP___SUPPORT_IBM_GETTOD_ZOS_H
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___SUPPORT_IBM_LOCALE_MGMT_ZOS_H
|
||||
#define _LIBCPP___SUPPORT_IBM_LOCALE_MGMT_ZOS_H
|
||||
|
||||
#if defined(__MVS__)
|
||||
# include <locale.h>
|
||||
# include <string>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
# define _LC_MAX LC_MESSAGES /* highest real category */
|
||||
# define _NCAT (_LC_MAX + 1) /* maximum + 1 */
|
||||
|
||||
# define _CATMASK(n) (1 << (n))
|
||||
# define LC_COLLATE_MASK _CATMASK(LC_COLLATE)
|
||||
# define LC_CTYPE_MASK _CATMASK(LC_CTYPE)
|
||||
# define LC_MONETARY_MASK _CATMASK(LC_MONETARY)
|
||||
# define LC_NUMERIC_MASK _CATMASK(LC_NUMERIC)
|
||||
# define LC_TIME_MASK _CATMASK(LC_TIME)
|
||||
# define LC_MESSAGES_MASK _CATMASK(LC_MESSAGES)
|
||||
# define LC_ALL_MASK (_CATMASK(_NCAT) - 1)
|
||||
|
||||
typedef struct locale_struct {
|
||||
int category_mask;
|
||||
std::string lc_collate;
|
||||
std::string lc_ctype;
|
||||
std::string lc_monetary;
|
||||
std::string lc_numeric;
|
||||
std::string lc_time;
|
||||
std::string lc_messages;
|
||||
}* locale_t;
|
||||
|
||||
// z/OS does not have newlocale, freelocale and uselocale.
|
||||
// The functions below are workarounds in single thread mode.
|
||||
locale_t newlocale(int category_mask, const char* locale, locale_t base);
|
||||
void freelocale(locale_t locobj);
|
||||
locale_t uselocale(locale_t newloc);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
#endif // defined(__MVS__)
|
||||
#endif // _LIBCPP___SUPPORT_IBM_LOCALE_MGMT_ZOS_H
|
||||
55
lib/libcxx/include/__support/ibm/nanosleep.h
vendored
55
lib/libcxx/include/__support/ibm/nanosleep.h
vendored
|
|
@ -1,55 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___SUPPORT_IBM_NANOSLEEP_H
|
||||
#define _LIBCPP___SUPPORT_IBM_NANOSLEEP_H
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
inline int nanosleep(const struct timespec* __req, struct timespec* __rem) {
|
||||
// The nanosleep() function is not available on z/OS. Therefore, we will call
|
||||
// sleep() to sleep for whole seconds and usleep() to sleep for any remaining
|
||||
// fraction of a second. Any remaining nanoseconds will round up to the next
|
||||
// microsecond.
|
||||
if (__req->tv_sec < 0 || __req->tv_nsec < 0 || __req->tv_nsec > 999999999) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
long __micro_sec = (__req->tv_nsec + 999) / 1000;
|
||||
time_t __sec = __req->tv_sec;
|
||||
if (__micro_sec > 999999) {
|
||||
++__sec;
|
||||
__micro_sec -= 1000000;
|
||||
}
|
||||
__sec = static_cast<time_t>(sleep(static_cast<unsigned int>(__sec)));
|
||||
if (__sec) {
|
||||
if (__rem) {
|
||||
// Updating the remaining time to sleep in case of unsuccessful call to sleep().
|
||||
__rem->tv_sec = __sec;
|
||||
__rem->tv_nsec = __micro_sec * 1000;
|
||||
}
|
||||
errno = EINTR;
|
||||
return -1;
|
||||
}
|
||||
if (__micro_sec) {
|
||||
int __rt = usleep(static_cast<unsigned int>(__micro_sec));
|
||||
if (__rt != 0 && __rem) {
|
||||
// The usleep() does not provide the amount of remaining time upon its failure,
|
||||
// so the time slept will be ignored.
|
||||
__rem->tv_sec = 0;
|
||||
__rem->tv_nsec = __micro_sec * 1000;
|
||||
// The errno is already set.
|
||||
return -1;
|
||||
}
|
||||
return __rt;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // _LIBCPP___SUPPORT_IBM_NANOSLEEP_H
|
||||
97
lib/libcxx/src/support/ibm/mbsnrtowcs.cpp
vendored
97
lib/libcxx/src/support/ibm/mbsnrtowcs.cpp
vendored
|
|
@ -1,97 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <cstddef> // size_t
|
||||
#include <cwchar> // mbstate_t
|
||||
#include <limits.h> // MB_LEN_MAX
|
||||
#include <string.h> // wmemcpy
|
||||
|
||||
// Returns the number of wide characters found in the multi byte sequence `src`
|
||||
// (of `src_size_bytes`), that fit in the buffer `dst` (of `max_dest_chars`
|
||||
// elements size). The count returned excludes the null terminator.
|
||||
// When `dst` is NULL, no characters are copied to `dst`.
|
||||
// Returns (size_t) -1 when an invalid sequence is encountered.
|
||||
// Leaves *`src` pointing to the next character to convert or NULL
|
||||
// if a null character was converted from *`src`.
|
||||
_LIBCPP_EXPORTED_FROM_ABI size_t mbsnrtowcs(
|
||||
wchar_t* __restrict dst,
|
||||
const char** __restrict src,
|
||||
size_t src_size_bytes,
|
||||
size_t max_dest_chars,
|
||||
mbstate_t* __restrict ps) {
|
||||
const size_t terminated_sequence = static_cast<size_t>(0);
|
||||
const size_t invalid_sequence = static_cast<size_t>(-1);
|
||||
const size_t incomplete_sequence = static_cast<size_t>(-2);
|
||||
|
||||
size_t source_converted;
|
||||
size_t dest_converted;
|
||||
size_t result = 0;
|
||||
|
||||
// If `dst` is null then `max_dest_chars` should be ignored according to the
|
||||
// standard. Setting `max_dest_chars` to a large value has this effect.
|
||||
if (dst == nullptr)
|
||||
max_dest_chars = static_cast<size_t>(-1);
|
||||
|
||||
for (dest_converted = source_converted = 0;
|
||||
source_converted < src_size_bytes && (!dst || dest_converted < max_dest_chars);
|
||||
++dest_converted, source_converted += result) {
|
||||
// Converts one multi byte character.
|
||||
// If result (char_size) is greater than 0, it's the size in bytes of that character.
|
||||
// If result (char_size) is zero, it indicates that the null character has been found.
|
||||
// Otherwise, it's an error and errno may be set.
|
||||
size_t source_remaining = src_size_bytes - source_converted;
|
||||
size_t dest_remaining = max_dest_chars - dest_converted;
|
||||
|
||||
if (dst == nullptr) {
|
||||
result = mbrtowc(nullptr, *src + source_converted, source_remaining, ps);
|
||||
} else if (dest_remaining >= source_remaining) {
|
||||
// dst has enough space to translate in-place.
|
||||
result = mbrtowc(dst + dest_converted, *src + source_converted, source_remaining, ps);
|
||||
} else {
|
||||
/*
|
||||
* dst may not have enough space, so use a temporary buffer.
|
||||
*
|
||||
* We need to save a copy of the conversion state
|
||||
* here so we can restore it if the multibyte
|
||||
* character is too long for the buffer.
|
||||
*/
|
||||
wchar_t buff[MB_LEN_MAX];
|
||||
mbstate_t mbstate_tmp;
|
||||
|
||||
if (ps != nullptr)
|
||||
mbstate_tmp = *ps;
|
||||
result = mbrtowc(buff, *src + source_converted, source_remaining, ps);
|
||||
|
||||
if (result > dest_remaining) {
|
||||
// Multi-byte sequence for character won't fit.
|
||||
if (ps != nullptr)
|
||||
*ps = mbstate_tmp;
|
||||
break;
|
||||
} else {
|
||||
// The buffer was used, so we need copy the translation to dst.
|
||||
wmemcpy(dst, buff, result);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't do anything to change errno from here on.
|
||||
if (result == invalid_sequence || result == terminated_sequence || result == incomplete_sequence) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dst) {
|
||||
if (result == terminated_sequence)
|
||||
*src = nullptr;
|
||||
else
|
||||
*src += source_converted;
|
||||
}
|
||||
if (result == invalid_sequence)
|
||||
return invalid_sequence;
|
||||
|
||||
return dest_converted;
|
||||
}
|
||||
94
lib/libcxx/src/support/ibm/wcsnrtombs.cpp
vendored
94
lib/libcxx/src/support/ibm/wcsnrtombs.cpp
vendored
|
|
@ -1,94 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <cwchar> // mbstate_t
|
||||
#include <limits.h> // MB_LEN_MAX
|
||||
#include <stdlib.h> // MB_CUR_MAX, size_t
|
||||
#include <string.h> // memcpy
|
||||
|
||||
// Converts `max_source_chars` from the wide character buffer pointer to by *`src`,
|
||||
// into the multi byte character sequence buffer stored at `dst`, which must be
|
||||
// `dst_size_bytes` bytes in size. Returns the number of bytes in the sequence
|
||||
// converted from *src, excluding the null terminator.
|
||||
// Returns (size_t) -1 if an error occurs and sets errno.
|
||||
// If `dst` is NULL, `dst_size_bytes` is ignored and no bytes are copied to `dst`.
|
||||
_LIBCPP_EXPORTED_FROM_ABI size_t wcsnrtombs(
|
||||
char* __restrict dst,
|
||||
const wchar_t** __restrict src,
|
||||
size_t max_source_chars,
|
||||
size_t dst_size_bytes,
|
||||
mbstate_t* __restrict ps) {
|
||||
const size_t invalid_wchar = static_cast<size_t>(-1);
|
||||
|
||||
size_t source_converted;
|
||||
size_t dest_converted;
|
||||
size_t result = 0;
|
||||
|
||||
// If `dst` is null then `dst_size_bytes` should be ignored according to the
|
||||
// standard. Setting dst_size_bytes to a large value has this effect.
|
||||
if (dst == nullptr)
|
||||
dst_size_bytes = static_cast<size_t>(-1);
|
||||
|
||||
for (dest_converted = source_converted = 0;
|
||||
source_converted < max_source_chars && (!dst || dest_converted < dst_size_bytes);
|
||||
++source_converted, dest_converted += result) {
|
||||
wchar_t c = (*src)[source_converted];
|
||||
size_t dest_remaining = dst_size_bytes - dest_converted;
|
||||
|
||||
if (dst == nullptr) {
|
||||
result = wcrtomb(nullptr, c, ps);
|
||||
} else if (dest_remaining >= static_cast<size_t>(MB_CUR_MAX)) {
|
||||
// dst has enough space to translate in-place.
|
||||
result = wcrtomb(dst + dest_converted, c, ps);
|
||||
} else {
|
||||
/*
|
||||
* dst may not have enough space, so use a temporary buffer.
|
||||
*
|
||||
* We need to save a copy of the conversion state
|
||||
* here so we can restore it if the multibyte
|
||||
* character is too long for the buffer.
|
||||
*/
|
||||
char buff[MB_LEN_MAX];
|
||||
mbstate_t mbstate_tmp;
|
||||
|
||||
if (ps != nullptr)
|
||||
mbstate_tmp = *ps;
|
||||
result = wcrtomb(buff, c, ps);
|
||||
|
||||
if (result > dest_remaining) {
|
||||
// Multi-byte sequence for character won't fit.
|
||||
if (ps != nullptr)
|
||||
*ps = mbstate_tmp;
|
||||
if (result != invalid_wchar)
|
||||
break;
|
||||
} else {
|
||||
// The buffer was used, so we need copy the translation to dst.
|
||||
memcpy(dst, buff, result);
|
||||
}
|
||||
}
|
||||
|
||||
// result (char_size) contains the size of the multi-byte-sequence converted.
|
||||
// Otherwise, result (char_size) is (size_t) -1 and wcrtomb() sets the errno.
|
||||
if (result == invalid_wchar) {
|
||||
if (dst)
|
||||
*src = *src + source_converted;
|
||||
return invalid_wchar;
|
||||
}
|
||||
|
||||
if (c == L'\0') {
|
||||
if (dst)
|
||||
*src = nullptr;
|
||||
return dest_converted;
|
||||
}
|
||||
}
|
||||
|
||||
if (dst)
|
||||
*src = *src + source_converted;
|
||||
|
||||
return dest_converted;
|
||||
}
|
||||
130
lib/libcxx/src/support/ibm/xlocale_zos.cpp
vendored
130
lib/libcxx/src/support/ibm/xlocale_zos.cpp
vendored
|
|
@ -1,130 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <__assert>
|
||||
#include <__support/ibm/xlocale.h>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
locale_t newlocale(int category_mask, const char* locale, locale_t base) {
|
||||
// Maintain current locale name(s) to restore later.
|
||||
std::string current_loc_name(setlocale(LC_ALL, 0));
|
||||
|
||||
// Check for errors.
|
||||
if (category_mask == LC_ALL_MASK && setlocale(LC_ALL, locale) == nullptr) {
|
||||
errno = EINVAL;
|
||||
return (locale_t)0;
|
||||
} else {
|
||||
for (int _Cat = 0; _Cat <= _LC_MAX; ++_Cat) {
|
||||
if ((_CATMASK(_Cat) & category_mask) != 0 && setlocale(_Cat, locale) == nullptr) {
|
||||
setlocale(LC_ALL, current_loc_name.c_str());
|
||||
errno = EINVAL;
|
||||
return (locale_t)0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create new locale.
|
||||
locale_t newloc = new locale_struct();
|
||||
|
||||
if (base) {
|
||||
if (category_mask != LC_ALL_MASK) {
|
||||
// Copy base when it will not be overwritten.
|
||||
memcpy(newloc, base, sizeof(locale_struct));
|
||||
newloc->category_mask = category_mask | base->category_mask;
|
||||
}
|
||||
delete base;
|
||||
} else {
|
||||
newloc->category_mask = category_mask;
|
||||
}
|
||||
|
||||
if (category_mask & LC_COLLATE_MASK)
|
||||
newloc->lc_collate = locale;
|
||||
if (category_mask & LC_CTYPE_MASK)
|
||||
newloc->lc_ctype = locale;
|
||||
if (category_mask & LC_MONETARY_MASK)
|
||||
newloc->lc_monetary = locale;
|
||||
if (category_mask & LC_NUMERIC_MASK)
|
||||
newloc->lc_numeric = locale;
|
||||
if (category_mask & LC_TIME_MASK)
|
||||
newloc->lc_time = locale;
|
||||
if (category_mask & LC_MESSAGES_MASK)
|
||||
newloc->lc_messages = locale;
|
||||
|
||||
// Restore current locale.
|
||||
setlocale(LC_ALL, current_loc_name.c_str());
|
||||
return (locale_t)newloc;
|
||||
}
|
||||
|
||||
void freelocale(locale_t locobj) { delete locobj; }
|
||||
|
||||
locale_t uselocale(locale_t newloc) {
|
||||
// Maintain current locale name(s).
|
||||
std::string current_loc_name(setlocale(LC_ALL, 0));
|
||||
|
||||
if (newloc) {
|
||||
// Set locales and check for errors.
|
||||
bool is_error =
|
||||
(newloc->category_mask & LC_COLLATE_MASK && setlocale(LC_COLLATE, newloc->lc_collate.c_str()) == nullptr) ||
|
||||
(newloc->category_mask & LC_CTYPE_MASK && setlocale(LC_CTYPE, newloc->lc_ctype.c_str()) == nullptr) ||
|
||||
(newloc->category_mask & LC_MONETARY_MASK && setlocale(LC_MONETARY, newloc->lc_monetary.c_str()) == nullptr) ||
|
||||
(newloc->category_mask & LC_NUMERIC_MASK && setlocale(LC_NUMERIC, newloc->lc_numeric.c_str()) == nullptr) ||
|
||||
(newloc->category_mask & LC_TIME_MASK && setlocale(LC_TIME, newloc->lc_time.c_str()) == nullptr) ||
|
||||
(newloc->category_mask & LC_MESSAGES_MASK && setlocale(LC_MESSAGES, newloc->lc_messages.c_str()) == nullptr);
|
||||
|
||||
if (is_error) {
|
||||
setlocale(LC_ALL, current_loc_name.c_str());
|
||||
errno = EINVAL;
|
||||
return (locale_t)0;
|
||||
}
|
||||
}
|
||||
|
||||
// Construct and return previous locale.
|
||||
locale_t previous_loc = new locale_struct();
|
||||
|
||||
// current_loc_name might be a comma-separated locale name list.
|
||||
if (current_loc_name.find(',') != std::string::npos) {
|
||||
// Tokenize locale name list.
|
||||
const char delimiter = ',';
|
||||
std::vector<std::string> tokenized;
|
||||
std::stringstream ss(current_loc_name);
|
||||
std::string s;
|
||||
|
||||
while (std::getline(ss, s, delimiter)) {
|
||||
tokenized.push_back(s);
|
||||
}
|
||||
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(tokenized.size() >= _NCAT, "locale-name list is too short");
|
||||
|
||||
previous_loc->lc_collate = tokenized[LC_COLLATE];
|
||||
previous_loc->lc_ctype = tokenized[LC_CTYPE];
|
||||
previous_loc->lc_monetary = tokenized[LC_MONETARY];
|
||||
previous_loc->lc_numeric = tokenized[LC_NUMERIC];
|
||||
previous_loc->lc_time = tokenized[LC_TIME];
|
||||
// Skip LC_TOD.
|
||||
previous_loc->lc_messages = tokenized[LC_MESSAGES];
|
||||
} else {
|
||||
previous_loc->lc_collate = current_loc_name;
|
||||
previous_loc->lc_ctype = current_loc_name;
|
||||
previous_loc->lc_monetary = current_loc_name;
|
||||
previous_loc->lc_numeric = current_loc_name;
|
||||
previous_loc->lc_time = current_loc_name;
|
||||
previous_loc->lc_messages = current_loc_name;
|
||||
}
|
||||
|
||||
previous_loc->category_mask = LC_ALL_MASK;
|
||||
return previous_loc;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
745
lib/libcxxabi/src/aix_state_tab_eh.inc
vendored
745
lib/libcxxabi/src/aix_state_tab_eh.inc
vendored
|
|
@ -1,745 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//
|
||||
// This file implements the personality and helper functions for the state
|
||||
// table based EH used by IBM legacy compilers xlC and xlclang++ on AIX.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <new>
|
||||
#include <stdio.h>
|
||||
#include <sys/debug.h>
|
||||
|
||||
/*
|
||||
The legacy IBM xlC and xlclang++ compilers use the state table for EH
|
||||
instead of the range table. Destructors, or addresses of the possible catch
|
||||
sites or cleanup code are specified in the state table which is a finite
|
||||
state machine (FSM). Each function that has a state table also has an
|
||||
autolocal state variable. The state variable represents the current state
|
||||
of the function for EH and is found through the traceback table of the
|
||||
function during unwinding, which is located at the end of each function.
|
||||
The FSM is an array of state entries. Each state entry has the following
|
||||
fields:
|
||||
|
||||
* offset/address/pointer - the offset used to locate the object, or the
|
||||
address of a global object, or the address of the next state if it is an
|
||||
old conditional state change entry;
|
||||
* dtor/landing pad - address of the destructor function to invoke,
|
||||
or address of the catch block or cleanup code in the user code to branch to;
|
||||
* element count/action flag - the number of elements or the flag for actions;
|
||||
* element size - if the object is an array this is the size of one element
|
||||
of the array;
|
||||
* flags - flags used to control how fields in the entry are interpreted;
|
||||
* next state - the state to execute next after the action for this state is
|
||||
performed. The value of zero indicates the end of the state for this
|
||||
function.
|
||||
|
||||
The following is the description of 'element count/action flag' field.
|
||||
+-----------------------------------------------------------------------------+
|
||||
| value | description | action |
|
||||
+-------+------------------------+--------------------------------------------+
|
||||
| > 1 | object is an array | calls __cxa_vec_cleanup to run dtor for |
|
||||
| | | each member of the array |
|
||||
+-------+------------------------+--------------------------------------------+
|
||||
| 1, 0 | object is a scalar | calls dtor for the object |
|
||||
+-------+------------------------+--------------------------------------------+
|
||||
| -1 | begin catch | branches to the handler which performes |
|
||||
| | | catch-match. If there is no catch that |
|
||||
| | | matches the exception it will be rethrown |
|
||||
+-------+------------------------+--------------------------------------------+
|
||||
| -2 | end catch | ends current catch block and continues |
|
||||
| | | attempting to catch the exception |
|
||||
+-------+------------------------+--------------------------------------------+
|
||||
| -3 | delete the object | calls the delete function of the object |
|
||||
+-------+------------------------+--------------------------------------------+
|
||||
| -4 | cleanup label | branches to the user code for cleaning up |
|
||||
+-------+------------------------+--------------------------------------------+
|
||||
*/
|
||||
|
||||
namespace __cxxabiv1 {
|
||||
|
||||
extern "C" {
|
||||
|
||||
// Macros for debugging the state table parsing.
|
||||
#ifdef NDEBUG
|
||||
# define _LIBCXXABI_TRACE_STATETAB(msg, ...)
|
||||
# define _LIBCXXABI_TRACE_STATETAB0(msg)
|
||||
# define _LIBCXXABI_TRACE_STATETAB1(msg)
|
||||
# define _LIBCXXABI_TRACING_STATETAB 0
|
||||
#else
|
||||
static bool state_tab_dbg() {
|
||||
static bool checked = false;
|
||||
static bool log = false;
|
||||
if (!checked) {
|
||||
log = (getenv("LIBCXXABI_PRINT_STATTAB") != NULL);
|
||||
checked = true;
|
||||
}
|
||||
return log;
|
||||
}
|
||||
|
||||
# define _LIBCXXABI_TRACE_STATETAB(msg, ...) \
|
||||
do { \
|
||||
if (state_tab_dbg()) \
|
||||
fprintf(stderr, "libcxxabi: " msg, __VA_ARGS__); \
|
||||
} while (0)
|
||||
# define _LIBCXXABI_TRACE_STATETAB0(msg) \
|
||||
do { \
|
||||
if (state_tab_dbg()) \
|
||||
fprintf(stderr, "libcxxabi: " msg); \
|
||||
} while (0)
|
||||
# define _LIBCXXABI_TRACE_STATETAB1(msg) \
|
||||
do { \
|
||||
if (state_tab_dbg()) \
|
||||
fprintf(stderr, msg); \
|
||||
} while (0)
|
||||
|
||||
# define _LIBCXXABI_TRACING_STATETAB state_tab_dbg()
|
||||
#endif // NDEBUG
|
||||
|
||||
namespace __state_table_eh {
|
||||
|
||||
// Definition of flags for the state table entry field 'action flag'.
|
||||
enum FSMEntryCount : intptr_t { beginCatch = -1, endCatch = -2, deleteObject = -3, cleanupLabel = -4, terminate = -5 };
|
||||
|
||||
// Definition of flags for the state table entry field 'flags'.
|
||||
enum FSMEntryFlag : int16_t {
|
||||
indirect = 0x100, // Object was thrown from a function where
|
||||
// the return value optimization was used.
|
||||
oldConditionalStateChange = 0x400, // State table entry is an indirect state
|
||||
// change, dereference the address in
|
||||
// offset as int for the target state.
|
||||
// This is deprecated. This indicates
|
||||
// the address is direct. (static local).
|
||||
conditionalStateChange = 0x800, // State table entry is an indirect state
|
||||
// change, dereference the address in
|
||||
// offset as int for the target state.
|
||||
// The temporary is an automatic. State
|
||||
// change is used in cases such as
|
||||
// (b?(T1(),foo()):(T2(),foo())),throw 42;
|
||||
// which causes a conditional state change
|
||||
// so that we know if T1 or T2 need to be
|
||||
// destroyed.
|
||||
thisFlag = 0x01, // The address of the object for the
|
||||
// cleanup action is based on the
|
||||
// StateVariable::thisValue.
|
||||
vBaseFlag = 0x02, // The object is of a virtual base class.
|
||||
globalObj = 0x04 // FSMEntry::address is the address of
|
||||
// a global object.
|
||||
};
|
||||
|
||||
namespace {
|
||||
// The finite state machine to be walked.
|
||||
struct FSMEntry {
|
||||
union {
|
||||
// Offset of the object within its stack frame or containing object.
|
||||
intptr_t offset;
|
||||
// Address of a global object.
|
||||
intptr_t address;
|
||||
// Address of the next state if it is an old conditional state change entry.
|
||||
intptr_t nextStatePtr;
|
||||
};
|
||||
union {
|
||||
// Address of the destructor function with 1 argument.
|
||||
void (*destructor)(void*);
|
||||
// Address of the destructor function with 2 arguments.
|
||||
void (*xlCDestructor)(void*, size_t);
|
||||
// The address of the catch block or cleanup code.
|
||||
void* landingPad;
|
||||
};
|
||||
union {
|
||||
// The flag for actions (when the value is negative).
|
||||
FSMEntryCount actionFlag;
|
||||
// The element count (when the value is positive or zero).
|
||||
size_t elementCount;
|
||||
};
|
||||
size_t elemSize;
|
||||
FSMEntryFlag flags;
|
||||
uint16_t nextState;
|
||||
};
|
||||
|
||||
struct FSM {
|
||||
uint32_t magic; // Magic number of the state table.
|
||||
int32_t numberOfStates;
|
||||
FSMEntry table[1]; // Actually table[numberOfStates].
|
||||
};
|
||||
|
||||
// The state variable on the stack.
|
||||
struct StateVariable {
|
||||
int32_t state;
|
||||
struct FSM* table;
|
||||
intptr_t thisValue;
|
||||
int32_t ignoreVBasePtrs;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
// State table magic number
|
||||
enum FSMMagic : uint32_t {
|
||||
number = 0xbeefdead, // State table generated by xlC compiler.
|
||||
number2 = 0xbeeedead, // State table generated by early version xlC compiler.
|
||||
number3 = 0x1cedbeef // State table generated by xlclang++ compiler.
|
||||
};
|
||||
|
||||
constexpr size_t dtorArgument = 0x02; // Flag to destructor indicating to free
|
||||
// virtual bases, don't delete object.
|
||||
|
||||
static void invoke_destructor(FSMEntry* fsmEntry, void* addr) {
|
||||
_LIBCXXABI_TRACE_STATETAB("Destruct object=%p, fsmEntry=%p\n", addr, reinterpret_cast<void*>(fsmEntry));
|
||||
try {
|
||||
if (fsmEntry->elementCount == 1) {
|
||||
_LIBCXXABI_TRACE_STATETAB0("calling scalar destructor\n");
|
||||
(*fsmEntry->xlCDestructor)(addr, dtorArgument);
|
||||
_LIBCXXABI_TRACE_STATETAB0("returned from scalar destructor\n");
|
||||
} else {
|
||||
_LIBCXXABI_TRACE_STATETAB0("calling vector destructor\n");
|
||||
__cxa_vec_cleanup(addr, reinterpret_cast<size_t>(fsmEntry->elementCount), fsmEntry->elemSize,
|
||||
fsmEntry->destructor);
|
||||
_LIBCXXABI_TRACE_STATETAB0("returned from vector destructor\n");
|
||||
}
|
||||
} catch (...) {
|
||||
_LIBCXXABI_TRACE_STATETAB0("Uncaught exception in destructor, terminating\n");
|
||||
std::terminate();
|
||||
}
|
||||
}
|
||||
|
||||
static void invoke_delete(FSMEntry* fsmEntry, void* addr) {
|
||||
char* objectAddress = *reinterpret_cast<char**>(addr);
|
||||
|
||||
_LIBCXXABI_TRACE_STATETAB("Delete object=%p, fsmEntry=%p\n", reinterpret_cast<void*>(objectAddress),
|
||||
reinterpret_cast<void*>(fsmEntry));
|
||||
try {
|
||||
_LIBCXXABI_TRACE_STATETAB0("..calling delete()\n");
|
||||
// 'destructor' holds a function pointer to delete().
|
||||
(*fsmEntry->xlCDestructor)(objectAddress, fsmEntry->elemSize);
|
||||
_LIBCXXABI_TRACE_STATETAB0("..returned from delete()\n");
|
||||
} catch (...) {
|
||||
_LIBCXXABI_TRACE_STATETAB0("Uncaught exception in delete(), terminating\n");
|
||||
std::terminate();
|
||||
}
|
||||
}
|
||||
|
||||
// Get the frame address of the current function from its traceback table
|
||||
// which is at the end of each function.
|
||||
static uintptr_t get_frame_addr(_Unwind_Context* context) {
|
||||
int framePointerReg = 1; // default frame pointer == SP.
|
||||
uint32_t* p = reinterpret_cast<uint32_t*>(_Unwind_GetIP(context));
|
||||
|
||||
// Keep looking forward until a word of 0 is found. The traceback
|
||||
// table starts at the following word.
|
||||
while (*p)
|
||||
++p;
|
||||
tbtable* TBTable = reinterpret_cast<tbtable*>(p + 1);
|
||||
|
||||
p = reinterpret_cast<uint32_t*>(&TBTable->tb_ext);
|
||||
|
||||
// Skip field parminfo if it exists.
|
||||
if (TBTable->tb.fixedparms || TBTable->tb.floatparms)
|
||||
++p;
|
||||
|
||||
// Skip field tb_offset if it exists.
|
||||
if (TBTable->tb.has_tboff)
|
||||
++p;
|
||||
|
||||
// Skip field hand_mask if it exists.
|
||||
if (TBTable->tb.int_hndl)
|
||||
++p;
|
||||
|
||||
// Skip fields ctl_info and ctl_info_disp if they exist.
|
||||
if (TBTable->tb.has_ctl)
|
||||
p += 1 + *p;
|
||||
|
||||
// Skip fields name_len and name if exist.
|
||||
if (TBTable->tb.name_present) {
|
||||
const uint16_t name_len = *reinterpret_cast<uint16_t*>(p);
|
||||
p = reinterpret_cast<uint32_t*>(reinterpret_cast<char*>(p) + name_len + sizeof(uint16_t));
|
||||
}
|
||||
|
||||
if (TBTable->tb.uses_alloca)
|
||||
framePointerReg = *reinterpret_cast<char*>(p);
|
||||
|
||||
return _Unwind_GetGR(context, framePointerReg);
|
||||
}
|
||||
|
||||
// Calculate the object address from the FSM entry.
|
||||
static void* compute_addr_from_table(FSMEntry* fsmEntry, StateVariable* const state, _Unwind_Context* context) {
|
||||
void* addr;
|
||||
if (fsmEntry->flags & FSMEntryFlag::globalObj) {
|
||||
addr = reinterpret_cast<void*>(fsmEntry->address);
|
||||
_LIBCXXABI_TRACE_STATETAB("Address calculation (global obj) addr=fsmEntry->address=%p\n", addr);
|
||||
} else if (fsmEntry->flags & FSMEntryFlag::thisFlag) {
|
||||
addr = reinterpret_cast<void*>(state->thisValue + fsmEntry->offset);
|
||||
_LIBCXXABI_TRACE_STATETAB("Address calculation (this obj) fsmEntry->offset=%ld : "
|
||||
"state->thisValue=%ld addr=(fsmEntry->offset+state->thisValue)=%p\n",
|
||||
fsmEntry->offset, state->thisValue, addr);
|
||||
} else if (fsmEntry->flags & FSMEntryFlag::indirect) {
|
||||
addr = reinterpret_cast<void*>(
|
||||
*reinterpret_cast<char**>(get_frame_addr(context) + static_cast<uintptr_t>(fsmEntry->offset)));
|
||||
_LIBCXXABI_TRACE_STATETAB("Address calculation (indirect obj) addr=%p, fsmEntry->offset=%ld \n",
|
||||
addr, fsmEntry->offset);
|
||||
} else {
|
||||
addr = reinterpret_cast<void*>(get_frame_addr(context) + static_cast<uintptr_t>(fsmEntry->offset));
|
||||
_LIBCXXABI_TRACE_STATETAB("Address calculation. (local obj) addr=fsmEntry->offset=%p\n",
|
||||
addr);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
static void scan_state_tab(scan_results& results, _Unwind_Action actions, bool native_exception,
|
||||
_Unwind_Exception* unwind_exception, _Unwind_Context* context) {
|
||||
// Initialize results to found nothing but an error.
|
||||
results.ttypeIndex = 0;
|
||||
results.actionRecord = 0;
|
||||
results.languageSpecificData = 0;
|
||||
results.landingPad = 0;
|
||||
results.adjustedPtr = 0;
|
||||
results.reason = _URC_FATAL_PHASE1_ERROR;
|
||||
|
||||
// Check for consistent actions.
|
||||
if (actions & _UA_SEARCH_PHASE) {
|
||||
// Do Phase 1
|
||||
if (actions & (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME | _UA_FORCE_UNWIND)) {
|
||||
// None of these flags should be set during Phase 1.
|
||||
// Client error
|
||||
results.reason = _URC_FATAL_PHASE1_ERROR;
|
||||
return;
|
||||
}
|
||||
} else if (actions & _UA_CLEANUP_PHASE) {
|
||||
if ((actions & _UA_HANDLER_FRAME) && (actions & _UA_FORCE_UNWIND)) {
|
||||
// _UA_HANDLER_FRAME should only be set if phase 1 found a handler.
|
||||
// If _UA_FORCE_UNWIND is set, phase 1 shouldn't have happened.
|
||||
// Client error
|
||||
results.reason = _URC_FATAL_PHASE2_ERROR;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Neither _UA_SEARCH_PHASE nor _UA_CLEANUP_PHASE is set.
|
||||
// Client error
|
||||
results.reason = _URC_FATAL_PHASE1_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_LIBCXXABI_TRACING_STATETAB) {
|
||||
_LIBCXXABI_TRACE_STATETAB1("\n");
|
||||
_LIBCXXABI_TRACE_STATETAB("%s: actions=%d (", __func__, actions);
|
||||
|
||||
if (_UA_SEARCH_PHASE & actions)
|
||||
_LIBCXXABI_TRACE_STATETAB1("_UA_SEARCH_PHASE ");
|
||||
if (_UA_CLEANUP_PHASE & actions)
|
||||
_LIBCXXABI_TRACE_STATETAB1("_UA_CLEANUP_PHASE ");
|
||||
if (_UA_HANDLER_FRAME & actions)
|
||||
_LIBCXXABI_TRACE_STATETAB1("_UA_HANDLER_FRAME ");
|
||||
if (_UA_FORCE_UNWIND & actions)
|
||||
_LIBCXXABI_TRACE_STATETAB1("_UA_FORCE_UNWIND ");
|
||||
_LIBCXXABI_TRACE_STATETAB1(")\n");
|
||||
_LIBCXXABI_TRACE_STATETAB(" unwind_exception=%p context=%p\n", reinterpret_cast<void*>(unwind_exception),
|
||||
reinterpret_cast<void*>(context));
|
||||
}
|
||||
|
||||
// Start scan by getting state table address.
|
||||
StateVariable* const state = reinterpret_cast<StateVariable* const>(_Unwind_GetLanguageSpecificData(context));
|
||||
if (state->state <= 0) {
|
||||
// The state is not correct - give up on this routine.
|
||||
_LIBCXXABI_TRACE_STATETAB("state=%d and is <= 0), continue unwinding\n", state->state);
|
||||
results.reason = _URC_CONTINUE_UNWIND;
|
||||
return;
|
||||
}
|
||||
// Parse the state table.
|
||||
FSM* const fsm = state->table;
|
||||
FSMEntry* currFSMEntry;
|
||||
|
||||
if (fsm->magic != FSMMagic::number && fsm->magic != FSMMagic::number2 && fsm->magic != FSMMagic::number3) {
|
||||
// Something is wrong with the state table we found.
|
||||
if (_UA_SEARCH_PHASE & actions) {
|
||||
_LIBCXXABI_TRACE_STATETAB0("Invalid FSM table, return _URC_FATAL_PHASE1_ERROR\n");
|
||||
results.reason = _URC_FATAL_PHASE1_ERROR;
|
||||
} else if (_UA_CLEANUP_PHASE & actions) {
|
||||
_LIBCXXABI_TRACE_STATETAB0("Invalid FSM table, return _URC_FATAL_PHASE2_ERROR\n");
|
||||
results.reason = _URC_FATAL_PHASE2_ERROR;
|
||||
} else {
|
||||
// We should never get here.
|
||||
_LIBCXXABI_TRACE_STATETAB0("Invalid FSM table + RT Internal error, return _URC_FATAL_PHASE2_ERROR\n");
|
||||
results.reason = _URC_FATAL_PHASE2_ERROR;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (_LIBCXXABI_TRACING_STATETAB) {
|
||||
// Print the state table for debugging purposes.
|
||||
_LIBCXXABI_TRACE_STATETAB("state->state=%d, state->ignoreVBasePtrs=%d\n", state->state, state->ignoreVBasePtrs);
|
||||
_LIBCXXABI_TRACE_STATETAB("fsm->magic=%#x, fsm->numberOfStates=%d\n", fsm->magic, fsm->numberOfStates);
|
||||
// Print out the FSM table.
|
||||
_LIBCXXABI_TRACE_STATETAB0("FSM table:\n");
|
||||
_LIBCXXABI_TRACE_STATETAB("%12s %10s %8s %10s %7s %7s %7s %7s\n", "Entry Addr", "state", "Offset", "DTR/lpad",
|
||||
"count", "el_size", "flags", "next");
|
||||
for (int i = 0; i < fsm->numberOfStates; i++) {
|
||||
currFSMEntry = &fsm->table[i];
|
||||
_LIBCXXABI_TRACE_STATETAB("%12p (%8d) %8ld %10p %7ld "
|
||||
"%7ld %#7x %7d\n",
|
||||
reinterpret_cast<void*>(&currFSMEntry), i + 1, currFSMEntry->offset,
|
||||
reinterpret_cast<void*>(currFSMEntry->destructor),
|
||||
currFSMEntry->elementCount, currFSMEntry->elemSize, currFSMEntry->flags,
|
||||
currFSMEntry->nextState);
|
||||
}
|
||||
}
|
||||
|
||||
if (_UA_SEARCH_PHASE & actions) {
|
||||
// Start walking the state table. Use a local copy of state->state so when
|
||||
// we return from search phase we don't change the state number.
|
||||
int currState = state->state;
|
||||
|
||||
while (currState > 0) {
|
||||
currFSMEntry = &fsm->table[currState - 1];
|
||||
_LIBCXXABI_TRACE_STATETAB("Processing state=%d, flags=0x%hx\n", currState, currFSMEntry->flags);
|
||||
|
||||
if (currFSMEntry->actionFlag == FSMEntryCount::beginCatch) {
|
||||
// Found a catch handler.
|
||||
if (fsm->magic == FSMMagic::number) {
|
||||
_LIBCXXABI_TRACE_STATETAB0("Found a xlC catch handler, return _URC_FATAL_PHASE1_ERROR\n");
|
||||
// xlC catch handlers cannot be entered because they use a
|
||||
// proprietary EH runtime that is not interoperable.
|
||||
results.reason = _URC_FATAL_PHASE1_ERROR;
|
||||
return;
|
||||
}
|
||||
// xlclang++ compiled frames use CXA-abi EH calls and any catch
|
||||
// block will include a catch(...) block so it is safe to assume that
|
||||
// the handler is found without checking the catch match. The
|
||||
// catch(...) block will rethrow the exception if there isn't a
|
||||
// match.
|
||||
_LIBCXXABI_TRACE_STATETAB0("Found a catch handler, return _URC_HANDLER_FOUND\n");
|
||||
results.reason = _URC_HANDLER_FOUND;
|
||||
return;
|
||||
}
|
||||
if (currFSMEntry->actionFlag == FSMEntryCount::terminate) {
|
||||
_LIBCXXABI_TRACE_STATETAB0("Found the terminate state, return _URC_HANDLER_FOUND\n");
|
||||
results.reason = _URC_HANDLER_FOUND;
|
||||
return;
|
||||
}
|
||||
if (currFSMEntry->flags & FSMEntryFlag::oldConditionalStateChange) {
|
||||
// Deprecated conditional expression.
|
||||
currState = *reinterpret_cast<int*>(currFSMEntry->nextStatePtr);
|
||||
_LIBCXXABI_TRACE_STATETAB("Flag: FSMEntryFlag::oldConditionalStateChange, dereference "
|
||||
"currFSMEntry->nextStatePtr(%ld), set state=%d\n",
|
||||
currFSMEntry->nextStatePtr, currState);
|
||||
continue; // We are done this iteration of the loop, since
|
||||
// we changed a state.
|
||||
}
|
||||
if (currFSMEntry->flags & FSMEntryFlag::conditionalStateChange) {
|
||||
void* addr = compute_addr_from_table(currFSMEntry, state, context);
|
||||
currState = *reinterpret_cast<int*>(addr);
|
||||
_LIBCXXABI_TRACE_STATETAB("Flag: FSMEntryFlag::conditionalStateChange, dereference "
|
||||
"addr(%p), set state=%d\n", addr, currState);
|
||||
continue; // We are done this iteration of the loop, since we
|
||||
// changed the state.
|
||||
}
|
||||
// Go to the next state.
|
||||
currState = currFSMEntry->nextState;
|
||||
}
|
||||
_LIBCXXABI_TRACE_STATETAB0("No catch handler found, return _URC_CONTINUE_UNWIND\n");
|
||||
results.reason = _URC_CONTINUE_UNWIND;
|
||||
return;
|
||||
}
|
||||
if (_UA_CLEANUP_PHASE & actions) {
|
||||
// Start walking the state table.
|
||||
while (state->state > 0) {
|
||||
currFSMEntry = &fsm->table[state->state - 1];
|
||||
|
||||
if (currFSMEntry->actionFlag == FSMEntryCount::terminate) {
|
||||
_LIBCXXABI_TRACE_STATETAB0("Reached terminate state. Call terminate.\n");
|
||||
std::terminate();
|
||||
}
|
||||
// Perform action according to the currFSMEntry->actionFlag,
|
||||
// except when flag is FSMEntryFlag::conditionalStateChange or
|
||||
// FSMEntryFlag::oldConditionalStateChange.
|
||||
_LIBCXXABI_TRACE_STATETAB("Processing state=%d, flags=0x%hx\n", state->state, currFSMEntry->flags);
|
||||
if (currFSMEntry->flags & FSMEntryFlag::oldConditionalStateChange) {
|
||||
state->state = *reinterpret_cast<int*>(currFSMEntry->nextStatePtr);
|
||||
_LIBCXXABI_TRACE_STATETAB("Flag: FSMEntryFlag::oldConditionalStateChange, dereference "
|
||||
"currFSMEntry->nextStatePtr(%ld), set state=%d\n",
|
||||
currFSMEntry->nextStatePtr, state->state);
|
||||
continue; // We are done with this iteration of the loop, since we changed a state.
|
||||
}
|
||||
if (currFSMEntry->flags & FSMEntryFlag::conditionalStateChange) {
|
||||
// A conditional state table entry holds the address of a local
|
||||
// that holds the next state.
|
||||
void* addr = compute_addr_from_table(currFSMEntry, state, context);
|
||||
state->state = *reinterpret_cast<int*>(addr);
|
||||
_LIBCXXABI_TRACE_STATETAB("Flag: FSMEntryFlag::conditionalStateChange, dereference "
|
||||
"addr(%p), set state=%d\n", addr, state->state);
|
||||
continue; // We are done with this iteration of the loop, since we changed a state.
|
||||
}
|
||||
if (currFSMEntry->actionFlag == FSMEntryCount::beginCatch || currFSMEntry->actionFlag == FSMEntryCount::endCatch ||
|
||||
currFSMEntry->actionFlag == FSMEntryCount::cleanupLabel) {
|
||||
|
||||
_LIBCXXABI_TRACE_STATETAB(
|
||||
"FSMEntryCount::%s: handler %p/%p, return _URC_HANDLER_FOUND\n",
|
||||
(currFSMEntry->actionFlag == FSMEntryCount::beginCatch
|
||||
? "beginCatch"
|
||||
: (currFSMEntry->actionFlag == FSMEntryCount::endCatch ? "endCatch" : "cleanupLabel")),
|
||||
currFSMEntry->landingPad, *reinterpret_cast<void**>(currFSMEntry->landingPad));
|
||||
|
||||
state->state = currFSMEntry->nextState;
|
||||
results.landingPad = reinterpret_cast<uintptr_t>(*reinterpret_cast<void**>(currFSMEntry->landingPad));
|
||||
results.reason = _URC_HANDLER_FOUND;
|
||||
return;
|
||||
}
|
||||
if (currFSMEntry->elementCount > 0) {
|
||||
if (currFSMEntry->flags & FSMEntryFlag::vBaseFlag && state->ignoreVBasePtrs) {
|
||||
_LIBCXXABI_TRACE_STATETAB0("Ignoring virtual base dtor.\n");
|
||||
} else {
|
||||
// We need to invoke the virtual base destructor. This must be
|
||||
// a frame from the legacy xlC compiler as the xlclang++ compiler
|
||||
// generates inline cleanup code rather than specifying
|
||||
// the destructor via the state table.
|
||||
void* addr = compute_addr_from_table(currFSMEntry, state, context);
|
||||
|
||||
// An extra indirect to get to the object according to the object
|
||||
// model used by the xlC compiler.
|
||||
addr = reinterpret_cast<void*>(*reinterpret_cast<char**>(addr));
|
||||
_LIBCXXABI_TRACE_STATETAB("Invoke dtor for object=%p\n", addr);
|
||||
invoke_destructor(currFSMEntry, addr);
|
||||
}
|
||||
} else if (currFSMEntry->actionFlag == FSMEntryCount::deleteObject) {
|
||||
void* addr = compute_addr_from_table(currFSMEntry, state, context);
|
||||
if (currFSMEntry->flags & FSMEntryFlag::vBaseFlag) {
|
||||
// We need to invoke the virtual base delete function. This must be
|
||||
// a frame from the legacy xlC compiler as the xlclang++ compiler
|
||||
// generates inline cleanup code rather than specifying
|
||||
// the delete function via the state table.
|
||||
|
||||
// An extra indirect to get to the object according to the object
|
||||
// model used by the xlC compiler.
|
||||
addr = reinterpret_cast<void*>(*reinterpret_cast<char**>(addr));
|
||||
}
|
||||
_LIBCXXABI_TRACE_STATETAB("Delete object at %p\n", addr);
|
||||
invoke_delete(currFSMEntry, addr);
|
||||
} else {
|
||||
_LIBCXXABI_TRACE_STATETAB("Unknown entry in FSM (count=%ld), ignored\n",
|
||||
currFSMEntry->elementCount);
|
||||
} // End of action switching.
|
||||
|
||||
// Go to next state.
|
||||
state->state = currFSMEntry->nextState;
|
||||
}
|
||||
_LIBCXXABI_TRACE_STATETAB0("No catch handler, return _URC_CONTINUE_UNWIND\n");
|
||||
results.reason = _URC_CONTINUE_UNWIND;
|
||||
return;
|
||||
}
|
||||
_LIBCXXABI_TRACE_STATETAB0("No state table entry for this exception, call_terminate()\n");
|
||||
// It is possible that no state table entry specify how to handle
|
||||
// this exception. By spec, terminate it immediately.
|
||||
call_terminate(native_exception, unwind_exception);
|
||||
}
|
||||
|
||||
// Personality routine for EH using the state table.
|
||||
_LIBCXXABI_FUNC_VIS _Unwind_Reason_Code
|
||||
__xlcxx_personality_v0(int version, _Unwind_Action actions, uint64_t exceptionClass,
|
||||
_Unwind_Exception* unwind_exception, _Unwind_Context* context) {
|
||||
if (version != 1 || unwind_exception == 0 || context == 0)
|
||||
return _URC_FATAL_PHASE1_ERROR;
|
||||
|
||||
bool native_exception = (exceptionClass & get_vendor_and_language) == (kOurExceptionClass & get_vendor_and_language);
|
||||
scan_results results;
|
||||
scan_state_tab(results, actions, native_exception, unwind_exception, context);
|
||||
if (actions & _UA_SEARCH_PHASE) {
|
||||
// Phase 1 search: All we're looking for in phase 1 is a handler that
|
||||
// halts unwinding
|
||||
return results.reason;
|
||||
}
|
||||
if (actions & _UA_CLEANUP_PHASE) {
|
||||
// Phase 2 cleanup:
|
||||
if (results.reason == _URC_HANDLER_FOUND) {
|
||||
// Store the address of unwind_exception in the stack field
|
||||
// reserved for compilers (SP + 3 * sizeof(uintptr_t)) in the stack of
|
||||
// the caller of the function containing the landing pad (within the link
|
||||
// area for the call to the latter) for __xlc_exception_handle()
|
||||
// to retrieve when it is called by the landing pad.
|
||||
uintptr_t *currentSP = reinterpret_cast<uintptr_t*>(_Unwind_GetGR(context, 1));
|
||||
uintptr_t *callersSP = reinterpret_cast<uintptr_t*>(currentSP[0]);
|
||||
callersSP[3] = reinterpret_cast<uintptr_t>(unwind_exception);
|
||||
_LIBCXXABI_TRACE_STATETAB("Handshake: save unwind_exception=%p in stack=%p\n",
|
||||
reinterpret_cast<void*>(unwind_exception), reinterpret_cast<void*>(callersSP));
|
||||
// Jump to the handler.
|
||||
_Unwind_SetIP(context, results.landingPad);
|
||||
return _URC_INSTALL_CONTEXT;
|
||||
}
|
||||
// Did not find a handler. Return the results of the scan. Normally
|
||||
// _URC_CONTINUE_UNWIND, but could have been _URC_FATAL_PHASE2_ERROR.
|
||||
return results.reason;
|
||||
}
|
||||
// We were called improperly: neither a phase 1 or phase 2 search.
|
||||
return _URC_FATAL_PHASE1_ERROR;
|
||||
}
|
||||
} // namespace __state_table_eh
|
||||
|
||||
// The following are EH helper functions for xlclang++ compiled code.
|
||||
|
||||
// __xlc_catch_matchv2
|
||||
// Check whether the thrown object matches the catch handler's exception
|
||||
// declaration. If there is a match, the function returns true with adjusted
|
||||
// address of the thrown object. Otherwise, returns false.
|
||||
_LIBCXXABI_FUNC_VIS bool
|
||||
__xlc_catch_matchv2(_Unwind_Exception* exceptionObject, std::type_info* catchTypeInfo, void*& obj) {
|
||||
_LIBCXXABI_TRACE_STATETAB("Entering %s, exceptionObject=%p\n", __func__, reinterpret_cast<void*>(exceptionObject));
|
||||
|
||||
if (!__isOurExceptionClass(exceptionObject)) {
|
||||
_LIBCXXABI_TRACE_STATETAB0("No match, not a C++ exception\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
__cxa_exception* exceptionHeader = 0;
|
||||
|
||||
if (__getExceptionClass(exceptionObject) == kOurDependentExceptionClass) {
|
||||
// Walk to the __cxa_dependent_exception primary exception for the
|
||||
// exception object and its type_info.
|
||||
__cxa_dependent_exception* dependentExceptionHeader =
|
||||
reinterpret_cast<__cxa_dependent_exception*>(exceptionObject + 1) - 1;
|
||||
exceptionHeader = reinterpret_cast<__cxa_exception*>(dependentExceptionHeader->primaryException) - 1;
|
||||
_LIBCXXABI_TRACE_STATETAB("exceptionObject 0x%p is a dependent, primary 0x%p\n",
|
||||
reinterpret_cast<void*>(exceptionObject),
|
||||
reinterpret_cast<void*>(&exceptionHeader->unwindHeader));
|
||||
exceptionObject = &exceptionHeader->unwindHeader;
|
||||
} else {
|
||||
_LIBCXXABI_TRACE_STATETAB("exceptionObject %p is NOT a dependent\n", reinterpret_cast<void*>(exceptionObject));
|
||||
exceptionHeader = reinterpret_cast<__cxa_exception*>(exceptionObject + 1) - 1;
|
||||
}
|
||||
|
||||
void* thrownObject = reinterpret_cast<void*>(exceptionObject + 1);
|
||||
std::type_info* throwTypeInfo = exceptionHeader->exceptionType;
|
||||
|
||||
// Get the type info for the thrown type and this catch clause and
|
||||
// see if the catch caluse can catch that type.
|
||||
|
||||
__cxxabiv1::__shim_type_info* catchType = reinterpret_cast<__cxxabiv1::__shim_type_info*>(catchTypeInfo);
|
||||
__cxxabiv1::__shim_type_info* throwType = reinterpret_cast<__cxxabiv1::__shim_type_info*>(throwTypeInfo);
|
||||
_LIBCXXABI_TRACE_STATETAB("UnwindException=%p, thrownObject=%p, throwTypeInfo=%p(%s), catchTypeInfo=%p(%s)\n",
|
||||
reinterpret_cast<void*>(exceptionObject), thrownObject, reinterpret_cast<void*>(throwType),
|
||||
throwType->name(), reinterpret_cast<void*>(catchType), catchType->name());
|
||||
if (catchType->can_catch(throwType, thrownObject)) {
|
||||
exceptionHeader->adjustedPtr = thrownObject;
|
||||
obj = thrownObject;
|
||||
_LIBCXXABI_TRACE_STATETAB("Match found for thrownObject=%p\n", thrownObject);
|
||||
return true;
|
||||
}
|
||||
_LIBCXXABI_TRACE_STATETAB0("No match\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// __xlc_throw_badexception
|
||||
// This function is for xlclang++. It allocates and throws a bad_exception.
|
||||
// During unwinding for this bad_exception, the previous exception which is
|
||||
// not matching the throw spec will be cleaned up. Thus having the same
|
||||
// effect as replace the top most exception (which is bad) with a bad_exception.
|
||||
_LIBCXXABI_FUNC_VIS void __xlc_throw_badexception() {
|
||||
_LIBCXXABI_TRACE_STATETAB("Entering function: %s\n\n", __func__);
|
||||
void* newexception = new (__cxa_allocate_exception(sizeof(std::bad_exception))) std::bad_exception;
|
||||
__cxa_throw(newexception, const_cast<std::type_info*>(&typeid(std::bad_exception)), 0);
|
||||
}
|
||||
|
||||
// skip_non_cxx_eh_aware_frames
|
||||
// This function skips non-C++ EH aware stack frames by unwinding from the
|
||||
// stack frame pointed by 'Sp' and returns the first C++ EH aware stack frame
|
||||
// found. 'Pc' is an instruction address inside the function that owns the
|
||||
// stack frame pointed to by 'Sp'.
|
||||
static uintptr_t* skip_non_cxx_eh_aware_frames(uint32_t* Pc, uintptr_t* Sp) {
|
||||
uint32_t* currentPc = Pc;
|
||||
uintptr_t* currentStack = Sp;
|
||||
|
||||
// Loop until a C++ EH aware frame is found or the return address is 0,
|
||||
// which is the return address of the startup function '__start'.
|
||||
while (currentPc != 0) {
|
||||
uint32_t* p = currentPc;
|
||||
|
||||
// Keep looking forward until a word of 0 is found. The traceback
|
||||
// table starts at the following word.
|
||||
while (*p)
|
||||
++p;
|
||||
tbtable* TBTable = reinterpret_cast<tbtable*>(p + 1);
|
||||
|
||||
// A stack frame with a C++ state table is C++ EH aware.
|
||||
if (TBTable->tb.lang == TB_CPLUSPLUS && TBTable->tb.has_ctl)
|
||||
return currentStack;
|
||||
|
||||
// Move up one stack frame.
|
||||
currentStack = reinterpret_cast<uintptr_t*>(currentStack[0]);
|
||||
// Get the value of the LR (saved, prior to incrementing the SP, by the
|
||||
// prolog of the function just inspected) from the frame.
|
||||
currentPc = reinterpret_cast<uint32_t*>(currentStack[2]);
|
||||
}
|
||||
// This should not happen.
|
||||
_LIBCXXABI_TRACE_STATETAB0("skip_non_cxx_eh_aware_frames() reached the end of stack frames, aborting\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
// __xlc_exception_handle
|
||||
// This function is for xlclang++. It returns the address of the exception
|
||||
// object stored in the reserved field in the stack of the caller of the
|
||||
// function that calls __xlc_exception_handle() (within the link area for the
|
||||
// call to the latter). The address is stored by the personality routine for
|
||||
// xlclang++ compiled code. If __xlc_exception_handle() is called by
|
||||
// non-C++ EH aware functions, their frames are skipped until a C++ EH aware
|
||||
// frame is found.
|
||||
// Note: make sure __xlc_exception_handle() is a non-leaf function. Currently
|
||||
// it calls skip_non_cxx_eh_aware_frames(), which in turn calls abort().
|
||||
_LIBCXXABI_FUNC_VIS uintptr_t __xlc_exception_handle() {
|
||||
// Get the SP of this function, i.e., __xlc_exception_handle().
|
||||
uintptr_t* lastStack = reinterpret_cast<uintptr_t*>(__builtin_frame_address(0));
|
||||
// Move one frame up to the frame of the caller of __xlc_exception_handle().
|
||||
lastStack = reinterpret_cast<uintptr_t*>(lastStack[0]);
|
||||
// Get the return address of this function, i.e., __xlc_exception_handle().
|
||||
uint32_t* returnAddress = reinterpret_cast<uint32_t*>(__builtin_return_address(0));
|
||||
|
||||
// Skip non-C++ EH aware frames and get the first C++ EH aware frame.
|
||||
uintptr_t* callerStack = skip_non_cxx_eh_aware_frames(returnAddress, lastStack);
|
||||
|
||||
// Get the SP of the caller of the C++ EH aware caller.
|
||||
callerStack = reinterpret_cast<uintptr_t*>(callerStack[0]);
|
||||
// Retrieve the exception object in the stack slot saved by the personality.
|
||||
uintptr_t exceptionObject = callerStack[3];
|
||||
_LIBCXXABI_TRACE_STATETAB("Handshake: retrieve exceptionObject=%p from stack=%p\n",
|
||||
reinterpret_cast<void*>(exceptionObject), reinterpret_cast<void*>(callerStack));
|
||||
return exceptionObject;
|
||||
}
|
||||
|
||||
// xlclang++ may generate calls to __Deleted_Virtual.
|
||||
_LIBCXXABI_FUNC_VIS void __Deleted_Virtual() { abort(); }
|
||||
|
||||
// __catchThrownException is called during AIX library initialization and
|
||||
// termination to handle exceptions. An implementation is also provided in
|
||||
// libC.a(shrcore.o). This implementation is provided for applications that
|
||||
// link with -lc++ (the xlclang++ or ibm-clang++ link default.)
|
||||
_LIBCXXABI_FUNC_VIS int
|
||||
__catchThrownException(void (*cdfunc)(void), // function which may fail
|
||||
void (*cleanup)(void*), // cleanup function
|
||||
void* cleanuparg, // parameter to cleanup function
|
||||
int action) { // control exception throwing and termination
|
||||
enum Action : int { None = 0, Rethrow = 1, Terminate = 2 };
|
||||
if (!cdfunc)
|
||||
return 0;
|
||||
if (action == Action::Rethrow && !cleanup) {
|
||||
// No cleanup and rethrow is effectively no-op.
|
||||
// Avoid the catch handler when possible to allow exceptions generated
|
||||
// from xlC binaries to flow through.
|
||||
(*cdfunc)();
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
(*cdfunc)();
|
||||
} catch (...) {
|
||||
if (action == Action::Terminate)
|
||||
std::terminate();
|
||||
if (cleanup)
|
||||
(*cleanup)(cleanuparg);
|
||||
if (action == Action::Rethrow)
|
||||
throw;
|
||||
assert(action == Action::None);
|
||||
return -1; // FAILED
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
} // __cxxabiv1
|
||||
45
lib/libtsan/interception/interception_aix.cpp
vendored
45
lib/libtsan/interception/interception_aix.cpp
vendored
|
|
@ -1,45 +0,0 @@
|
|||
//===-- interception_aix.cpp ------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// AIX-specific interception methods.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "interception.h"
|
||||
#include "sanitizer_common/sanitizer_common.h"
|
||||
|
||||
#if SANITIZER_AIX
|
||||
|
||||
# include <dlfcn.h> // for dlsym()
|
||||
|
||||
namespace __interception {
|
||||
|
||||
static void *GetFuncAddr(const char *name, uptr wrapper_addr) {
|
||||
// AIX dlsym can only defect the functions that are exported, so
|
||||
// on AIX, we can not intercept some basic functions like memcpy.
|
||||
// FIXME: if we are going to ship dynamic asan library, we may need to search
|
||||
// all the loaded modules with RTLD_DEFAULT if RTLD_NEXT failed.
|
||||
void *addr = dlsym(RTLD_NEXT, name);
|
||||
|
||||
// In case `name' is not loaded, dlsym ends up finding the actual wrapper.
|
||||
// We don't want to intercept the wrapper and have it point to itself.
|
||||
if ((uptr)addr == wrapper_addr)
|
||||
addr = nullptr;
|
||||
return addr;
|
||||
}
|
||||
|
||||
bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
|
||||
uptr wrapper) {
|
||||
void *addr = GetFuncAddr(name, wrapper);
|
||||
*ptr_to_real = (uptr)addr;
|
||||
return addr && (func == wrapper);
|
||||
}
|
||||
|
||||
} // namespace __interception
|
||||
#endif // SANITIZER_AIX
|
||||
36
lib/libtsan/interception/interception_aix.h
vendored
36
lib/libtsan/interception/interception_aix.h
vendored
|
|
@ -1,36 +0,0 @@
|
|||
//===-- interception_aix.h --------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// AIX-specific interception methods.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#if SANITIZER_AIX
|
||||
|
||||
# if !defined(INCLUDED_FROM_INTERCEPTION_LIB)
|
||||
# error \
|
||||
"interception_aix.h should be included from interception library only"
|
||||
# endif
|
||||
|
||||
# ifndef INTERCEPTION_AIX_H
|
||||
# define INTERCEPTION_AIX_H
|
||||
|
||||
namespace __interception {
|
||||
bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
|
||||
uptr wrapper);
|
||||
} // namespace __interception
|
||||
|
||||
# define INTERCEPT_FUNCTION_AIX(func) \
|
||||
::__interception::InterceptFunction( \
|
||||
#func, (::__interception::uptr *)&REAL(func), \
|
||||
(::__interception::uptr) & (func), \
|
||||
(::__interception::uptr) & WRAP(func))
|
||||
|
||||
# endif // INTERCEPTION_AIX_H
|
||||
#endif // SANITIZER_AIX
|
||||
12
lib/libtsan/sanitizer_common/sanitizer_linux.cpp
vendored
12
lib/libtsan/sanitizer_common/sanitizer_linux.cpp
vendored
|
|
@ -174,8 +174,6 @@ const int FUTEX_WAKE_PRIVATE = FUTEX_WAKE | FUTEX_PRIVATE_FLAG;
|
|||
|
||||
# if SANITIZER_FREEBSD
|
||||
# define SANITIZER_USE_GETENTROPY 1
|
||||
extern "C" void *__sys_mmap(void *addr, size_t len, int prot, int flags, int fd,
|
||||
off_t offset);
|
||||
# endif
|
||||
|
||||
namespace __sanitizer {
|
||||
|
|
@ -265,9 +263,8 @@ ScopedBlockSignals::~ScopedBlockSignals() { SetSigProcMask(&saved_, nullptr); }
|
|||
# if !SANITIZER_S390
|
||||
uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
|
||||
u64 offset) {
|
||||
# if SANITIZER_FREEBSD
|
||||
return (uptr)__sys_mmap(addr, length, prot, flags, fd, offset);
|
||||
# elif SANITIZER_LINUX_USES_64BIT_SYSCALLS
|
||||
/* zig patch: use direct syscall for freebsd mmap */
|
||||
# if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS
|
||||
return internal_syscall(SYSCALL(mmap), (uptr)addr, length, prot, flags, fd,
|
||||
offset);
|
||||
# else
|
||||
|
|
@ -942,6 +939,11 @@ int internal_fork() {
|
|||
}
|
||||
|
||||
# if SANITIZER_FREEBSD
|
||||
int internal_sigaction(int signum, const void *act, void *oldact) {
|
||||
/* zig patch: use direct syscall for freebsd mmap */
|
||||
return internal_syscall(SYSCALL(sigaction), signum, (uptr)act, (uptr)oldact);
|
||||
}
|
||||
|
||||
int internal_sysctl(const int *name, unsigned int namelen, void *oldp,
|
||||
uptr *oldlenp, const void *newp, uptr newlen) {
|
||||
return internal_syscall(SYSCALL(__sysctl), name, namelen, oldp,
|
||||
|
|
|
|||
|
|
@ -69,8 +69,6 @@
|
|||
# undef MAP_NORESERVE
|
||||
# define MAP_NORESERVE 0
|
||||
extern const Elf_Auxinfo *__elf_aux_vector __attribute__((weak));
|
||||
extern "C" int __sys_sigaction(int signum, const struct sigaction *act,
|
||||
struct sigaction *oldact);
|
||||
# endif
|
||||
|
||||
# if SANITIZER_NETBSD
|
||||
|
|
@ -100,24 +98,17 @@ namespace __sanitizer {
|
|||
SANITIZER_WEAK_ATTRIBUTE int real_sigaction(int signum, const void *act,
|
||||
void *oldact);
|
||||
|
||||
/* zig patch: use direct syscall for freebsd sigaction (sanitizer_linux.cpp) */
|
||||
# if !SANITIZER_FREEBSD
|
||||
int internal_sigaction(int signum, const void *act, void *oldact) {
|
||||
# if SANITIZER_FREEBSD
|
||||
// On FreeBSD, call the sigaction syscall directly (part of libsys in FreeBSD
|
||||
// 15) since the libc version goes via a global interposing table. Due to
|
||||
// library initialization order the table can be relocated after the call to
|
||||
// InitializeDeadlySignals() which then crashes when dereferencing the
|
||||
// uninitialized pointer in libc.
|
||||
return __sys_sigaction(signum, (const struct sigaction *)act,
|
||||
(struct sigaction *)oldact);
|
||||
# else
|
||||
# if !SANITIZER_GO
|
||||
if (&real_sigaction)
|
||||
return real_sigaction(signum, act, oldact);
|
||||
# endif
|
||||
return sigaction(signum, (const struct sigaction *)act,
|
||||
(struct sigaction *)oldact);
|
||||
# endif
|
||||
}
|
||||
# endif
|
||||
|
||||
void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
|
||||
uptr *stack_bottom) {
|
||||
|
|
|
|||
63
lib/libunwind/src/Unwind_AIXExtras.cpp
vendored
63
lib/libunwind/src/Unwind_AIXExtras.cpp
vendored
|
|
@ -1,63 +0,0 @@
|
|||
//===--------------------- Unwind_AIXExtras.cpp -------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// This file is only used for AIX.
|
||||
#if defined(_AIX)
|
||||
|
||||
#include "config.h"
|
||||
#include "libunwind_ext.h"
|
||||
#include <sys/debug.h>
|
||||
|
||||
namespace libunwind {
|
||||
// getFuncNameFromTBTable
|
||||
// Get the function name from its traceback table.
|
||||
char *getFuncNameFromTBTable(uintptr_t Pc, uint16_t &NameLen,
|
||||
unw_word_t *Offset) {
|
||||
uint32_t *p = reinterpret_cast<uint32_t *>(Pc);
|
||||
*Offset = 0;
|
||||
|
||||
// Keep looking forward until a word of 0 is found. The traceback
|
||||
// table starts at the following word.
|
||||
while (*p)
|
||||
p++;
|
||||
tbtable *TBTable = reinterpret_cast<tbtable *>(p + 1);
|
||||
|
||||
if (!TBTable->tb.name_present)
|
||||
return NULL;
|
||||
|
||||
// Get to the name of the function.
|
||||
p = reinterpret_cast<uint32_t *>(&TBTable->tb_ext);
|
||||
|
||||
// Skip field parminfo if it exists.
|
||||
if (TBTable->tb.fixedparms || TBTable->tb.floatparms)
|
||||
p++;
|
||||
|
||||
// If the tb_offset field exists, get the offset from the start of
|
||||
// the function to pc. Skip the field.
|
||||
if (TBTable->tb.has_tboff) {
|
||||
unw_word_t StartIp =
|
||||
reinterpret_cast<uintptr_t>(TBTable) - *p - sizeof(uint32_t);
|
||||
*Offset = Pc - StartIp;
|
||||
p++;
|
||||
}
|
||||
|
||||
// Skip field hand_mask if it exists.
|
||||
if (TBTable->tb.int_hndl)
|
||||
p++;
|
||||
|
||||
// Skip fields ctl_info and ctl_info_disp if they exist.
|
||||
if (TBTable->tb.has_ctl) {
|
||||
p += 1 + *p;
|
||||
}
|
||||
|
||||
NameLen = *(reinterpret_cast<uint16_t *>(p));
|
||||
return reinterpret_cast<char *>(p) + sizeof(uint16_t);
|
||||
}
|
||||
} // namespace libunwind
|
||||
#endif // defined(_AIX)
|
||||
|
|
@ -105,6 +105,7 @@ pub fn prepend(list: *DoublyLinkedList, new_node: *Node) void {
|
|||
}
|
||||
|
||||
/// Remove a node from the list.
|
||||
/// Assumes the node is in the list.
|
||||
///
|
||||
/// Arguments:
|
||||
/// node: Pointer to the node to be removed.
|
||||
|
|
|
|||
|
|
@ -604,7 +604,7 @@ pub fn print(w: *Writer, comptime fmt: []const u8, args: anytype) Error!void {
|
|||
@compileError("32 arguments max are supported per format call");
|
||||
}
|
||||
|
||||
@setEvalBranchQuota(fmt.len * 1000);
|
||||
@setEvalBranchQuota(@as(comptime_int, fmt.len) * 1000); // NOTE: We're upcasting as 16-bit usize overflows.
|
||||
comptime var arg_state: std.fmt.ArgState = .{ .args_len = fields_info.len };
|
||||
comptime var i = 0;
|
||||
comptime var literal: []const u8 = "";
|
||||
|
|
|
|||
|
|
@ -1547,7 +1547,7 @@ fn handleSigWinch(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopaque)
|
|||
const have_sigwinch = switch (builtin.os.tag) {
|
||||
.linux,
|
||||
.plan9,
|
||||
.solaris,
|
||||
.illumos,
|
||||
.netbsd,
|
||||
.openbsd,
|
||||
.haiku,
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ pub fn prepend(list: *SinglyLinkedList, new_node: *Node) void {
|
|||
list.first = new_node;
|
||||
}
|
||||
|
||||
/// Remove `node` from the list.
|
||||
/// Asserts that `node` is in the list.
|
||||
pub fn remove(list: *SinglyLinkedList, node: *Node) void {
|
||||
if (list.first == node) {
|
||||
list.first = node.next;
|
||||
|
|
|
|||
|
|
@ -24,14 +24,13 @@ pub const Os = struct {
|
|||
hermit,
|
||||
managarm,
|
||||
|
||||
aix,
|
||||
haiku,
|
||||
hurd,
|
||||
illumos,
|
||||
linux,
|
||||
plan9,
|
||||
rtems,
|
||||
serenity,
|
||||
zos,
|
||||
|
||||
dragonfly,
|
||||
freebsd,
|
||||
|
|
@ -45,9 +44,6 @@ pub const Os = struct {
|
|||
visionos,
|
||||
watchos,
|
||||
|
||||
illumos,
|
||||
solaris,
|
||||
|
||||
windows,
|
||||
uefi,
|
||||
|
||||
|
|
@ -98,10 +94,6 @@ pub const Os = struct {
|
|||
};
|
||||
}
|
||||
|
||||
pub inline fn isSolarish(tag: Tag) bool {
|
||||
return tag == .solaris or tag == .illumos;
|
||||
}
|
||||
|
||||
pub fn exeFileExt(tag: Tag, arch: Cpu.Arch) [:0]const u8 {
|
||||
return switch (tag) {
|
||||
.windows => ".exe",
|
||||
|
|
@ -163,11 +155,10 @@ pub const Os = struct {
|
|||
.managarm,
|
||||
|
||||
.haiku,
|
||||
.illumos,
|
||||
.plan9,
|
||||
.serenity,
|
||||
|
||||
.illumos,
|
||||
|
||||
.ps3,
|
||||
.ps4,
|
||||
.ps5,
|
||||
|
|
@ -181,9 +172,7 @@ pub const Os = struct {
|
|||
.fuchsia,
|
||||
.hermit,
|
||||
|
||||
.aix,
|
||||
.rtems,
|
||||
.zos,
|
||||
|
||||
.dragonfly,
|
||||
.freebsd,
|
||||
|
|
@ -197,8 +186,6 @@ pub const Os = struct {
|
|||
.visionos,
|
||||
.watchos,
|
||||
|
||||
.solaris,
|
||||
|
||||
.uefi,
|
||||
|
||||
.@"3ds",
|
||||
|
|
@ -395,11 +382,10 @@ pub const Os = struct {
|
|||
.managarm,
|
||||
|
||||
.haiku,
|
||||
.illumos,
|
||||
.plan9,
|
||||
.serenity,
|
||||
|
||||
.illumos,
|
||||
|
||||
.ps3,
|
||||
.ps4,
|
||||
.ps5,
|
||||
|
|
@ -428,12 +414,6 @@ pub const Os = struct {
|
|||
},
|
||||
},
|
||||
|
||||
.aix => .{
|
||||
.semver = .{
|
||||
.min = .{ .major = 7, .minor = 2, .patch = 5 },
|
||||
.max = .{ .major = 7, .minor = 3, .patch = 3 },
|
||||
},
|
||||
},
|
||||
.hurd => .{
|
||||
.hurd = .{
|
||||
.range = .{
|
||||
|
|
@ -504,12 +484,6 @@ pub const Os = struct {
|
|||
.max = .{ .major = 6, .minor = 1, .patch = 0 },
|
||||
},
|
||||
},
|
||||
.zos => .{
|
||||
.semver = .{
|
||||
.min = .{ .major = 2, .minor = 5, .patch = 0 },
|
||||
.max = .{ .major = 3, .minor = 1, .patch = 0 },
|
||||
},
|
||||
},
|
||||
|
||||
.dragonfly => .{
|
||||
.semver = .{
|
||||
|
|
@ -597,13 +571,6 @@ pub const Os = struct {
|
|||
},
|
||||
},
|
||||
|
||||
.solaris => .{
|
||||
.semver = .{
|
||||
.min = .{ .major = 11, .minor = 0, .patch = 0 },
|
||||
.max = .{ .major = 11, .minor = 4, .patch = 0 },
|
||||
},
|
||||
},
|
||||
|
||||
.windows => .{
|
||||
.windows = .{
|
||||
.min = .win10,
|
||||
|
|
@ -842,7 +809,6 @@ pub const Abi = enum {
|
|||
=> .eabi,
|
||||
else => .none,
|
||||
},
|
||||
.aix => if (arch == .powerpc) .eabihf else .none,
|
||||
.haiku => switch (arch) {
|
||||
.arm,
|
||||
.powerpc,
|
||||
|
|
@ -930,15 +896,13 @@ pub const Abi = enum {
|
|||
.contiki,
|
||||
.fuchsia,
|
||||
.hermit,
|
||||
.illumos,
|
||||
.managarm,
|
||||
.plan9,
|
||||
.serenity,
|
||||
.zos,
|
||||
.dragonfly,
|
||||
.driverkit,
|
||||
.macos,
|
||||
.illumos,
|
||||
.solaris,
|
||||
.ps3,
|
||||
.ps4,
|
||||
.ps5,
|
||||
|
|
@ -1024,8 +988,6 @@ pub const ObjectFormat = enum {
|
|||
coff,
|
||||
/// The Executable and Linkable Format used by many Unixes.
|
||||
elf,
|
||||
/// The Generalized Object File Format used by z/OS.
|
||||
goff,
|
||||
/// The Intel HEX format for storing binary code in ASCII text.
|
||||
hex,
|
||||
/// The Mach object format used by macOS and other Apple platforms.
|
||||
|
|
@ -1038,8 +1000,6 @@ pub const ObjectFormat = enum {
|
|||
spirv,
|
||||
/// The WebAssembly binary format.
|
||||
wasm,
|
||||
/// The eXtended Common Object File Format used by AIX.
|
||||
xcoff,
|
||||
|
||||
// LLVM tags deliberately omitted:
|
||||
// - dxcontainer
|
||||
|
|
@ -1048,7 +1008,7 @@ pub const ObjectFormat = enum {
|
|||
return switch (of) {
|
||||
.c => ".c",
|
||||
.coff => ".obj",
|
||||
.elf, .goff, .macho, .wasm, .xcoff => ".o",
|
||||
.elf, .macho, .wasm => ".o",
|
||||
.hex => ".ihex",
|
||||
.plan9 => arch.plan9Ext(),
|
||||
.raw => ".bin",
|
||||
|
|
@ -1058,11 +1018,9 @@ pub const ObjectFormat = enum {
|
|||
|
||||
pub fn default(os_tag: Os.Tag, arch: Cpu.Arch) ObjectFormat {
|
||||
return switch (os_tag) {
|
||||
.aix => .xcoff,
|
||||
.driverkit, .ios, .macos, .tvos, .visionos, .watchos => .macho,
|
||||
.plan9 => .plan9,
|
||||
.uefi, .windows => .coff,
|
||||
.zos => .goff,
|
||||
else => switch (arch) {
|
||||
.spirv32, .spirv64 => .spirv,
|
||||
.wasm32, .wasm64 => .wasm,
|
||||
|
|
@ -1101,7 +1059,7 @@ pub fn toElfMachine(target: *const Target) std.elf.EM {
|
|||
.sparc => if (target.cpu.has(.sparc, .v9)) .SPARC32PLUS else .SPARC,
|
||||
.sparc64 => .SPARCV9,
|
||||
.ve => .VE,
|
||||
.x86 => .@"386",
|
||||
.x86_16, .x86 => .@"386",
|
||||
.x86_64 => .X86_64,
|
||||
.xcore => .XCORE,
|
||||
.xtensa, .xtensaeb => .XTENSA,
|
||||
|
|
@ -1172,6 +1130,7 @@ pub fn toCoffMachine(target: *const Target) std.coff.IMAGE.FILE.MACHINE {
|
|||
.ve,
|
||||
.wasm32,
|
||||
.wasm64,
|
||||
.x86_16,
|
||||
.xcore,
|
||||
.xtensa,
|
||||
.xtensaeb,
|
||||
|
|
@ -1394,6 +1353,7 @@ pub const Cpu = struct {
|
|||
ve,
|
||||
wasm32,
|
||||
wasm64,
|
||||
x86_16,
|
||||
x86,
|
||||
x86_64,
|
||||
xcore,
|
||||
|
|
@ -1485,7 +1445,7 @@ pub const Cpu = struct {
|
|||
.spirv32, .spirv64 => .spirv,
|
||||
.ve => .ve,
|
||||
.wasm32, .wasm64 => .wasm,
|
||||
.x86, .x86_64 => .x86,
|
||||
.x86_16, .x86, .x86_64 => .x86,
|
||||
.xcore => .xcore,
|
||||
.xtensa, .xtensaeb => .xtensa,
|
||||
};
|
||||
|
|
@ -1493,7 +1453,7 @@ pub const Cpu = struct {
|
|||
|
||||
pub inline fn isX86(arch: Arch) bool {
|
||||
return switch (arch) {
|
||||
.x86, .x86_64 => true,
|
||||
.x86_16, .x86, .x86_64 => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
|
@ -1687,6 +1647,7 @@ pub const Cpu = struct {
|
|||
.ve,
|
||||
.wasm32,
|
||||
.wasm64,
|
||||
.x86_16,
|
||||
.x86,
|
||||
.x86_64,
|
||||
.xcore,
|
||||
|
|
@ -1807,6 +1768,12 @@ pub const Cpu = struct {
|
|||
.x86_interrupt,
|
||||
=> &.{.x86},
|
||||
|
||||
.x86_16_cdecl,
|
||||
.x86_16_stdcall,
|
||||
.x86_16_regparmcall,
|
||||
.x86_16_interrupt,
|
||||
=> &.{.x86_16},
|
||||
|
||||
.aarch64_aapcs,
|
||||
.aarch64_aapcs_darwin,
|
||||
.aarch64_aapcs_win,
|
||||
|
|
@ -1989,6 +1956,7 @@ pub const Cpu = struct {
|
|||
.riscv64, .riscv64be => &riscv.cpu.generic_rv64,
|
||||
.sparc64 => &sparc.cpu.v9, // SPARC can only be 64-bit from v9 and up.
|
||||
.wasm32, .wasm64 => &wasm.cpu.mvp,
|
||||
.x86_16 => &x86.cpu.i86,
|
||||
.x86 => &x86.cpu.i386,
|
||||
.x86_64 => &x86.cpu.x86_64,
|
||||
inline else => |a| &@field(Target, @tagName(a.family())).cpu.generic,
|
||||
|
|
@ -2038,15 +2006,8 @@ pub const Cpu = struct {
|
|||
.riscv32, .riscv32be => &riscv.cpu.baseline_rv32,
|
||||
.riscv64, .riscv64be => &riscv.cpu.baseline_rv64,
|
||||
// gcc/clang do not have a generic s390x model.
|
||||
.s390x => switch (os.tag) {
|
||||
.zos => &s390x.cpu.arch10,
|
||||
else => &s390x.cpu.arch8,
|
||||
},
|
||||
.s390x => &s390x.cpu.arch8,
|
||||
.sparc => &sparc.cpu.v9, // glibc does not work with 'plain' v8.
|
||||
.sparc64 => switch (os.tag) {
|
||||
.solaris => &sparc.cpu.ultrasparc3,
|
||||
else => generic(arch),
|
||||
},
|
||||
.x86 => &x86.cpu.pentium4,
|
||||
.x86_64 => switch (os.tag) {
|
||||
.driverkit => &x86.cpu.nehalem,
|
||||
|
|
@ -2174,7 +2135,7 @@ pub inline fn isWasiLibC(target: *const Target) bool {
|
|||
/// syscall interface, for example.
|
||||
pub fn requiresLibC(target: *const Target) bool {
|
||||
return switch (target.os.tag) {
|
||||
.aix,
|
||||
.illumos,
|
||||
.driverkit,
|
||||
.macos,
|
||||
.ios,
|
||||
|
|
@ -2184,8 +2145,6 @@ pub fn requiresLibC(target: *const Target) bool {
|
|||
.dragonfly,
|
||||
.openbsd,
|
||||
.haiku,
|
||||
.solaris,
|
||||
.illumos,
|
||||
.serenity,
|
||||
=> true,
|
||||
|
||||
|
|
@ -2202,7 +2161,6 @@ pub fn requiresLibC(target: *const Target) bool {
|
|||
.fuchsia,
|
||||
.managarm,
|
||||
.ps3,
|
||||
.zos,
|
||||
.rtems,
|
||||
.cuda,
|
||||
.nvcl,
|
||||
|
|
@ -2260,7 +2218,10 @@ pub fn supportsAddressSpace(
|
|||
|
||||
return switch (address_space) {
|
||||
.generic => true,
|
||||
.fs, .gs, .ss => (arch == .x86_64 or arch == .x86) and (context == null or context == .pointer),
|
||||
.fs, .gs, .ss => (arch == .x86_64 or arch == .x86 or arch == .x86_16) and (context == null or context == .pointer),
|
||||
// Technically x86 can use segmentation...
|
||||
.far => (arch == .x86_16),
|
||||
|
||||
.flash, .flash1, .flash2, .flash3, .flash4, .flash5 => arch == .avr, // TODO this should also check how many flash banks the cpu has
|
||||
.cog, .hub => arch == .propeller,
|
||||
.lut => arch == .propeller and std.Target.propeller.featureSetHas(target.cpu.features, .p2),
|
||||
|
|
@ -2332,6 +2293,7 @@ pub const DynamicLinker = struct {
|
|||
.fuchsia,
|
||||
|
||||
.haiku,
|
||||
.illumos,
|
||||
.serenity,
|
||||
|
||||
.dragonfly,
|
||||
|
|
@ -2345,9 +2307,6 @@ pub const DynamicLinker = struct {
|
|||
.tvos,
|
||||
.visionos,
|
||||
.watchos,
|
||||
|
||||
.illumos,
|
||||
.solaris,
|
||||
=> .arch_os,
|
||||
.hurd,
|
||||
.linux,
|
||||
|
|
@ -2359,10 +2318,8 @@ pub const DynamicLinker = struct {
|
|||
.hermit,
|
||||
.managarm, // Needs to be double-checked.
|
||||
|
||||
.aix,
|
||||
.plan9,
|
||||
.rtems,
|
||||
.zos,
|
||||
|
||||
.uefi,
|
||||
.windows,
|
||||
|
|
@ -2439,6 +2396,14 @@ pub const DynamicLinker = struct {
|
|||
else => none,
|
||||
},
|
||||
|
||||
.illumos,
|
||||
=> switch (cpu.arch) {
|
||||
.x86,
|
||||
.x86_64,
|
||||
=> initFmt("/lib/{s}ld.so.1", .{if (ptrBitWidth_cpu_abi(cpu, .none) == 64) "64/" else ""}),
|
||||
else => none,
|
||||
},
|
||||
|
||||
.linux => if (abi.isAndroid())
|
||||
switch (cpu.arch) {
|
||||
.arm => if (abi == .androideabi) init("/system/bin/linker") else none,
|
||||
|
|
@ -2755,22 +2720,6 @@ pub const DynamicLinker = struct {
|
|||
else => none,
|
||||
},
|
||||
|
||||
.illumos,
|
||||
=> switch (cpu.arch) {
|
||||
.x86,
|
||||
.x86_64,
|
||||
=> initFmt("/lib/{s}ld.so.1", .{if (ptrBitWidth_cpu_abi(cpu, .none) == 64) "64/" else ""}),
|
||||
else => none,
|
||||
},
|
||||
|
||||
.solaris,
|
||||
=> switch (cpu.arch) {
|
||||
.sparc64,
|
||||
.x86_64,
|
||||
=> initFmt("/lib/{s}ld.so.1", .{if (ptrBitWidth_cpu_abi(cpu, .none) == 64) "64/" else ""}),
|
||||
else => none,
|
||||
},
|
||||
|
||||
// Operating systems in this list have been verified as not having a standard
|
||||
// dynamic linker path.
|
||||
.freestanding,
|
||||
|
|
@ -2779,10 +2728,8 @@ pub const DynamicLinker = struct {
|
|||
.contiki,
|
||||
.hermit,
|
||||
|
||||
.aix,
|
||||
.plan9,
|
||||
.rtems,
|
||||
.zos,
|
||||
|
||||
.uefi,
|
||||
.windows,
|
||||
|
|
@ -2833,6 +2780,7 @@ pub fn ptrBitWidth_arch_abi(cpu_arch: Cpu.Arch, abi: Abi) u16 {
|
|||
return switch (cpu_arch) {
|
||||
.avr,
|
||||
.msp430,
|
||||
.x86_16,
|
||||
=> 16,
|
||||
|
||||
.arc,
|
||||
|
|
@ -2935,7 +2883,7 @@ pub fn stackAlignment(target: *const Target) u16 {
|
|||
// can't handle that level of nuance yet.
|
||||
.powerpc64,
|
||||
.powerpc64le,
|
||||
=> if (target.os.tag == .linux or target.os.tag == .aix) return 16,
|
||||
=> if (target.os.tag == .linux) return 16,
|
||||
.riscv32,
|
||||
.riscv32be,
|
||||
.riscv64,
|
||||
|
|
@ -3046,7 +2994,7 @@ pub fn cTypeByteSize(t: *const Target, c_type: CType) u16 {
|
|||
pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {
|
||||
switch (target.os.tag) {
|
||||
.freestanding, .other => switch (target.cpu.arch) {
|
||||
.msp430 => switch (c_type) {
|
||||
.msp430, .x86_16 => switch (c_type) {
|
||||
.char => return 8,
|
||||
.short, .ushort, .int, .uint => return 16,
|
||||
.float, .long, .ulong => return 32,
|
||||
|
|
@ -3131,23 +3079,19 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {
|
|||
.fuchsia,
|
||||
.hermit,
|
||||
|
||||
.aix,
|
||||
.haiku,
|
||||
.hurd,
|
||||
.illumos,
|
||||
.linux,
|
||||
.plan9,
|
||||
.rtems,
|
||||
.serenity,
|
||||
.zos,
|
||||
|
||||
.freebsd,
|
||||
.dragonfly,
|
||||
.netbsd,
|
||||
.openbsd,
|
||||
|
||||
.illumos,
|
||||
.solaris,
|
||||
|
||||
.wasi,
|
||||
.emscripten,
|
||||
=> switch (target.cpu.arch) {
|
||||
|
|
@ -3196,7 +3140,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {
|
|||
.muslx32,
|
||||
=> return 64,
|
||||
else => switch (target.os.tag) {
|
||||
.aix, .freebsd, .netbsd, .openbsd => return 64,
|
||||
.freebsd, .netbsd, .openbsd => return 64,
|
||||
else => return 128,
|
||||
},
|
||||
},
|
||||
|
|
@ -3212,7 +3156,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {
|
|||
.muslx32,
|
||||
=> return 64,
|
||||
else => switch (target.os.tag) {
|
||||
.aix, .freebsd, .openbsd => return 64,
|
||||
.freebsd, .openbsd => return 64,
|
||||
else => return 128,
|
||||
},
|
||||
},
|
||||
|
|
@ -3382,13 +3326,6 @@ pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 {
|
|||
.int, .uint, .long, .ulong => return 2,
|
||||
else => {},
|
||||
},
|
||||
.powerpc, .powerpcle, .powerpc64, .powerpc64le => switch (target.os.tag) {
|
||||
.aix => switch (c_type) {
|
||||
.double, .longdouble => return 4,
|
||||
else => {},
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
.wasm32, .wasm64 => switch (target.os.tag) {
|
||||
.emscripten => switch (c_type) {
|
||||
.longdouble => return 8,
|
||||
|
|
@ -3404,6 +3341,7 @@ pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 {
|
|||
std.math.ceilPowerOfTwoAssert(u16, (cTypeBitSize(target, c_type) + 7) / 8),
|
||||
@as(u16, switch (target.cpu.arch) {
|
||||
.msp430,
|
||||
.x86_16,
|
||||
=> 2,
|
||||
|
||||
.arc,
|
||||
|
|
@ -3511,7 +3449,7 @@ pub fn cTypePreferredAlignment(target: *const Target, c_type: CType) u16 {
|
|||
return @min(
|
||||
std.math.ceilPowerOfTwoAssert(u16, (cTypeBitSize(target, c_type) + 7) / 8),
|
||||
@as(u16, switch (target.cpu.arch) {
|
||||
.msp430 => 2,
|
||||
.x86_16, .msp430 => 2,
|
||||
|
||||
.arc,
|
||||
.arceb,
|
||||
|
|
@ -3583,7 +3521,7 @@ pub fn cMaxIntAlignment(target: *const Target) u16 {
|
|||
return switch (target.cpu.arch) {
|
||||
.avr => 1,
|
||||
|
||||
.msp430 => 2,
|
||||
.msp430, .x86_16 => 2,
|
||||
|
||||
.arc,
|
||||
.arceb,
|
||||
|
|
@ -3660,6 +3598,7 @@ pub fn cCallingConvention(target: *const Target) ?std.builtin.CallingConvention
|
|||
.windows, .uefi => .{ .x86_win = .{} },
|
||||
else => .{ .x86_sysv = .{} },
|
||||
},
|
||||
.x86_16 => .{ .x86_16_cdecl = .{} },
|
||||
.aarch64, .aarch64_be => if (target.os.tag.isDarwin())
|
||||
.{ .aarch64_aapcs_darwin = .{} }
|
||||
else switch (target.os.tag) {
|
||||
|
|
@ -3685,10 +3624,7 @@ pub fn cCallingConvention(target: *const Target) ?std.builtin.CallingConvention
|
|||
else
|
||||
.{ .powerpc64_elf = .{} },
|
||||
.powerpc64le => .{ .powerpc64_elf_v2 = .{} },
|
||||
.powerpc, .powerpcle => switch (target.os.tag) {
|
||||
.aix => .{ .powerpc_aix = .{} },
|
||||
else => .{ .powerpc_sysv = .{} },
|
||||
},
|
||||
.powerpc, .powerpcle => .{ .powerpc_sysv = .{} },
|
||||
.wasm32, .wasm64 => .{ .wasm_mvp = .{} },
|
||||
.arc, .arceb => .{ .arc_sysv = .{} },
|
||||
.avr => .avr_gnu,
|
||||
|
|
@ -3713,7 +3649,7 @@ pub fn cCallingConvention(target: *const Target) ?std.builtin.CallingConvention
|
|||
.sh, .sheb => .{ .sh_gnu = .{} },
|
||||
.ve => .{ .ve_sysv = .{} },
|
||||
.xcore => .{ .xcore_xs1 = .{} },
|
||||
.xtensa, .xtensaeb => .{ .xtensa_windowed = .{} },
|
||||
.xtensa, .xtensaeb => .{ .xtensa_call0 = .{} },
|
||||
.amdgcn => .{ .amdgcn_device = .{} },
|
||||
.nvptx, .nvptx64 => .nvptx_device,
|
||||
.spirv32, .spirv64 => .spirv_device,
|
||||
|
|
|
|||
|
|
@ -339,6 +339,7 @@ pub fn parseCpuArch(args: ParseOptions) ?Target.Cpu.Arch {
|
|||
/// Similar to `SemanticVersion.parse`, but with following changes:
|
||||
/// * Leading zeroes are allowed.
|
||||
/// * Supports only 2 or 3 version components (major, minor, [patch]). If 3-rd component is omitted, it will be 0.
|
||||
/// * Prerelease and build components are disallowed.
|
||||
pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticVersion {
|
||||
const parseVersionComponentFn = (struct {
|
||||
fn parseVersionComponentInner(component: []const u8) error{ InvalidVersion, Overflow }!usize {
|
||||
|
|
@ -348,11 +349,14 @@ pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticV
|
|||
};
|
||||
}
|
||||
}).parseVersionComponentInner;
|
||||
|
||||
var version_components = mem.splitScalar(u8, ver, '.');
|
||||
|
||||
const major = version_components.first();
|
||||
const minor = version_components.next() orelse return error.InvalidVersion;
|
||||
const patch = version_components.next() orelse "0";
|
||||
if (version_components.next() != null) return error.InvalidVersion;
|
||||
|
||||
return .{
|
||||
.major = try parseVersionComponentFn(major),
|
||||
.minor = try parseVersionComponentFn(minor),
|
||||
|
|
@ -361,10 +365,12 @@ pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticV
|
|||
}
|
||||
|
||||
test parseVersion {
|
||||
try std.testing.expectError(error.InvalidVersion, parseVersion("1"));
|
||||
try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 0 }, try parseVersion("1.2"));
|
||||
try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 3 }, try parseVersion("1.2.3"));
|
||||
|
||||
try std.testing.expectError(error.InvalidVersion, parseVersion("1"));
|
||||
try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3.4"));
|
||||
try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3-dev"));
|
||||
}
|
||||
|
||||
pub fn isNativeCpu(self: Query) bool {
|
||||
|
|
|
|||
|
|
@ -1778,10 +1778,8 @@ pub const all_features = blk: {
|
|||
.description = "Support ARM v9.6a architecture",
|
||||
.dependencies = featureSet(&[_]Feature{
|
||||
.cmpbr,
|
||||
.fprcvt,
|
||||
.lsui,
|
||||
.occmo,
|
||||
.sve2p2,
|
||||
.v9_5a,
|
||||
}),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,10 +7,6 @@ const CpuModel = std.Target.Cpu.Model;
|
|||
pub const Feature = enum {
|
||||
@"64bit",
|
||||
@"64bitregs",
|
||||
aix,
|
||||
aix_shared_lib_tls_model_opt,
|
||||
aix_small_local_dynamic_tls,
|
||||
aix_small_local_exec_tls,
|
||||
allow_unaligned_fp_access,
|
||||
altivec,
|
||||
booke,
|
||||
|
|
@ -61,7 +57,6 @@ pub const Feature = enum {
|
|||
longcall,
|
||||
mfocrf,
|
||||
mma,
|
||||
modern_aix_as,
|
||||
msync,
|
||||
paired_vector_memops,
|
||||
partword_atomics,
|
||||
|
|
@ -110,26 +105,6 @@ pub const all_features = blk: {
|
|||
.description = "Enable 64-bit registers usage for ppc32 [beta]",
|
||||
.dependencies = featureSet(&[_]Feature{}),
|
||||
};
|
||||
result[@intFromEnum(Feature.aix)] = .{
|
||||
.llvm_name = "aix",
|
||||
.description = "AIX OS",
|
||||
.dependencies = featureSet(&[_]Feature{}),
|
||||
};
|
||||
result[@intFromEnum(Feature.aix_shared_lib_tls_model_opt)] = .{
|
||||
.llvm_name = "aix-shared-lib-tls-model-opt",
|
||||
.description = "Tune TLS model at function level in shared library loaded with the main program (for 64-bit AIX only)",
|
||||
.dependencies = featureSet(&[_]Feature{}),
|
||||
};
|
||||
result[@intFromEnum(Feature.aix_small_local_dynamic_tls)] = .{
|
||||
.llvm_name = "aix-small-local-dynamic-tls",
|
||||
.description = "Produce a faster local-dynamic TLS sequence for this function for 64-bit AIX",
|
||||
.dependencies = featureSet(&[_]Feature{}),
|
||||
};
|
||||
result[@intFromEnum(Feature.aix_small_local_exec_tls)] = .{
|
||||
.llvm_name = "aix-small-local-exec-tls",
|
||||
.description = "Produce a TOC-free local-exec TLS sequence for this function for 64-bit AIX",
|
||||
.dependencies = featureSet(&[_]Feature{}),
|
||||
};
|
||||
result[@intFromEnum(Feature.allow_unaligned_fp_access)] = .{
|
||||
.llvm_name = "allow-unaligned-fp-access",
|
||||
.description = "CPU does not trap on unaligned FP access",
|
||||
|
|
@ -446,11 +421,6 @@ pub const all_features = blk: {
|
|||
.power9_altivec,
|
||||
}),
|
||||
};
|
||||
result[@intFromEnum(Feature.modern_aix_as)] = .{
|
||||
.llvm_name = "modern-aix-as",
|
||||
.description = "AIX system assembler is modern enough to support new mnes",
|
||||
.dependencies = featureSet(&[_]Feature{}),
|
||||
};
|
||||
result[@intFromEnum(Feature.msync)] = .{
|
||||
.llvm_name = "msync",
|
||||
.description = "Has only the msync instruction instead of sync",
|
||||
|
|
|
|||
|
|
@ -3081,6 +3081,11 @@ pub const cpu = struct {
|
|||
.xsaveopt,
|
||||
}),
|
||||
};
|
||||
pub const @"i86": CpuModel = .{
|
||||
.name = "i86",
|
||||
.llvm_name = null,
|
||||
.features = featureSet(&[_]Feature{}),
|
||||
};
|
||||
pub const @"i386": CpuModel = .{
|
||||
.name = "i386",
|
||||
.llvm_name = "i386",
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ pub const max_name_len = switch (native_os) {
|
|||
.freebsd => 15,
|
||||
.openbsd => 23,
|
||||
.dragonfly => 1023,
|
||||
.solaris, .illumos => 31,
|
||||
.illumos => 31,
|
||||
// https://github.com/SerenityOS/serenity/blob/6b4c300353da49d3508b5442cf61da70bd04d757/Kernel/Tasks/Thread.h#L102
|
||||
.serenity => 63,
|
||||
else => 0,
|
||||
|
|
@ -211,7 +211,7 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {
|
|||
else => |e| return posix.unexpectedErrno(e),
|
||||
}
|
||||
},
|
||||
.netbsd, .solaris, .illumos => if (use_pthreads) {
|
||||
.netbsd, .illumos => if (use_pthreads) {
|
||||
const err = std.c.pthread_setname_np(self.getHandle(), name_with_terminator.ptr, null);
|
||||
switch (@as(posix.E, @enumFromInt(err))) {
|
||||
.SUCCESS => return,
|
||||
|
|
@ -324,7 +324,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co
|
|||
else => |e| return posix.unexpectedErrno(e),
|
||||
}
|
||||
},
|
||||
.netbsd, .solaris, .illumos => if (use_pthreads) {
|
||||
.netbsd, .illumos => if (use_pthreads) {
|
||||
const err = std.c.pthread_getname_np(self.getHandle(), buffer.ptr, max_name_len + 1);
|
||||
switch (@as(posix.E, @enumFromInt(err))) {
|
||||
.SUCCESS => return std.mem.sliceTo(buffer, 0),
|
||||
|
|
@ -739,10 +739,10 @@ const PosixThreadImpl = struct {
|
|||
};
|
||||
return @as(usize, @intCast(count));
|
||||
},
|
||||
.solaris, .illumos, .serenity => {
|
||||
.illumos, .serenity => {
|
||||
// The "proper" way to get the cpu count would be to query
|
||||
// /dev/kstat via ioctls, and traverse a linked list for each
|
||||
// cpu. (solaris, illumos)
|
||||
// cpu. (illumos)
|
||||
const rc = c.sysconf(@intFromEnum(std.c._SC.NPROCESSORS_ONLN));
|
||||
return switch (posix.errno(rc)) {
|
||||
.SUCCESS => @as(usize, @intCast(rc)),
|
||||
|
|
|
|||
|
|
@ -223,6 +223,13 @@ pub const CallingConvention = union(enum(u8)) {
|
|||
x86_vectorcall: CommonOptions,
|
||||
x86_interrupt: CommonOptions,
|
||||
|
||||
// Calling conventions for the `x86_16` architecture.
|
||||
|
||||
x86_16_cdecl: CommonOptions,
|
||||
x86_16_stdcall: CommonOptions,
|
||||
x86_16_regparmcall: CommonOptions,
|
||||
x86_16_interrupt: CommonOptions,
|
||||
|
||||
// Calling conventions for the `aarch64` and `aarch64_be` architectures.
|
||||
aarch64_aapcs: CommonOptions,
|
||||
aarch64_aapcs_darwin: CommonOptions,
|
||||
|
|
@ -523,6 +530,10 @@ pub const AddressSpace = enum(u5) {
|
|||
fs,
|
||||
ss,
|
||||
|
||||
// x86_16 extra address spaces.
|
||||
/// Allows addressing the entire address space by storing both segment and offset.
|
||||
far,
|
||||
|
||||
// GPU address spaces.
|
||||
global,
|
||||
constant,
|
||||
|
|
@ -1020,10 +1031,7 @@ pub const VaList = switch (builtin.cpu.arch) {
|
|||
.alpha => VaListAlpha,
|
||||
.arm, .armeb, .thumb, .thumbeb => VaListArm,
|
||||
.hexagon => if (builtin.target.abi.isMusl()) VaListHexagon else *u8,
|
||||
.powerpc, .powerpcle => switch (builtin.os.tag) {
|
||||
.aix => *u8,
|
||||
else => VaListPowerPc,
|
||||
},
|
||||
.powerpc, .powerpcle => VaListPowerPc,
|
||||
.s390x => VaListS390x,
|
||||
.sh, .sheb => VaListSh, // This is wrong for `sh_renesas`: https://github.com/ziglang/zig/issues/24692#issuecomment-3150779829
|
||||
.x86_64 => switch (builtin.os.tag) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
pub const Clobbers = switch (@import("builtin").cpu.arch) {
|
||||
.x86, .x86_64 => packed struct {
|
||||
.x86_16, .x86, .x86_64 => packed struct {
|
||||
/// Whether the inline assembly code may perform stores to memory
|
||||
/// addresses other than those derived from input pointer provenance.
|
||||
memory: bool = false,
|
||||
|
|
|
|||
269
lib/std/c.zig
269
lib/std/c.zig
|
|
@ -14,7 +14,7 @@ const windows = std.os.windows;
|
|||
const ws2_32 = std.os.windows.ws2_32;
|
||||
const darwin = @import("c/darwin.zig");
|
||||
const freebsd = @import("c/freebsd.zig");
|
||||
const solaris = @import("c/solaris.zig");
|
||||
const illumos = @import("c/illumos.zig");
|
||||
const netbsd = @import("c/netbsd.zig");
|
||||
const dragonfly = @import("c/dragonfly.zig");
|
||||
const haiku = @import("c/haiku.zig");
|
||||
|
|
@ -117,7 +117,7 @@ pub const timespec = switch (native_os) {
|
|||
sec: isize,
|
||||
nsec: isize,
|
||||
},
|
||||
.netbsd, .solaris, .illumos => extern struct {
|
||||
.netbsd, .illumos => extern struct {
|
||||
sec: i64,
|
||||
nsec: isize,
|
||||
},
|
||||
|
|
@ -132,7 +132,7 @@ pub const dev_t = switch (native_os) {
|
|||
.linux => linux.dev_t,
|
||||
.emscripten => emscripten.dev_t,
|
||||
.wasi => wasi.device_t,
|
||||
.openbsd, .haiku, .solaris, .illumos, .macos, .ios, .tvos, .watchos, .visionos => i32,
|
||||
.openbsd, .haiku, .illumos, .macos, .ios, .tvos, .watchos, .visionos => i32,
|
||||
// https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L43
|
||||
.netbsd, .freebsd, .serenity => u64,
|
||||
else => void,
|
||||
|
|
@ -141,7 +141,7 @@ pub const dev_t = switch (native_os) {
|
|||
pub const mode_t = switch (native_os) {
|
||||
.linux => linux.mode_t,
|
||||
.emscripten => emscripten.mode_t,
|
||||
.openbsd, .haiku, .netbsd, .solaris, .illumos, .wasi, .windows => u32,
|
||||
.openbsd, .haiku, .netbsd, .illumos, .wasi, .windows => u32,
|
||||
// https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L44
|
||||
.freebsd, .macos, .ios, .tvos, .watchos, .visionos, .dragonfly, .serenity => u16,
|
||||
else => u0,
|
||||
|
|
@ -153,7 +153,7 @@ pub const nlink_t = switch (native_os) {
|
|||
.wasi => c_ulonglong,
|
||||
// https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L45
|
||||
.freebsd, .serenity => u64,
|
||||
.openbsd, .netbsd, .solaris, .illumos => u32,
|
||||
.openbsd, .netbsd, .illumos => u32,
|
||||
.haiku => i32,
|
||||
else => void,
|
||||
};
|
||||
|
|
@ -310,7 +310,7 @@ pub const clockid_t = switch (native_os) {
|
|||
THREAD_CPUTIME_ID = 14,
|
||||
PROCESS_CPUTIME_ID = 15,
|
||||
},
|
||||
.solaris, .illumos => enum(u32) {
|
||||
.illumos => enum(u32) {
|
||||
VIRTUAL = 1,
|
||||
THREAD_CPUTIME_ID = 2,
|
||||
REALTIME = 3,
|
||||
|
|
@ -457,7 +457,7 @@ pub const E = switch (native_os) {
|
|||
},
|
||||
.macos, .ios, .tvos, .watchos, .visionos => darwin.E,
|
||||
.freebsd => freebsd.E,
|
||||
.solaris, .illumos => enum(u16) {
|
||||
.illumos => enum(u16) {
|
||||
/// No error occurred.
|
||||
SUCCESS = 0,
|
||||
/// Not super-user
|
||||
|
|
@ -1002,7 +1002,7 @@ pub const F = switch (native_os) {
|
|||
|
||||
pub const GETOWNER_UIDS = 17;
|
||||
},
|
||||
.solaris, .illumos => struct {
|
||||
.illumos => struct {
|
||||
/// Unlock a previously locked region
|
||||
pub const ULOCK = 0;
|
||||
/// Lock a region for exclusive use
|
||||
|
|
@ -1263,7 +1263,7 @@ pub const Flock = switch (native_os) {
|
|||
/// Remote system id or zero for local.
|
||||
sysid: i32,
|
||||
},
|
||||
.solaris, .illumos => extern struct {
|
||||
.illumos => extern struct {
|
||||
type: c_short,
|
||||
whence: c_short,
|
||||
start: off_t,
|
||||
|
|
@ -1293,7 +1293,7 @@ pub const Flock = switch (native_os) {
|
|||
pub const HOST_NAME_MAX = switch (native_os) {
|
||||
.linux => linux.HOST_NAME_MAX,
|
||||
.macos, .ios, .tvos, .watchos, .visionos => 72,
|
||||
.openbsd, .haiku, .dragonfly, .netbsd, .solaris, .illumos, .freebsd => 255,
|
||||
.openbsd, .haiku, .dragonfly, .netbsd, .illumos, .freebsd => 255,
|
||||
// https://github.com/SerenityOS/serenity/blob/c87557e9c1865fa1a6440de34ff6ce6fc858a2b7/Kernel/API/POSIX/sys/limits.h#L22
|
||||
.serenity => 64,
|
||||
else => {},
|
||||
|
|
@ -1302,7 +1302,7 @@ pub const IOV_MAX = switch (native_os) {
|
|||
.linux => linux.IOV_MAX,
|
||||
.emscripten => emscripten.IOV_MAX,
|
||||
// https://github.com/SerenityOS/serenity/blob/098af0f846a87b651731780ff48420205fd33754/Kernel/API/POSIX/sys/uio.h#L16
|
||||
.openbsd, .haiku, .solaris, .illumos, .wasi, .serenity => 1024,
|
||||
.openbsd, .haiku, .illumos, .wasi, .serenity => 1024,
|
||||
.macos, .ios, .tvos, .watchos, .visionos => 16,
|
||||
.dragonfly, .netbsd, .freebsd => KERN.IOV_MAX,
|
||||
else => {},
|
||||
|
|
@ -1549,7 +1549,7 @@ pub const MADV = switch (native_os) {
|
|||
pub const CORE = 9;
|
||||
pub const PROTECT = 10;
|
||||
},
|
||||
.solaris, .illumos => struct {
|
||||
.illumos => struct {
|
||||
/// no further special treatment
|
||||
pub const NORMAL = 0;
|
||||
/// expect random page references
|
||||
|
|
@ -1605,9 +1605,8 @@ pub const MCL = switch (native_os) {
|
|||
// https://github.com/DragonFlyBSD/DragonFlyBSD/blob/088552723935447397400336f5ddb7aa5f5de660/sys/sys/mman.h#L118
|
||||
// https://github.com/NetBSD/src/blob/fd2741deca927c18e3ba15acdf78b8b14b2abe36/sys/sys/mman.h#L179
|
||||
// https://github.com/openbsd/src/blob/39404228f6d36c0ca4be5f04ab5385568ebd6aa3/sys/sys/mman.h#L129
|
||||
// https://github.com/kofemann/opensolaris/blob/80192cd83bf665e708269dae856f9145f7190f74/usr/src/uts/common/sys/mman.h#L379
|
||||
// https://github.com/illumos/illumos-gate/blob/5280477614f83fea20fc938729df6adb3e44340d/usr/src/uts/common/sys/mman.h#L343
|
||||
.freebsd, .dragonfly, .netbsd, .openbsd, .solaris, .illumos => packed struct(c_int) {
|
||||
.freebsd, .dragonfly, .netbsd, .openbsd, .illumos => packed struct(c_int) {
|
||||
CURRENT: bool = 0,
|
||||
FUTURE: bool = 0,
|
||||
_: std.meta.Int(.unsigned, @bitSizeOf(c_int) - 2) = 0,
|
||||
|
|
@ -1630,7 +1629,7 @@ pub const MSF = switch (native_os) {
|
|||
pub const DEACTIVATE = 0x8;
|
||||
pub const SYNC = 0x10;
|
||||
},
|
||||
.openbsd, .haiku, .dragonfly, .netbsd, .solaris, .illumos, .freebsd => struct {
|
||||
.openbsd, .haiku, .dragonfly, .netbsd, .illumos, .freebsd => struct {
|
||||
pub const ASYNC = 1;
|
||||
pub const INVALIDATE = 2;
|
||||
pub const SYNC = 4;
|
||||
|
|
@ -1650,7 +1649,7 @@ pub const NAME_MAX = switch (native_os) {
|
|||
// character, but POSIX definition says that NAME_MAX does not include the
|
||||
// terminating null.
|
||||
// https://github.com/SerenityOS/serenity/blob/c87557e9c1865fa1a6440de34ff6ce6fc858a2b7/Kernel/API/POSIX/sys/limits.h#L20
|
||||
.haiku, .openbsd, .dragonfly, .netbsd, .solaris, .illumos, .freebsd, .macos, .ios, .tvos, .watchos, .visionos, .serenity => 255,
|
||||
.haiku, .openbsd, .dragonfly, .netbsd, .illumos, .freebsd, .macos, .ios, .tvos, .watchos, .visionos, .serenity => 255,
|
||||
else => {},
|
||||
};
|
||||
pub const PATH_MAX = switch (native_os) {
|
||||
|
|
@ -1658,7 +1657,7 @@ pub const PATH_MAX = switch (native_os) {
|
|||
.emscripten => emscripten.PATH_MAX,
|
||||
.wasi => 4096,
|
||||
.windows => 260,
|
||||
.openbsd, .haiku, .dragonfly, .netbsd, .solaris, .illumos, .freebsd, .macos, .ios, .tvos, .watchos, .visionos, .serenity => 1024,
|
||||
.openbsd, .haiku, .dragonfly, .netbsd, .illumos, .freebsd, .macos, .ios, .tvos, .watchos, .visionos, .serenity => 1024,
|
||||
else => {},
|
||||
};
|
||||
|
||||
|
|
@ -1721,7 +1720,7 @@ pub const POLL = switch (native_os) {
|
|||
|
||||
pub const STANDARD = IN | PRI | OUT | RDNORM | RDBAND | WRBAND | ERR | HUP | NVAL;
|
||||
},
|
||||
.solaris, .illumos => struct {
|
||||
.illumos => struct {
|
||||
pub const IN = 0x0001;
|
||||
pub const PRI = 0x0002;
|
||||
pub const OUT = 0x0004;
|
||||
|
|
@ -1812,7 +1811,7 @@ pub const PROT = switch (native_os) {
|
|||
.linux => linux.PROT,
|
||||
.emscripten => emscripten.PROT,
|
||||
// https://github.com/SerenityOS/serenity/blob/6d59d4d3d9e76e39112842ec487840828f1c9bfe/Kernel/API/POSIX/sys/mman.h#L28-L31
|
||||
.openbsd, .haiku, .dragonfly, .netbsd, .solaris, .illumos, .freebsd, .windows, .serenity => struct {
|
||||
.openbsd, .haiku, .dragonfly, .netbsd, .illumos, .freebsd, .windows, .serenity => struct {
|
||||
/// page can not be accessed
|
||||
pub const NONE = 0x0;
|
||||
/// page can be read
|
||||
|
|
@ -1852,7 +1851,7 @@ pub const RLIM = switch (native_os) {
|
|||
pub const SAVED_MAX = INFINITY;
|
||||
pub const SAVED_CUR = INFINITY;
|
||||
},
|
||||
.solaris, .illumos => struct {
|
||||
.illumos => struct {
|
||||
/// No limit
|
||||
pub const INFINITY: rlim_t = (1 << 63) - 3;
|
||||
pub const SAVED_MAX: rlim_t = (1 << 63) - 2;
|
||||
|
|
@ -2022,7 +2021,7 @@ pub const S = switch (native_os) {
|
|||
return m & IFMT == IFWHT;
|
||||
}
|
||||
},
|
||||
.solaris, .illumos => struct {
|
||||
.illumos => struct {
|
||||
pub const IFMT = 0o170000;
|
||||
|
||||
pub const IFIFO = 0o010000;
|
||||
|
|
@ -2424,7 +2423,7 @@ pub const SA = switch (native_os) {
|
|||
pub const NOCLDWAIT = 0x0020;
|
||||
pub const SIGINFO = 0x0040;
|
||||
},
|
||||
.solaris, .illumos => struct {
|
||||
.illumos => struct {
|
||||
pub const ONSTACK = 0x00000001;
|
||||
pub const RESETHAND = 0x00000002;
|
||||
pub const RESTART = 0x00000004;
|
||||
|
|
@ -2485,7 +2484,7 @@ pub const SA = switch (native_os) {
|
|||
else => void,
|
||||
};
|
||||
pub const sigval_t = switch (native_os) {
|
||||
.netbsd, .solaris, .illumos => extern union {
|
||||
.netbsd, .illumos => extern union {
|
||||
int: i32,
|
||||
ptr: ?*anyopaque,
|
||||
},
|
||||
|
|
@ -2525,7 +2524,7 @@ pub const _SC = if (builtin.abi.isAndroid()) enum(c_int) {
|
|||
.openbsd => enum(c_int) {
|
||||
PAGESIZE = 28,
|
||||
},
|
||||
.solaris, .illumos => enum(c_int) {
|
||||
.illumos => enum(c_int) {
|
||||
PAGESIZE = 11,
|
||||
NPROCESSORS_ONLN = 15,
|
||||
SIGRT_MIN = 40,
|
||||
|
|
@ -2566,7 +2565,7 @@ pub const SEEK = switch (native_os) {
|
|||
pub const CUR = 1;
|
||||
pub const END = 2;
|
||||
},
|
||||
.dragonfly, .solaris, .illumos => struct {
|
||||
.dragonfly, .illumos => struct {
|
||||
pub const SET = 0;
|
||||
pub const CUR = 1;
|
||||
pub const END = 2;
|
||||
|
|
@ -2765,7 +2764,7 @@ pub const SIG = switch (native_os) {
|
|||
return sig <= MAXSIG and sig > 0;
|
||||
}
|
||||
},
|
||||
.solaris, .illumos => struct {
|
||||
.illumos => struct {
|
||||
pub const DFL: ?Sigaction.handler_fn = @ptrFromInt(0);
|
||||
pub const ERR: ?Sigaction.handler_fn = @ptrFromInt(maxInt(usize));
|
||||
pub const IGN: ?Sigaction.handler_fn = @ptrFromInt(1);
|
||||
|
|
@ -3089,7 +3088,7 @@ pub const SIG = switch (native_os) {
|
|||
pub const SIOCGIFINDEX = switch (native_os) {
|
||||
.linux => linux.SIOCGIFINDEX,
|
||||
.emscripten => emscripten.SIOCGIFINDEX,
|
||||
.solaris, .illumos => solaris.SIOCGLIFINDEX,
|
||||
.illumos => illumos.SIOCGLIFINDEX,
|
||||
// https://github.com/SerenityOS/serenity/blob/cb10f70394fb7e9cfc77f827adb2e46d199bc3a5/Kernel/API/Ioctl.h#L118
|
||||
.serenity => 34,
|
||||
else => void,
|
||||
|
|
@ -3204,7 +3203,7 @@ pub const Sigaction = switch (native_os) {
|
|||
/// signal mask to apply
|
||||
mask: sigset_t,
|
||||
},
|
||||
.solaris, .illumos => extern struct {
|
||||
.illumos => extern struct {
|
||||
pub const handler_fn = *align(1) const fn (i32) callconv(.c) void;
|
||||
pub const sigaction_fn = *const fn (i32, *const siginfo_t, ?*anyopaque) callconv(.c) void;
|
||||
|
||||
|
|
@ -3301,7 +3300,7 @@ pub const T = switch (native_os) {
|
|||
pub const IOCGPTN = 0x4004740f;
|
||||
pub const IOCSIG = 0x2004745f;
|
||||
},
|
||||
.solaris, .illumos => struct {
|
||||
.illumos => struct {
|
||||
pub const CGETA = tioc('T', 1);
|
||||
pub const CSETA = tioc('T', 2);
|
||||
pub const CSETAW = tioc('T', 3);
|
||||
|
|
@ -3731,7 +3730,7 @@ pub const W = switch (native_os) {
|
|||
return (s & 0xffff) -% 1 < 0xff;
|
||||
}
|
||||
},
|
||||
.solaris, .illumos => struct {
|
||||
.illumos => struct {
|
||||
pub const EXITED = 0o001;
|
||||
pub const TRAPPED = 0o002;
|
||||
pub const UNTRACED = 0o004;
|
||||
|
|
@ -3944,7 +3943,7 @@ pub const clock_t = switch (native_os) {
|
|||
.emscripten => emscripten.clock_t,
|
||||
.macos, .ios, .tvos, .watchos, .visionos => c_ulong,
|
||||
.freebsd => isize,
|
||||
.openbsd, .solaris, .illumos => i64,
|
||||
.openbsd, .illumos => i64,
|
||||
.netbsd => u32,
|
||||
.haiku => i32,
|
||||
// https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L50
|
||||
|
|
@ -3975,7 +3974,7 @@ pub const dl_phdr_info = switch (native_os) {
|
|||
tls_modid: usize,
|
||||
tls_data: ?*anyopaque,
|
||||
},
|
||||
.solaris, .illumos => extern struct {
|
||||
.illumos => extern struct {
|
||||
addr: std.elf.Addr,
|
||||
name: ?[*:0]const u8,
|
||||
phdr: [*]std.elf.Phdr,
|
||||
|
|
@ -4001,7 +4000,7 @@ pub const epoll_event = switch (native_os) {
|
|||
pub const ifreq = switch (native_os) {
|
||||
.linux => linux.ifreq,
|
||||
.emscripten => emscripten.ifreq,
|
||||
.solaris, .illumos => lifreq,
|
||||
.illumos => lifreq,
|
||||
// https://github.com/SerenityOS/serenity/blob/9882848e0bf783dfc8e8a6d887a848d70d9c58f4/Kernel/API/POSIX/net/if.h#L49-L82
|
||||
.serenity => extern struct {
|
||||
// Not actually in a union, but the stdlib expects one for ifreq
|
||||
|
|
@ -4026,10 +4025,9 @@ pub const ifreq = switch (native_os) {
|
|||
};
|
||||
pub const in_pktinfo = switch (native_os) {
|
||||
.linux => linux.in_pktinfo,
|
||||
// https://github.com/kofemann/opensolaris/blob/80192cd83bf665e708269dae856f9145f7190f74/usr/src/uts/common/netinet/in.h#L1084
|
||||
// https://github.com/illumos/illumos-gate/blob/608eb926e14f4ba4736b2d59e891335f1cba9e1e/usr/src/uts/common/netinet/in.h#L1132
|
||||
// https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/netinet/in.h#L696
|
||||
.solaris, .illumos, .driverkit, .ios, .macos, .tvos, .watchos, .visionos => extern struct {
|
||||
.illumos, .driverkit, .ios, .macos, .tvos, .watchos, .visionos => extern struct {
|
||||
ifindex: u32,
|
||||
spec_dst: u32,
|
||||
addr: u32,
|
||||
|
|
@ -4042,12 +4040,11 @@ pub const in6_pktinfo = switch (native_os) {
|
|||
// https://github.com/DragonFlyBSD/DragonFlyBSD/blob/6098912863ed4c7b3f70d7483910ce2956cf4ed3/sys/netinet6/in6.h#L575
|
||||
// https://github.com/NetBSD/src/blob/80bf25a5691072d4755e84567ccbdf0729370dea/sys/netinet6/in6.h#L468
|
||||
// https://github.com/openbsd/src/blob/718a31b40d39fc6064de6355eb144e74633133fc/sys/netinet6/in6.h#L365
|
||||
// https://github.com/kofemann/opensolaris/blob/80192cd83bf665e708269dae856f9145f7190f74/usr/src/uts/common/netinet/in.h#L1093
|
||||
// https://github.com/illumos/illumos-gate/blob/608eb926e14f4ba4736b2d59e891335f1cba9e1e/usr/src/uts/common/netinet/in.h#L114IP1
|
||||
// https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/netinet6/in6.h#L737
|
||||
// https://github.com/haiku/haiku/blob/2aab5f5f14aeb3f34c3a3d9a9064cc3c0d914bea/headers/posix/netinet6/in6.h#L63
|
||||
// https://github.com/SerenityOS/serenity/blob/5bd8af99be0bc4b2e14f361fd7d7590e6bcfa4d6/Kernel/API/POSIX/sys/socket.h#L122
|
||||
.freebsd, .dragonfly, .netbsd, .openbsd, .solaris, .illumos, .driverkit, .ios, .macos, .tvos, .watchos, .visionos, .haiku, .serenity => extern struct {
|
||||
.freebsd, .dragonfly, .netbsd, .openbsd, .illumos, .driverkit, .ios, .macos, .tvos, .watchos, .visionos, .haiku, .serenity => extern struct {
|
||||
addr: [16]u8,
|
||||
ifindex: u32,
|
||||
},
|
||||
|
|
@ -4071,8 +4068,6 @@ pub const linger = switch (native_os) {
|
|||
.netbsd,
|
||||
// https://github.com/openbsd/src/blob/718a31b40d39fc6064de6355eb144e74633133fc/sys/sys/socket.h#L126
|
||||
.openbsd,
|
||||
// https://github.com/kofemann/opensolaris/blob/80192cd83bf665e708269dae856f9145f7190f74/usr/src/uts/common/sys/socket.h#L214
|
||||
.solaris,
|
||||
// https://github.com/illumos/illumos-gate/blob/608eb926e14f4ba4736b2d59e891335f1cba9e1e/usr/src/uts/common/sys/socket.h#L250
|
||||
.illumos,
|
||||
// https://github.com/haiku/haiku/blob/2aab5f5f14aeb3f34c3a3d9a9064cc3c0d914bea/headers/posix/sys/socket.h#L87
|
||||
|
|
@ -4100,7 +4095,6 @@ pub const msghdr = switch (native_os) {
|
|||
.freebsd,
|
||||
.netbsd,
|
||||
.haiku,
|
||||
.solaris,
|
||||
.illumos,
|
||||
.macos,
|
||||
.driverkit,
|
||||
|
|
@ -4144,7 +4138,6 @@ pub const msghdr_const = switch (native_os) {
|
|||
.freebsd,
|
||||
.netbsd,
|
||||
.haiku,
|
||||
.solaris,
|
||||
.illumos,
|
||||
.macos,
|
||||
.driverkit,
|
||||
|
|
@ -4190,8 +4183,6 @@ pub const cmsghdr = switch (native_os) {
|
|||
.netbsd,
|
||||
// https://github.com/openbsd/src/blob/master/sys/sys/socket.h#L527
|
||||
.openbsd,
|
||||
// https://github.com/kofemann/opensolaris/blob/80192cd83bf665e708269dae856f9145f7190f74/usr/src/uts/common/sys/socket.h#L416
|
||||
.solaris,
|
||||
// https://github.com/illumos/illumos-gate/blob/afdf2e523873cb523df379676067bf9785a0f456/usr/src/uts/common/sys/socket.h#L460
|
||||
.illumos,
|
||||
// https://github.com/SerenityOS/serenity/blob/4ee360a348a5e2490eeaeeabb3eb19e70dd450eb/Kernel/API/POSIX/sys/socket.h#L68
|
||||
|
|
@ -4215,7 +4206,7 @@ pub const cmsghdr = switch (native_os) {
|
|||
pub const nfds_t = switch (native_os) {
|
||||
.linux => linux.nfds_t,
|
||||
.emscripten => emscripten.nfds_t,
|
||||
.haiku, .solaris, .illumos, .wasi => usize,
|
||||
.haiku, .illumos, .wasi => usize,
|
||||
.windows => c_ulong,
|
||||
.openbsd, .dragonfly, .netbsd, .freebsd, .macos, .ios, .tvos, .watchos, .visionos => u32,
|
||||
// https://github.com/SerenityOS/serenity/blob/265764ff2fec038855193296588a887fc322d76a/Kernel/API/POSIX/poll.h#L32
|
||||
|
|
@ -4253,7 +4244,7 @@ pub const pollfd = switch (native_os) {
|
|||
pub const rlim_t = switch (native_os) {
|
||||
.linux => linux.rlim_t,
|
||||
.emscripten => emscripten.rlim_t,
|
||||
.openbsd, .netbsd, .solaris, .illumos, .macos, .ios, .tvos, .watchos, .visionos => u64,
|
||||
.openbsd, .netbsd, .illumos, .macos, .ios, .tvos, .watchos, .visionos => u64,
|
||||
.haiku, .dragonfly, .freebsd => i64,
|
||||
// https://github.com/SerenityOS/serenity/blob/aae106e37b48f2158e68902293df1e4bf7b80c0f/Userland/Libraries/LibC/sys/resource.h#L54
|
||||
.serenity => usize,
|
||||
|
|
@ -4307,7 +4298,7 @@ pub const rlimit_resource = switch (native_os) {
|
|||
|
||||
pub const AS: rlimit_resource = .VMEM;
|
||||
},
|
||||
.solaris, .illumos => enum(c_int) {
|
||||
.illumos => enum(c_int) {
|
||||
CPU = 0,
|
||||
FSIZE = 1,
|
||||
DATA = 2,
|
||||
|
|
@ -4401,7 +4392,7 @@ pub const rusage = switch (native_os) {
|
|||
pub const SELF = 0;
|
||||
pub const CHILDREN = -1;
|
||||
},
|
||||
.solaris, .illumos => extern struct {
|
||||
.illumos => extern struct {
|
||||
utime: timeval,
|
||||
stime: timeval,
|
||||
maxrss: isize,
|
||||
|
|
@ -4510,7 +4501,7 @@ pub const siginfo_t = switch (native_os) {
|
|||
},
|
||||
},
|
||||
},
|
||||
.solaris, .illumos => extern struct {
|
||||
.illumos => extern struct {
|
||||
signo: c_int,
|
||||
code: c_int,
|
||||
errno: c_int,
|
||||
|
|
@ -4530,8 +4521,8 @@ pub const siginfo_t = switch (native_os) {
|
|||
stime: clock_t,
|
||||
},
|
||||
},
|
||||
contract: solaris.ctid_t,
|
||||
zone: solaris.zoneid_t,
|
||||
contract: illumos.ctid_t,
|
||||
zone: illumos.zoneid_t,
|
||||
},
|
||||
fault: extern struct {
|
||||
addr: *allowzero anyopaque,
|
||||
|
|
@ -4642,7 +4633,7 @@ pub const sigset_t = switch (native_os) {
|
|||
// https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/signal.h#L19
|
||||
.openbsd, .serenity => u32,
|
||||
.macos, .ios, .tvos, .watchos, .visionos => darwin.sigset_t,
|
||||
.dragonfly, .netbsd, .solaris, .illumos, .freebsd => extern struct {
|
||||
.dragonfly, .netbsd, .illumos, .freebsd => extern struct {
|
||||
__bits: [SIG.WORDS]u32,
|
||||
},
|
||||
.haiku => u64,
|
||||
|
|
@ -4681,7 +4672,7 @@ pub const addrinfo = if (builtin.abi.isAndroid()) extern struct {
|
|||
addr: ?*sockaddr,
|
||||
next: ?*addrinfo,
|
||||
},
|
||||
.solaris, .illumos => extern struct {
|
||||
.illumos => extern struct {
|
||||
flags: AI,
|
||||
family: i32,
|
||||
socktype: i32,
|
||||
|
|
@ -4819,7 +4810,7 @@ pub const sockaddr = switch (native_os) {
|
|||
path: [104]u8,
|
||||
};
|
||||
},
|
||||
.solaris, .illumos => extern struct {
|
||||
.illumos => extern struct {
|
||||
/// address family
|
||||
family: sa_family_t,
|
||||
|
||||
|
|
@ -5081,7 +5072,7 @@ pub const sa_family_t = switch (native_os) {
|
|||
.windows => ws2_32.ADDRESS_FAMILY,
|
||||
.openbsd, .haiku, .dragonfly, .netbsd, .freebsd, .macos, .ios, .tvos, .watchos, .visionos => u8,
|
||||
// https://github.com/SerenityOS/serenity/blob/ac44ec5ebc707f9dd0c3d4759a1e17e91db5d74f/Kernel/API/POSIX/sys/socket.h#L66
|
||||
.solaris, .illumos, .serenity => u16,
|
||||
.illumos, .serenity => u16,
|
||||
else => void,
|
||||
};
|
||||
pub const AF = if (builtin.abi.isAndroid()) struct {
|
||||
|
|
@ -5219,7 +5210,7 @@ pub const AF = if (builtin.abi.isAndroid()) struct {
|
|||
pub const INET6_SDP = 42;
|
||||
pub const MAX = 42;
|
||||
},
|
||||
.solaris, .illumos => struct {
|
||||
.illumos => struct {
|
||||
pub const UNSPEC = 0;
|
||||
pub const UNIX = 1;
|
||||
pub const LOCAL = UNIX;
|
||||
|
|
@ -5499,7 +5490,7 @@ pub const PF = if (builtin.abi.isAndroid()) struct {
|
|||
pub const INET6_SDP = AF.INET6_SDP;
|
||||
pub const MAX = AF.MAX;
|
||||
},
|
||||
.solaris, .illumos => struct {
|
||||
.illumos => struct {
|
||||
pub const UNSPEC = AF.UNSPEC;
|
||||
pub const UNIX = AF.UNIX;
|
||||
pub const LOCAL = UNIX;
|
||||
|
|
@ -5778,7 +5769,7 @@ pub const MSG = switch (native_os) {
|
|||
pub const FBLOCKING = 0x10000;
|
||||
pub const FNONBLOCKING = 0x20000;
|
||||
},
|
||||
.solaris, .illumos => struct {
|
||||
.illumos => struct {
|
||||
pub const OOB = 0x0001;
|
||||
pub const PEEK = 0x0002;
|
||||
pub const DONTROUTE = 0x0004;
|
||||
|
|
@ -5825,7 +5816,7 @@ pub const SOCK = switch (native_os) {
|
|||
pub const CLOEXEC = 0x10000000;
|
||||
pub const NONBLOCK = 0x20000000;
|
||||
},
|
||||
.solaris, .illumos => struct {
|
||||
.illumos => struct {
|
||||
/// Datagram.
|
||||
pub const DGRAM = 1;
|
||||
/// STREAM.
|
||||
|
|
@ -6155,7 +6146,7 @@ pub const IPPROTO = switch (native_os) {
|
|||
/// Reserved
|
||||
pub const RESERVED_254 = 254;
|
||||
},
|
||||
.solaris, .illumos => struct {
|
||||
.illumos => struct {
|
||||
/// dummy for IP
|
||||
pub const IP = 0;
|
||||
/// Hop by hop header for IPv6
|
||||
|
|
@ -6514,7 +6505,7 @@ pub const IP = switch (native_os) {
|
|||
.dragonfly => dragonfly.IP,
|
||||
.netbsd => netbsd.IP,
|
||||
.openbsd => openbsd.IP,
|
||||
.solaris, .illumos => solaris.IP,
|
||||
.illumos => illumos.IP,
|
||||
.haiku => haiku.IP,
|
||||
.serenity => serenity.IP,
|
||||
else => void,
|
||||
|
|
@ -6525,7 +6516,7 @@ pub const IPV6 = switch (native_os) {
|
|||
.dragonfly => dragonfly.IPV6,
|
||||
.netbsd => netbsd.IPV6,
|
||||
.openbsd => openbsd.IPV6,
|
||||
.solaris, .illumos => solaris.IPV6,
|
||||
.illumos => illumos.IPV6,
|
||||
.haiku => haiku.IPV6,
|
||||
.serenity => serenity.IPV6,
|
||||
else => void,
|
||||
|
|
@ -6536,7 +6527,7 @@ pub const IPTOS = switch (native_os) {
|
|||
.dragonfly => dragonfly.IPTOS,
|
||||
.netbsd => netbsd.IPTOS,
|
||||
.openbsd => openbsd.IPTOS,
|
||||
.solaris, .illumos => solaris.IPTOS,
|
||||
.illumos => illumos.IPTOS,
|
||||
.haiku => haiku.IPTOS,
|
||||
.serenity => serenity.IPTOS,
|
||||
else => void,
|
||||
|
|
@ -6548,7 +6539,7 @@ pub const SOL = switch (native_os) {
|
|||
.openbsd, .haiku, .dragonfly, .netbsd, .freebsd, .macos, .ios, .tvos, .watchos, .visionos => struct {
|
||||
pub const SOCKET = 0xffff;
|
||||
},
|
||||
.solaris, .illumos => struct {
|
||||
.illumos => struct {
|
||||
pub const SOCKET = 0xffff;
|
||||
pub const ROUTE = 0xfffe;
|
||||
pub const PACKET = 0xfffd;
|
||||
|
|
@ -6632,7 +6623,7 @@ pub const SO = switch (native_os) {
|
|||
pub const MAX_PACING_RATE = 0x1018;
|
||||
pub const DOMAIN = 0x1019;
|
||||
},
|
||||
.solaris, .illumos => struct {
|
||||
.illumos => struct {
|
||||
pub const DEBUG = 0x0001;
|
||||
pub const ACCEPTCONN = 0x0002;
|
||||
pub const REUSEADDR = 0x0004;
|
||||
|
|
@ -6803,7 +6794,7 @@ pub const SOMAXCONN = switch (native_os) {
|
|||
.linux => linux.SOMAXCONN,
|
||||
.windows => ws2_32.SOMAXCONN,
|
||||
// https://github.com/SerenityOS/serenity/blob/ac44ec5ebc707f9dd0c3d4759a1e17e91db5d74f/Kernel/API/POSIX/sys/socket.h#L128
|
||||
.solaris, .illumos, .serenity => 128,
|
||||
.illumos, .serenity => 128,
|
||||
// https://github.com/freebsd/freebsd-src/blob/9ab31f821ad1c6bad474510447387c50bef2c24c/sys/sys/socket.h#L434
|
||||
// https://github.com/DragonFlyBSD/DragonFlyBSD/blob/fd3d1949d526ffa646e57037770acd6f2f3bb617/sys/sys/socket.h#L393
|
||||
// https://github.com/NetBSD/src/blob/a673fb3f8487e974c669216064f7588207229fea/sys/sys/socket.h#L472
|
||||
|
|
@ -6814,9 +6805,8 @@ pub const SOMAXCONN = switch (native_os) {
|
|||
};
|
||||
pub const SCM = switch (native_os) {
|
||||
.linux, .emscripten => linux.SCM,
|
||||
// https://github.com/kofemann/opensolaris/blob/80192cd83bf665e708269dae856f9145f7190f74/usr/src/uts/common/sys/socket.h#L172
|
||||
// https://github.com/illumos/illumos-gate/blob/489f6310fe8952e87fc1dce8af87990fcfd90f18/usr/src/uts/common/sys/socket.h#L196
|
||||
.solaris, .illumos => struct {
|
||||
.illumos => struct {
|
||||
pub const RIGHTS = 0x1010;
|
||||
pub const UCRED = 0x1012;
|
||||
pub const TIMESTAMP = SO.TIMESTAMP;
|
||||
|
|
@ -6874,7 +6864,7 @@ pub const IFNAMESIZE = switch (native_os) {
|
|||
.windows => 30,
|
||||
// https://github.com/SerenityOS/serenity/blob/9882848e0bf783dfc8e8a6d887a848d70d9c58f4/Kernel/API/POSIX/net/if.h#L50
|
||||
.openbsd, .dragonfly, .netbsd, .freebsd, .macos, .ios, .tvos, .watchos, .visionos, .serenity => 16,
|
||||
.solaris, .illumos => 32,
|
||||
.illumos => 32,
|
||||
else => void,
|
||||
};
|
||||
|
||||
|
|
@ -6910,7 +6900,7 @@ pub const time_t = switch (native_os) {
|
|||
};
|
||||
pub const suseconds_t = switch (native_os) {
|
||||
// https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L49
|
||||
.solaris, .illumos, .serenity => i64,
|
||||
.illumos, .serenity => i64,
|
||||
.freebsd, .dragonfly => c_long,
|
||||
.netbsd => c_int,
|
||||
.haiku => i32,
|
||||
|
|
@ -6929,7 +6919,7 @@ pub const timeval = switch (native_os) {
|
|||
usec: i32,
|
||||
},
|
||||
// https://github.com/SerenityOS/serenity/blob/6b6eca0631c893c5f8cfb8274cdfe18e2d0637c0/Kernel/API/POSIX/sys/time.h#L15-L18
|
||||
.dragonfly, .netbsd, .freebsd, .solaris, .illumos, .serenity => extern struct {
|
||||
.dragonfly, .netbsd, .freebsd, .illumos, .serenity => extern struct {
|
||||
/// seconds
|
||||
sec: time_t,
|
||||
/// microseconds
|
||||
|
|
@ -6963,7 +6953,7 @@ pub const user_desc = switch (native_os) {
|
|||
pub const utsname = switch (native_os) {
|
||||
.linux => linux.utsname,
|
||||
.emscripten => emscripten.utsname,
|
||||
.solaris, .illumos => extern struct {
|
||||
.illumos => extern struct {
|
||||
sysname: [256:0]u8,
|
||||
nodename: [256:0]u8,
|
||||
release: [256:0]u8,
|
||||
|
|
@ -7003,7 +6993,7 @@ pub const _errno = switch (native_os) {
|
|||
.wasi, .dragonfly => private.errnoFromThreadLocal,
|
||||
.windows => private._errno,
|
||||
.macos, .ios, .tvos, .watchos, .visionos, .freebsd => private.__error,
|
||||
.solaris, .illumos => private.___errno,
|
||||
.illumos => private.___errno,
|
||||
.openbsd, .netbsd => private.__errno,
|
||||
.haiku => haiku._errnop,
|
||||
// https://github.com/SerenityOS/serenity/blob/a353ceecf13b6f156a078e32f1ddf1d21366934c/Userland/Libraries/LibC/errno.h#L33
|
||||
|
|
@ -7049,7 +7039,7 @@ pub const RTLD = switch (native_os) {
|
|||
NOLOAD: bool = false,
|
||||
_: u18 = 0,
|
||||
},
|
||||
.solaris, .illumos => packed struct(u32) {
|
||||
.illumos => packed struct(u32) {
|
||||
LAZY: bool = false,
|
||||
NOW: bool = false,
|
||||
NOLOAD: bool = false,
|
||||
|
|
@ -7128,7 +7118,7 @@ pub const dirent = switch (native_os) {
|
|||
/// Name of entry.
|
||||
name: [255:0]u8,
|
||||
},
|
||||
.solaris, .illumos => extern struct {
|
||||
.illumos => extern struct {
|
||||
/// Inode number of entry.
|
||||
ino: ino_t,
|
||||
/// Offset of this entry on disk.
|
||||
|
|
@ -7177,7 +7167,7 @@ pub const dirent = switch (native_os) {
|
|||
else => void,
|
||||
};
|
||||
pub const MAXNAMLEN = switch (native_os) {
|
||||
.netbsd, .solaris, .illumos => 511,
|
||||
.netbsd, .illumos => 511,
|
||||
// https://github.com/SerenityOS/serenity/blob/1262a7d1424d0d2e89d80644409721cbf056ab17/Kernel/API/POSIX/dirent.h#L37
|
||||
.haiku, .serenity => NAME_MAX,
|
||||
.openbsd => 255,
|
||||
|
|
@ -7228,7 +7218,7 @@ pub const AI = if (builtin.abi.isAndroid()) packed struct(u32) {
|
|||
ADDRCONFIG: bool = false,
|
||||
_: u21 = 0,
|
||||
},
|
||||
.solaris, .illumos => packed struct(u32) {
|
||||
.illumos => packed struct(u32) {
|
||||
V4MAPPED: bool = false,
|
||||
ALL: bool = false,
|
||||
ADDRCONFIG: bool = false,
|
||||
|
|
@ -7286,7 +7276,7 @@ pub const NI = switch (native_os) {
|
|||
NUMERICSCOPE: bool = false,
|
||||
_: u23 = 0,
|
||||
},
|
||||
.solaris, .illumos => packed struct(u32) {
|
||||
.illumos => packed struct(u32) {
|
||||
NOFQDN: bool = false,
|
||||
NUMERICHOST: bool = false,
|
||||
NAMEREQD: bool = false,
|
||||
|
|
@ -7396,7 +7386,7 @@ pub const EAI = if (builtin.abi.isAndroid()) enum(c_int) {
|
|||
OVERFLOW = 14,
|
||||
_,
|
||||
},
|
||||
.solaris, .illumos => enum(c_int) {
|
||||
.illumos => enum(c_int) {
|
||||
/// address family for hostname not supported
|
||||
ADDRFAMILY = 1,
|
||||
/// name could not be resolved at this time
|
||||
|
|
@ -7736,7 +7726,7 @@ pub const Stat = switch (native_os) {
|
|||
}
|
||||
},
|
||||
.freebsd => freebsd.Stat,
|
||||
.solaris, .illumos => extern struct {
|
||||
.illumos => extern struct {
|
||||
dev: dev_t,
|
||||
ino: ino_t,
|
||||
mode: mode_t,
|
||||
|
|
@ -7970,7 +7960,7 @@ pub const pthread_mutex_t = switch (native_os) {
|
|||
owner: i32 = -1,
|
||||
owner_count: i32 = 0,
|
||||
},
|
||||
.solaris, .illumos => extern struct {
|
||||
.illumos => extern struct {
|
||||
flag1: u16 = 0,
|
||||
flag2: u8 = 0,
|
||||
ceiling: u8 = 0,
|
||||
|
|
@ -8025,7 +8015,7 @@ pub const pthread_cond_t = switch (native_os) {
|
|||
waiter_count: i32 = 0,
|
||||
lock: i32 = 0,
|
||||
},
|
||||
.solaris, .illumos => extern struct {
|
||||
.illumos => extern struct {
|
||||
flag: [4]u8 = [_]u8{0} ** 4,
|
||||
type: u16 = 0,
|
||||
magic: u16 = 0x4356,
|
||||
|
|
@ -8084,7 +8074,7 @@ pub const pthread_rwlock_t = switch (native_os) {
|
|||
owner: ?pthread_t = null,
|
||||
private: ?*anyopaque = null,
|
||||
},
|
||||
.solaris, .illumos => extern struct {
|
||||
.illumos => extern struct {
|
||||
readers: i32 = 0,
|
||||
type: u16 = 0,
|
||||
magic: u16 = 0x5257,
|
||||
|
|
@ -8118,7 +8108,7 @@ pub const pthread_attr_t = switch (native_os) {
|
|||
.freebsd, .openbsd, .serenity => extern struct {
|
||||
inner: ?*anyopaque = null,
|
||||
},
|
||||
.solaris, .illumos => extern struct {
|
||||
.illumos => extern struct {
|
||||
mutexattr: ?*anyopaque = null,
|
||||
},
|
||||
.netbsd => extern struct {
|
||||
|
|
@ -8140,7 +8130,7 @@ pub const pthread_key_t = switch (native_os) {
|
|||
.linux, .emscripten => c_uint,
|
||||
.macos, .ios, .tvos, .watchos, .visionos => c_ulong,
|
||||
// https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L65
|
||||
.openbsd, .solaris, .illumos, .serenity => c_int,
|
||||
.openbsd, .illumos, .serenity => c_int,
|
||||
else => void,
|
||||
};
|
||||
|
||||
|
|
@ -8180,7 +8170,7 @@ pub const sem_t = switch (native_os) {
|
|||
},
|
||||
_padding: u32,
|
||||
},
|
||||
.solaris, .illumos => extern struct {
|
||||
.illumos => extern struct {
|
||||
count: u32 = 0,
|
||||
type: u16 = 0,
|
||||
magic: u16 = 0x534d,
|
||||
|
|
@ -8271,12 +8261,12 @@ pub const Kevent = switch (native_os) {
|
|||
};
|
||||
|
||||
pub const port_t = switch (native_os) {
|
||||
.solaris, .illumos => c_int,
|
||||
.illumos => c_int,
|
||||
else => void,
|
||||
};
|
||||
|
||||
pub const port_event = switch (native_os) {
|
||||
.solaris, .illumos => extern struct {
|
||||
.illumos => extern struct {
|
||||
events: u32,
|
||||
/// Event source.
|
||||
source: u16,
|
||||
|
|
@ -8364,7 +8354,7 @@ pub const AT = switch (native_os) {
|
|||
pub const REMOVEDIR = 0x04;
|
||||
pub const EACCESS = 0x08;
|
||||
},
|
||||
.solaris, .illumos => struct {
|
||||
.illumos => struct {
|
||||
/// Magic value that specify the use of the current working directory
|
||||
/// to determine the target of relative file paths in the openat() and
|
||||
/// similar syscalls.
|
||||
|
|
@ -8461,7 +8451,7 @@ pub const O = switch (native_os) {
|
|||
// ignored in C code. Thus no mapping in Zig.
|
||||
_: u3 = 0,
|
||||
},
|
||||
.solaris, .illumos => packed struct(u32) {
|
||||
.illumos => packed struct(u32) {
|
||||
ACCMODE: std.posix.ACCMODE = .RDONLY,
|
||||
NDELAY: bool = false,
|
||||
APPEND: bool = false,
|
||||
|
|
@ -8672,7 +8662,7 @@ pub const MAP = switch (native_os) {
|
|||
FIXED_NOREPLACE: bool = false,
|
||||
_: u11 = 0,
|
||||
},
|
||||
.solaris, .illumos => packed struct(u32) {
|
||||
.illumos => packed struct(u32) {
|
||||
TYPE: enum(u4) {
|
||||
SHARED = 0x01,
|
||||
PRIVATE = 0x02,
|
||||
|
|
@ -8869,7 +8859,7 @@ pub const V = switch (native_os) {
|
|||
STOP,
|
||||
SUSP,
|
||||
},
|
||||
.solaris, .illumos => enum {
|
||||
.illumos => enum {
|
||||
INTR,
|
||||
QUIT,
|
||||
ERASE,
|
||||
|
|
@ -8936,7 +8926,7 @@ pub const NCCS = switch (native_os) {
|
|||
.linux => linux.NCCS,
|
||||
.macos, .ios, .tvos, .watchos, .visionos, .freebsd, .netbsd, .openbsd, .dragonfly => 20,
|
||||
.haiku => 11,
|
||||
.solaris, .illumos => 19,
|
||||
.illumos => 19,
|
||||
// https://github.com/SerenityOS/serenity/blob/d277cdfd4c7ed21d5248a83217ae03b9f890c3c8/Kernel/API/POSIX/termios.h#L15
|
||||
.emscripten, .wasi, .serenity => 32,
|
||||
else => void,
|
||||
|
|
@ -8973,7 +8963,7 @@ pub const termios = switch (native_os) {
|
|||
ospeed: speed_t,
|
||||
cc: [NCCS]cc_t,
|
||||
},
|
||||
.solaris, .illumos => extern struct {
|
||||
.illumos => extern struct {
|
||||
iflag: tc_iflag_t,
|
||||
oflag: tc_oflag_t,
|
||||
cflag: tc_cflag_t,
|
||||
|
|
@ -9063,7 +9053,7 @@ pub const tc_iflag_t = switch (native_os) {
|
|||
IXOFF: bool = false,
|
||||
_: u19 = 0,
|
||||
},
|
||||
.solaris, .illumos => packed struct(u32) {
|
||||
.illumos => packed struct(u32) {
|
||||
IGNBRK: bool = false,
|
||||
BRKINT: bool = false,
|
||||
IGNPAR: bool = false,
|
||||
|
|
@ -9156,7 +9146,7 @@ pub const tc_oflag_t = switch (native_os) {
|
|||
ONLRET: bool = false,
|
||||
_: u25 = 0,
|
||||
},
|
||||
.solaris, .illumos => packed struct(u32) {
|
||||
.illumos => packed struct(u32) {
|
||||
OPOST: bool = false,
|
||||
OLCUC: bool = false,
|
||||
ONLCR: bool = false,
|
||||
|
|
@ -9303,7 +9293,7 @@ pub const tc_cflag_t = switch (native_os) {
|
|||
RTSFLOW: bool = false,
|
||||
_: u17 = 0,
|
||||
},
|
||||
.solaris, .illumos => packed struct(u32) {
|
||||
.illumos => packed struct(u32) {
|
||||
_0: u4 = 0,
|
||||
CSIZE: CSIZE = .CS5,
|
||||
CSTOPB: bool = false,
|
||||
|
|
@ -9441,7 +9431,7 @@ pub const tc_lflag_t = switch (native_os) {
|
|||
PENDIN: bool = false,
|
||||
_: u17 = 0,
|
||||
},
|
||||
.solaris, .illumos => packed struct(u32) {
|
||||
.illumos => packed struct(u32) {
|
||||
ISIG: bool = false,
|
||||
ICANON: bool = false,
|
||||
XCASE: bool = false,
|
||||
|
|
@ -9609,7 +9599,7 @@ pub const speed_t = switch (native_os) {
|
|||
B230400 = 0x12,
|
||||
B31250 = 0x13,
|
||||
},
|
||||
.solaris, .illumos => enum(c_uint) {
|
||||
.illumos => enum(c_uint) {
|
||||
B0 = 0,
|
||||
B50 = 1,
|
||||
B75 = 2,
|
||||
|
|
@ -9696,7 +9686,7 @@ pub const NSIG = switch (native_os) {
|
|||
.haiku => 65,
|
||||
.netbsd, .freebsd => 32,
|
||||
.macos => darwin.NSIG,
|
||||
.solaris, .illumos => 75,
|
||||
.illumos => 75,
|
||||
// https://github.com/SerenityOS/serenity/blob/046c23f567a17758d762a33bdf04bacbfd088f9f/Kernel/API/POSIX/signal_numbers.h#L42
|
||||
.openbsd, .serenity => 33,
|
||||
else => {},
|
||||
|
|
@ -9709,7 +9699,7 @@ pub const MINSIGSTKSZ = switch (native_os) {
|
|||
.arm, .aarch64 => 4096,
|
||||
else => @compileError("unsupported arch"),
|
||||
},
|
||||
.solaris, .illumos => 2048,
|
||||
.illumos => 2048,
|
||||
.haiku, .netbsd => 8192,
|
||||
.openbsd => 1 << openbsd.MAX_PAGE_SHIFT,
|
||||
// https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/signal.h#L58
|
||||
|
|
@ -9719,7 +9709,7 @@ pub const MINSIGSTKSZ = switch (native_os) {
|
|||
pub const SIGSTKSZ = switch (native_os) {
|
||||
.macos, .ios, .tvos, .watchos, .visionos => 131072,
|
||||
.netbsd, .freebsd => MINSIGSTKSZ + 32768,
|
||||
.solaris, .illumos => 8192,
|
||||
.illumos => 8192,
|
||||
.haiku => 16384,
|
||||
.openbsd => MINSIGSTKSZ + (1 << openbsd.MAX_PAGE_SHIFT) * 4,
|
||||
// https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/signal.h#L59
|
||||
|
|
@ -9733,7 +9723,7 @@ pub const SS = switch (native_os) {
|
|||
pub const DISABLE = 4;
|
||||
},
|
||||
// https://github.com/SerenityOS/serenity/blob/ec492a1a0819e6239ea44156825c4ee7234ca3db/Kernel/API/POSIX/signal.h#L54-L55
|
||||
.haiku, .solaris, .illumos, .serenity => struct {
|
||||
.haiku, .illumos, .serenity => struct {
|
||||
pub const ONSTACK = 0x1;
|
||||
pub const DISABLE = 0x2;
|
||||
},
|
||||
|
|
@ -10314,7 +10304,7 @@ pub extern "c" fn setrlimit64(resource: rlimit_resource, rlim: *const rlimit) c_
|
|||
|
||||
pub const arc4random_buf = switch (native_os) {
|
||||
.linux => if (builtin.abi.isAndroid()) private.arc4random_buf else {},
|
||||
.dragonfly, .netbsd, .freebsd, .solaris, .illumos, .openbsd, .serenity, .macos, .ios, .tvos, .watchos, .visionos => private.arc4random_buf,
|
||||
.dragonfly, .netbsd, .freebsd, .illumos, .openbsd, .serenity, .macos, .ios, .tvos, .watchos, .visionos => private.arc4random_buf,
|
||||
else => {},
|
||||
};
|
||||
pub const getentropy = switch (native_os) {
|
||||
|
|
@ -10383,7 +10373,7 @@ pub const sigaltstack = switch (native_os) {
|
|||
|
||||
pub extern "c" fn memfd_create(name: [*:0]const u8, flags: c_uint) c_int;
|
||||
pub const pipe2 = switch (native_os) {
|
||||
.dragonfly, .emscripten, .netbsd, .freebsd, .solaris, .illumos, .openbsd, .linux, .serenity => private.pipe2,
|
||||
.dragonfly, .emscripten, .netbsd, .freebsd, .illumos, .openbsd, .linux, .serenity => private.pipe2,
|
||||
else => {},
|
||||
};
|
||||
pub const copy_file_range = switch (native_os) {
|
||||
|
|
@ -10443,12 +10433,12 @@ pub const munlock = switch (native_os) {
|
|||
};
|
||||
|
||||
pub const mlockall = switch (native_os) {
|
||||
.linux, .freebsd, .dragonfly, .netbsd, .openbsd, .solaris, .illumos => private.mlockall,
|
||||
.linux, .freebsd, .dragonfly, .netbsd, .openbsd, .illumos => private.mlockall,
|
||||
else => {},
|
||||
};
|
||||
|
||||
pub const munlockall = switch (native_os) {
|
||||
.linux, .freebsd, .dragonfly, .netbsd, .openbsd, .solaris, .illumos => private.munlockall,
|
||||
.linux, .freebsd, .dragonfly, .netbsd, .openbsd, .illumos => private.munlockall,
|
||||
else => {},
|
||||
};
|
||||
|
||||
|
|
@ -10491,7 +10481,7 @@ pub fn sigrtmin() u8 {
|
|||
return switch (native_os) {
|
||||
.freebsd => 65,
|
||||
.netbsd => 33,
|
||||
.solaris, .illumos => @truncate(sysconf(@intFromEnum(_SC.SIGRT_MIN))),
|
||||
.illumos => @truncate(sysconf(@intFromEnum(_SC.SIGRT_MIN))),
|
||||
else => @truncate(@as(c_uint, @bitCast(private.__libc_current_sigrtmin()))),
|
||||
};
|
||||
}
|
||||
|
|
@ -10501,7 +10491,7 @@ pub fn sigrtmax() u8 {
|
|||
return switch (native_os) {
|
||||
.freebsd => 126,
|
||||
.netbsd => 63,
|
||||
.solaris, .illumos => @truncate(sysconf(@intFromEnum(_SC.SIGRT_MAX))),
|
||||
.illumos => @truncate(sysconf(@intFromEnum(_SC.SIGRT_MAX))),
|
||||
else => @truncate(@as(c_uint, @bitCast(private.__libc_current_sigrtmax()))),
|
||||
};
|
||||
}
|
||||
|
|
@ -10556,11 +10546,11 @@ pub const malloc_usable_size = switch (native_os) {
|
|||
else => {},
|
||||
};
|
||||
pub const posix_memalign = switch (native_os) {
|
||||
.dragonfly, .netbsd, .freebsd, .solaris, .openbsd, .linux, .macos, .ios, .tvos, .watchos, .visionos, .serenity => private.posix_memalign,
|
||||
.dragonfly, .netbsd, .freebsd, .illumos, .openbsd, .linux, .macos, .ios, .tvos, .watchos, .visionos, .serenity => private.posix_memalign,
|
||||
else => {},
|
||||
};
|
||||
pub const sysconf = switch (native_os) {
|
||||
.solaris => solaris.sysconf,
|
||||
.illumos => illumos.sysconf,
|
||||
else => private.sysconf,
|
||||
};
|
||||
|
||||
|
|
@ -10629,7 +10619,6 @@ pub const fork = switch (native_os) {
|
|||
.macos,
|
||||
.netbsd,
|
||||
.openbsd,
|
||||
.solaris,
|
||||
.illumos,
|
||||
.tvos,
|
||||
.watchos,
|
||||
|
|
@ -10777,7 +10766,7 @@ pub extern "c" fn pthread_setspecific(key: pthread_key_t, value: ?*anyopaque) c_
|
|||
pub extern "c" fn pthread_sigmask(how: c_int, set: *const sigset_t, oldset: *sigset_t) c_int;
|
||||
pub const pthread_setname_np = switch (native_os) {
|
||||
.macos, .ios, .tvos, .watchos, .visionos => darwin.pthread_setname_np,
|
||||
.solaris, .illumos => solaris.pthread_setname_np,
|
||||
.illumos => illumos.pthread_setname_np,
|
||||
.netbsd => netbsd.pthread_setname_np,
|
||||
else => private.pthread_setname_np,
|
||||
};
|
||||
|
|
@ -10987,33 +10976,33 @@ pub extern "c" fn pthread_get_name_np(thread: pthread_t, name: [*:0]u8, len: usi
|
|||
// OS-specific bits. These are protected from being used on the wrong OS by
|
||||
// comptime assertions inside each OS-specific file.
|
||||
|
||||
pub const AF_SUN = solaris.AF_SUN;
|
||||
pub const AT_SUN = solaris.AT_SUN;
|
||||
pub const FILE_EVENT = solaris.FILE_EVENT;
|
||||
pub const GETCONTEXT = solaris.GETCONTEXT;
|
||||
pub const GETUSTACK = solaris.GETUSTACK;
|
||||
pub const PORT_ALERT = solaris.PORT_ALERT;
|
||||
pub const PORT_SOURCE = solaris.PORT_SOURCE;
|
||||
pub const POSIX_FADV = solaris.POSIX_FADV;
|
||||
pub const SETCONTEXT = solaris.SETCONTEXT;
|
||||
pub const SETUSTACK = solaris.GETUSTACK;
|
||||
pub const SFD = solaris.SFD;
|
||||
pub const ctid_t = solaris.ctid_t;
|
||||
pub const file_obj = solaris.file_obj;
|
||||
pub const id_t = solaris.id_t;
|
||||
pub const lif_ifinfo_req = solaris.lif_ifinfo_req;
|
||||
pub const lif_nd_req = solaris.lif_nd_req;
|
||||
pub const lifreq = solaris.lifreq;
|
||||
pub const major_t = solaris.major_t;
|
||||
pub const minor_t = solaris.minor_t;
|
||||
pub const poolid_t = solaris.poolid_t;
|
||||
pub const port_notify = solaris.port_notify;
|
||||
pub const priority = solaris.priority;
|
||||
pub const procfs = solaris.procfs;
|
||||
pub const projid_t = solaris.projid_t;
|
||||
pub const signalfd_siginfo = solaris.signalfd_siginfo;
|
||||
pub const taskid_t = solaris.taskid_t;
|
||||
pub const zoneid_t = solaris.zoneid_t;
|
||||
pub const AF_SUN = illumos.AF_SUN;
|
||||
pub const AT_SUN = illumos.AT_SUN;
|
||||
pub const FILE_EVENT = illumos.FILE_EVENT;
|
||||
pub const GETCONTEXT = illumos.GETCONTEXT;
|
||||
pub const GETUSTACK = illumos.GETUSTACK;
|
||||
pub const PORT_ALERT = illumos.PORT_ALERT;
|
||||
pub const PORT_SOURCE = illumos.PORT_SOURCE;
|
||||
pub const POSIX_FADV = illumos.POSIX_FADV;
|
||||
pub const SETCONTEXT = illumos.SETCONTEXT;
|
||||
pub const SETUSTACK = illumos.GETUSTACK;
|
||||
pub const SFD = illumos.SFD;
|
||||
pub const ctid_t = illumos.ctid_t;
|
||||
pub const file_obj = illumos.file_obj;
|
||||
pub const id_t = illumos.id_t;
|
||||
pub const lif_ifinfo_req = illumos.lif_ifinfo_req;
|
||||
pub const lif_nd_req = illumos.lif_nd_req;
|
||||
pub const lifreq = illumos.lifreq;
|
||||
pub const major_t = illumos.major_t;
|
||||
pub const minor_t = illumos.minor_t;
|
||||
pub const poolid_t = illumos.poolid_t;
|
||||
pub const port_notify = illumos.port_notify;
|
||||
pub const priority = illumos.priority;
|
||||
pub const procfs = illumos.procfs;
|
||||
pub const projid_t = illumos.projid_t;
|
||||
pub const signalfd_siginfo = illumos.signalfd_siginfo;
|
||||
pub const taskid_t = illumos.taskid_t;
|
||||
pub const zoneid_t = illumos.zoneid_t;
|
||||
|
||||
pub const DirEnt = haiku.DirEnt;
|
||||
pub const _get_next_area_info = haiku._get_next_area_info;
|
||||
|
|
@ -11361,7 +11350,7 @@ const private = struct {
|
|||
extern "c" fn getdirentries(fd: fd_t, buf_ptr: [*]u8, nbytes: usize, basep: *i64) isize;
|
||||
extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) switch (native_os) {
|
||||
.freebsd => isize,
|
||||
.solaris, .illumos => usize,
|
||||
.illumos => usize,
|
||||
else => c_int,
|
||||
};
|
||||
extern "c" fn getrusage(who: c_int, usage: *rusage) c_int;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ const uid_t = std.c.uid_t;
|
|||
const IFNAMESIZE = std.c.IFNAMESIZE;
|
||||
|
||||
comptime {
|
||||
assert(builtin.os.tag == .solaris or builtin.os.tag == .illumos); // Prevent access of std.c symbols on wrong OS.
|
||||
assert(builtin.os.tag == .illumos); // Prevent access of std.c symbols on wrong OS.
|
||||
}
|
||||
|
||||
pub extern "c" fn pthread_setname_np(thread: pthread_t, name: [*:0]const u8, arg: ?*anyopaque) c_int;
|
||||
|
|
@ -63,7 +63,7 @@ pub fn rescan(cb: *Bundle, gpa: Allocator) RescanError!void {
|
|||
.freebsd, .openbsd => return rescanWithPath(cb, gpa, "/etc/ssl/cert.pem"),
|
||||
.netbsd => return rescanWithPath(cb, gpa, "/etc/openssl/certs/ca-certificates.crt"),
|
||||
.dragonfly => return rescanWithPath(cb, gpa, "/usr/local/etc/ssl/cert.pem"),
|
||||
.solaris, .illumos => return rescanWithPath(cb, gpa, "/etc/ssl/cacert.pem"),
|
||||
.illumos => return rescanWithPath(cb, gpa, "/etc/ssl/cacert.pem"),
|
||||
.haiku => return rescanWithPath(cb, gpa, "/boot/system/data/ssl/CARootCertificates.pem"),
|
||||
// https://github.com/SerenityOS/serenity/blob/222acc9d389bc6b490d4c39539761b043a4bfcb0/Ports/ca-certificates/package.sh#L19
|
||||
.serenity => return rescanWithPath(cb, gpa, "/etc/ssl/certs/ca-certificates.crt"),
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ else switch (std.Target.ObjectFormat.default(native_os, native_arch)) {
|
|||
else => @import("debug/SelfInfo/Elf.zig"),
|
||||
},
|
||||
.macho => @import("debug/SelfInfo/MachO.zig"),
|
||||
.goff, .plan9, .spirv, .wasm, .xcoff => void,
|
||||
.plan9, .spirv, .wasm => void,
|
||||
.c, .hex, .raw => unreachable,
|
||||
};
|
||||
|
||||
|
|
@ -1368,7 +1368,6 @@ pub const have_segfault_handling_support = switch (native_os) {
|
|||
.watchos,
|
||||
|
||||
.illumos,
|
||||
.solaris,
|
||||
|
||||
.windows,
|
||||
=> true,
|
||||
|
|
@ -1471,7 +1470,6 @@ fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopa
|
|||
.openbsd,
|
||||
=> @intFromPtr(info.data.fault.addr),
|
||||
.illumos,
|
||||
.solaris,
|
||||
=> @intFromPtr(info.reason.fault.addr),
|
||||
else => comptime unreachable,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -160,9 +160,6 @@ pub const can_unwind: bool = s: {
|
|||
.x86,
|
||||
.x86_64,
|
||||
},
|
||||
.solaris => &.{
|
||||
.x86_64,
|
||||
},
|
||||
|
||||
else => unreachable,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -961,7 +961,6 @@ const Powerpc = extern struct {
|
|||
// * System V Application Binary Interface - PowerPC Processor Supplement §3-46
|
||||
// * Power Architecture 32-bit Application Binary Interface Supplement 1.0 - Linux & Embedded §3.4
|
||||
// * 64-bit ELF V2 ABI Specification - Power Architecture Revision 1.5 §2.4
|
||||
// * ??? AIX?
|
||||
//
|
||||
// Are we having fun yet?
|
||||
|
||||
|
|
@ -1936,40 +1935,6 @@ const signal_ucontext_t = switch (native_os) {
|
|||
else => unreachable,
|
||||
},
|
||||
},
|
||||
// This needs to be audited by someone with access to the Solaris headers.
|
||||
.solaris => switch (native_arch) {
|
||||
.sparc64 => @compileError("sparc64-solaris ucontext_t missing"),
|
||||
.x86_64 => extern struct {
|
||||
_flags: u64,
|
||||
_link: ?*signal_ucontext_t,
|
||||
_sigmask: std.c.sigset_t,
|
||||
_stack: std.c.stack_t,
|
||||
mcontext: extern struct {
|
||||
r15: u64,
|
||||
r14: u64,
|
||||
r13: u64,
|
||||
r12: u64,
|
||||
r11: u64,
|
||||
r10: u64,
|
||||
r9: u64,
|
||||
r8: u64,
|
||||
rdi: u64,
|
||||
rsi: u64,
|
||||
rbp: u64,
|
||||
rbx: u64,
|
||||
rdx: u64,
|
||||
rcx: u64,
|
||||
rax: u64,
|
||||
_trapno: i64,
|
||||
_err: i64,
|
||||
rip: u64,
|
||||
_cs: i64,
|
||||
_rflags: i64,
|
||||
rsp: u64,
|
||||
},
|
||||
},
|
||||
else => unreachable,
|
||||
},
|
||||
// https://github.com/illumos/illumos-gate/blob/d4ce137bba3bd16823db6374d9e9a643264ce245/usr/src/uts/intel/sys/ucontext.h
|
||||
.illumos => extern struct {
|
||||
_flags: usize,
|
||||
|
|
@ -1997,7 +1962,7 @@ const signal_ucontext_t = switch (native_os) {
|
|||
},
|
||||
// https://github.com/illumos/illumos-gate/blob/d4ce137bba3bd16823db6374d9e9a643264ce245/usr/src/uts/intel/sys/mcontext.h
|
||||
.x86_64 => extern struct {
|
||||
r15: u64,
|
||||
r15: u64 align(16),
|
||||
r14: u64,
|
||||
r13: u64,
|
||||
r12: u64,
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ pub const DynLib = struct {
|
|||
else
|
||||
DlDynLib,
|
||||
.windows => WindowsDynLib,
|
||||
.macos, .tvos, .watchos, .ios, .visionos, .freebsd, .netbsd, .openbsd, .dragonfly, .solaris, .illumos => DlDynLib,
|
||||
.macos, .tvos, .watchos, .ios, .visionos, .freebsd, .netbsd, .openbsd, .dragonfly, .illumos => DlDynLib,
|
||||
else => struct {
|
||||
const open = @compileError("unsupported platform");
|
||||
const openZ = @compileError("unsupported platform");
|
||||
|
|
@ -672,7 +672,7 @@ pub const DlDynLib = struct {
|
|||
|
||||
test "dynamic_library" {
|
||||
const libname = switch (native_os) {
|
||||
.linux, .freebsd, .openbsd, .solaris, .illumos => "invalid_so.so",
|
||||
.linux, .freebsd, .openbsd, .illumos => "invalid_so.so",
|
||||
.windows => "invalid_dll.dll",
|
||||
.macos, .tvos, .watchos, .ios, .visionos => "invalid_dylib.dylib",
|
||||
else => return error.SkipZigTest,
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ pub const GetAppDataDirError = @import("fs/get_app_data_dir.zig").GetAppDataDirE
|
|||
/// * On other platforms, `[]u8` file paths are opaque sequences of bytes with
|
||||
/// no particular encoding.
|
||||
pub const max_path_bytes = switch (native_os) {
|
||||
.linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .haiku, .solaris, .illumos, .plan9, .emscripten, .wasi, .serenity => posix.PATH_MAX,
|
||||
.linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .haiku, .illumos, .plan9, .emscripten, .wasi, .serenity => posix.PATH_MAX,
|
||||
// Each WTF-16LE code unit may be expanded to 3 WTF-8 bytes.
|
||||
// If it would require 4 WTF-8 bytes, then there would be a surrogate
|
||||
// pair in the WTF-16LE, and we (over)account 3 bytes for it that way.
|
||||
|
|
@ -72,7 +72,7 @@ pub const max_path_bytes = switch (native_os) {
|
|||
/// On WASI, file name components are encoded as valid UTF-8.
|
||||
/// On other platforms, `[]u8` components are an opaque sequence of bytes with no particular encoding.
|
||||
pub const max_name_bytes = switch (native_os) {
|
||||
.linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .solaris, .illumos, .serenity => posix.NAME_MAX,
|
||||
.linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .illumos, .serenity => posix.NAME_MAX,
|
||||
// Haiku's NAME_MAX includes the null terminator, so subtract one.
|
||||
.haiku => posix.NAME_MAX - 1,
|
||||
// Each WTF-16LE character may be expanded to 3 WTF-8 bytes.
|
||||
|
|
@ -571,7 +571,7 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
|
|||
error.NetworkNotFound => unreachable, // Windows-only
|
||||
else => |e| return e,
|
||||
},
|
||||
.solaris, .illumos => return posix.readlinkZ("/proc/self/path/a.out", out_buffer) catch |err| switch (err) {
|
||||
.illumos => return posix.readlinkZ("/proc/self/path/a.out", out_buffer) catch |err| switch (err) {
|
||||
error.InvalidUtf8 => unreachable, // WASI-only
|
||||
error.InvalidWtf8 => unreachable, // Windows-only
|
||||
error.UnsupportedReparsePointType => unreachable, // Windows-only
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ const IteratorError = error{
|
|||
} || posix.UnexpectedError;
|
||||
|
||||
pub const Iterator = switch (native_os) {
|
||||
.macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris, .illumos => struct {
|
||||
.macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .illumos => struct {
|
||||
dir: Dir,
|
||||
seek: i64,
|
||||
buf: [1024]u8 align(@alignOf(posix.system.dirent)),
|
||||
|
|
@ -57,7 +57,7 @@ pub const Iterator = switch (native_os) {
|
|||
switch (native_os) {
|
||||
.macos, .ios => return self.nextDarwin(),
|
||||
.freebsd, .netbsd, .dragonfly, .openbsd => return self.nextBsd(),
|
||||
.solaris, .illumos => return self.nextSolaris(),
|
||||
.illumos => return self.nextIllumos(),
|
||||
else => @compileError("unimplemented"),
|
||||
}
|
||||
}
|
||||
|
|
@ -116,7 +116,7 @@ pub const Iterator = switch (native_os) {
|
|||
}
|
||||
}
|
||||
|
||||
fn nextSolaris(self: *Self) !?Entry {
|
||||
fn nextIllumos(self: *Self) !?Entry {
|
||||
start_over: while (true) {
|
||||
if (self.index >= self.end_index) {
|
||||
if (self.first_iter) {
|
||||
|
|
@ -144,7 +144,7 @@ pub const Iterator = switch (native_os) {
|
|||
if (mem.eql(u8, name, ".") or mem.eql(u8, name, ".."))
|
||||
continue :start_over;
|
||||
|
||||
// Solaris dirent doesn't expose type, so we have to call stat to get it.
|
||||
// illumos dirent doesn't expose type, so we have to call stat to get it.
|
||||
const stat_info = posix.fstatat(
|
||||
self.dir.fd,
|
||||
name,
|
||||
|
|
@ -619,7 +619,6 @@ fn iterateImpl(self: Dir, first_iter_start_value: bool) Iterator {
|
|||
.netbsd,
|
||||
.dragonfly,
|
||||
.openbsd,
|
||||
.solaris,
|
||||
.illumos,
|
||||
=> return Iterator{
|
||||
.dir = self,
|
||||
|
|
@ -1770,7 +1769,7 @@ pub fn deleteFileZ(self: Dir, sub_path_c: [*:0]const u8) DeleteFileError!void {
|
|||
error.AccessDenied, error.PermissionDenied => |e| switch (native_os) {
|
||||
// non-Linux POSIX systems return permission errors when trying to delete a
|
||||
// directory, so we need to handle that case specifically and translate the error
|
||||
.macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris, .illumos => {
|
||||
.macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .illumos => {
|
||||
// Don't follow symlinks to match unlinkat (which acts on symlinks rather than follows them)
|
||||
const fstat = posix.fstatatZ(self.fd, sub_path_c, posix.AT.SYMLINK_NOFOLLOW) catch return e;
|
||||
const is_dir = fstat.mode & posix.S.IFMT == posix.S.IFDIR;
|
||||
|
|
|
|||
|
|
@ -444,7 +444,7 @@ pub const Stat = struct {
|
|||
posix.S.IFSOCK => break :k .unix_domain_socket,
|
||||
else => {},
|
||||
}
|
||||
if (builtin.os.tag.isSolarish()) switch (m) {
|
||||
if (builtin.os.tag == .illumos) switch (m) {
|
||||
posix.S.IFDOOR => break :k .door,
|
||||
posix.S.IFPORT => break :k .event_port,
|
||||
else => {},
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ pub fn getAppDataDir(allocator: mem.Allocator, appname: []const u8) GetAppDataDi
|
|||
};
|
||||
return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname });
|
||||
},
|
||||
.linux, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris, .illumos, .serenity => {
|
||||
.linux, .freebsd, .netbsd, .dragonfly, .openbsd, .illumos, .serenity => {
|
||||
if (posix.getenv("XDG_DATA_HOME")) |xdg| {
|
||||
if (xdg.len > 0) {
|
||||
return fs.path.join(allocator, &[_][]const u8{ xdg, appname });
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ const CAllocator = struct {
|
|||
else {};
|
||||
|
||||
pub const supports_posix_memalign = switch (builtin.os.tag) {
|
||||
.dragonfly, .netbsd, .freebsd, .solaris, .openbsd, .linux, .macos, .ios, .tvos, .watchos, .visionos, .serenity => true,
|
||||
.dragonfly, .netbsd, .freebsd, .illumos, .openbsd, .linux, .macos, .ios, .tvos, .watchos, .visionos, .serenity => true,
|
||||
else => false,
|
||||
};
|
||||
|
||||
|
|
@ -768,7 +768,7 @@ const page_size_min_default: ?usize = switch (builtin.os.tag) {
|
|||
.sparc64 => 8 << 10,
|
||||
else => null,
|
||||
},
|
||||
.solaris, .illumos => switch (builtin.cpu.arch) {
|
||||
.illumos => switch (builtin.cpu.arch) {
|
||||
// src/uts/*/sys/machparam.h
|
||||
.x86, .x86_64 => 4 << 10,
|
||||
.sparc, .sparc64 => 8 << 10,
|
||||
|
|
@ -926,7 +926,7 @@ const page_size_max_default: ?usize = switch (builtin.os.tag) {
|
|||
.sparc64 => 8 << 10,
|
||||
else => null,
|
||||
},
|
||||
.solaris, .illumos => switch (builtin.cpu.arch) {
|
||||
.illumos => switch (builtin.cpu.arch) {
|
||||
// src/uts/*/sys/machparam.h
|
||||
.x86, .x86_64 => 4 << 10,
|
||||
.sparc, .sparc64 => 8 << 10,
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@
|
|||
//! versa.
|
||||
//!
|
||||
//! When a bucket is full, a new one is allocated, containing a pointer to the
|
||||
//! previous one. This singly-linked list is iterated during leak detection.
|
||||
//! previous one. This doubly-linked list is iterated during leak detection.
|
||||
//!
|
||||
//! Resizing and remapping work the same on small allocations: if the size
|
||||
//! class would not change, then the operation succeeds, and the address is
|
||||
|
|
|
|||
|
|
@ -80,7 +80,6 @@ pub fn isGetFdPathSupportedOnTarget(os: std.Target.Os) bool {
|
|||
.tvos,
|
||||
.visionos,
|
||||
.linux,
|
||||
.solaris,
|
||||
.illumos,
|
||||
.freebsd,
|
||||
.serenity,
|
||||
|
|
@ -147,7 +146,7 @@ pub fn getFdPath(fd: std.posix.fd_t, out_buffer: *[max_path_bytes]u8) std.posix.
|
|||
};
|
||||
return target;
|
||||
},
|
||||
.solaris, .illumos => {
|
||||
.illumos => {
|
||||
var procfs_buf: ["/proc/self/path/-2147483648\x00".len]u8 = undefined;
|
||||
const proc_path = std.fmt.bufPrintSentinel(procfs_buf[0..], "/proc/self/path/{d}", .{fd}, 0) catch unreachable;
|
||||
|
||||
|
|
|
|||
|
|
@ -4634,25 +4634,28 @@ pub const TEB = extern struct {
|
|||
};
|
||||
|
||||
comptime {
|
||||
// Offsets taken from WinDbg info and Geoff Chappell[1] (RIP)
|
||||
// [1]: https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/pebteb/teb/index.htm
|
||||
assert(@offsetOf(TEB, "NtTib") == 0x00);
|
||||
if (@sizeOf(usize) == 4) {
|
||||
assert(@offsetOf(TEB, "EnvironmentPointer") == 0x1C);
|
||||
assert(@offsetOf(TEB, "ClientId") == 0x20);
|
||||
assert(@offsetOf(TEB, "ActiveRpcHandle") == 0x28);
|
||||
assert(@offsetOf(TEB, "ThreadLocalStoragePointer") == 0x2C);
|
||||
assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x30);
|
||||
assert(@offsetOf(TEB, "LastErrorValue") == 0x34);
|
||||
assert(@offsetOf(TEB, "TlsSlots") == 0xe10);
|
||||
} else if (@sizeOf(usize) == 8) {
|
||||
assert(@offsetOf(TEB, "EnvironmentPointer") == 0x38);
|
||||
assert(@offsetOf(TEB, "ClientId") == 0x40);
|
||||
assert(@offsetOf(TEB, "ActiveRpcHandle") == 0x50);
|
||||
assert(@offsetOf(TEB, "ThreadLocalStoragePointer") == 0x58);
|
||||
assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x60);
|
||||
assert(@offsetOf(TEB, "LastErrorValue") == 0x68);
|
||||
assert(@offsetOf(TEB, "TlsSlots") == 0x1480);
|
||||
// XXX: Without this check we cannot use `std.Io.Writer` on 16-bit platforms. `std.fmt.bufPrint` will hit the unreachable in `PEB.GdiHandleBuffer` without this guard.
|
||||
if (builtin.os.tag == .windows) {
|
||||
// Offsets taken from WinDbg info and Geoff Chappell[1] (RIP)
|
||||
// [1]: https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/pebteb/teb/index.htm
|
||||
assert(@offsetOf(TEB, "NtTib") == 0x00);
|
||||
if (@sizeOf(usize) == 4) {
|
||||
assert(@offsetOf(TEB, "EnvironmentPointer") == 0x1C);
|
||||
assert(@offsetOf(TEB, "ClientId") == 0x20);
|
||||
assert(@offsetOf(TEB, "ActiveRpcHandle") == 0x28);
|
||||
assert(@offsetOf(TEB, "ThreadLocalStoragePointer") == 0x2C);
|
||||
assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x30);
|
||||
assert(@offsetOf(TEB, "LastErrorValue") == 0x34);
|
||||
assert(@offsetOf(TEB, "TlsSlots") == 0xe10);
|
||||
} else if (@sizeOf(usize) == 8) {
|
||||
assert(@offsetOf(TEB, "EnvironmentPointer") == 0x38);
|
||||
assert(@offsetOf(TEB, "ClientId") == 0x40);
|
||||
assert(@offsetOf(TEB, "ActiveRpcHandle") == 0x50);
|
||||
assert(@offsetOf(TEB, "ThreadLocalStoragePointer") == 0x58);
|
||||
assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x60);
|
||||
assert(@offsetOf(TEB, "LastErrorValue") == 0x68);
|
||||
assert(@offsetOf(TEB, "TlsSlots") == 0x1480);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6035,7 +6035,7 @@ pub fn sigaction(sig: u8, noalias act: ?*const Sigaction, noalias oact: ?*Sigact
|
|||
switch (errno(system.sigaction(sig, act, oact))) {
|
||||
.SUCCESS => return,
|
||||
// EINVAL means the signal is either invalid or some signal that cannot have its action
|
||||
// changed. For POSIX, this means SIGKILL/SIGSTOP. For e.g. Solaris, this also includes the
|
||||
// changed. For POSIX, this means SIGKILL/SIGSTOP. For e.g. illumos, this also includes the
|
||||
// non-standard SIGWAITING, SIGCANCEL, and SIGLWP. Either way, programmer error.
|
||||
.INVAL => unreachable,
|
||||
else => unreachable,
|
||||
|
|
@ -7414,7 +7414,6 @@ pub fn ptrace(request: u32, pid: pid_t, addr: usize, data: usize) PtraceError!vo
|
|||
.wasi,
|
||||
.emscripten,
|
||||
.haiku,
|
||||
.solaris,
|
||||
.illumos,
|
||||
.plan9,
|
||||
=> @compileError("ptrace unsupported by target OS"),
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ test "linkat with different directories" {
|
|||
if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; // `nstat.nlink` assertion is failing with LLVM 20+ for unclear reasons.
|
||||
|
||||
switch (native_os) {
|
||||
.wasi, .linux, .solaris, .illumos => {},
|
||||
.wasi, .linux, .illumos => {},
|
||||
else => return error.SkipZigTest,
|
||||
}
|
||||
|
||||
|
|
@ -558,7 +558,7 @@ test "fcntl" {
|
|||
|
||||
test "signalfd" {
|
||||
switch (native_os) {
|
||||
.linux, .solaris, .illumos => {},
|
||||
.linux, .illumos => {},
|
||||
else => return error.SkipZigTest,
|
||||
}
|
||||
_ = &posix.signalfd;
|
||||
|
|
@ -577,7 +577,7 @@ test "sync" {
|
|||
|
||||
test "fsync" {
|
||||
switch (native_os) {
|
||||
.linux, .windows, .solaris, .illumos => {},
|
||||
.linux, .windows, .illumos => {},
|
||||
else => return error.SkipZigTest,
|
||||
}
|
||||
|
||||
|
|
@ -708,7 +708,7 @@ test "sigset add/del" {
|
|||
|
||||
test "dup & dup2" {
|
||||
switch (native_os) {
|
||||
.linux, .solaris, .illumos => {},
|
||||
.linux, .illumos => {},
|
||||
else => return error.SkipZigTest,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1539,7 +1539,6 @@ pub fn getUserInfo(name: []const u8) !UserInfo {
|
|||
.netbsd,
|
||||
.openbsd,
|
||||
.haiku,
|
||||
.solaris,
|
||||
.illumos,
|
||||
.serenity,
|
||||
=> posixGetUserInfo(name),
|
||||
|
|
|
|||
|
|
@ -761,7 +761,7 @@ fn maybeIgnoreSigpipe() void {
|
|||
const have_sigpipe_support = switch (builtin.os.tag) {
|
||||
.linux,
|
||||
.plan9,
|
||||
.solaris,
|
||||
.illumos,
|
||||
.netbsd,
|
||||
.openbsd,
|
||||
.haiku,
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ pub fn binNameAlloc(allocator: Allocator, options: BinNameOptions) error{OutOfMe
|
|||
},
|
||||
.Obj => return std.fmt.allocPrint(allocator, "{s}.obj", .{root_name}),
|
||||
},
|
||||
.elf, .goff, .xcoff => switch (options.output_mode) {
|
||||
.elf => switch (options.output_mode) {
|
||||
.Exe => return allocator.dupe(u8, root_name),
|
||||
.Lib => {
|
||||
switch (options.link_mode orelse .static) {
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation {
|
|||
try self.findNativeIncludeDirPosix(args);
|
||||
try self.findNativeGccDirHaiku(args);
|
||||
self.crt_dir = try args.allocator.dupeZ(u8, "/system/develop/lib");
|
||||
} else if (builtin.target.os.tag.isSolarish()) {
|
||||
} else if (builtin.target.os.tag == .illumos) {
|
||||
// There is only one libc, and its headers/libraries are always in the same spot.
|
||||
self.include_dir = try args.allocator.dupeZ(u8, "/usr/include");
|
||||
self.sys_include_dir = try args.allocator.dupeZ(u8, "/usr/include");
|
||||
|
|
@ -935,7 +935,7 @@ pub const CrtBasenames = struct {
|
|||
.crtn = "crtn.o",
|
||||
},
|
||||
},
|
||||
.solaris, .illumos => switch (mode) {
|
||||
.illumos => switch (mode) {
|
||||
.dynamic_lib => .{
|
||||
.crti = "crti.o",
|
||||
.crtn = "crtn.o",
|
||||
|
|
|
|||
|
|
@ -215,25 +215,17 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
|
|||
var os = query_os_tag.defaultVersionRange(query_cpu_arch, query_abi);
|
||||
if (query.os_tag == null) {
|
||||
switch (builtin.target.os.tag) {
|
||||
.linux => {
|
||||
.linux, .illumos => {
|
||||
const uts = posix.uname();
|
||||
const release = mem.sliceTo(&uts.release, 0);
|
||||
// The release field sometimes has a weird format,
|
||||
// `Version.parse` will attempt to find some meaningful interpretation.
|
||||
if (std.SemanticVersion.parse(release)) |ver| {
|
||||
os.version_range.linux.range.min = ver;
|
||||
os.version_range.linux.range.max = ver;
|
||||
} else |err| switch (err) {
|
||||
error.Overflow => {},
|
||||
error.InvalidVersion => {},
|
||||
}
|
||||
},
|
||||
.solaris, .illumos => {
|
||||
const uts = posix.uname();
|
||||
const release = mem.sliceTo(&uts.release, 0);
|
||||
if (std.SemanticVersion.parse(release)) |ver| {
|
||||
os.version_range.semver.min = ver;
|
||||
os.version_range.semver.max = ver;
|
||||
var stripped = ver;
|
||||
stripped.pre = null;
|
||||
stripped.build = null;
|
||||
os.version_range.linux.range.min = stripped;
|
||||
os.version_range.linux.range.max = stripped;
|
||||
} else |err| switch (err) {
|
||||
error.Overflow => {},
|
||||
error.InvalidVersion => {},
|
||||
|
|
@ -307,10 +299,9 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
|
|||
posix.CTL.KERN,
|
||||
posix.KERN.OSRELEASE,
|
||||
};
|
||||
var buf: [64]u8 = undefined;
|
||||
var buf: [64:0]u8 = undefined;
|
||||
// consider that sysctl result includes null-termination
|
||||
// reserve 1 byte to ensure we never overflow when appending ".0"
|
||||
var len: usize = buf.len - 1;
|
||||
var len: usize = buf.len + 1;
|
||||
|
||||
posix.sysctl(&mib, &buf, &len, null, 0) catch |err| switch (err) {
|
||||
error.NameTooLong => unreachable, // constant, known good value
|
||||
|
|
@ -320,12 +311,9 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
|
|||
error.Unexpected => return error.OSVersionDetectionFail,
|
||||
};
|
||||
|
||||
// append ".0" to satisfy semver
|
||||
buf[len - 1] = '.';
|
||||
buf[len] = '0';
|
||||
len += 1;
|
||||
|
||||
if (std.SemanticVersion.parse(buf[0..len])) |ver| {
|
||||
if (Target.Query.parseVersion(buf[0..len :0])) |ver| {
|
||||
assert(ver.build == null);
|
||||
assert(ver.pre == null);
|
||||
os.version_range.semver.min = ver;
|
||||
os.version_range.semver.max = ver;
|
||||
} else |_| {
|
||||
|
|
@ -386,6 +374,11 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
|
|||
// However, the "mode" flags can be used as overrides, so if the user explicitly
|
||||
// sets one of them, that takes precedence.
|
||||
switch (query_cpu_arch) {
|
||||
.x86_16 => {
|
||||
cpu.features.addFeature(
|
||||
@intFromEnum(Target.x86.Feature.@"16bit_mode"),
|
||||
);
|
||||
},
|
||||
.x86 => {
|
||||
if (!Target.x86.featureSetHasAny(query.cpu_features_add, .{
|
||||
.@"16bit_mode", .@"32bit_mode",
|
||||
|
|
@ -1058,13 +1051,13 @@ fn detectAbiAndDynamicLinker(
|
|||
) DetectError!Target {
|
||||
const native_target_has_ld = comptime Target.DynamicLinker.kind(builtin.os.tag) != .none;
|
||||
const is_linux = builtin.target.os.tag == .linux;
|
||||
const is_solarish = builtin.target.os.tag.isSolarish();
|
||||
const is_illumos = builtin.target.os.tag == .illumos;
|
||||
const is_darwin = builtin.target.os.tag.isDarwin();
|
||||
const have_all_info = query.dynamic_linker.get() != null and
|
||||
query.abi != null and (!is_linux or query.abi.?.isGnu());
|
||||
const os_is_non_native = query.os_tag != null;
|
||||
// The Solaris/illumos environment is always the same.
|
||||
if (!native_target_has_ld or have_all_info or os_is_non_native or is_solarish or is_darwin) {
|
||||
// The illumos environment is always the same.
|
||||
if (!native_target_has_ld or have_all_info or os_is_non_native or is_illumos or is_darwin) {
|
||||
return defaultAbiAndDynamicLinker(cpu, os, query);
|
||||
}
|
||||
if (query.abi) |abi| {
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ pub fn detect(arena: Allocator, native_target: *const std.Target) !NativePaths {
|
|||
return self;
|
||||
}
|
||||
|
||||
if (builtin.os.tag.isSolarish()) {
|
||||
if (builtin.os.tag == .illumos) {
|
||||
try self.addLibDir("/usr/lib/64");
|
||||
try self.addLibDir("/usr/local/lib/64");
|
||||
try self.addLibDir("/lib/64");
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@ pub fn detect(target_os: *Target.Os) !void {
|
|||
if (parseSystemVersion(bytes)) |ver| {
|
||||
// never return non-canonical `10.(16+)`
|
||||
if (!(ver.major == 10 and ver.minor >= 16)) {
|
||||
assert(ver.pre == null);
|
||||
assert(ver.build == null);
|
||||
target_os.version_range.semver.min = ver;
|
||||
target_os.version_range.semver.max = ver;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -472,8 +472,9 @@ fn eqlIgnoreCase(ignore_case: bool, a: []const u8, b: []const u8) bool {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn intByteSize(target: *const std.Target, bits: u16) u19 {
|
||||
return std.mem.alignForward(u19, @intCast((@as(u17, bits) + 7) / 8), intAlignment(target, bits));
|
||||
pub fn intByteSize(target: *const std.Target, bits: u16) u16 {
|
||||
const previous_aligned = std.mem.alignBackward(u16, bits, 8);
|
||||
return std.mem.alignForward(u16, @divExact(previous_aligned, 8) + @intFromBool(previous_aligned != bits), intAlignment(target, bits));
|
||||
}
|
||||
|
||||
pub fn intAlignment(target: *const std.Target, bits: u16) u16 {
|
||||
|
|
|
|||
17
lib/zig.h
17
lib/zig.h
|
|
@ -74,6 +74,9 @@
|
|||
#elif defined (__x86_64__) || (defined(zig_msvc) && defined(_M_X64))
|
||||
#define zig_x86_64
|
||||
#define zig_x86
|
||||
#elif defined(__I86__)
|
||||
#define zig_x86_16
|
||||
#define zig_x86
|
||||
#endif
|
||||
|
||||
#if defined(zig_msvc) || __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
|
|
@ -84,9 +87,7 @@
|
|||
#define zig_big_endian 1
|
||||
#endif
|
||||
|
||||
#if defined(_AIX)
|
||||
#define zig_aix
|
||||
#elif defined(__MACH__)
|
||||
#if defined(__MACH__)
|
||||
#define zig_darwin
|
||||
#elif defined(__DragonFly__)
|
||||
#define zig_dragonfly
|
||||
|
|
@ -116,20 +117,14 @@
|
|||
#define zig_wasi
|
||||
#elif defined(_WIN32)
|
||||
#define zig_windows
|
||||
#elif defined(__MVS__)
|
||||
#define zig_zos
|
||||
#endif
|
||||
|
||||
#if defined(zig_windows)
|
||||
#define zig_coff
|
||||
#elif defined(__ELF__)
|
||||
#define zig_elf
|
||||
#elif defined(zig_zos)
|
||||
#define zig_goff
|
||||
#elif defined(zig_darwin)
|
||||
#define zig_macho
|
||||
#elif defined(zig_aix)
|
||||
#define zig_xcoff
|
||||
#endif
|
||||
|
||||
#define zig_concat(lhs, rhs) lhs##rhs
|
||||
|
|
@ -400,6 +395,8 @@
|
|||
#define zig_trap() __asm__ volatile("j 0x2")
|
||||
#elif defined(zig_sparc)
|
||||
#define zig_trap() __asm__ volatile("illtrap")
|
||||
#elif defined(zig_x86_16)
|
||||
#define zig_trap() __asm__ volatile("int $0x3")
|
||||
#elif defined(zig_x86)
|
||||
#define zig_trap() __asm__ volatile("ud2")
|
||||
#else
|
||||
|
|
@ -4219,7 +4216,7 @@ static inline void zig_loongarch_cpucfg(uint32_t word, uint32_t* result) {
|
|||
#endif
|
||||
}
|
||||
|
||||
#elif defined(zig_x86)
|
||||
#elif defined(zig_x86) && !defined(zig_x86_16)
|
||||
|
||||
static inline void zig_x86_cpuid(uint32_t leaf_id, uint32_t subid, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) {
|
||||
#if defined(zig_msvc)
|
||||
|
|
|
|||
|
|
@ -6864,8 +6864,11 @@ fn addCommonCCArgs(
|
|||
},
|
||||
}
|
||||
|
||||
// Homebrew targets without LLVM support; use communities's preferred macros.
|
||||
switch (target.os.tag) {
|
||||
// LLVM doesn't distinguish between Solaris and illumos, but the illumos GCC fork
|
||||
// defines this macro.
|
||||
.illumos => try argv.append("__illumos__"),
|
||||
// Homebrew targets without LLVM support; use communities's preferred macros.
|
||||
.@"3ds" => try argv.append("-D__3DS__"),
|
||||
.vita => try argv.append("-D__vita__"),
|
||||
else => {},
|
||||
|
|
|
|||
|
|
@ -492,7 +492,7 @@ pub fn resolve(options: Options) ResolveError!Config {
|
|||
if (root_strip and !options.any_non_stripped) break :b .strip;
|
||||
if (options.debug_format) |x| break :b x;
|
||||
break :b switch (target.ofmt) {
|
||||
.elf, .goff, .macho, .wasm, .xcoff => .{ .dwarf = .@"32" },
|
||||
.elf, .macho, .wasm => .{ .dwarf = .@"32" },
|
||||
.coff => .code_view,
|
||||
.c => switch (target.os.tag) {
|
||||
.windows, .uefi => .code_view,
|
||||
|
|
|
|||
|
|
@ -9034,6 +9034,7 @@ pub fn handleExternLibName(
|
|||
/// Any calling conventions not included here are either not yet verified to work with variadic
|
||||
/// functions or there are no more other calling conventions that support variadic functions.
|
||||
const calling_conventions_supporting_var_args = [_]std.builtin.CallingConvention.Tag{
|
||||
.x86_16_cdecl,
|
||||
.x86_64_sysv,
|
||||
.x86_64_x32,
|
||||
.x86_64_win,
|
||||
|
|
|
|||
109
src/Zcu.zig
109
src/Zcu.zig
|
|
@ -272,7 +272,7 @@ analysis_roots_len: usize = 0,
|
|||
/// This is the cached result of `Zcu.resolveReferences`. It is computed on-demand, and
|
||||
/// reset to `null` when any semantic analysis occurs (since this invalidates the data).
|
||||
/// Allocated into `gpa`.
|
||||
resolved_references: ?std.AutoHashMapUnmanaged(AnalUnit, ?ResolvedReference) = null,
|
||||
resolved_references: ?std.AutoArrayHashMapUnmanaged(AnalUnit, ?ResolvedReference) = null,
|
||||
|
||||
/// If `true`, then semantic analysis must not occur on this update due to AstGen errors.
|
||||
/// Essentially the entire pipeline after AstGen, including Sema, codegen, and link, is skipped.
|
||||
|
|
@ -3985,45 +3985,42 @@ pub const ResolvedReference = struct {
|
|||
/// If an `AnalUnit` is not in the returned map, it is unreferenced.
|
||||
/// The returned hashmap is owned by the `Zcu`, so should not be freed by the caller.
|
||||
/// This hashmap is cached, so repeated calls to this function are cheap.
|
||||
pub fn resolveReferences(zcu: *Zcu) !*const std.AutoHashMapUnmanaged(AnalUnit, ?ResolvedReference) {
|
||||
pub fn resolveReferences(zcu: *Zcu) !*const std.AutoArrayHashMapUnmanaged(AnalUnit, ?ResolvedReference) {
|
||||
if (zcu.resolved_references == null) {
|
||||
zcu.resolved_references = try zcu.resolveReferencesInner();
|
||||
}
|
||||
return &zcu.resolved_references.?;
|
||||
}
|
||||
fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?ResolvedReference) {
|
||||
fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?ResolvedReference) {
|
||||
const gpa = zcu.gpa;
|
||||
const comp = zcu.comp;
|
||||
const ip = &zcu.intern_pool;
|
||||
|
||||
var result: std.AutoHashMapUnmanaged(AnalUnit, ?ResolvedReference) = .empty;
|
||||
errdefer result.deinit(gpa);
|
||||
|
||||
var checked_types: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .empty;
|
||||
var type_queue: std.AutoArrayHashMapUnmanaged(InternPool.Index, ?ResolvedReference) = .empty;
|
||||
var unit_queue: std.AutoArrayHashMapUnmanaged(AnalUnit, ?ResolvedReference) = .empty;
|
||||
var units: std.AutoArrayHashMapUnmanaged(AnalUnit, ?ResolvedReference) = .empty;
|
||||
var types: std.AutoArrayHashMapUnmanaged(InternPool.Index, ?ResolvedReference) = .empty;
|
||||
defer {
|
||||
checked_types.deinit(gpa);
|
||||
type_queue.deinit(gpa);
|
||||
unit_queue.deinit(gpa);
|
||||
units.deinit(gpa);
|
||||
types.deinit(gpa);
|
||||
}
|
||||
|
||||
// This is not a sufficient size, but a lower bound.
|
||||
try result.ensureTotalCapacity(gpa, @intCast(zcu.reference_table.count()));
|
||||
// This is not a sufficient size, but an approximate lower bound.
|
||||
try units.ensureTotalCapacity(gpa, @intCast(zcu.reference_table.count()));
|
||||
|
||||
try type_queue.ensureTotalCapacity(gpa, zcu.analysis_roots_len);
|
||||
try types.ensureTotalCapacity(gpa, zcu.analysis_roots_len);
|
||||
for (zcu.analysisRoots()) |mod| {
|
||||
const file = zcu.module_roots.get(mod).?.unwrap() orelse continue;
|
||||
const root_ty = zcu.fileRootType(file);
|
||||
if (root_ty == .none) continue;
|
||||
type_queue.putAssumeCapacityNoClobber(root_ty, null);
|
||||
types.putAssumeCapacityNoClobber(root_ty, null);
|
||||
}
|
||||
|
||||
var unit_idx: usize = 0;
|
||||
var type_idx: usize = 0;
|
||||
while (true) {
|
||||
if (type_queue.pop()) |kv| {
|
||||
const ty = kv.key;
|
||||
const referencer = kv.value;
|
||||
try checked_types.putNoClobber(gpa, ty, {});
|
||||
if (type_idx < types.count()) {
|
||||
const ty = types.keys()[type_idx];
|
||||
const referencer = types.values()[type_idx];
|
||||
type_idx += 1;
|
||||
|
||||
log.debug("handle type '{f}'", .{Type.fromInterned(ty).containerTypeName(ip).fmt(ip)});
|
||||
|
||||
|
|
@ -4037,8 +4034,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
|
|||
if (has_resolution) {
|
||||
// this should only be referenced by the type
|
||||
const unit: AnalUnit = .wrap(.{ .type = ty });
|
||||
assert(!result.contains(unit));
|
||||
try unit_queue.putNoClobber(gpa, unit, referencer);
|
||||
try units.putNoClobber(gpa, unit, referencer);
|
||||
}
|
||||
|
||||
// If this is a union with a generated tag, its tag type is automatically referenced.
|
||||
|
|
@ -4047,9 +4043,8 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
|
|||
const tag_ty = union_obj.enum_tag_ty;
|
||||
if (tag_ty != .none) {
|
||||
if (ip.indexToKey(tag_ty).enum_type == .generated_tag) {
|
||||
if (!checked_types.contains(tag_ty)) {
|
||||
try type_queue.put(gpa, tag_ty, referencer);
|
||||
}
|
||||
const gop = try types.getOrPut(gpa, tag_ty);
|
||||
if (!gop.found_existing) gop.value_ptr.* = referencer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4060,12 +4055,13 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
|
|||
for (zcu.namespacePtr(ns).comptime_decls.items) |cu| {
|
||||
// `comptime` decls are always analyzed.
|
||||
const unit: AnalUnit = .wrap(.{ .@"comptime" = cu });
|
||||
if (!result.contains(unit)) {
|
||||
const gop = try units.getOrPut(gpa, unit);
|
||||
if (!gop.found_existing) {
|
||||
log.debug("type '{f}': ref comptime %{}", .{
|
||||
Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
|
||||
@intFromEnum(ip.getComptimeUnit(cu).zir_index.resolve(ip) orelse continue),
|
||||
});
|
||||
try unit_queue.put(gpa, unit, referencer);
|
||||
gop.value_ptr.* = referencer;
|
||||
}
|
||||
}
|
||||
for (zcu.namespacePtr(ns).test_decls.items) |nav_id| {
|
||||
|
|
@ -4092,14 +4088,20 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
|
|||
},
|
||||
};
|
||||
if (want_analysis) {
|
||||
log.debug("type '{f}': ref test %{}", .{
|
||||
Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
|
||||
@intFromEnum(inst_info.inst),
|
||||
});
|
||||
try unit_queue.put(gpa, .wrap(.{ .nav_val = nav_id }), referencer);
|
||||
{
|
||||
const gop = try units.getOrPut(gpa, .wrap(.{ .nav_val = nav_id }));
|
||||
if (!gop.found_existing) {
|
||||
log.debug("type '{f}': ref test %{}", .{
|
||||
Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
|
||||
@intFromEnum(inst_info.inst),
|
||||
});
|
||||
gop.value_ptr.* = referencer;
|
||||
}
|
||||
}
|
||||
// Non-fatal AstGen errors could mean this test decl failed
|
||||
if (nav.status == .fully_resolved) {
|
||||
try unit_queue.put(gpa, .wrap(.{ .func = nav.status.fully_resolved.val }), referencer);
|
||||
const gop = try units.getOrPut(gpa, .wrap(.{ .func = nav.status.fully_resolved.val }));
|
||||
if (!gop.found_existing) gop.value_ptr.* = referencer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4110,12 +4112,13 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
|
|||
const decl = file.zir.?.getDeclaration(inst_info.inst);
|
||||
if (decl.linkage == .@"export") {
|
||||
const unit: AnalUnit = .wrap(.{ .nav_val = nav });
|
||||
if (!result.contains(unit)) {
|
||||
const gop = try units.getOrPut(gpa, unit);
|
||||
if (!gop.found_existing) {
|
||||
log.debug("type '{f}': ref named %{}", .{
|
||||
Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
|
||||
@intFromEnum(inst_info.inst),
|
||||
});
|
||||
try unit_queue.put(gpa, unit, referencer);
|
||||
gop.value_ptr.* = referencer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4126,20 +4129,21 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
|
|||
const decl = file.zir.?.getDeclaration(inst_info.inst);
|
||||
if (decl.linkage == .@"export") {
|
||||
const unit: AnalUnit = .wrap(.{ .nav_val = nav });
|
||||
if (!result.contains(unit)) {
|
||||
const gop = try units.getOrPut(gpa, unit);
|
||||
if (!gop.found_existing) {
|
||||
log.debug("type '{f}': ref named %{}", .{
|
||||
Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
|
||||
@intFromEnum(inst_info.inst),
|
||||
});
|
||||
try unit_queue.put(gpa, unit, referencer);
|
||||
gop.value_ptr.* = referencer;
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (unit_queue.pop()) |kv| {
|
||||
const unit = kv.key;
|
||||
try result.putNoClobber(gpa, unit, kv.value);
|
||||
if (unit_idx < units.count()) {
|
||||
const unit = units.keys()[unit_idx];
|
||||
unit_idx += 1;
|
||||
|
||||
// `nav_val` and `nav_ty` reference each other *implicitly* to save memory.
|
||||
queue_paired: {
|
||||
|
|
@ -4148,8 +4152,9 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
|
|||
.nav_ty => |n| .{ .nav_val = n },
|
||||
.@"comptime", .type, .func, .memoized_state => break :queue_paired,
|
||||
});
|
||||
if (result.contains(other)) break :queue_paired;
|
||||
try unit_queue.put(gpa, other, kv.value); // same reference location
|
||||
const gop = try units.getOrPut(gpa, other);
|
||||
if (gop.found_existing) break :queue_paired;
|
||||
gop.value_ptr.* = units.values()[unit_idx]; // same reference location
|
||||
}
|
||||
|
||||
log.debug("handle unit '{f}'", .{zcu.fmtAnalUnit(unit)});
|
||||
|
|
@ -4159,16 +4164,17 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
|
|||
var ref_idx = first_ref_idx;
|
||||
while (ref_idx != std.math.maxInt(u32)) {
|
||||
const ref = zcu.all_references.items[ref_idx];
|
||||
if (!result.contains(ref.referenced)) {
|
||||
const gop = try units.getOrPut(gpa, ref.referenced);
|
||||
if (!gop.found_existing) {
|
||||
log.debug("unit '{f}': ref unit '{f}'", .{
|
||||
zcu.fmtAnalUnit(unit),
|
||||
zcu.fmtAnalUnit(ref.referenced),
|
||||
});
|
||||
try unit_queue.put(gpa, ref.referenced, .{
|
||||
gop.value_ptr.* = .{
|
||||
.referencer = unit,
|
||||
.src = ref.src,
|
||||
.inline_frame = ref.inline_frame,
|
||||
});
|
||||
};
|
||||
}
|
||||
ref_idx = ref.next;
|
||||
}
|
||||
|
|
@ -4178,16 +4184,17 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
|
|||
var ref_idx = first_ref_idx;
|
||||
while (ref_idx != std.math.maxInt(u32)) {
|
||||
const ref = zcu.all_type_references.items[ref_idx];
|
||||
if (!checked_types.contains(ref.referenced)) {
|
||||
const gop = try types.getOrPut(gpa, ref.referenced);
|
||||
if (!gop.found_existing) {
|
||||
log.debug("unit '{f}': ref type '{f}'", .{
|
||||
zcu.fmtAnalUnit(unit),
|
||||
Type.fromInterned(ref.referenced).containerTypeName(ip).fmt(ip),
|
||||
});
|
||||
try type_queue.put(gpa, ref.referenced, .{
|
||||
gop.value_ptr.* = .{
|
||||
.referencer = unit,
|
||||
.src = ref.src,
|
||||
.inline_frame = .none,
|
||||
});
|
||||
};
|
||||
}
|
||||
ref_idx = ref.next;
|
||||
}
|
||||
|
|
@ -4197,7 +4204,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
|
|||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
return units.move();
|
||||
}
|
||||
|
||||
pub fn analysisRoots(zcu: *Zcu) []*Package.Module {
|
||||
|
|
@ -4406,6 +4413,10 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu
|
|||
}
|
||||
}
|
||||
break :ok switch (cc) {
|
||||
.x86_16_cdecl,
|
||||
.x86_16_stdcall,
|
||||
.x86_16_regparmcall,
|
||||
.x86_16_interrupt,
|
||||
.x86_64_sysv,
|
||||
.x86_64_win,
|
||||
.x86_64_vectorcall,
|
||||
|
|
|
|||
|
|
@ -8055,9 +8055,11 @@ fn toCallingConvention(cc: std.builtin.CallingConvention, zcu: *Zcu) ?[]const u8
|
|||
return switch (cc) {
|
||||
.auto, .naked => null,
|
||||
|
||||
.x86_16_cdecl => "cdecl",
|
||||
.x86_16_regparmcall => "regparmcall",
|
||||
.x86_64_sysv, .x86_sysv => "sysv_abi",
|
||||
.x86_64_win, .x86_win => "ms_abi",
|
||||
.x86_stdcall => "stdcall",
|
||||
.x86_16_stdcall, .x86_stdcall => "stdcall",
|
||||
.x86_fastcall => "fastcall",
|
||||
.x86_thiscall => "thiscall",
|
||||
|
||||
|
|
@ -8127,6 +8129,7 @@ fn toCallingConvention(cc: std.builtin.CallingConvention, zcu: *Zcu) ?[]const u8
|
|||
.csky_interrupt,
|
||||
.m68k_interrupt,
|
||||
.msp430_interrupt,
|
||||
.x86_16_interrupt,
|
||||
.x86_interrupt,
|
||||
.x86_64_interrupt,
|
||||
=> "interrupt",
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8
|
|||
.propeller,
|
||||
.sh,
|
||||
.sheb,
|
||||
.x86_16,
|
||||
.xtensaeb,
|
||||
=> unreachable, // Gated by hasLlvmSupport().
|
||||
};
|
||||
|
|
@ -178,9 +179,6 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8
|
|||
try llvm_triple.append('-');
|
||||
|
||||
try llvm_triple.appendSlice(switch (target.os.tag) {
|
||||
.aix,
|
||||
.zos,
|
||||
=> "ibm",
|
||||
.driverkit,
|
||||
.ios,
|
||||
.macos,
|
||||
|
|
@ -211,12 +209,10 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8
|
|||
.linux => "linux",
|
||||
.netbsd => "netbsd",
|
||||
.openbsd => "openbsd",
|
||||
.solaris, .illumos => "solaris",
|
||||
.illumos => "solaris",
|
||||
.windows, .uefi => "windows",
|
||||
.zos => "zos",
|
||||
.haiku => "haiku",
|
||||
.rtems => "rtems",
|
||||
.aix => "aix",
|
||||
.cuda => "cuda",
|
||||
.nvcl => "nvcl",
|
||||
.amdhsa => "amdhsa",
|
||||
|
|
@ -381,13 +377,9 @@ pub fn dataLayout(target: *const std.Target) []const u8 {
|
|||
else => "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
|
||||
},
|
||||
.m68k => "E-m:e-p:32:16:32-i8:8:8-i16:16:16-i32:16:32-n8:16:32-a:0:16-S16",
|
||||
.powerpc => if (target.os.tag == .aix)
|
||||
"E-m:a-p:32:32-Fi32-i64:64-n32"
|
||||
else
|
||||
"E-m:e-p:32:32-Fn32-i64:64-n32",
|
||||
.powerpc => "E-m:e-p:32:32-Fn32-i64:64-n32",
|
||||
.powerpcle => "e-m:e-p:32:32-Fn32-i64:64-n32",
|
||||
.powerpc64 => switch (target.os.tag) {
|
||||
.aix => "E-m:a-Fi64-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512",
|
||||
.linux => if (target.abi.isMusl())
|
||||
"E-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512"
|
||||
else
|
||||
|
|
@ -424,10 +416,7 @@ pub fn dataLayout(target: *const std.Target) []const u8 {
|
|||
"E-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
|
||||
.sparc => "E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64",
|
||||
.sparc64 => "E-m:e-i64:64-i128:128-n32:64-S128",
|
||||
.s390x => if (target.os.tag == .zos)
|
||||
"E-m:l-p1:32:32-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
|
||||
else
|
||||
"E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64",
|
||||
.s390x => "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64",
|
||||
.x86 => if (target.os.tag == .windows or target.os.tag == .uefi) switch (target.abi) {
|
||||
.cygnus => "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32",
|
||||
.gnu => if (target.ofmt == .coff)
|
||||
|
|
@ -493,6 +482,7 @@ pub fn dataLayout(target: *const std.Target) []const u8 {
|
|||
.propeller,
|
||||
.sh,
|
||||
.sheb,
|
||||
.x86_16,
|
||||
.xtensaeb,
|
||||
=> unreachable, // Gated by hasLlvmSupport().
|
||||
};
|
||||
|
|
@ -515,7 +505,7 @@ fn codeModel(model: std.builtin.CodeModel, target: *const std.Target) CodeModel
|
|||
.extreme, .large => .large,
|
||||
.kernel => .kernel,
|
||||
.medany => if (target.cpu.arch.isRISCV()) .medium else .large,
|
||||
.medium => if (target.os.tag == .aix) .large else .medium,
|
||||
.medium => .medium,
|
||||
.medmid => .medium,
|
||||
.normal, .medlow, .small => .small,
|
||||
.tiny => .tiny,
|
||||
|
|
@ -11902,6 +11892,10 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: *const s
|
|||
|
||||
// All the calling conventions which LLVM does not have a general representation for.
|
||||
// Note that these are often still supported through the `cCallingConvention` path above via `ccc`.
|
||||
.x86_16_cdecl,
|
||||
.x86_16_stdcall,
|
||||
.x86_16_regparmcall,
|
||||
.x86_16_interrupt,
|
||||
.x86_sysv,
|
||||
.x86_win,
|
||||
.x86_thiscall_mingw,
|
||||
|
|
@ -12822,12 +12816,6 @@ fn backendSupportsF128(target: *const std.Target) bool {
|
|||
// https://github.com/llvm/llvm-project/issues/41838
|
||||
.sparc,
|
||||
=> false,
|
||||
// https://github.com/llvm/llvm-project/issues/101545
|
||||
.powerpc,
|
||||
.powerpcle,
|
||||
.powerpc64,
|
||||
.powerpc64le,
|
||||
=> target.os.tag != .aix,
|
||||
.arm,
|
||||
.armeb,
|
||||
.thumb,
|
||||
|
|
@ -13131,6 +13119,7 @@ pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
|
|||
.propeller,
|
||||
.sh,
|
||||
.sheb,
|
||||
.x86_16,
|
||||
.xtensaeb,
|
||||
=> unreachable,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6145,7 +6145,7 @@ fn airWorkGroupSize(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
|||
if (cg.liveness.isUnused(inst)) return null;
|
||||
const pl_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
|
||||
const dimension = pl_op.payload;
|
||||
return try cg.builtin3D(.u32, .workgroup_id, dimension, 0);
|
||||
return try cg.builtin3D(.u32, .workgroup_size, dimension, 0);
|
||||
}
|
||||
|
||||
fn airWorkGroupId(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
|
|
|
|||
|
|
@ -927,6 +927,7 @@ pub fn storageClass(module: *Module, as: std.builtin.AddressSpace) spec.StorageC
|
|||
.gs,
|
||||
.fs,
|
||||
.ss,
|
||||
.far,
|
||||
.param,
|
||||
.flash,
|
||||
.flash1,
|
||||
|
|
|
|||
|
|
@ -104,8 +104,6 @@ pub const Env = enum {
|
|||
.wasm_linker,
|
||||
.spirv_linker,
|
||||
.plan9_linker,
|
||||
.goff_linker,
|
||||
.xcoff_linker,
|
||||
=> true,
|
||||
.cc_command,
|
||||
.translate_c_command,
|
||||
|
|
@ -293,8 +291,6 @@ pub const Feature = enum {
|
|||
wasm_linker,
|
||||
spirv_linker,
|
||||
plan9_linker,
|
||||
goff_linker,
|
||||
xcoff_linker,
|
||||
};
|
||||
|
||||
/// Makes the code following the call to this function unreachable if `feature` is disabled.
|
||||
|
|
|
|||
|
|
@ -79,9 +79,6 @@ const libcxx_base_files = [_][]const u8{
|
|||
"src/stdexcept.cpp",
|
||||
"src/string.cpp",
|
||||
"src/strstream.cpp",
|
||||
"src/support/ibm/mbsnrtowcs.cpp",
|
||||
"src/support/ibm/wcsnrtombs.cpp",
|
||||
"src/support/ibm/xlocale_zos.cpp",
|
||||
"src/support/win32/locale_win32.cpp",
|
||||
"src/support/win32/support.cpp",
|
||||
"src/system_error.cpp",
|
||||
|
|
@ -203,8 +200,6 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
|
|||
continue;
|
||||
if (std.mem.startsWith(u8, cxx_src, "src/support/win32/") and target.os.tag != .windows)
|
||||
continue;
|
||||
if (std.mem.startsWith(u8, cxx_src, "src/support/ibm/") and target.os.tag != .zos)
|
||||
continue;
|
||||
|
||||
var cflags = std.array_list.Managed([]const u8).init(arena);
|
||||
|
||||
|
|
@ -223,11 +218,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
|
|||
try cflags.append("-fvisibility=hidden");
|
||||
try cflags.append("-fvisibility-inlines-hidden");
|
||||
|
||||
if (target.os.tag == .zos) {
|
||||
try cflags.append("-fno-aligned-allocation");
|
||||
} else {
|
||||
try cflags.append("-faligned-allocation");
|
||||
}
|
||||
try cflags.append("-faligned-allocation");
|
||||
|
||||
try cflags.append("-nostdinc++");
|
||||
try cflags.append("-std=c++23");
|
||||
|
|
|
|||
|
|
@ -480,7 +480,6 @@ const sanitizer_symbolizer_sources = [_][]const u8{
|
|||
};
|
||||
|
||||
const interception_sources = [_][]const u8{
|
||||
"interception_aix.cpp",
|
||||
"interception_linux.cpp",
|
||||
"interception_mac.cpp",
|
||||
"interception_win.cpp",
|
||||
|
|
|
|||
|
|
@ -198,6 +198,5 @@ const unwind_src_list = [_][]const u8{
|
|||
"libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-wasm.c",
|
||||
"libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersRestore.S",
|
||||
"libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersSave.S",
|
||||
"libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind_AIXExtras.cpp",
|
||||
"libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "gcc_personality_v0.c",
|
||||
};
|
||||
|
|
|
|||
22
src/link.zig
22
src/link.zig
|
|
@ -574,9 +574,9 @@ pub const File = struct {
|
|||
const gpa = comp.gpa;
|
||||
switch (base.tag) {
|
||||
.lld => assert(base.file == null),
|
||||
.elf, .macho, .wasm, .goff, .xcoff => {
|
||||
.elf, .macho, .wasm => {
|
||||
if (base.file != null) return;
|
||||
dev.checkAny(&.{ .coff_linker, .elf_linker, .macho_linker, .plan9_linker, .wasm_linker, .goff_linker, .xcoff_linker });
|
||||
dev.checkAny(&.{ .coff_linker, .elf_linker, .macho_linker, .plan9_linker, .wasm_linker });
|
||||
const emit = base.emit;
|
||||
if (base.child_pid) |pid| {
|
||||
if (builtin.os.tag == .windows) {
|
||||
|
|
@ -681,8 +681,8 @@ pub const File = struct {
|
|||
}
|
||||
}
|
||||
},
|
||||
.macho, .wasm, .goff, .xcoff => if (base.file) |f| {
|
||||
dev.checkAny(&.{ .coff_linker, .macho_linker, .plan9_linker, .wasm_linker, .goff_linker, .xcoff_linker });
|
||||
.macho, .wasm => if (base.file) |f| {
|
||||
dev.checkAny(&.{ .coff_linker, .macho_linker, .plan9_linker, .wasm_linker });
|
||||
f.close();
|
||||
base.file = null;
|
||||
|
||||
|
|
@ -825,7 +825,6 @@ pub const File = struct {
|
|||
switch (base.tag) {
|
||||
.lld => unreachable,
|
||||
.spirv => {},
|
||||
.goff, .xcoff => {},
|
||||
.plan9 => unreachable,
|
||||
.elf2, .coff2 => {},
|
||||
inline else => |tag| {
|
||||
|
|
@ -973,7 +972,6 @@ pub const File = struct {
|
|||
.c => unreachable,
|
||||
.spirv => unreachable,
|
||||
.wasm => unreachable,
|
||||
.goff, .xcoff => unreachable,
|
||||
.plan9 => unreachable,
|
||||
inline else => |tag| {
|
||||
dev.check(tag.devFeature());
|
||||
|
|
@ -996,7 +994,6 @@ pub const File = struct {
|
|||
.c => unreachable,
|
||||
.spirv => unreachable,
|
||||
.wasm => unreachable,
|
||||
.goff, .xcoff => unreachable,
|
||||
.plan9 => unreachable,
|
||||
inline else => |tag| {
|
||||
dev.check(tag.devFeature());
|
||||
|
|
@ -1013,7 +1010,6 @@ pub const File = struct {
|
|||
.c => unreachable,
|
||||
.spirv => unreachable,
|
||||
.wasm => unreachable,
|
||||
.goff, .xcoff => unreachable,
|
||||
.plan9 => unreachable,
|
||||
inline else => |tag| {
|
||||
dev.check(tag.devFeature());
|
||||
|
|
@ -1034,8 +1030,6 @@ pub const File = struct {
|
|||
.plan9 => unreachable,
|
||||
|
||||
.spirv,
|
||||
.goff,
|
||||
.xcoff,
|
||||
=> {},
|
||||
|
||||
inline else => |tag| {
|
||||
|
|
@ -1171,8 +1165,6 @@ pub const File = struct {
|
|||
wasm,
|
||||
spirv,
|
||||
plan9,
|
||||
goff,
|
||||
xcoff,
|
||||
lld,
|
||||
|
||||
pub fn Type(comptime tag: Tag) type {
|
||||
|
|
@ -1184,8 +1176,6 @@ pub const File = struct {
|
|||
.c => C,
|
||||
.wasm => Wasm,
|
||||
.spirv => SpirV,
|
||||
.goff => Goff,
|
||||
.xcoff => Xcoff,
|
||||
.lld => Lld,
|
||||
.plan9 => comptime unreachable,
|
||||
};
|
||||
|
|
@ -1200,8 +1190,6 @@ pub const File = struct {
|
|||
.plan9 => .plan9,
|
||||
.c => .c,
|
||||
.spirv => .spirv,
|
||||
.goff => .goff,
|
||||
.xcoff => .xcoff,
|
||||
.hex => @panic("TODO implement hex object format"),
|
||||
.raw => @panic("TODO implement raw object format"),
|
||||
};
|
||||
|
|
@ -1284,8 +1272,6 @@ pub const File = struct {
|
|||
pub const MachO = @import("link/MachO.zig");
|
||||
pub const SpirV = @import("link/SpirV.zig");
|
||||
pub const Wasm = @import("link/Wasm.zig");
|
||||
pub const Goff = @import("link/Goff.zig");
|
||||
pub const Xcoff = @import("link/Xcoff.zig");
|
||||
pub const Dwarf = @import("link/Dwarf.zig");
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1561,7 +1561,7 @@ pub fn writeElfHeader(self: *Elf) !void {
|
|||
else => switch (target.os.tag) {
|
||||
.freebsd, .ps4 => .FREEBSD,
|
||||
.hermit => .STANDALONE,
|
||||
.illumos, .solaris => .SOLARIS,
|
||||
.illumos => .SOLARIS,
|
||||
.openbsd => .OPENBSD,
|
||||
else => .NONE,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -417,9 +417,9 @@ fn create(
|
|||
else => .NONE,
|
||||
.freestanding, .other => .STANDALONE,
|
||||
.netbsd => .NETBSD,
|
||||
.solaris => .SOLARIS,
|
||||
.aix => .AIX,
|
||||
.freebsd => .FREEBSD,
|
||||
.illumos => .SOLARIS,
|
||||
.freebsd, .ps4 => .FREEBSD,
|
||||
.openbsd => .OPENBSD,
|
||||
.cuda => .CUDA,
|
||||
.amdhsa => .AMDGPU_HSA,
|
||||
.amdpal => .AMDGPU_PAL,
|
||||
|
|
|
|||
|
|
@ -1,112 +0,0 @@
|
|||
//! Stub linker support for GOFF based on LLVM.
|
||||
|
||||
const Goff = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
const assert = std.debug.assert;
|
||||
const log = std.log.scoped(.link);
|
||||
const Path = std.Build.Cache.Path;
|
||||
|
||||
const Zcu = @import("../Zcu.zig");
|
||||
const InternPool = @import("../InternPool.zig");
|
||||
const Compilation = @import("../Compilation.zig");
|
||||
const codegen = @import("../codegen.zig");
|
||||
const link = @import("../link.zig");
|
||||
const trace = @import("../tracy.zig").trace;
|
||||
const build_options = @import("build_options");
|
||||
|
||||
base: link.File,
|
||||
|
||||
pub fn createEmpty(
|
||||
arena: Allocator,
|
||||
comp: *Compilation,
|
||||
emit: Path,
|
||||
options: link.File.OpenOptions,
|
||||
) !*Goff {
|
||||
const target = &comp.root_mod.resolved_target.result;
|
||||
const use_lld = build_options.have_llvm and comp.config.use_lld;
|
||||
const use_llvm = comp.config.use_llvm;
|
||||
|
||||
assert(use_llvm); // Caught by Compilation.Config.resolve.
|
||||
assert(!use_lld); // Caught by Compilation.Config.resolve.
|
||||
assert(target.os.tag == .zos); // Caught by Compilation.Config.resolve.
|
||||
|
||||
const goff = try arena.create(Goff);
|
||||
goff.* = .{
|
||||
.base = .{
|
||||
.tag = .goff,
|
||||
.comp = comp,
|
||||
.emit = emit,
|
||||
.zcu_object_basename = emit.sub_path,
|
||||
.gc_sections = options.gc_sections orelse false,
|
||||
.print_gc_sections = options.print_gc_sections,
|
||||
.stack_size = options.stack_size orelse 0,
|
||||
.allow_shlib_undefined = options.allow_shlib_undefined orelse false,
|
||||
.file = null,
|
||||
.build_id = options.build_id,
|
||||
},
|
||||
};
|
||||
|
||||
return goff;
|
||||
}
|
||||
|
||||
pub fn open(
|
||||
arena: Allocator,
|
||||
comp: *Compilation,
|
||||
emit: Path,
|
||||
options: link.File.OpenOptions,
|
||||
) !*Goff {
|
||||
const target = &comp.root_mod.resolved_target.result;
|
||||
assert(target.ofmt == .goff);
|
||||
return createEmpty(arena, comp, emit, options);
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Goff) void {
|
||||
_ = self;
|
||||
}
|
||||
|
||||
pub fn updateFunc(
|
||||
self: *Goff,
|
||||
pt: Zcu.PerThread,
|
||||
func_index: InternPool.Index,
|
||||
mir: *const codegen.AnyMir,
|
||||
) link.File.UpdateNavError!void {
|
||||
_ = self;
|
||||
_ = pt;
|
||||
_ = func_index;
|
||||
_ = mir;
|
||||
unreachable; // we always use llvm
|
||||
}
|
||||
|
||||
pub fn updateNav(self: *Goff, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void {
|
||||
_ = self;
|
||||
_ = pt;
|
||||
_ = nav;
|
||||
unreachable; // we always use llvm
|
||||
}
|
||||
|
||||
pub fn updateExports(
|
||||
self: *Goff,
|
||||
pt: Zcu.PerThread,
|
||||
exported: Zcu.Exported,
|
||||
export_indices: []const Zcu.Export.Index,
|
||||
) !void {
|
||||
_ = self;
|
||||
_ = pt;
|
||||
_ = exported;
|
||||
_ = export_indices;
|
||||
unreachable; // we always use llvm
|
||||
}
|
||||
|
||||
pub fn flush(self: *Goff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .goff)
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
|
||||
_ = self;
|
||||
_ = arena;
|
||||
_ = tid;
|
||||
_ = prog_node;
|
||||
}
|
||||
|
|
@ -348,7 +348,6 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void {
|
|||
object_files.items.ptr,
|
||||
object_files.items.len,
|
||||
switch (target.os.tag) {
|
||||
.aix => .AIXBIG,
|
||||
.windows => .COFF,
|
||||
else => if (target.os.tag.isDarwin()) .DARWIN else .GNU,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,112 +0,0 @@
|
|||
//! Stub linker support for GOFF based on LLVM.
|
||||
|
||||
const Xcoff = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
const assert = std.debug.assert;
|
||||
const log = std.log.scoped(.link);
|
||||
const Path = std.Build.Cache.Path;
|
||||
|
||||
const Zcu = @import("../Zcu.zig");
|
||||
const InternPool = @import("../InternPool.zig");
|
||||
const Compilation = @import("../Compilation.zig");
|
||||
const codegen = @import("../codegen.zig");
|
||||
const link = @import("../link.zig");
|
||||
const trace = @import("../tracy.zig").trace;
|
||||
const build_options = @import("build_options");
|
||||
|
||||
base: link.File,
|
||||
|
||||
pub fn createEmpty(
|
||||
arena: Allocator,
|
||||
comp: *Compilation,
|
||||
emit: Path,
|
||||
options: link.File.OpenOptions,
|
||||
) !*Xcoff {
|
||||
const target = &comp.root_mod.resolved_target.result;
|
||||
const use_lld = build_options.have_llvm and comp.config.use_lld;
|
||||
const use_llvm = comp.config.use_llvm;
|
||||
|
||||
assert(use_llvm); // Caught by Compilation.Config.resolve.
|
||||
assert(!use_lld); // Caught by Compilation.Config.resolve.
|
||||
assert(target.os.tag == .aix); // Caught by Compilation.Config.resolve.
|
||||
|
||||
const xcoff = try arena.create(Xcoff);
|
||||
xcoff.* = .{
|
||||
.base = .{
|
||||
.tag = .xcoff,
|
||||
.comp = comp,
|
||||
.emit = emit,
|
||||
.zcu_object_basename = emit.sub_path,
|
||||
.gc_sections = options.gc_sections orelse false,
|
||||
.print_gc_sections = options.print_gc_sections,
|
||||
.stack_size = options.stack_size orelse 0,
|
||||
.allow_shlib_undefined = options.allow_shlib_undefined orelse false,
|
||||
.file = null,
|
||||
.build_id = options.build_id,
|
||||
},
|
||||
};
|
||||
|
||||
return xcoff;
|
||||
}
|
||||
|
||||
pub fn open(
|
||||
arena: Allocator,
|
||||
comp: *Compilation,
|
||||
emit: Path,
|
||||
options: link.File.OpenOptions,
|
||||
) !*Xcoff {
|
||||
const target = &comp.root_mod.resolved_target.result;
|
||||
assert(target.ofmt == .xcoff);
|
||||
return createEmpty(arena, comp, emit, options);
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Xcoff) void {
|
||||
_ = self;
|
||||
}
|
||||
|
||||
pub fn updateFunc(
|
||||
self: *Xcoff,
|
||||
pt: Zcu.PerThread,
|
||||
func_index: InternPool.Index,
|
||||
mir: *const codegen.AnyMir,
|
||||
) link.File.UpdateNavError!void {
|
||||
_ = self;
|
||||
_ = pt;
|
||||
_ = func_index;
|
||||
_ = mir;
|
||||
unreachable; // we always use llvm
|
||||
}
|
||||
|
||||
pub fn updateNav(self: *Xcoff, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void {
|
||||
_ = self;
|
||||
_ = pt;
|
||||
_ = nav;
|
||||
unreachable; // we always use llvm
|
||||
}
|
||||
|
||||
pub fn updateExports(
|
||||
self: *Xcoff,
|
||||
pt: Zcu.PerThread,
|
||||
exported: Zcu.Exported,
|
||||
export_indices: []const Zcu.Export.Index,
|
||||
) !void {
|
||||
_ = self;
|
||||
_ = pt;
|
||||
_ = exported;
|
||||
_ = export_indices;
|
||||
unreachable; // we always use llvm
|
||||
}
|
||||
|
||||
pub fn flush(self: *Xcoff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .xcoff)
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
|
||||
_ = self;
|
||||
_ = arena;
|
||||
_ = tid;
|
||||
_ = prog_node;
|
||||
}
|
||||
|
|
@ -129,13 +129,13 @@ pub fn hasValgrindSupport(target: *const std.Target, backend: std.builtin.Compil
|
|||
else => false,
|
||||
},
|
||||
.x86 => switch (target.os.tag) {
|
||||
.linux, .freebsd, .solaris, .illumos => true,
|
||||
.linux, .freebsd, .illumos => true,
|
||||
.windows => !ofmt_c_msvc,
|
||||
else => false,
|
||||
},
|
||||
.x86_64 => switch (target.os.tag) {
|
||||
.linux => target.abi != .gnux32 and target.abi != .muslx32,
|
||||
.freebsd, .solaris, .illumos => true,
|
||||
.freebsd, .illumos => true,
|
||||
.windows => !ofmt_c_msvc,
|
||||
else => false,
|
||||
},
|
||||
|
|
@ -155,13 +155,11 @@ pub fn hasLlvmSupport(target: *const std.Target, ofmt: std.Target.ObjectFormat)
|
|||
|
||||
.coff,
|
||||
.elf,
|
||||
.goff,
|
||||
.hex,
|
||||
.macho,
|
||||
.spirv,
|
||||
.raw,
|
||||
.wasm,
|
||||
.xcoff,
|
||||
=> {},
|
||||
}
|
||||
|
||||
|
|
@ -227,6 +225,7 @@ pub fn hasLlvmSupport(target: *const std.Target, ofmt: std.Target.ObjectFormat)
|
|||
.propeller,
|
||||
.sh,
|
||||
.sheb,
|
||||
.x86_16,
|
||||
.xtensaeb,
|
||||
=> false,
|
||||
};
|
||||
|
|
@ -257,7 +256,7 @@ pub fn hasNewLinkerSupport(ofmt: std.Target.ObjectFormat, backend: std.builtin.C
|
|||
pub fn selfHostedBackendIsAsRobustAsLlvm(target: *const std.Target) bool {
|
||||
if (target.cpu.arch.isSpirV()) return true;
|
||||
if (target.cpu.arch == .x86_64 and target.ptrBitWidth() == 64) {
|
||||
if (target.os.tag.isSolarish()) {
|
||||
if (target.os.tag == .illumos) {
|
||||
// https://github.com/ziglang/zig/issues/25699
|
||||
return false;
|
||||
}
|
||||
|
|
@ -428,8 +427,7 @@ pub fn libcFullLinkFlags(target: *const std.Target) []const []const u8 {
|
|||
// c compilers such as gcc or clang use.
|
||||
const result: []const []const u8 = switch (target.os.tag) {
|
||||
.dragonfly, .freebsd, .netbsd, .openbsd => &.{ "-lm", "-lpthread", "-lc", "-lutil" },
|
||||
// Solaris releases after 10 merged the threading libraries into libc.
|
||||
.solaris, .illumos => &.{ "-lm", "-lsocket", "-lnsl", "-lc" },
|
||||
.illumos => &.{ "-lm", "-lsocket", "-lnsl", "-lc" },
|
||||
.haiku => &.{ "-lm", "-lroot", "-lpthread", "-lc", "-lnetwork" },
|
||||
.linux => switch (target.abi) {
|
||||
.android, .androideabi, .ohos, .ohoseabi => &.{ "-lm", "-lc", "-ldl" },
|
||||
|
|
|
|||
|
|
@ -175,7 +175,6 @@ const targets = [_]std.Target.Query{
|
|||
.{ .cpu_arch = .nvptx64, .os_tag = .cuda, .abi = .none },
|
||||
.{ .cpu_arch = .nvptx64, .os_tag = .nvcl, .abi = .none },
|
||||
|
||||
.{ .cpu_arch = .powerpc, .os_tag = .aix, .abi = .eabihf },
|
||||
.{ .cpu_arch = .powerpc, .os_tag = .freestanding, .abi = .eabi },
|
||||
.{ .cpu_arch = .powerpc, .os_tag = .freestanding, .abi = .eabihf },
|
||||
.{ .cpu_arch = .powerpc, .os_tag = .haiku, .abi = .eabi },
|
||||
|
|
@ -196,7 +195,6 @@ const targets = [_]std.Target.Query{
|
|||
.{ .cpu_arch = .powerpcle, .os_tag = .freestanding, .abi = .eabi },
|
||||
.{ .cpu_arch = .powerpcle, .os_tag = .freestanding, .abi = .eabihf },
|
||||
|
||||
.{ .cpu_arch = .powerpc64, .os_tag = .aix, .abi = .none },
|
||||
.{ .cpu_arch = .powerpc64, .os_tag = .freebsd, .abi = .none },
|
||||
.{ .cpu_arch = .powerpc64, .os_tag = .freestanding, .abi = .none },
|
||||
.{ .cpu_arch = .powerpc64, .os_tag = .linux, .abi = .gnu },
|
||||
|
|
@ -239,7 +237,6 @@ const targets = [_]std.Target.Query{
|
|||
.{ .cpu_arch = .s390x, .os_tag = .freestanding, .abi = .none },
|
||||
.{ .cpu_arch = .s390x, .os_tag = .linux, .abi = .gnu },
|
||||
.{ .cpu_arch = .s390x, .os_tag = .linux, .abi = .none },
|
||||
// .{ .cpu_arch = .s390x, .os_tag = .zos, .abi = .none },
|
||||
|
||||
.{ .cpu_arch = .sparc, .os_tag = .freestanding, .abi = .none },
|
||||
.{ .cpu_arch = .sparc, .os_tag = .linux, .abi = .gnu },
|
||||
|
|
@ -254,7 +251,6 @@ const targets = [_]std.Target.Query{
|
|||
.{ .cpu_arch = .sparc64, .os_tag = .netbsd, .abi = .none },
|
||||
.{ .cpu_arch = .sparc64, .os_tag = .openbsd, .abi = .none },
|
||||
.{ .cpu_arch = .sparc64, .os_tag = .rtems, .abi = .none },
|
||||
.{ .cpu_arch = .sparc64, .os_tag = .solaris, .abi = .none },
|
||||
|
||||
.{ .cpu_arch = .thumb, .os_tag = .freestanding, .abi = .eabi },
|
||||
.{ .cpu_arch = .thumb, .os_tag = .freestanding, .abi = .eabihf },
|
||||
|
|
@ -338,7 +334,6 @@ const targets = [_]std.Target.Query{
|
|||
.{ .cpu_arch = .x86_64, .os_tag = .openbsd, .abi = .none },
|
||||
.{ .cpu_arch = .x86_64, .os_tag = .rtems, .abi = .none },
|
||||
.{ .cpu_arch = .x86_64, .os_tag = .serenity, .abi = .none },
|
||||
.{ .cpu_arch = .x86_64, .os_tag = .solaris, .abi = .none },
|
||||
.{ .cpu_arch = .x86_64, .os_tag = .tvos, .abi = .simulator },
|
||||
.{ .cpu_arch = .x86_64, .os_tag = .uefi, .abi = .none },
|
||||
.{ .cpu_arch = .x86_64, .os_tag = .visionos, .abi = .simulator },
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ pub fn addCase(self: *ErrorTrace, case: Case) void {
|
|||
fn shouldTestNonLlvm(target: *const std.Target) bool {
|
||||
return switch (target.cpu.arch) {
|
||||
.x86_64 => switch (target.ofmt) {
|
||||
.elf => !target.os.tag.isBSD() and !target.os.tag.isSolarish(),
|
||||
.elf => !target.os.tag.isBSD() and target.os.tag != .illumos,
|
||||
else => false,
|
||||
},
|
||||
else => false,
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ fn addCaseTarget(
|
|||
) void {
|
||||
const both_backends = switch (target.result.cpu.arch) {
|
||||
.x86_64 => switch (target.result.ofmt) {
|
||||
.elf => !target.result.os.tag.isBSD() and !target.result.os.tag.isSolarish(),
|
||||
.elf => !target.result.os.tag.isBSD() and target.result.os.tag != .illumos,
|
||||
else => false,
|
||||
},
|
||||
else => false,
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ fn test_symlink(a: std.mem.Allocator, tmp: std.testing.TmpDir) !void {
|
|||
|
||||
fn test_link(tmp: std.testing.TmpDir) !void {
|
||||
switch (builtin.target.os.tag) {
|
||||
.linux, .solaris, .illumos => {},
|
||||
.linux, .illumos => {},
|
||||
else => return,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ pub fn build(b: *std.Build) !void {
|
|||
.{ .linux, &.{ .aarch64, .aarch64_be, .loongarch64, .powerpc64, .powerpc64le, .riscv64, .x86_64 } },
|
||||
.{ .macos, &.{ .aarch64, .x86_64 } },
|
||||
|
||||
// https://github.com/ziglang/zig/issues/24841
|
||||
// .{ .freebsd, &.{ .aarch64, .powerpc64, .powerpc64le, .riscv64, .x86_64 } },
|
||||
// powerpc64, powerpc64le, and riscv64 are not supported by TSan yet.
|
||||
.{ .freebsd, &.{ .aarch64, .x86_64 } },
|
||||
|
||||
.{ .netbsd, &.{.x86_64} },
|
||||
|
||||
|
|
|
|||
|
|
@ -2493,7 +2493,7 @@ pub fn wouldUseLlvm(use_llvm: ?bool, query: std.Target.Query, optimize_mode: Opt
|
|||
const cpu_arch = query.cpu_arch orelse builtin.cpu.arch;
|
||||
const os_tag = query.os_tag orelse builtin.os.tag;
|
||||
switch (cpu_arch) {
|
||||
.x86_64 => if (os_tag.isBSD() or os_tag.isSolarish() or std.Target.ptrBitWidth_arch_abi(cpu_arch, query.abi orelse .none) != 64) return true,
|
||||
.x86_64 => if (os_tag.isBSD() or os_tag == .illumos or std.Target.ptrBitWidth_arch_abi(cpu_arch, query.abi orelse .none) != 64) return true,
|
||||
.spirv32, .spirv64 => return false,
|
||||
else => return true,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1051,6 +1051,28 @@ const targets = [_]ArchTarget{
|
|||
.name = "PowerPC",
|
||||
.td_name = "PPC",
|
||||
},
|
||||
.feature_overrides = &.{
|
||||
.{
|
||||
.llvm_name = "aix",
|
||||
.omit = true,
|
||||
},
|
||||
.{
|
||||
.llvm_name = "aix-shared-lib-tls-model-opt",
|
||||
.omit = true,
|
||||
},
|
||||
.{
|
||||
.llvm_name = "aix-small-local-dynamic-tls",
|
||||
.omit = true,
|
||||
},
|
||||
.{
|
||||
.llvm_name = "aix-small-local-exec-tls",
|
||||
.omit = true,
|
||||
},
|
||||
.{
|
||||
.llvm_name = "modern-aix-as",
|
||||
.omit = true,
|
||||
},
|
||||
},
|
||||
.omit_cpus = &.{
|
||||
"ppc32",
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue