From a7119d4269f0c31281cd472aab6228593378b294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Wed, 29 Oct 2025 07:32:01 +0100 Subject: [PATCH] remove all IBM AIX and z/OS support As with Solaris (dba1bf935390ddb0184a4dc72245454de6c06fd2), we have no way to actually audit contributions for these OSs. IBM also makes it even harder than Oracle to actually obtain these OSs. closes #23695 closes #23694 closes #3655 closes #23693 --- CMakeLists.txt | 2 - lib/compiler/aro/aro/Compilation.zig | 8 - lib/compiler/aro/aro/Driver.zig | 2 +- lib/compiler/aro/aro/Toolchain.zig | 10 +- lib/compiler/aro/aro/TypeStore.zig | 5 +- lib/compiler/aro/aro/target.zig | 10 +- lib/include/zos_wrappers/builtins.h | 18 - .../__locale_dir/locale_base_api/ibm.h | 108 --- lib/libcxx/include/__support/ibm/gettod_zos.h | 52 -- .../include/__support/ibm/locale_mgmt_zos.h | 53 -- lib/libcxx/include/__support/ibm/nanosleep.h | 55 -- lib/libcxx/src/support/ibm/mbsnrtowcs.cpp | 97 --- lib/libcxx/src/support/ibm/wcsnrtombs.cpp | 94 --- lib/libcxx/src/support/ibm/xlocale_zos.cpp | 130 --- lib/libcxxabi/src/aix_state_tab_eh.inc | 745 ------------------ lib/libtsan/interception/interception_aix.cpp | 45 -- lib/libtsan/interception/interception_aix.h | 36 - lib/libunwind/src/Unwind_AIXExtras.cpp | 63 -- lib/std/Target.zig | 57 +- lib/std/Target/powerpc.zig | 30 - lib/std/builtin.zig | 5 +- lib/std/debug.zig | 2 +- lib/std/zig.zig | 2 +- lib/zig.h | 10 +- src/Compilation/Config.zig | 2 +- src/codegen/llvm.zig | 24 +- src/dev.zig | 4 - src/libs/libcxx.zig | 11 +- src/libs/libtsan.zig | 1 - src/libs/libunwind.zig | 1 - src/link.zig | 22 +- src/link/Elf2.zig | 1 - src/link/Goff.zig | 112 --- src/link/Lld.zig | 1 - src/link/Xcoff.zig | 112 --- src/target.zig | 2 - test/llvm_targets.zig | 3 - tools/update_cpu_features.zig | 22 + 38 files changed, 47 insertions(+), 1910 deletions(-) delete mode 100644 lib/include/zos_wrappers/builtins.h delete mode 100644 lib/libcxx/include/__locale_dir/locale_base_api/ibm.h delete mode 100644 lib/libcxx/include/__support/ibm/gettod_zos.h delete mode 100644 lib/libcxx/include/__support/ibm/locale_mgmt_zos.h delete mode 100644 lib/libcxx/include/__support/ibm/nanosleep.h delete mode 100644 lib/libcxx/src/support/ibm/mbsnrtowcs.cpp delete mode 100644 lib/libcxx/src/support/ibm/wcsnrtombs.cpp delete mode 100644 lib/libcxx/src/support/ibm/xlocale_zos.cpp delete mode 100644 lib/libcxxabi/src/aix_state_tab_eh.inc delete mode 100644 lib/libtsan/interception/interception_aix.cpp delete mode 100644 lib/libtsan/interception/interception_aix.h delete mode 100644 lib/libunwind/src/Unwind_AIXExtras.cpp delete mode 100644 src/link/Goff.zig delete mode 100644 src/link/Xcoff.zig diff --git a/CMakeLists.txt b/CMakeLists.txt index 6efe4e7490..9b71e3c78f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/lib/compiler/aro/aro/Compilation.zig b/lib/compiler/aro/aro/Compilation.zig index fea2ba2a62..2de501e37b 100644 --- a/lib/compiler/aro/aro/Compilation.zig +++ b/lib/compiler/aro/aro/Compilation.zig @@ -362,7 +362,6 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void { .haiku, .hurd, .illumos, - .aix, .emscripten, .ps4, .ps5, @@ -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| { diff --git a/lib/compiler/aro/aro/Driver.zig b/lib/compiler/aro/aro/Driver.zig index 5d87268a5b..ec186a28d2 100644 --- a/lib/compiler/aro/aro/Driver.zig +++ b/lib/compiler/aro/aro/Driver.zig @@ -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, diff --git a/lib/compiler/aro/aro/Toolchain.zig b/lib/compiler/aro/aro/Toolchain.zig index 23e8d929b9..90315ce176 100644 --- a/lib/compiler/aro/aro/Toolchain.zig +++ b/lib/compiler/aro/aro/Toolchain.zig @@ -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; @@ -408,7 +408,7 @@ 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) { @@ -417,11 +417,7 @@ fn addUnwindLibrary(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !voi 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)) { diff --git a/lib/compiler/aro/aro/TypeStore.zig b/lib/compiler/aro/aro/TypeStore.zig index 655211f35b..8f19e318fa 100644 --- a/lib/compiler/aro/aro/TypeStore.zig +++ b/lib/compiler/aro/aro/TypeStore.zig @@ -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, diff --git a/lib/compiler/aro/aro/target.zig b/lib/compiler/aro/aro/target.zig index 080e99d6df..c703b8ed75 100644 --- a/lib/compiler/aro/aro/target.zig +++ b/lib/compiler/aro/aro/target.zig @@ -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) { @@ -656,10 +655,8 @@ pub fn toLLVMTriple(target: std.Target, buf: []u8) []const u8 { .openbsd => "openbsd", .illumos => "solaris", .windows => "windows", - .zos => "zos", .haiku => "haiku", .rtems => "rtems", - .aix => "aix", .cuda => "cuda", .nvcl => "nvcl", .amdhsa => "amdhsa", @@ -741,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, @@ -765,7 +761,6 @@ pub fn isPIEDefault(target: std.Target) DefaultPIStatus { .ps5, .hurd, - .zos, => .no, .openbsd, @@ -810,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, @@ -830,7 +824,6 @@ pub fn isPICdefault(target: std.Target) DefaultPIStatus { .fuchsia, .cuda, - .zos, => .no, .dragonfly, @@ -889,7 +882,7 @@ 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, @@ -903,7 +896,6 @@ pub fn isPICDefaultForced(target: std.Target) DefaultPIStatus { .hurd, .linux, .fuchsia, - .zos, => .no, .windows => { diff --git a/lib/include/zos_wrappers/builtins.h b/lib/include/zos_wrappers/builtins.h deleted file mode 100644 index 1f0d0e27ec..0000000000 --- a/lib/include/zos_wrappers/builtins.h +++ /dev/null @@ -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 -#if defined(__VEC__) -#include -#endif -#endif /* defined(__MVS__) */ -#endif /* __ZOS_WRAPPERS_BUILTINS_H */ diff --git a/lib/libcxx/include/__locale_dir/locale_base_api/ibm.h b/lib/libcxx/include/__locale_dir/locale_base_api/ibm.h deleted file mode 100644 index 1d1d15df9f..0000000000 --- a/lib/libcxx/include/__locale_dir/locale_base_api/ibm.h +++ /dev/null @@ -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 -#include -#include - -#include "cstdlib" - -#if defined(__MVS__) -# include -// 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 diff --git a/lib/libcxx/include/__support/ibm/gettod_zos.h b/lib/libcxx/include/__support/ibm/gettod_zos.h deleted file mode 100644 index bd7e467736..0000000000 --- a/lib/libcxx/include/__support/ibm/gettod_zos.h +++ /dev/null @@ -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 - -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 diff --git a/lib/libcxx/include/__support/ibm/locale_mgmt_zos.h b/lib/libcxx/include/__support/ibm/locale_mgmt_zos.h deleted file mode 100644 index 5fc04b6b4b..0000000000 --- a/lib/libcxx/include/__support/ibm/locale_mgmt_zos.h +++ /dev/null @@ -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 -# include - -# 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 diff --git a/lib/libcxx/include/__support/ibm/nanosleep.h b/lib/libcxx/include/__support/ibm/nanosleep.h deleted file mode 100644 index fadc784c02..0000000000 --- a/lib/libcxx/include/__support/ibm/nanosleep.h +++ /dev/null @@ -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 - -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(sleep(static_cast(__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(__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 diff --git a/lib/libcxx/src/support/ibm/mbsnrtowcs.cpp b/lib/libcxx/src/support/ibm/mbsnrtowcs.cpp deleted file mode 100644 index d0006a8468..0000000000 --- a/lib/libcxx/src/support/ibm/mbsnrtowcs.cpp +++ /dev/null @@ -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 // size_t -#include // mbstate_t -#include // MB_LEN_MAX -#include // 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(0); - const size_t invalid_sequence = static_cast(-1); - const size_t incomplete_sequence = static_cast(-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(-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; -} diff --git a/lib/libcxx/src/support/ibm/wcsnrtombs.cpp b/lib/libcxx/src/support/ibm/wcsnrtombs.cpp deleted file mode 100644 index df87b9ea07..0000000000 --- a/lib/libcxx/src/support/ibm/wcsnrtombs.cpp +++ /dev/null @@ -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 // mbstate_t -#include // MB_LEN_MAX -#include // MB_CUR_MAX, size_t -#include // 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(-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(-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(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; -} diff --git a/lib/libcxx/src/support/ibm/xlocale_zos.cpp b/lib/libcxx/src/support/ibm/xlocale_zos.cpp deleted file mode 100644 index 136999ec0b..0000000000 --- a/lib/libcxx/src/support/ibm/xlocale_zos.cpp +++ /dev/null @@ -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 -#include - -#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 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 diff --git a/lib/libcxxabi/src/aix_state_tab_eh.inc b/lib/libcxxabi/src/aix_state_tab_eh.inc deleted file mode 100644 index 0ed329890a..0000000000 --- a/lib/libcxxabi/src/aix_state_tab_eh.inc +++ /dev/null @@ -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 -#include -#include - -/* - 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(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(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(addr); - - _LIBCXXABI_TRACE_STATETAB("Delete object=%p, fsmEntry=%p\n", reinterpret_cast(objectAddress), - reinterpret_cast(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(_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(p + 1); - - p = reinterpret_cast(&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(p); - p = reinterpret_cast(reinterpret_cast(p) + name_len + sizeof(uint16_t)); - } - - if (TBTable->tb.uses_alloca) - framePointerReg = *reinterpret_cast(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(fsmEntry->address); - _LIBCXXABI_TRACE_STATETAB("Address calculation (global obj) addr=fsmEntry->address=%p\n", addr); - } else if (fsmEntry->flags & FSMEntryFlag::thisFlag) { - addr = reinterpret_cast(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( - *reinterpret_cast(get_frame_addr(context) + static_cast(fsmEntry->offset))); - _LIBCXXABI_TRACE_STATETAB("Address calculation (indirect obj) addr=%p, fsmEntry->offset=%ld \n", - addr, fsmEntry->offset); - } else { - addr = reinterpret_cast(get_frame_addr(context) + static_cast(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(unwind_exception), - reinterpret_cast(context)); - } - - // Start scan by getting state table address. - StateVariable* const state = reinterpret_cast(_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(&currFSMEntry), i + 1, currFSMEntry->offset, - reinterpret_cast(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(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(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(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(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(currFSMEntry->landingPad)); - - state->state = currFSMEntry->nextState; - results.landingPad = reinterpret_cast(*reinterpret_cast(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(*reinterpret_cast(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(*reinterpret_cast(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(_Unwind_GetGR(context, 1)); - uintptr_t *callersSP = reinterpret_cast(currentSP[0]); - callersSP[3] = reinterpret_cast(unwind_exception); - _LIBCXXABI_TRACE_STATETAB("Handshake: save unwind_exception=%p in stack=%p\n", - reinterpret_cast(unwind_exception), reinterpret_cast(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(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(exceptionObject), - reinterpret_cast(&exceptionHeader->unwindHeader)); - exceptionObject = &exceptionHeader->unwindHeader; - } else { - _LIBCXXABI_TRACE_STATETAB("exceptionObject %p is NOT a dependent\n", reinterpret_cast(exceptionObject)); - exceptionHeader = reinterpret_cast<__cxa_exception*>(exceptionObject + 1) - 1; - } - - void* thrownObject = reinterpret_cast(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(exceptionObject), thrownObject, reinterpret_cast(throwType), - throwType->name(), reinterpret_cast(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(&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(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(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(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(__builtin_frame_address(0)); - // Move one frame up to the frame of the caller of __xlc_exception_handle(). - lastStack = reinterpret_cast(lastStack[0]); - // Get the return address of this function, i.e., __xlc_exception_handle(). - uint32_t* returnAddress = reinterpret_cast(__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(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(exceptionObject), reinterpret_cast(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 diff --git a/lib/libtsan/interception/interception_aix.cpp b/lib/libtsan/interception/interception_aix.cpp deleted file mode 100644 index 953bbad96e..0000000000 --- a/lib/libtsan/interception/interception_aix.cpp +++ /dev/null @@ -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 // 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 diff --git a/lib/libtsan/interception/interception_aix.h b/lib/libtsan/interception/interception_aix.h deleted file mode 100644 index b86ae89f50..0000000000 --- a/lib/libtsan/interception/interception_aix.h +++ /dev/null @@ -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 diff --git a/lib/libunwind/src/Unwind_AIXExtras.cpp b/lib/libunwind/src/Unwind_AIXExtras.cpp deleted file mode 100644 index 66194ab4a1..0000000000 --- a/lib/libunwind/src/Unwind_AIXExtras.cpp +++ /dev/null @@ -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 - -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(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(p + 1); - - if (!TBTable->tb.name_present) - return NULL; - - // Get to the name of the function. - p = reinterpret_cast(&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(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(p)); - return reinterpret_cast(p) + sizeof(uint16_t); -} -} // namespace libunwind -#endif // defined(_AIX) diff --git a/lib/std/Target.zig b/lib/std/Target.zig index 26cff86ecd..292af8dad1 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -24,7 +24,6 @@ pub const Os = struct { hermit, managarm, - aix, haiku, hurd, illumos, @@ -32,7 +31,6 @@ pub const Os = struct { plan9, rtems, serenity, - zos, dragonfly, freebsd, @@ -174,9 +172,7 @@ pub const Os = struct { .fuchsia, .hermit, - .aix, .rtems, - .zos, .dragonfly, .freebsd, @@ -418,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 = .{ @@ -494,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 = .{ @@ -825,7 +809,6 @@ pub const Abi = enum { => .eabi, else => .none, }, - .aix => if (arch == .powerpc) .eabihf else .none, .haiku => switch (arch) { .arm, .powerpc, @@ -917,7 +900,6 @@ pub const Abi = enum { .managarm, .plan9, .serenity, - .zos, .dragonfly, .driverkit, .macos, @@ -1006,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. @@ -1020,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 @@ -1030,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", @@ -1040,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, @@ -2030,10 +2006,7 @@ 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. .x86 => &x86.cpu.pentium4, .x86_64 => switch (os.tag) { @@ -2162,7 +2135,6 @@ 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, @@ -2189,7 +2161,6 @@ pub fn requiresLibC(target: *const Target) bool { .fuchsia, .managarm, .ps3, - .zos, .rtems, .cuda, .nvcl, @@ -2347,10 +2318,8 @@ pub const DynamicLinker = struct { .hermit, .managarm, // Needs to be double-checked. - .aix, .plan9, .rtems, - .zos, .uefi, .windows, @@ -2759,10 +2728,8 @@ pub const DynamicLinker = struct { .contiki, .hermit, - .aix, .plan9, .rtems, - .zos, .uefi, .windows, @@ -2916,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, @@ -3112,7 +3079,6 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 { .fuchsia, .hermit, - .aix, .haiku, .hurd, .illumos, @@ -3120,7 +3086,6 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 { .plan9, .rtems, .serenity, - .zos, .freebsd, .dragonfly, @@ -3175,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, }, }, @@ -3191,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, }, }, @@ -3361,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, @@ -3666,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, diff --git a/lib/std/Target/powerpc.zig b/lib/std/Target/powerpc.zig index be68c0ecd5..5348359f96 100644 --- a/lib/std/Target/powerpc.zig +++ b/lib/std/Target/powerpc.zig @@ -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", diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index c0be44b939..2f013a1ea8 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -1031,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) { diff --git a/lib/std/debug.zig b/lib/std/debug.zig index f6287135e5..ad3f2160b1 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -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, }; diff --git a/lib/std/zig.zig b/lib/std/zig.zig index dfae03dea7..9dc3818241 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -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) { diff --git a/lib/zig.h b/lib/zig.h index eebe4cf818..6acbfd0904 100644 --- a/lib/zig.h +++ b/lib/zig.h @@ -87,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 @@ -119,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 diff --git a/src/Compilation/Config.zig b/src/Compilation/Config.zig index a4f8eefab7..c2b9240480 100644 --- a/src/Compilation/Config.zig +++ b/src/Compilation/Config.zig @@ -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, diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 8242958073..5829401e21 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -179,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, @@ -214,10 +211,8 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8 .openbsd => "openbsd", .illumos => "solaris", .windows, .uefi => "windows", - .zos => "zos", .haiku => "haiku", .rtems => "rtems", - .aix => "aix", .cuda => "cuda", .nvcl => "nvcl", .amdhsa => "amdhsa", @@ -382,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 @@ -425,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) @@ -517,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, @@ -12828,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, diff --git a/src/dev.zig b/src/dev.zig index eb5ac52550..1deb3260ac 100644 --- a/src/dev.zig +++ b/src/dev.zig @@ -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. diff --git a/src/libs/libcxx.zig b/src/libs/libcxx.zig index 4e39d1e03a..0956f2e299 100644 --- a/src/libs/libcxx.zig +++ b/src/libs/libcxx.zig @@ -79,9 +79,6 @@ const libcxx_base_files = [_][]const u8{ "src/stdexcept.cpp", "src/string.cpp", "src/strstream.cpp", - "src/support/ibm/mbsnrtowcs.cpp", - "src/support/ibm/wcsnrtombs.cpp", - "src/support/ibm/xlocale_zos.cpp", "src/support/win32/locale_win32.cpp", "src/support/win32/support.cpp", "src/system_error.cpp", @@ -203,8 +200,6 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! continue; if (std.mem.startsWith(u8, cxx_src, "src/support/win32/") and target.os.tag != .windows) continue; - if (std.mem.startsWith(u8, cxx_src, "src/support/ibm/") and target.os.tag != .zos) - continue; var cflags = std.array_list.Managed([]const u8).init(arena); @@ -223,11 +218,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! try cflags.append("-fvisibility=hidden"); try cflags.append("-fvisibility-inlines-hidden"); - if (target.os.tag == .zos) { - try cflags.append("-fno-aligned-allocation"); - } else { - try cflags.append("-faligned-allocation"); - } + try cflags.append("-faligned-allocation"); try cflags.append("-nostdinc++"); try cflags.append("-std=c++23"); diff --git a/src/libs/libtsan.zig b/src/libs/libtsan.zig index 7a72ae2ac3..259fccd26f 100644 --- a/src/libs/libtsan.zig +++ b/src/libs/libtsan.zig @@ -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", diff --git a/src/libs/libunwind.zig b/src/libs/libunwind.zig index 765058087f..6bd13bad51 100644 --- a/src/libs/libunwind.zig +++ b/src/libs/libunwind.zig @@ -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", }; diff --git a/src/link.zig b/src/link.zig index a0acce1073..0efc46c4f1 100644 --- a/src/link.zig +++ b/src/link.zig @@ -574,9 +574,9 @@ pub const File = struct { const gpa = comp.gpa; switch (base.tag) { .lld => assert(base.file == null), - .elf, .macho, .wasm, .goff, .xcoff => { + .elf, .macho, .wasm => { if (base.file != null) return; - dev.checkAny(&.{ .coff_linker, .elf_linker, .macho_linker, .plan9_linker, .wasm_linker, .goff_linker, .xcoff_linker }); + dev.checkAny(&.{ .coff_linker, .elf_linker, .macho_linker, .plan9_linker, .wasm_linker }); const emit = base.emit; if (base.child_pid) |pid| { if (builtin.os.tag == .windows) { @@ -681,8 +681,8 @@ pub const File = struct { } } }, - .macho, .wasm, .goff, .xcoff => if (base.file) |f| { - dev.checkAny(&.{ .coff_linker, .macho_linker, .plan9_linker, .wasm_linker, .goff_linker, .xcoff_linker }); + .macho, .wasm => if (base.file) |f| { + dev.checkAny(&.{ .coff_linker, .macho_linker, .plan9_linker, .wasm_linker }); f.close(); base.file = null; @@ -825,7 +825,6 @@ pub const File = struct { switch (base.tag) { .lld => unreachable, .spirv => {}, - .goff, .xcoff => {}, .plan9 => unreachable, .elf2, .coff2 => {}, inline else => |tag| { @@ -973,7 +972,6 @@ pub const File = struct { .c => unreachable, .spirv => unreachable, .wasm => unreachable, - .goff, .xcoff => unreachable, .plan9 => unreachable, inline else => |tag| { dev.check(tag.devFeature()); @@ -996,7 +994,6 @@ pub const File = struct { .c => unreachable, .spirv => unreachable, .wasm => unreachable, - .goff, .xcoff => unreachable, .plan9 => unreachable, inline else => |tag| { dev.check(tag.devFeature()); @@ -1013,7 +1010,6 @@ pub const File = struct { .c => unreachable, .spirv => unreachable, .wasm => unreachable, - .goff, .xcoff => unreachable, .plan9 => unreachable, inline else => |tag| { dev.check(tag.devFeature()); @@ -1034,8 +1030,6 @@ pub const File = struct { .plan9 => unreachable, .spirv, - .goff, - .xcoff, => {}, inline else => |tag| { @@ -1171,8 +1165,6 @@ pub const File = struct { wasm, spirv, plan9, - goff, - xcoff, lld, pub fn Type(comptime tag: Tag) type { @@ -1184,8 +1176,6 @@ pub const File = struct { .c => C, .wasm => Wasm, .spirv => SpirV, - .goff => Goff, - .xcoff => Xcoff, .lld => Lld, .plan9 => comptime unreachable, }; @@ -1200,8 +1190,6 @@ pub const File = struct { .plan9 => .plan9, .c => .c, .spirv => .spirv, - .goff => .goff, - .xcoff => .xcoff, .hex => @panic("TODO implement hex object format"), .raw => @panic("TODO implement raw object format"), }; @@ -1284,8 +1272,6 @@ pub const File = struct { pub const MachO = @import("link/MachO.zig"); pub const SpirV = @import("link/SpirV.zig"); pub const Wasm = @import("link/Wasm.zig"); - pub const Goff = @import("link/Goff.zig"); - pub const Xcoff = @import("link/Xcoff.zig"); pub const Dwarf = @import("link/Dwarf.zig"); }; diff --git a/src/link/Elf2.zig b/src/link/Elf2.zig index 67c54b72d5..93fa490907 100644 --- a/src/link/Elf2.zig +++ b/src/link/Elf2.zig @@ -418,7 +418,6 @@ fn create( .freestanding, .other => .STANDALONE, .netbsd => .NETBSD, .illumos => .SOLARIS, - .aix => .AIX, .freebsd, .ps4 => .FREEBSD, .openbsd => .OPENBSD, .cuda => .CUDA, diff --git a/src/link/Goff.zig b/src/link/Goff.zig deleted file mode 100644 index 9a39e4b9f8..0000000000 --- a/src/link/Goff.zig +++ /dev/null @@ -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; -} diff --git a/src/link/Lld.zig b/src/link/Lld.zig index 2a3310384b..28a26175b5 100644 --- a/src/link/Lld.zig +++ b/src/link/Lld.zig @@ -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, }, diff --git a/src/link/Xcoff.zig b/src/link/Xcoff.zig deleted file mode 100644 index 127ff18917..0000000000 --- a/src/link/Xcoff.zig +++ /dev/null @@ -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; -} diff --git a/src/target.zig b/src/target.zig index fd7536f7ec..86ae405676 100644 --- a/src/target.zig +++ b/src/target.zig @@ -155,13 +155,11 @@ pub fn hasLlvmSupport(target: *const std.Target, ofmt: std.Target.ObjectFormat) .coff, .elf, - .goff, .hex, .macho, .spirv, .raw, .wasm, - .xcoff, => {}, } diff --git a/test/llvm_targets.zig b/test/llvm_targets.zig index 4fc41b532f..e74c5556e1 100644 --- a/test/llvm_targets.zig +++ b/test/llvm_targets.zig @@ -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 }, diff --git a/tools/update_cpu_features.zig b/tools/update_cpu_features.zig index 29877fff15..a51c6983d4 100644 --- a/tools/update_cpu_features.zig +++ b/tools/update_cpu_features.zig @@ -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", },