Merge branch 'master' into ambiguous-precedence

This commit is contained in:
CMDRZero 2025-10-29 12:48:15 -05:00 committed by GitHub
commit aae73cfab2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
88 changed files with 453 additions and 2351 deletions

View file

@ -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()
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")

View file

@ -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);
},

View file

@ -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#}

View file

@ -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| {

View file

@ -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,

View file

@ -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));
}
}

View file

@ -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,

View file

@ -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 => {

View file

@ -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),

View file

@ -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 */

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -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) {

View file

@ -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)

View file

@ -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.

View file

@ -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 = "";

View file

@ -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,

View file

@ -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;

View file

@ -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,

View file

@ -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 {

View file

@ -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,
}),
};

View file

@ -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",

View file

@ -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",

View file

@ -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)),

View file

@ -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) {

View file

@ -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,

View file

@ -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;

View file

@ -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;

View file

@ -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"),

View file

@ -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,
};

View file

@ -160,9 +160,6 @@ pub const can_unwind: bool = s: {
.x86,
.x86_64,
},
.solaris => &.{
.x86_64,
},
else => unreachable,
};

View file

@ -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,

View file

@ -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,

View file

@ -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

View file

@ -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;

View file

@ -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 => {},

View file

@ -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 });

View file

@ -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,

View file

@ -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

View file

@ -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;

View file

@ -4634,6 +4634,8 @@ pub const TEB = extern struct {
};
comptime {
// 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);
@ -4654,6 +4656,7 @@ comptime {
assert(@offsetOf(TEB, "LastErrorValue") == 0x68);
assert(@offsetOf(TEB, "TlsSlots") == 0x1480);
}
}
}
pub const EXCEPTION_REGISTRATION_RECORD = extern struct {

View file

@ -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"),

View file

@ -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,
}

View file

@ -1539,7 +1539,6 @@ pub fn getUserInfo(name: []const u8) !UserInfo {
.netbsd,
.openbsd,
.haiku,
.solaris,
.illumos,
.serenity,
=> posixGetUserInfo(name),

View file

@ -761,7 +761,7 @@ fn maybeIgnoreSigpipe() void {
const have_sigpipe_support = switch (builtin.os.tag) {
.linux,
.plan9,
.solaris,
.illumos,
.netbsd,
.openbsd,
.haiku,

View file

@ -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) {

View file

@ -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",

View file

@ -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| {

View file

@ -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");

View file

@ -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;

View file

@ -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 {

View file

@ -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)

View file

@ -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 => {},

View file

@ -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,

View file

@ -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,

View file

@ -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) {
{
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),
});
try unit_queue.put(gpa, .wrap(.{ .nav_val = nav_id }), referencer);
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,

View file

@ -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",

View file

@ -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,
}

View file

@ -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 {

View file

@ -927,6 +927,7 @@ pub fn storageClass(module: *Module, as: std.builtin.AddressSpace) spec.StorageC
.gs,
.fs,
.ss,
.far,
.param,
.flash,
.flash1,

View file

@ -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.

View file

@ -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("-nostdinc++");
try cflags.append("-std=c++23");

View file

@ -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",

View file

@ -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",
};

View file

@ -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");
};

View file

@ -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,
},

View file

@ -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,

View file

@ -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;
}

View file

@ -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,
},

View file

@ -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;
}

View file

@ -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" },

View file

@ -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 },

View file

@ -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,

View file

@ -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,

View file

@ -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,
}

View file

@ -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} },

View file

@ -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,
}

View file

@ -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",
},