authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-29 07:32:01+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-29 14:25:51+01:00
loga7119d4269f0c31281cd472aab6228593378b294
tree409a3b7035331c76fdfaf0ca34a926378f9ee26d
parent6568f0f75b900d2ee27363b2ba81bedf206a13e7

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

38 files changed, 47 insertions(+), 1910 deletions(-)

CMakeLists.txt-2
...@@ -581,7 +581,6 @@ set(ZIG_STAGE2_SOURCES...@@ -581,7 +581,6 @@ set(ZIG_STAGE2_SOURCES
581 src/link/Elf/relocation.zig581 src/link/Elf/relocation.zig
582 src/link/Elf/synthetic_sections.zig582 src/link/Elf/synthetic_sections.zig
583 src/link/Elf2.zig583 src/link/Elf2.zig
584 src/link/Goff.zig
585 src/link/LdScript.zig584 src/link/LdScript.zig
586 src/link/Lld.zig585 src/link/Lld.zig
587 src/link/MachO.zig586 src/link/MachO.zig
...@@ -617,7 +616,6 @@ set(ZIG_STAGE2_SOURCES...@@ -617,7 +616,6 @@ set(ZIG_STAGE2_SOURCES
617 src/link/Wasm/Archive.zig616 src/link/Wasm/Archive.zig
618 src/link/Wasm/Flush.zig617 src/link/Wasm/Flush.zig
619 src/link/Wasm/Object.zig618 src/link/Wasm/Object.zig
620 src/link/Xcoff.zig
621 src/link/aarch64.zig619 src/link/aarch64.zig
622 src/link/riscv.zig620 src/link/riscv.zig
623 src/link/table_section.zig621 src/link/table_section.zig
lib/compiler/aro/aro/Compilation.zig-8
...@@ -362,7 +362,6 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {...@@ -362,7 +362,6 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
362 .haiku,362 .haiku,
363 .hurd,363 .hurd,
364 .illumos,364 .illumos,
365 .aix,
366 .emscripten,365 .emscripten,
367 .ps4,366 .ps4,
368 .ps5,367 .ps5,
...@@ -1006,13 +1005,6 @@ fn writeBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefinesMode...@@ -1006,13 +1005,6 @@ fn writeBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefinesMode
1006 \\1005 \\
1007 );1006 );
1008 },1007 },
1009 .aix => {
1010 try w.writeAll(
1011 \\#define __STDC_NO_THREADS__ 1
1012 \\#define __STDC_NO_ATOMICS__ 1
1013 \\
1014 );
1015 },
1016 else => {},1008 else => {},
1017 };1009 };
1018 if (comp.langopts.standard.StdCVersionMacro()) |stdc_version| {1010 if (comp.langopts.standard.StdCVersionMacro()) |stdc_version| {
lib/compiler/aro/aro/Driver.zig+1-1
...@@ -810,7 +810,7 @@ pub fn parseArgs(...@@ -810,7 +810,7 @@ pub fn parseArgs(
810 if (strip) break :debug .strip;810 if (strip) break :debug .strip;
811 if (debug) |explicit| break :debug explicit;811 if (debug) |explicit| break :debug explicit;
812 break :debug switch (d.comp.target.ofmt) {812 break :debug switch (d.comp.target.ofmt) {
813 .elf, .goff, .macho, .wasm, .xcoff => .{ .dwarf = .@"32" },813 .elf, .macho, .wasm => .{ .dwarf = .@"32" },
814 .coff => .code_view,814 .coff => .code_view,
815 .c => switch (d.comp.target.os.tag) {815 .c => switch (d.comp.target.os.tag) {
816 .windows, .uefi => .code_view,816 .windows, .uefi => .code_view,
lib/compiler/aro/aro/Toolchain.zig+3-7
...@@ -369,7 +369,7 @@ fn getUnwindLibKind(tc: *const Toolchain) !UnwindLibKind {...@@ -369,7 +369,7 @@ fn getUnwindLibKind(tc: *const Toolchain) !UnwindLibKind {
369 switch (tc.getRuntimeLibKind()) {369 switch (tc.getRuntimeLibKind()) {
370 .compiler_rt => {370 .compiler_rt => {
371 const target = tc.getTarget();371 const target = tc.getTarget();
372 if (target.abi.isAndroid() or target.os.tag == .aix) {372 if (target.abi.isAndroid()) {
373 return .compiler_rt;373 return .compiler_rt;
374 } else {374 } else {
375 return .none;375 return .none;
...@@ -408,7 +408,7 @@ fn addUnwindLibrary(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !voi...@@ -408,7 +408,7 @@ fn addUnwindLibrary(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !voi
408 unw == .none) return;408 unw == .none) return;
409409
410 const lgk = tc.getLibGCCKind();410 const lgk = tc.getLibGCCKind();
411 const as_needed = lgk == .unspecified and !target.abi.isAndroid() and !target_util.isCygwinMinGW(target) and target.os.tag != .aix;411 const as_needed = lgk == .unspecified and !target.abi.isAndroid() and !target_util.isCygwinMinGW(target);
412412
413 try argv.ensureUnusedCapacity(tc.driver.comp.gpa, 3);413 try argv.ensureUnusedCapacity(tc.driver.comp.gpa, 3);
414 if (as_needed) {414 if (as_needed) {
...@@ -417,11 +417,7 @@ fn addUnwindLibrary(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !voi...@@ -417,11 +417,7 @@ fn addUnwindLibrary(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !voi
417 switch (unw) {417 switch (unw) {
418 .none => return,418 .none => return,
419 .libgcc => argv.appendAssumeCapacity(if (lgk == .static) "-lgcc_eh" else "-lgcc_s"),419 .libgcc => argv.appendAssumeCapacity(if (lgk == .static) "-lgcc_eh" else "-lgcc_s"),
420 .compiler_rt => if (target.os.tag == .aix) {420 .compiler_rt => if (lgk == .static) {
421 if (lgk != .static) {
422 argv.appendAssumeCapacity("-lunwind");
423 }
424 } else if (lgk == .static) {
425 argv.appendAssumeCapacity("-l:libunwind.a");421 argv.appendAssumeCapacity("-l:libunwind.a");
426 } else if (lgk == .shared) {422 } else if (lgk == .shared) {
427 if (target_util.isCygwinMinGW(target)) {423 if (target_util.isCygwinMinGW(target)) {
lib/compiler/aro/aro/TypeStore.zig+1-4
...@@ -2099,10 +2099,7 @@ fn generateVaListType(ts: *TypeStore, comp: *Compilation) !QualType {...@@ -2099,10 +2099,7 @@ fn generateVaListType(ts: *TypeStore, comp: *Compilation) !QualType {
2099 .hexagon_va_list2099 .hexagon_va_list
2100 else2100 else
2101 return .char_pointer,2101 return .char_pointer,
2102 .powerpc, .powerpcle => switch (comp.target.os.tag) {2102 .powerpc, .powerpcle => .powerpc_va_list,
2103 .aix => return .char_pointer,
2104 else => .powerpc_va_list,
2105 },
2106 .s390x => .s390x_va_list,2103 .s390x => .s390x_va_list,
2107 .x86_64 => switch (comp.target.os.tag) {2104 .x86_64 => switch (comp.target.os.tag) {
2108 .uefi, .windows => return .char_pointer,2105 .uefi, .windows => return .char_pointer,
lib/compiler/aro/aro/target.zig+1-9
...@@ -403,7 +403,6 @@ pub fn builtinEnabled(target: std.Target, enabled_for: TargetSet) bool {...@@ -403,7 +403,6 @@ pub fn builtinEnabled(target: std.Target, enabled_for: TargetSet) bool {
403}403}
404404
405pub fn defaultFpEvalMethod(target: std.Target) LangOpts.FPEvalMethod {405pub fn defaultFpEvalMethod(target: std.Target) LangOpts.FPEvalMethod {
406 if (target.os.tag == .aix) return .double;
407 switch (target.cpu.arch) {406 switch (target.cpu.arch) {
408 .x86, .x86_64 => {407 .x86, .x86_64 => {
409 if (target.ptrBitWidth() == 32 and target.os.tag == .netbsd) {408 if (target.ptrBitWidth() == 32 and target.os.tag == .netbsd) {
...@@ -656,10 +655,8 @@ pub fn toLLVMTriple(target: std.Target, buf: []u8) []const u8 {...@@ -656,10 +655,8 @@ pub fn toLLVMTriple(target: std.Target, buf: []u8) []const u8 {
656 .openbsd => "openbsd",655 .openbsd => "openbsd",
657 .illumos => "solaris",656 .illumos => "solaris",
658 .windows => "windows",657 .windows => "windows",
659 .zos => "zos",
660 .haiku => "haiku",658 .haiku => "haiku",
661 .rtems => "rtems",659 .rtems => "rtems",
662 .aix => "aix",
663 .cuda => "cuda",660 .cuda => "cuda",
664 .nvcl => "nvcl",661 .nvcl => "nvcl",
665 .amdhsa => "amdhsa",662 .amdhsa => "amdhsa",
...@@ -741,7 +738,6 @@ pub const DefaultPIStatus = enum { yes, no, depends_on_linker };...@@ -741,7 +738,6 @@ pub const DefaultPIStatus = enum { yes, no, depends_on_linker };
741738
742pub fn isPIEDefault(target: std.Target) DefaultPIStatus {739pub fn isPIEDefault(target: std.Target) DefaultPIStatus {
743 return switch (target.os.tag) {740 return switch (target.os.tag) {
744 .aix,
745 .haiku,741 .haiku,
746742
747 .macos,743 .macos,
...@@ -765,7 +761,6 @@ pub fn isPIEDefault(target: std.Target) DefaultPIStatus {...@@ -765,7 +761,6 @@ pub fn isPIEDefault(target: std.Target) DefaultPIStatus {
765 .ps5,761 .ps5,
766762
767 .hurd,763 .hurd,
768 .zos,
769 => .no,764 => .no,
770765
771 .openbsd,766 .openbsd,
...@@ -810,7 +805,6 @@ pub fn isPIEDefault(target: std.Target) DefaultPIStatus {...@@ -810,7 +805,6 @@ pub fn isPIEDefault(target: std.Target) DefaultPIStatus {
810805
811pub fn isPICdefault(target: std.Target) DefaultPIStatus {806pub fn isPICdefault(target: std.Target) DefaultPIStatus {
812 return switch (target.os.tag) {807 return switch (target.os.tag) {
813 .aix,
814 .haiku,808 .haiku,
815809
816 .macos,810 .macos,
...@@ -830,7 +824,6 @@ pub fn isPICdefault(target: std.Target) DefaultPIStatus {...@@ -830,7 +824,6 @@ pub fn isPICdefault(target: std.Target) DefaultPIStatus {
830824
831 .fuchsia,825 .fuchsia,
832 .cuda,826 .cuda,
833 .zos,
834 => .no,827 => .no,
835828
836 .dragonfly,829 .dragonfly,
...@@ -889,7 +882,7 @@ pub fn isPICdefault(target: std.Target) DefaultPIStatus {...@@ -889,7 +882,7 @@ pub fn isPICdefault(target: std.Target) DefaultPIStatus {
889882
890pub fn isPICDefaultForced(target: std.Target) DefaultPIStatus {883pub fn isPICDefaultForced(target: std.Target) DefaultPIStatus {
891 return switch (target.os.tag) {884 return switch (target.os.tag) {
892 .aix, .amdhsa, .amdpal, .mesa3d => .yes,885 .amdhsa, .amdpal, .mesa3d => .yes,
893886
894 .haiku,887 .haiku,
895 .dragonfly,888 .dragonfly,
...@@ -903,7 +896,6 @@ pub fn isPICDefaultForced(target: std.Target) DefaultPIStatus {...@@ -903,7 +896,6 @@ pub fn isPICDefaultForced(target: std.Target) DefaultPIStatus {
903 .hurd,896 .hurd,
904 .linux,897 .linux,
905 .fuchsia,898 .fuchsia,
906 .zos,
907 => .no,899 => .no,
908900
909 .windows => {901 .windows => {
lib/include/zos_wrappers/builtins.h deleted-18
...@@ -1,18 +0,0 @@
1/*===---- builtins.h - z/Architecture Builtin Functions --------------------===
2 *
3 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 * See https://llvm.org/LICENSE.txt for license information.
5 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 *
7 *===-----------------------------------------------------------------------===
8 */
9
10#ifndef __ZOS_WRAPPERS_BUILTINS_H
11#define __ZOS_WRAPPERS_BUILTINS_H
12#if defined(__MVS__)
13#include_next <builtins.h>
14#if defined(__VEC__)
15#include <vecintrin.h>
16#endif
17#endif /* defined(__MVS__) */
18#endif /* __ZOS_WRAPPERS_BUILTINS_H */
lib/libcxx/include/__locale_dir/locale_base_api/ibm.h deleted-108
...@@ -1,108 +0,0 @@
1// -*- C++ -*-
2//===-----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_IBM_H
11#define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_IBM_H
12
13#if defined(__MVS__)
14# include <__support/ibm/locale_mgmt_zos.h>
15#endif // defined(__MVS__)
16
17#include <locale.h>
18#include <stdarg.h>
19#include <stdio.h>
20
21#include "cstdlib"
22
23#if defined(__MVS__)
24# include <wctype.h>
25// POSIX routines
26# include <__support/xlocale/__posix_l_fallback.h>
27#endif // defined(__MVS__)
28
29namespace {
30
31struct __setAndRestore {
32 explicit __setAndRestore(locale_t locale) {
33 if (locale == (locale_t)0) {
34 __cloc = newlocale(LC_ALL_MASK, "C", /* base */ (locale_t)0);
35 __stored = uselocale(__cloc);
36 } else {
37 __stored = uselocale(locale);
38 }
39 }
40
41 ~__setAndRestore() {
42 uselocale(__stored);
43 if (__cloc)
44 freelocale(__cloc);
45 }
46
47private:
48 locale_t __stored = (locale_t)0;
49 locale_t __cloc = (locale_t)0;
50};
51
52} // namespace
53
54// The following are not POSIX routines. These are quick-and-dirty hacks
55// to make things pretend to work
56inline _LIBCPP_HIDE_FROM_ABI long long strtoll_l(const char* __nptr, char** __endptr, int __base, locale_t locale) {
57 __setAndRestore __newloc(locale);
58 return ::strtoll(__nptr, __endptr, __base);
59}
60
61inline _LIBCPP_HIDE_FROM_ABI double strtod_l(const char* __nptr, char** __endptr, locale_t locale) {
62 __setAndRestore __newloc(locale);
63 return ::strtod(__nptr, __endptr);
64}
65
66inline _LIBCPP_HIDE_FROM_ABI float strtof_l(const char* __nptr, char** __endptr, locale_t locale) {
67 __setAndRestore __newloc(locale);
68 return ::strtof(__nptr, __endptr);
69}
70
71inline _LIBCPP_HIDE_FROM_ABI long double strtold_l(const char* __nptr, char** __endptr, locale_t locale) {
72 __setAndRestore __newloc(locale);
73 return ::strtold(__nptr, __endptr);
74}
75
76inline _LIBCPP_HIDE_FROM_ABI unsigned long long
77strtoull_l(const char* __nptr, char** __endptr, int __base, locale_t locale) {
78 __setAndRestore __newloc(locale);
79 return ::strtoull(__nptr, __endptr, __base);
80}
81
82inline _LIBCPP_HIDE_FROM_ABI
83_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 2, 0) int vasprintf(char** strp, const char* fmt, va_list ap) {
84 const size_t buff_size = 256;
85 if ((*strp = (char*)malloc(buff_size)) == nullptr) {
86 return -1;
87 }
88
89 va_list ap_copy;
90 // va_copy may not be provided by the C library in C++03 mode.
91#if defined(_LIBCPP_CXX03_LANG) && __has_builtin(__builtin_va_copy)
92 __builtin_va_copy(ap_copy, ap);
93#else
94 va_copy(ap_copy, ap);
95#endif
96 int str_size = vsnprintf(*strp, buff_size, fmt, ap_copy);
97 va_end(ap_copy);
98
99 if ((size_t)str_size >= buff_size) {
100 if ((*strp = (char*)realloc(*strp, str_size + 1)) == nullptr) {
101 return -1;
102 }
103 str_size = vsnprintf(*strp, str_size + 1, fmt, ap);
104 }
105 return str_size;
106}
107
108#endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_IBM_H
lib/libcxx/include/__support/ibm/gettod_zos.h deleted-52
...@@ -1,52 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___SUPPORT_IBM_GETTOD_ZOS_H
11#define _LIBCPP___SUPPORT_IBM_GETTOD_ZOS_H
12
13#include <time.h>
14
15inline _LIBCPP_HIDE_FROM_ABI int gettimeofdayMonotonic(struct timespec64* Output) {
16 // The POSIX gettimeofday() function is not available on z/OS. Therefore,
17 // we will call stcke and other hardware instructions in implement equivalent.
18 // Note that nanoseconds alone will overflow when reaching new epoch in 2042.
19
20 struct _t {
21 uint64_t Hi;
22 uint64_t Lo;
23 };
24 struct _t Value = {0, 0};
25 uint64_t CC = 0;
26 asm(" stcke %0\n"
27 " ipm %1\n"
28 " srlg %1,%1,28\n"
29 : "=m"(Value), "+r"(CC)::);
30
31 if (CC != 0) {
32 errno = EMVSTODNOTSET;
33 return CC;
34 }
35 uint64_t us = (Value.Hi >> 4);
36 uint64_t ns = ((Value.Hi & 0x0F) << 8) + (Value.Lo >> 56);
37 ns = (ns * 1000) >> 12;
38 us = us - 2208988800000000;
39
40 register uint64_t DivPair0 asm("r0"); // dividend (upper half), remainder
41 DivPair0 = 0;
42 register uint64_t DivPair1 asm("r1"); // dividend (lower half), quotient
43 DivPair1 = us;
44 uint64_t Divisor = 1000000;
45 asm(" dlgr %0,%2" : "+r"(DivPair0), "+r"(DivPair1) : "r"(Divisor) :);
46
47 Output->tv_sec = DivPair1;
48 Output->tv_nsec = DivPair0 * 1000 + ns;
49 return 0;
50}
51
52#endif // _LIBCPP___SUPPORT_IBM_GETTOD_ZOS_H
lib/libcxx/include/__support/ibm/locale_mgmt_zos.h deleted-53
...@@ -1,53 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___SUPPORT_IBM_LOCALE_MGMT_ZOS_H
11#define _LIBCPP___SUPPORT_IBM_LOCALE_MGMT_ZOS_H
12
13#if defined(__MVS__)
14# include <locale.h>
15# include <string>
16
17# ifdef __cplusplus
18extern "C" {
19# endif
20
21# define _LC_MAX LC_MESSAGES /* highest real category */
22# define _NCAT (_LC_MAX + 1) /* maximum + 1 */
23
24# define _CATMASK(n) (1 << (n))
25# define LC_COLLATE_MASK _CATMASK(LC_COLLATE)
26# define LC_CTYPE_MASK _CATMASK(LC_CTYPE)
27# define LC_MONETARY_MASK _CATMASK(LC_MONETARY)
28# define LC_NUMERIC_MASK _CATMASK(LC_NUMERIC)
29# define LC_TIME_MASK _CATMASK(LC_TIME)
30# define LC_MESSAGES_MASK _CATMASK(LC_MESSAGES)
31# define LC_ALL_MASK (_CATMASK(_NCAT) - 1)
32
33typedef struct locale_struct {
34 int category_mask;
35 std::string lc_collate;
36 std::string lc_ctype;
37 std::string lc_monetary;
38 std::string lc_numeric;
39 std::string lc_time;
40 std::string lc_messages;
41}* locale_t;
42
43// z/OS does not have newlocale, freelocale and uselocale.
44// The functions below are workarounds in single thread mode.
45locale_t newlocale(int category_mask, const char* locale, locale_t base);
46void freelocale(locale_t locobj);
47locale_t uselocale(locale_t newloc);
48
49# ifdef __cplusplus
50}
51# endif
52#endif // defined(__MVS__)
53#endif // _LIBCPP___SUPPORT_IBM_LOCALE_MGMT_ZOS_H
lib/libcxx/include/__support/ibm/nanosleep.h deleted-55
...@@ -1,55 +0,0 @@
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___SUPPORT_IBM_NANOSLEEP_H
11#define _LIBCPP___SUPPORT_IBM_NANOSLEEP_H
12
13#include <unistd.h>
14
15inline int nanosleep(const struct timespec* __req, struct timespec* __rem) {
16 // The nanosleep() function is not available on z/OS. Therefore, we will call
17 // sleep() to sleep for whole seconds and usleep() to sleep for any remaining
18 // fraction of a second. Any remaining nanoseconds will round up to the next
19 // microsecond.
20 if (__req->tv_sec < 0 || __req->tv_nsec < 0 || __req->tv_nsec > 999999999) {
21 errno = EINVAL;
22 return -1;
23 }
24 long __micro_sec = (__req->tv_nsec + 999) / 1000;
25 time_t __sec = __req->tv_sec;
26 if (__micro_sec > 999999) {
27 ++__sec;
28 __micro_sec -= 1000000;
29 }
30 __sec = static_cast<time_t>(sleep(static_cast<unsigned int>(__sec)));
31 if (__sec) {
32 if (__rem) {
33 // Updating the remaining time to sleep in case of unsuccessful call to sleep().
34 __rem->tv_sec = __sec;
35 __rem->tv_nsec = __micro_sec * 1000;
36 }
37 errno = EINTR;
38 return -1;
39 }
40 if (__micro_sec) {
41 int __rt = usleep(static_cast<unsigned int>(__micro_sec));
42 if (__rt != 0 && __rem) {
43 // The usleep() does not provide the amount of remaining time upon its failure,
44 // so the time slept will be ignored.
45 __rem->tv_sec = 0;
46 __rem->tv_nsec = __micro_sec * 1000;
47 // The errno is already set.
48 return -1;
49 }
50 return __rt;
51 }
52 return 0;
53}
54
55#endif // _LIBCPP___SUPPORT_IBM_NANOSLEEP_H
lib/libcxx/src/support/ibm/mbsnrtowcs.cpp deleted-97
...@@ -1,97 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <cstddef> // size_t
10#include <cwchar> // mbstate_t
11#include <limits.h> // MB_LEN_MAX
12#include <string.h> // wmemcpy
13
14// Returns the number of wide characters found in the multi byte sequence `src`
15// (of `src_size_bytes`), that fit in the buffer `dst` (of `max_dest_chars`
16// elements size). The count returned excludes the null terminator.
17// When `dst` is NULL, no characters are copied to `dst`.
18// Returns (size_t) -1 when an invalid sequence is encountered.
19// Leaves *`src` pointing to the next character to convert or NULL
20// if a null character was converted from *`src`.
21_LIBCPP_EXPORTED_FROM_ABI size_t mbsnrtowcs(
22 wchar_t* __restrict dst,
23 const char** __restrict src,
24 size_t src_size_bytes,
25 size_t max_dest_chars,
26 mbstate_t* __restrict ps) {
27 const size_t terminated_sequence = static_cast<size_t>(0);
28 const size_t invalid_sequence = static_cast<size_t>(-1);
29 const size_t incomplete_sequence = static_cast<size_t>(-2);
30
31 size_t source_converted;
32 size_t dest_converted;
33 size_t result = 0;
34
35 // If `dst` is null then `max_dest_chars` should be ignored according to the
36 // standard. Setting `max_dest_chars` to a large value has this effect.
37 if (dst == nullptr)
38 max_dest_chars = static_cast<size_t>(-1);
39
40 for (dest_converted = source_converted = 0;
41 source_converted < src_size_bytes && (!dst || dest_converted < max_dest_chars);
42 ++dest_converted, source_converted += result) {
43 // Converts one multi byte character.
44 // If result (char_size) is greater than 0, it's the size in bytes of that character.
45 // If result (char_size) is zero, it indicates that the null character has been found.
46 // Otherwise, it's an error and errno may be set.
47 size_t source_remaining = src_size_bytes - source_converted;
48 size_t dest_remaining = max_dest_chars - dest_converted;
49
50 if (dst == nullptr) {
51 result = mbrtowc(nullptr, *src + source_converted, source_remaining, ps);
52 } else if (dest_remaining >= source_remaining) {
53 // dst has enough space to translate in-place.
54 result = mbrtowc(dst + dest_converted, *src + source_converted, source_remaining, ps);
55 } else {
56 /*
57 * dst may not have enough space, so use a temporary buffer.
58 *
59 * We need to save a copy of the conversion state
60 * here so we can restore it if the multibyte
61 * character is too long for the buffer.
62 */
63 wchar_t buff[MB_LEN_MAX];
64 mbstate_t mbstate_tmp;
65
66 if (ps != nullptr)
67 mbstate_tmp = *ps;
68 result = mbrtowc(buff, *src + source_converted, source_remaining, ps);
69
70 if (result > dest_remaining) {
71 // Multi-byte sequence for character won't fit.
72 if (ps != nullptr)
73 *ps = mbstate_tmp;
74 break;
75 } else {
76 // The buffer was used, so we need copy the translation to dst.
77 wmemcpy(dst, buff, result);
78 }
79 }
80
81 // Don't do anything to change errno from here on.
82 if (result == invalid_sequence || result == terminated_sequence || result == incomplete_sequence) {
83 break;
84 }
85 }
86
87 if (dst) {
88 if (result == terminated_sequence)
89 *src = nullptr;
90 else
91 *src += source_converted;
92 }
93 if (result == invalid_sequence)
94 return invalid_sequence;
95
96 return dest_converted;
97}
lib/libcxx/src/support/ibm/wcsnrtombs.cpp deleted-94
...@@ -1,94 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <cwchar> // mbstate_t
10#include <limits.h> // MB_LEN_MAX
11#include <stdlib.h> // MB_CUR_MAX, size_t
12#include <string.h> // memcpy
13
14// Converts `max_source_chars` from the wide character buffer pointer to by *`src`,
15// into the multi byte character sequence buffer stored at `dst`, which must be
16// `dst_size_bytes` bytes in size. Returns the number of bytes in the sequence
17// converted from *src, excluding the null terminator.
18// Returns (size_t) -1 if an error occurs and sets errno.
19// If `dst` is NULL, `dst_size_bytes` is ignored and no bytes are copied to `dst`.
20_LIBCPP_EXPORTED_FROM_ABI size_t wcsnrtombs(
21 char* __restrict dst,
22 const wchar_t** __restrict src,
23 size_t max_source_chars,
24 size_t dst_size_bytes,
25 mbstate_t* __restrict ps) {
26 const size_t invalid_wchar = static_cast<size_t>(-1);
27
28 size_t source_converted;
29 size_t dest_converted;
30 size_t result = 0;
31
32 // If `dst` is null then `dst_size_bytes` should be ignored according to the
33 // standard. Setting dst_size_bytes to a large value has this effect.
34 if (dst == nullptr)
35 dst_size_bytes = static_cast<size_t>(-1);
36
37 for (dest_converted = source_converted = 0;
38 source_converted < max_source_chars && (!dst || dest_converted < dst_size_bytes);
39 ++source_converted, dest_converted += result) {
40 wchar_t c = (*src)[source_converted];
41 size_t dest_remaining = dst_size_bytes - dest_converted;
42
43 if (dst == nullptr) {
44 result = wcrtomb(nullptr, c, ps);
45 } else if (dest_remaining >= static_cast<size_t>(MB_CUR_MAX)) {
46 // dst has enough space to translate in-place.
47 result = wcrtomb(dst + dest_converted, c, ps);
48 } else {
49 /*
50 * dst may not have enough space, so use a temporary buffer.
51 *
52 * We need to save a copy of the conversion state
53 * here so we can restore it if the multibyte
54 * character is too long for the buffer.
55 */
56 char buff[MB_LEN_MAX];
57 mbstate_t mbstate_tmp;
58
59 if (ps != nullptr)
60 mbstate_tmp = *ps;
61 result = wcrtomb(buff, c, ps);
62
63 if (result > dest_remaining) {
64 // Multi-byte sequence for character won't fit.
65 if (ps != nullptr)
66 *ps = mbstate_tmp;
67 if (result != invalid_wchar)
68 break;
69 } else {
70 // The buffer was used, so we need copy the translation to dst.
71 memcpy(dst, buff, result);
72 }
73 }
74
75 // result (char_size) contains the size of the multi-byte-sequence converted.
76 // Otherwise, result (char_size) is (size_t) -1 and wcrtomb() sets the errno.
77 if (result == invalid_wchar) {
78 if (dst)
79 *src = *src + source_converted;
80 return invalid_wchar;
81 }
82
83 if (c == L'\0') {
84 if (dst)
85 *src = nullptr;
86 return dest_converted;
87 }
88 }
89
90 if (dst)
91 *src = *src + source_converted;
92
93 return dest_converted;
94}
lib/libcxx/src/support/ibm/xlocale_zos.cpp deleted-130
...@@ -1,130 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <__assert>
10#include <__support/ibm/xlocale.h>
11#include <sstream>
12#include <vector>
13
14#ifdef __cplusplus
15extern "C" {
16#endif // __cplusplus
17
18locale_t newlocale(int category_mask, const char* locale, locale_t base) {
19 // Maintain current locale name(s) to restore later.
20 std::string current_loc_name(setlocale(LC_ALL, 0));
21
22 // Check for errors.
23 if (category_mask == LC_ALL_MASK && setlocale(LC_ALL, locale) == nullptr) {
24 errno = EINVAL;
25 return (locale_t)0;
26 } else {
27 for (int _Cat = 0; _Cat <= _LC_MAX; ++_Cat) {
28 if ((_CATMASK(_Cat) & category_mask) != 0 && setlocale(_Cat, locale) == nullptr) {
29 setlocale(LC_ALL, current_loc_name.c_str());
30 errno = EINVAL;
31 return (locale_t)0;
32 }
33 }
34 }
35
36 // Create new locale.
37 locale_t newloc = new locale_struct();
38
39 if (base) {
40 if (category_mask != LC_ALL_MASK) {
41 // Copy base when it will not be overwritten.
42 memcpy(newloc, base, sizeof(locale_struct));
43 newloc->category_mask = category_mask | base->category_mask;
44 }
45 delete base;
46 } else {
47 newloc->category_mask = category_mask;
48 }
49
50 if (category_mask & LC_COLLATE_MASK)
51 newloc->lc_collate = locale;
52 if (category_mask & LC_CTYPE_MASK)
53 newloc->lc_ctype = locale;
54 if (category_mask & LC_MONETARY_MASK)
55 newloc->lc_monetary = locale;
56 if (category_mask & LC_NUMERIC_MASK)
57 newloc->lc_numeric = locale;
58 if (category_mask & LC_TIME_MASK)
59 newloc->lc_time = locale;
60 if (category_mask & LC_MESSAGES_MASK)
61 newloc->lc_messages = locale;
62
63 // Restore current locale.
64 setlocale(LC_ALL, current_loc_name.c_str());
65 return (locale_t)newloc;
66}
67
68void freelocale(locale_t locobj) { delete locobj; }
69
70locale_t uselocale(locale_t newloc) {
71 // Maintain current locale name(s).
72 std::string current_loc_name(setlocale(LC_ALL, 0));
73
74 if (newloc) {
75 // Set locales and check for errors.
76 bool is_error =
77 (newloc->category_mask & LC_COLLATE_MASK && setlocale(LC_COLLATE, newloc->lc_collate.c_str()) == nullptr) ||
78 (newloc->category_mask & LC_CTYPE_MASK && setlocale(LC_CTYPE, newloc->lc_ctype.c_str()) == nullptr) ||
79 (newloc->category_mask & LC_MONETARY_MASK && setlocale(LC_MONETARY, newloc->lc_monetary.c_str()) == nullptr) ||
80 (newloc->category_mask & LC_NUMERIC_MASK && setlocale(LC_NUMERIC, newloc->lc_numeric.c_str()) == nullptr) ||
81 (newloc->category_mask & LC_TIME_MASK && setlocale(LC_TIME, newloc->lc_time.c_str()) == nullptr) ||
82 (newloc->category_mask & LC_MESSAGES_MASK && setlocale(LC_MESSAGES, newloc->lc_messages.c_str()) == nullptr);
83
84 if (is_error) {
85 setlocale(LC_ALL, current_loc_name.c_str());
86 errno = EINVAL;
87 return (locale_t)0;
88 }
89 }
90
91 // Construct and return previous locale.
92 locale_t previous_loc = new locale_struct();
93
94 // current_loc_name might be a comma-separated locale name list.
95 if (current_loc_name.find(',') != std::string::npos) {
96 // Tokenize locale name list.
97 const char delimiter = ',';
98 std::vector<std::string> tokenized;
99 std::stringstream ss(current_loc_name);
100 std::string s;
101
102 while (std::getline(ss, s, delimiter)) {
103 tokenized.push_back(s);
104 }
105
106 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(tokenized.size() >= _NCAT, "locale-name list is too short");
107
108 previous_loc->lc_collate = tokenized[LC_COLLATE];
109 previous_loc->lc_ctype = tokenized[LC_CTYPE];
110 previous_loc->lc_monetary = tokenized[LC_MONETARY];
111 previous_loc->lc_numeric = tokenized[LC_NUMERIC];
112 previous_loc->lc_time = tokenized[LC_TIME];
113 // Skip LC_TOD.
114 previous_loc->lc_messages = tokenized[LC_MESSAGES];
115 } else {
116 previous_loc->lc_collate = current_loc_name;
117 previous_loc->lc_ctype = current_loc_name;
118 previous_loc->lc_monetary = current_loc_name;
119 previous_loc->lc_numeric = current_loc_name;
120 previous_loc->lc_time = current_loc_name;
121 previous_loc->lc_messages = current_loc_name;
122 }
123
124 previous_loc->category_mask = LC_ALL_MASK;
125 return previous_loc;
126}
127
128#ifdef __cplusplus
129}
130#endif // __cplusplus
lib/libcxxabi/src/aix_state_tab_eh.inc deleted-745
...@@ -1,745 +0,0 @@
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//
8// This file implements the personality and helper functions for the state
9// table based EH used by IBM legacy compilers xlC and xlclang++ on AIX.
10//
11//===----------------------------------------------------------------------===//
12
13#include <new>
14#include <stdio.h>
15#include <sys/debug.h>
16
17/*
18 The legacy IBM xlC and xlclang++ compilers use the state table for EH
19 instead of the range table. Destructors, or addresses of the possible catch
20 sites or cleanup code are specified in the state table which is a finite
21 state machine (FSM). Each function that has a state table also has an
22 autolocal state variable. The state variable represents the current state
23 of the function for EH and is found through the traceback table of the
24 function during unwinding, which is located at the end of each function.
25 The FSM is an array of state entries. Each state entry has the following
26 fields:
27
28 * offset/address/pointer - the offset used to locate the object, or the
29 address of a global object, or the address of the next state if it is an
30 old conditional state change entry;
31 * dtor/landing pad - address of the destructor function to invoke,
32 or address of the catch block or cleanup code in the user code to branch to;
33 * element count/action flag - the number of elements or the flag for actions;
34 * element size - if the object is an array this is the size of one element
35 of the array;
36 * flags - flags used to control how fields in the entry are interpreted;
37 * next state - the state to execute next after the action for this state is
38 performed. The value of zero indicates the end of the state for this
39 function.
40
41 The following is the description of 'element count/action flag' field.
42+-----------------------------------------------------------------------------+
43| value | description | action |
44+-------+------------------------+--------------------------------------------+
45| > 1 | object is an array | calls __cxa_vec_cleanup to run dtor for |
46| | | each member of the array |
47+-------+------------------------+--------------------------------------------+
48| 1, 0 | object is a scalar | calls dtor for the object |
49+-------+------------------------+--------------------------------------------+
50| -1 | begin catch | branches to the handler which performes |
51| | | catch-match. If there is no catch that |
52| | | matches the exception it will be rethrown |
53+-------+------------------------+--------------------------------------------+
54| -2 | end catch | ends current catch block and continues |
55| | | attempting to catch the exception |
56+-------+------------------------+--------------------------------------------+
57| -3 | delete the object | calls the delete function of the object |
58+-------+------------------------+--------------------------------------------+
59| -4 | cleanup label | branches to the user code for cleaning up |
60+-------+------------------------+--------------------------------------------+
61*/
62
63namespace __cxxabiv1 {
64
65extern "C" {
66
67// Macros for debugging the state table parsing.
68#ifdef NDEBUG
69# define _LIBCXXABI_TRACE_STATETAB(msg, ...)
70# define _LIBCXXABI_TRACE_STATETAB0(msg)
71# define _LIBCXXABI_TRACE_STATETAB1(msg)
72# define _LIBCXXABI_TRACING_STATETAB 0
73#else
74static bool state_tab_dbg() {
75 static bool checked = false;
76 static bool log = false;
77 if (!checked) {
78 log = (getenv("LIBCXXABI_PRINT_STATTAB") != NULL);
79 checked = true;
80 }
81 return log;
82}
83
84# define _LIBCXXABI_TRACE_STATETAB(msg, ...) \
85 do { \
86 if (state_tab_dbg()) \
87 fprintf(stderr, "libcxxabi: " msg, __VA_ARGS__); \
88 } while (0)
89# define _LIBCXXABI_TRACE_STATETAB0(msg) \
90 do { \
91 if (state_tab_dbg()) \
92 fprintf(stderr, "libcxxabi: " msg); \
93 } while (0)
94# define _LIBCXXABI_TRACE_STATETAB1(msg) \
95 do { \
96 if (state_tab_dbg()) \
97 fprintf(stderr, msg); \
98 } while (0)
99
100# define _LIBCXXABI_TRACING_STATETAB state_tab_dbg()
101#endif // NDEBUG
102
103namespace __state_table_eh {
104
105// Definition of flags for the state table entry field 'action flag'.
106enum FSMEntryCount : intptr_t { beginCatch = -1, endCatch = -2, deleteObject = -3, cleanupLabel = -4, terminate = -5 };
107
108// Definition of flags for the state table entry field 'flags'.
109enum FSMEntryFlag : int16_t {
110 indirect = 0x100, // Object was thrown from a function where
111 // the return value optimization was used.
112 oldConditionalStateChange = 0x400, // State table entry is an indirect state
113 // change, dereference the address in
114 // offset as int for the target state.
115 // This is deprecated. This indicates
116 // the address is direct. (static local).
117 conditionalStateChange = 0x800, // State table entry is an indirect state
118 // change, dereference the address in
119 // offset as int for the target state.
120 // The temporary is an automatic. State
121 // change is used in cases such as
122 // (b?(T1(),foo()):(T2(),foo())),throw 42;
123 // which causes a conditional state change
124 // so that we know if T1 or T2 need to be
125 // destroyed.
126 thisFlag = 0x01, // The address of the object for the
127 // cleanup action is based on the
128 // StateVariable::thisValue.
129 vBaseFlag = 0x02, // The object is of a virtual base class.
130 globalObj = 0x04 // FSMEntry::address is the address of
131 // a global object.
132};
133
134namespace {
135// The finite state machine to be walked.
136struct FSMEntry {
137 union {
138 // Offset of the object within its stack frame or containing object.
139 intptr_t offset;
140 // Address of a global object.
141 intptr_t address;
142 // Address of the next state if it is an old conditional state change entry.
143 intptr_t nextStatePtr;
144 };
145 union {
146 // Address of the destructor function with 1 argument.
147 void (*destructor)(void*);
148 // Address of the destructor function with 2 arguments.
149 void (*xlCDestructor)(void*, size_t);
150 // The address of the catch block or cleanup code.
151 void* landingPad;
152 };
153 union {
154 // The flag for actions (when the value is negative).
155 FSMEntryCount actionFlag;
156 // The element count (when the value is positive or zero).
157 size_t elementCount;
158 };
159 size_t elemSize;
160 FSMEntryFlag flags;
161 uint16_t nextState;
162};
163
164struct FSM {
165 uint32_t magic; // Magic number of the state table.
166 int32_t numberOfStates;
167 FSMEntry table[1]; // Actually table[numberOfStates].
168};
169
170// The state variable on the stack.
171struct StateVariable {
172 int32_t state;
173 struct FSM* table;
174 intptr_t thisValue;
175 int32_t ignoreVBasePtrs;
176};
177} // namespace
178
179// State table magic number
180enum FSMMagic : uint32_t {
181 number = 0xbeefdead, // State table generated by xlC compiler.
182 number2 = 0xbeeedead, // State table generated by early version xlC compiler.
183 number3 = 0x1cedbeef // State table generated by xlclang++ compiler.
184};
185
186constexpr size_t dtorArgument = 0x02; // Flag to destructor indicating to free
187 // virtual bases, don't delete object.
188
189static void invoke_destructor(FSMEntry* fsmEntry, void* addr) {
190 _LIBCXXABI_TRACE_STATETAB("Destruct object=%p, fsmEntry=%p\n", addr, reinterpret_cast<void*>(fsmEntry));
191 try {
192 if (fsmEntry->elementCount == 1) {
193 _LIBCXXABI_TRACE_STATETAB0("calling scalar destructor\n");
194 (*fsmEntry->xlCDestructor)(addr, dtorArgument);
195 _LIBCXXABI_TRACE_STATETAB0("returned from scalar destructor\n");
196 } else {
197 _LIBCXXABI_TRACE_STATETAB0("calling vector destructor\n");
198 __cxa_vec_cleanup(addr, reinterpret_cast<size_t>(fsmEntry->elementCount), fsmEntry->elemSize,
199 fsmEntry->destructor);
200 _LIBCXXABI_TRACE_STATETAB0("returned from vector destructor\n");
201 }
202 } catch (...) {
203 _LIBCXXABI_TRACE_STATETAB0("Uncaught exception in destructor, terminating\n");
204 std::terminate();
205 }
206}
207
208static void invoke_delete(FSMEntry* fsmEntry, void* addr) {
209 char* objectAddress = *reinterpret_cast<char**>(addr);
210
211 _LIBCXXABI_TRACE_STATETAB("Delete object=%p, fsmEntry=%p\n", reinterpret_cast<void*>(objectAddress),
212 reinterpret_cast<void*>(fsmEntry));
213 try {
214 _LIBCXXABI_TRACE_STATETAB0("..calling delete()\n");
215 // 'destructor' holds a function pointer to delete().
216 (*fsmEntry->xlCDestructor)(objectAddress, fsmEntry->elemSize);
217 _LIBCXXABI_TRACE_STATETAB0("..returned from delete()\n");
218 } catch (...) {
219 _LIBCXXABI_TRACE_STATETAB0("Uncaught exception in delete(), terminating\n");
220 std::terminate();
221 }
222}
223
224// Get the frame address of the current function from its traceback table
225// which is at the end of each function.
226static uintptr_t get_frame_addr(_Unwind_Context* context) {
227 int framePointerReg = 1; // default frame pointer == SP.
228 uint32_t* p = reinterpret_cast<uint32_t*>(_Unwind_GetIP(context));
229
230 // Keep looking forward until a word of 0 is found. The traceback
231 // table starts at the following word.
232 while (*p)
233 ++p;
234 tbtable* TBTable = reinterpret_cast<tbtable*>(p + 1);
235
236 p = reinterpret_cast<uint32_t*>(&TBTable->tb_ext);
237
238 // Skip field parminfo if it exists.
239 if (TBTable->tb.fixedparms || TBTable->tb.floatparms)
240 ++p;
241
242 // Skip field tb_offset if it exists.
243 if (TBTable->tb.has_tboff)
244 ++p;
245
246 // Skip field hand_mask if it exists.
247 if (TBTable->tb.int_hndl)
248 ++p;
249
250 // Skip fields ctl_info and ctl_info_disp if they exist.
251 if (TBTable->tb.has_ctl)
252 p += 1 + *p;
253
254 // Skip fields name_len and name if exist.
255 if (TBTable->tb.name_present) {
256 const uint16_t name_len = *reinterpret_cast<uint16_t*>(p);
257 p = reinterpret_cast<uint32_t*>(reinterpret_cast<char*>(p) + name_len + sizeof(uint16_t));
258 }
259
260 if (TBTable->tb.uses_alloca)
261 framePointerReg = *reinterpret_cast<char*>(p);
262
263 return _Unwind_GetGR(context, framePointerReg);
264}
265
266// Calculate the object address from the FSM entry.
267static void* compute_addr_from_table(FSMEntry* fsmEntry, StateVariable* const state, _Unwind_Context* context) {
268 void* addr;
269 if (fsmEntry->flags & FSMEntryFlag::globalObj) {
270 addr = reinterpret_cast<void*>(fsmEntry->address);
271 _LIBCXXABI_TRACE_STATETAB("Address calculation (global obj) addr=fsmEntry->address=%p\n", addr);
272 } else if (fsmEntry->flags & FSMEntryFlag::thisFlag) {
273 addr = reinterpret_cast<void*>(state->thisValue + fsmEntry->offset);
274 _LIBCXXABI_TRACE_STATETAB("Address calculation (this obj) fsmEntry->offset=%ld : "
275 "state->thisValue=%ld addr=(fsmEntry->offset+state->thisValue)=%p\n",
276 fsmEntry->offset, state->thisValue, addr);
277 } else if (fsmEntry->flags & FSMEntryFlag::indirect) {
278 addr = reinterpret_cast<void*>(
279 *reinterpret_cast<char**>(get_frame_addr(context) + static_cast<uintptr_t>(fsmEntry->offset)));
280 _LIBCXXABI_TRACE_STATETAB("Address calculation (indirect obj) addr=%p, fsmEntry->offset=%ld \n",
281 addr, fsmEntry->offset);
282 } else {
283 addr = reinterpret_cast<void*>(get_frame_addr(context) + static_cast<uintptr_t>(fsmEntry->offset));
284 _LIBCXXABI_TRACE_STATETAB("Address calculation. (local obj) addr=fsmEntry->offset=%p\n",
285 addr);
286 }
287 return addr;
288}
289
290static void scan_state_tab(scan_results& results, _Unwind_Action actions, bool native_exception,
291 _Unwind_Exception* unwind_exception, _Unwind_Context* context) {
292 // Initialize results to found nothing but an error.
293 results.ttypeIndex = 0;
294 results.actionRecord = 0;
295 results.languageSpecificData = 0;
296 results.landingPad = 0;
297 results.adjustedPtr = 0;
298 results.reason = _URC_FATAL_PHASE1_ERROR;
299
300 // Check for consistent actions.
301 if (actions & _UA_SEARCH_PHASE) {
302 // Do Phase 1
303 if (actions & (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME | _UA_FORCE_UNWIND)) {
304 // None of these flags should be set during Phase 1.
305 // Client error
306 results.reason = _URC_FATAL_PHASE1_ERROR;
307 return;
308 }
309 } else if (actions & _UA_CLEANUP_PHASE) {
310 if ((actions & _UA_HANDLER_FRAME) && (actions & _UA_FORCE_UNWIND)) {
311 // _UA_HANDLER_FRAME should only be set if phase 1 found a handler.
312 // If _UA_FORCE_UNWIND is set, phase 1 shouldn't have happened.
313 // Client error
314 results.reason = _URC_FATAL_PHASE2_ERROR;
315 return;
316 }
317 } else {
318 // Neither _UA_SEARCH_PHASE nor _UA_CLEANUP_PHASE is set.
319 // Client error
320 results.reason = _URC_FATAL_PHASE1_ERROR;
321 return;
322 }
323
324 if (_LIBCXXABI_TRACING_STATETAB) {
325 _LIBCXXABI_TRACE_STATETAB1("\n");
326 _LIBCXXABI_TRACE_STATETAB("%s: actions=%d (", __func__, actions);
327
328 if (_UA_SEARCH_PHASE & actions)
329 _LIBCXXABI_TRACE_STATETAB1("_UA_SEARCH_PHASE ");
330 if (_UA_CLEANUP_PHASE & actions)
331 _LIBCXXABI_TRACE_STATETAB1("_UA_CLEANUP_PHASE ");
332 if (_UA_HANDLER_FRAME & actions)
333 _LIBCXXABI_TRACE_STATETAB1("_UA_HANDLER_FRAME ");
334 if (_UA_FORCE_UNWIND & actions)
335 _LIBCXXABI_TRACE_STATETAB1("_UA_FORCE_UNWIND ");
336 _LIBCXXABI_TRACE_STATETAB1(")\n");
337 _LIBCXXABI_TRACE_STATETAB(" unwind_exception=%p context=%p\n", reinterpret_cast<void*>(unwind_exception),
338 reinterpret_cast<void*>(context));
339 }
340
341 // Start scan by getting state table address.
342 StateVariable* const state = reinterpret_cast<StateVariable* const>(_Unwind_GetLanguageSpecificData(context));
343 if (state->state <= 0) {
344 // The state is not correct - give up on this routine.
345 _LIBCXXABI_TRACE_STATETAB("state=%d and is <= 0), continue unwinding\n", state->state);
346 results.reason = _URC_CONTINUE_UNWIND;
347 return;
348 }
349 // Parse the state table.
350 FSM* const fsm = state->table;
351 FSMEntry* currFSMEntry;
352
353 if (fsm->magic != FSMMagic::number && fsm->magic != FSMMagic::number2 && fsm->magic != FSMMagic::number3) {
354 // Something is wrong with the state table we found.
355 if (_UA_SEARCH_PHASE & actions) {
356 _LIBCXXABI_TRACE_STATETAB0("Invalid FSM table, return _URC_FATAL_PHASE1_ERROR\n");
357 results.reason = _URC_FATAL_PHASE1_ERROR;
358 } else if (_UA_CLEANUP_PHASE & actions) {
359 _LIBCXXABI_TRACE_STATETAB0("Invalid FSM table, return _URC_FATAL_PHASE2_ERROR\n");
360 results.reason = _URC_FATAL_PHASE2_ERROR;
361 } else {
362 // We should never get here.
363 _LIBCXXABI_TRACE_STATETAB0("Invalid FSM table + RT Internal error, return _URC_FATAL_PHASE2_ERROR\n");
364 results.reason = _URC_FATAL_PHASE2_ERROR;
365 }
366 return;
367 }
368
369 if (_LIBCXXABI_TRACING_STATETAB) {
370 // Print the state table for debugging purposes.
371 _LIBCXXABI_TRACE_STATETAB("state->state=%d, state->ignoreVBasePtrs=%d\n", state->state, state->ignoreVBasePtrs);
372 _LIBCXXABI_TRACE_STATETAB("fsm->magic=%#x, fsm->numberOfStates=%d\n", fsm->magic, fsm->numberOfStates);
373 // Print out the FSM table.
374 _LIBCXXABI_TRACE_STATETAB0("FSM table:\n");
375 _LIBCXXABI_TRACE_STATETAB("%12s %10s %8s %10s %7s %7s %7s %7s\n", "Entry Addr", "state", "Offset", "DTR/lpad",
376 "count", "el_size", "flags", "next");
377 for (int i = 0; i < fsm->numberOfStates; i++) {
378 currFSMEntry = &fsm->table[i];
379 _LIBCXXABI_TRACE_STATETAB("%12p (%8d) %8ld %10p %7ld "
380 "%7ld %#7x %7d\n",
381 reinterpret_cast<void*>(&currFSMEntry), i + 1, currFSMEntry->offset,
382 reinterpret_cast<void*>(currFSMEntry->destructor),
383 currFSMEntry->elementCount, currFSMEntry->elemSize, currFSMEntry->flags,
384 currFSMEntry->nextState);
385 }
386 }
387
388 if (_UA_SEARCH_PHASE & actions) {
389 // Start walking the state table. Use a local copy of state->state so when
390 // we return from search phase we don't change the state number.
391 int currState = state->state;
392
393 while (currState > 0) {
394 currFSMEntry = &fsm->table[currState - 1];
395 _LIBCXXABI_TRACE_STATETAB("Processing state=%d, flags=0x%hx\n", currState, currFSMEntry->flags);
396
397 if (currFSMEntry->actionFlag == FSMEntryCount::beginCatch) {
398 // Found a catch handler.
399 if (fsm->magic == FSMMagic::number) {
400 _LIBCXXABI_TRACE_STATETAB0("Found a xlC catch handler, return _URC_FATAL_PHASE1_ERROR\n");
401 // xlC catch handlers cannot be entered because they use a
402 // proprietary EH runtime that is not interoperable.
403 results.reason = _URC_FATAL_PHASE1_ERROR;
404 return;
405 }
406 // xlclang++ compiled frames use CXA-abi EH calls and any catch
407 // block will include a catch(...) block so it is safe to assume that
408 // the handler is found without checking the catch match. The
409 // catch(...) block will rethrow the exception if there isn't a
410 // match.
411 _LIBCXXABI_TRACE_STATETAB0("Found a catch handler, return _URC_HANDLER_FOUND\n");
412 results.reason = _URC_HANDLER_FOUND;
413 return;
414 }
415 if (currFSMEntry->actionFlag == FSMEntryCount::terminate) {
416 _LIBCXXABI_TRACE_STATETAB0("Found the terminate state, return _URC_HANDLER_FOUND\n");
417 results.reason = _URC_HANDLER_FOUND;
418 return;
419 }
420 if (currFSMEntry->flags & FSMEntryFlag::oldConditionalStateChange) {
421 // Deprecated conditional expression.
422 currState = *reinterpret_cast<int*>(currFSMEntry->nextStatePtr);
423 _LIBCXXABI_TRACE_STATETAB("Flag: FSMEntryFlag::oldConditionalStateChange, dereference "
424 "currFSMEntry->nextStatePtr(%ld), set state=%d\n",
425 currFSMEntry->nextStatePtr, currState);
426 continue; // We are done this iteration of the loop, since
427 // we changed a state.
428 }
429 if (currFSMEntry->flags & FSMEntryFlag::conditionalStateChange) {
430 void* addr = compute_addr_from_table(currFSMEntry, state, context);
431 currState = *reinterpret_cast<int*>(addr);
432 _LIBCXXABI_TRACE_STATETAB("Flag: FSMEntryFlag::conditionalStateChange, dereference "
433 "addr(%p), set state=%d\n", addr, currState);
434 continue; // We are done this iteration of the loop, since we
435 // changed the state.
436 }
437 // Go to the next state.
438 currState = currFSMEntry->nextState;
439 }
440 _LIBCXXABI_TRACE_STATETAB0("No catch handler found, return _URC_CONTINUE_UNWIND\n");
441 results.reason = _URC_CONTINUE_UNWIND;
442 return;
443 }
444 if (_UA_CLEANUP_PHASE & actions) {
445 // Start walking the state table.
446 while (state->state > 0) {
447 currFSMEntry = &fsm->table[state->state - 1];
448
449 if (currFSMEntry->actionFlag == FSMEntryCount::terminate) {
450 _LIBCXXABI_TRACE_STATETAB0("Reached terminate state. Call terminate.\n");
451 std::terminate();
452 }
453 // Perform action according to the currFSMEntry->actionFlag,
454 // except when flag is FSMEntryFlag::conditionalStateChange or
455 // FSMEntryFlag::oldConditionalStateChange.
456 _LIBCXXABI_TRACE_STATETAB("Processing state=%d, flags=0x%hx\n", state->state, currFSMEntry->flags);
457 if (currFSMEntry->flags & FSMEntryFlag::oldConditionalStateChange) {
458 state->state = *reinterpret_cast<int*>(currFSMEntry->nextStatePtr);
459 _LIBCXXABI_TRACE_STATETAB("Flag: FSMEntryFlag::oldConditionalStateChange, dereference "
460 "currFSMEntry->nextStatePtr(%ld), set state=%d\n",
461 currFSMEntry->nextStatePtr, state->state);
462 continue; // We are done with this iteration of the loop, since we changed a state.
463 }
464 if (currFSMEntry->flags & FSMEntryFlag::conditionalStateChange) {
465 // A conditional state table entry holds the address of a local
466 // that holds the next state.
467 void* addr = compute_addr_from_table(currFSMEntry, state, context);
468 state->state = *reinterpret_cast<int*>(addr);
469 _LIBCXXABI_TRACE_STATETAB("Flag: FSMEntryFlag::conditionalStateChange, dereference "
470 "addr(%p), set state=%d\n", addr, state->state);
471 continue; // We are done with this iteration of the loop, since we changed a state.
472 }
473 if (currFSMEntry->actionFlag == FSMEntryCount::beginCatch || currFSMEntry->actionFlag == FSMEntryCount::endCatch ||
474 currFSMEntry->actionFlag == FSMEntryCount::cleanupLabel) {
475
476 _LIBCXXABI_TRACE_STATETAB(
477 "FSMEntryCount::%s: handler %p/%p, return _URC_HANDLER_FOUND\n",
478 (currFSMEntry->actionFlag == FSMEntryCount::beginCatch
479 ? "beginCatch"
480 : (currFSMEntry->actionFlag == FSMEntryCount::endCatch ? "endCatch" : "cleanupLabel")),
481 currFSMEntry->landingPad, *reinterpret_cast<void**>(currFSMEntry->landingPad));
482
483 state->state = currFSMEntry->nextState;
484 results.landingPad = reinterpret_cast<uintptr_t>(*reinterpret_cast<void**>(currFSMEntry->landingPad));
485 results.reason = _URC_HANDLER_FOUND;
486 return;
487 }
488 if (currFSMEntry->elementCount > 0) {
489 if (currFSMEntry->flags & FSMEntryFlag::vBaseFlag && state->ignoreVBasePtrs) {
490 _LIBCXXABI_TRACE_STATETAB0("Ignoring virtual base dtor.\n");
491 } else {
492 // We need to invoke the virtual base destructor. This must be
493 // a frame from the legacy xlC compiler as the xlclang++ compiler
494 // generates inline cleanup code rather than specifying
495 // the destructor via the state table.
496 void* addr = compute_addr_from_table(currFSMEntry, state, context);
497
498 // An extra indirect to get to the object according to the object
499 // model used by the xlC compiler.
500 addr = reinterpret_cast<void*>(*reinterpret_cast<char**>(addr));
501 _LIBCXXABI_TRACE_STATETAB("Invoke dtor for object=%p\n", addr);
502 invoke_destructor(currFSMEntry, addr);
503 }
504 } else if (currFSMEntry->actionFlag == FSMEntryCount::deleteObject) {
505 void* addr = compute_addr_from_table(currFSMEntry, state, context);
506 if (currFSMEntry->flags & FSMEntryFlag::vBaseFlag) {
507 // We need to invoke the virtual base delete function. This must be
508 // a frame from the legacy xlC compiler as the xlclang++ compiler
509 // generates inline cleanup code rather than specifying
510 // the delete function via the state table.
511
512 // An extra indirect to get to the object according to the object
513 // model used by the xlC compiler.
514 addr = reinterpret_cast<void*>(*reinterpret_cast<char**>(addr));
515 }
516 _LIBCXXABI_TRACE_STATETAB("Delete object at %p\n", addr);
517 invoke_delete(currFSMEntry, addr);
518 } else {
519 _LIBCXXABI_TRACE_STATETAB("Unknown entry in FSM (count=%ld), ignored\n",
520 currFSMEntry->elementCount);
521 } // End of action switching.
522
523 // Go to next state.
524 state->state = currFSMEntry->nextState;
525 }
526 _LIBCXXABI_TRACE_STATETAB0("No catch handler, return _URC_CONTINUE_UNWIND\n");
527 results.reason = _URC_CONTINUE_UNWIND;
528 return;
529 }
530 _LIBCXXABI_TRACE_STATETAB0("No state table entry for this exception, call_terminate()\n");
531 // It is possible that no state table entry specify how to handle
532 // this exception. By spec, terminate it immediately.
533 call_terminate(native_exception, unwind_exception);
534}
535
536// Personality routine for EH using the state table.
537_LIBCXXABI_FUNC_VIS _Unwind_Reason_Code
538__xlcxx_personality_v0(int version, _Unwind_Action actions, uint64_t exceptionClass,
539 _Unwind_Exception* unwind_exception, _Unwind_Context* context) {
540 if (version != 1 || unwind_exception == 0 || context == 0)
541 return _URC_FATAL_PHASE1_ERROR;
542
543 bool native_exception = (exceptionClass & get_vendor_and_language) == (kOurExceptionClass & get_vendor_and_language);
544 scan_results results;
545 scan_state_tab(results, actions, native_exception, unwind_exception, context);
546 if (actions & _UA_SEARCH_PHASE) {
547 // Phase 1 search: All we're looking for in phase 1 is a handler that
548 // halts unwinding
549 return results.reason;
550 }
551 if (actions & _UA_CLEANUP_PHASE) {
552 // Phase 2 cleanup:
553 if (results.reason == _URC_HANDLER_FOUND) {
554 // Store the address of unwind_exception in the stack field
555 // reserved for compilers (SP + 3 * sizeof(uintptr_t)) in the stack of
556 // the caller of the function containing the landing pad (within the link
557 // area for the call to the latter) for __xlc_exception_handle()
558 // to retrieve when it is called by the landing pad.
559 uintptr_t *currentSP = reinterpret_cast<uintptr_t*>(_Unwind_GetGR(context, 1));
560 uintptr_t *callersSP = reinterpret_cast<uintptr_t*>(currentSP[0]);
561 callersSP[3] = reinterpret_cast<uintptr_t>(unwind_exception);
562 _LIBCXXABI_TRACE_STATETAB("Handshake: save unwind_exception=%p in stack=%p\n",
563 reinterpret_cast<void*>(unwind_exception), reinterpret_cast<void*>(callersSP));
564 // Jump to the handler.
565 _Unwind_SetIP(context, results.landingPad);
566 return _URC_INSTALL_CONTEXT;
567 }
568 // Did not find a handler. Return the results of the scan. Normally
569 // _URC_CONTINUE_UNWIND, but could have been _URC_FATAL_PHASE2_ERROR.
570 return results.reason;
571 }
572 // We were called improperly: neither a phase 1 or phase 2 search.
573 return _URC_FATAL_PHASE1_ERROR;
574}
575} // namespace __state_table_eh
576
577// The following are EH helper functions for xlclang++ compiled code.
578
579// __xlc_catch_matchv2
580// Check whether the thrown object matches the catch handler's exception
581// declaration. If there is a match, the function returns true with adjusted
582// address of the thrown object. Otherwise, returns false.
583_LIBCXXABI_FUNC_VIS bool
584__xlc_catch_matchv2(_Unwind_Exception* exceptionObject, std::type_info* catchTypeInfo, void*& obj) {
585 _LIBCXXABI_TRACE_STATETAB("Entering %s, exceptionObject=%p\n", __func__, reinterpret_cast<void*>(exceptionObject));
586
587 if (!__isOurExceptionClass(exceptionObject)) {
588 _LIBCXXABI_TRACE_STATETAB0("No match, not a C++ exception\n");
589 return false;
590 }
591
592 __cxa_exception* exceptionHeader = 0;
593
594 if (__getExceptionClass(exceptionObject) == kOurDependentExceptionClass) {
595 // Walk to the __cxa_dependent_exception primary exception for the
596 // exception object and its type_info.
597 __cxa_dependent_exception* dependentExceptionHeader =
598 reinterpret_cast<__cxa_dependent_exception*>(exceptionObject + 1) - 1;
599 exceptionHeader = reinterpret_cast<__cxa_exception*>(dependentExceptionHeader->primaryException) - 1;
600 _LIBCXXABI_TRACE_STATETAB("exceptionObject 0x%p is a dependent, primary 0x%p\n",
601 reinterpret_cast<void*>(exceptionObject),
602 reinterpret_cast<void*>(&exceptionHeader->unwindHeader));
603 exceptionObject = &exceptionHeader->unwindHeader;
604 } else {
605 _LIBCXXABI_TRACE_STATETAB("exceptionObject %p is NOT a dependent\n", reinterpret_cast<void*>(exceptionObject));
606 exceptionHeader = reinterpret_cast<__cxa_exception*>(exceptionObject + 1) - 1;
607 }
608
609 void* thrownObject = reinterpret_cast<void*>(exceptionObject + 1);
610 std::type_info* throwTypeInfo = exceptionHeader->exceptionType;
611
612 // Get the type info for the thrown type and this catch clause and
613 // see if the catch caluse can catch that type.
614
615 __cxxabiv1::__shim_type_info* catchType = reinterpret_cast<__cxxabiv1::__shim_type_info*>(catchTypeInfo);
616 __cxxabiv1::__shim_type_info* throwType = reinterpret_cast<__cxxabiv1::__shim_type_info*>(throwTypeInfo);
617 _LIBCXXABI_TRACE_STATETAB("UnwindException=%p, thrownObject=%p, throwTypeInfo=%p(%s), catchTypeInfo=%p(%s)\n",
618 reinterpret_cast<void*>(exceptionObject), thrownObject, reinterpret_cast<void*>(throwType),
619 throwType->name(), reinterpret_cast<void*>(catchType), catchType->name());
620 if (catchType->can_catch(throwType, thrownObject)) {
621 exceptionHeader->adjustedPtr = thrownObject;
622 obj = thrownObject;
623 _LIBCXXABI_TRACE_STATETAB("Match found for thrownObject=%p\n", thrownObject);
624 return true;
625 }
626 _LIBCXXABI_TRACE_STATETAB0("No match\n");
627 return false;
628}
629
630// __xlc_throw_badexception
631// This function is for xlclang++. It allocates and throws a bad_exception.
632// During unwinding for this bad_exception, the previous exception which is
633// not matching the throw spec will be cleaned up. Thus having the same
634// effect as replace the top most exception (which is bad) with a bad_exception.
635_LIBCXXABI_FUNC_VIS void __xlc_throw_badexception() {
636 _LIBCXXABI_TRACE_STATETAB("Entering function: %s\n\n", __func__);
637 void* newexception = new (__cxa_allocate_exception(sizeof(std::bad_exception))) std::bad_exception;
638 __cxa_throw(newexception, const_cast<std::type_info*>(&typeid(std::bad_exception)), 0);
639}
640
641// skip_non_cxx_eh_aware_frames
642// This function skips non-C++ EH aware stack frames by unwinding from the
643// stack frame pointed by 'Sp' and returns the first C++ EH aware stack frame
644// found. 'Pc' is an instruction address inside the function that owns the
645// stack frame pointed to by 'Sp'.
646static uintptr_t* skip_non_cxx_eh_aware_frames(uint32_t* Pc, uintptr_t* Sp) {
647 uint32_t* currentPc = Pc;
648 uintptr_t* currentStack = Sp;
649
650 // Loop until a C++ EH aware frame is found or the return address is 0,
651 // which is the return address of the startup function '__start'.
652 while (currentPc != 0) {
653 uint32_t* p = currentPc;
654
655 // Keep looking forward until a word of 0 is found. The traceback
656 // table starts at the following word.
657 while (*p)
658 ++p;
659 tbtable* TBTable = reinterpret_cast<tbtable*>(p + 1);
660
661 // A stack frame with a C++ state table is C++ EH aware.
662 if (TBTable->tb.lang == TB_CPLUSPLUS && TBTable->tb.has_ctl)
663 return currentStack;
664
665 // Move up one stack frame.
666 currentStack = reinterpret_cast<uintptr_t*>(currentStack[0]);
667 // Get the value of the LR (saved, prior to incrementing the SP, by the
668 // prolog of the function just inspected) from the frame.
669 currentPc = reinterpret_cast<uint32_t*>(currentStack[2]);
670 }
671 // This should not happen.
672 _LIBCXXABI_TRACE_STATETAB0("skip_non_cxx_eh_aware_frames() reached the end of stack frames, aborting\n");
673 abort();
674}
675
676// __xlc_exception_handle
677// This function is for xlclang++. It returns the address of the exception
678// object stored in the reserved field in the stack of the caller of the
679// function that calls __xlc_exception_handle() (within the link area for the
680// call to the latter). The address is stored by the personality routine for
681// xlclang++ compiled code. If __xlc_exception_handle() is called by
682// non-C++ EH aware functions, their frames are skipped until a C++ EH aware
683// frame is found.
684// Note: make sure __xlc_exception_handle() is a non-leaf function. Currently
685// it calls skip_non_cxx_eh_aware_frames(), which in turn calls abort().
686_LIBCXXABI_FUNC_VIS uintptr_t __xlc_exception_handle() {
687 // Get the SP of this function, i.e., __xlc_exception_handle().
688 uintptr_t* lastStack = reinterpret_cast<uintptr_t*>(__builtin_frame_address(0));
689 // Move one frame up to the frame of the caller of __xlc_exception_handle().
690 lastStack = reinterpret_cast<uintptr_t*>(lastStack[0]);
691 // Get the return address of this function, i.e., __xlc_exception_handle().
692 uint32_t* returnAddress = reinterpret_cast<uint32_t*>(__builtin_return_address(0));
693
694 // Skip non-C++ EH aware frames and get the first C++ EH aware frame.
695 uintptr_t* callerStack = skip_non_cxx_eh_aware_frames(returnAddress, lastStack);
696
697 // Get the SP of the caller of the C++ EH aware caller.
698 callerStack = reinterpret_cast<uintptr_t*>(callerStack[0]);
699 // Retrieve the exception object in the stack slot saved by the personality.
700 uintptr_t exceptionObject = callerStack[3];
701 _LIBCXXABI_TRACE_STATETAB("Handshake: retrieve exceptionObject=%p from stack=%p\n",
702 reinterpret_cast<void*>(exceptionObject), reinterpret_cast<void*>(callerStack));
703 return exceptionObject;
704}
705
706// xlclang++ may generate calls to __Deleted_Virtual.
707_LIBCXXABI_FUNC_VIS void __Deleted_Virtual() { abort(); }
708
709// __catchThrownException is called during AIX library initialization and
710// termination to handle exceptions. An implementation is also provided in
711// libC.a(shrcore.o). This implementation is provided for applications that
712// link with -lc++ (the xlclang++ or ibm-clang++ link default.)
713_LIBCXXABI_FUNC_VIS int
714__catchThrownException(void (*cdfunc)(void), // function which may fail
715 void (*cleanup)(void*), // cleanup function
716 void* cleanuparg, // parameter to cleanup function
717 int action) { // control exception throwing and termination
718 enum Action : int { None = 0, Rethrow = 1, Terminate = 2 };
719 if (!cdfunc)
720 return 0;
721 if (action == Action::Rethrow && !cleanup) {
722 // No cleanup and rethrow is effectively no-op.
723 // Avoid the catch handler when possible to allow exceptions generated
724 // from xlC binaries to flow through.
725 (*cdfunc)();
726 return 0;
727 }
728 try {
729 (*cdfunc)();
730 } catch (...) {
731 if (action == Action::Terminate)
732 std::terminate();
733 if (cleanup)
734 (*cleanup)(cleanuparg);
735 if (action == Action::Rethrow)
736 throw;
737 assert(action == Action::None);
738 return -1; // FAILED
739 }
740 return 0;
741}
742
743} // extern "C"
744
745} // __cxxabiv1
lib/libtsan/interception/interception_aix.cpp deleted-45
...@@ -1,45 +0,0 @@
1//===-- interception_aix.cpp ------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is a part of AddressSanitizer, an address sanity checker.
10//
11// AIX-specific interception methods.
12//===----------------------------------------------------------------------===//
13
14#include "interception.h"
15#include "sanitizer_common/sanitizer_common.h"
16
17#if SANITIZER_AIX
18
19# include <dlfcn.h> // for dlsym()
20
21namespace __interception {
22
23static void *GetFuncAddr(const char *name, uptr wrapper_addr) {
24 // AIX dlsym can only defect the functions that are exported, so
25 // on AIX, we can not intercept some basic functions like memcpy.
26 // FIXME: if we are going to ship dynamic asan library, we may need to search
27 // all the loaded modules with RTLD_DEFAULT if RTLD_NEXT failed.
28 void *addr = dlsym(RTLD_NEXT, name);
29
30 // In case `name' is not loaded, dlsym ends up finding the actual wrapper.
31 // We don't want to intercept the wrapper and have it point to itself.
32 if ((uptr)addr == wrapper_addr)
33 addr = nullptr;
34 return addr;
35}
36
37bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
38 uptr wrapper) {
39 void *addr = GetFuncAddr(name, wrapper);
40 *ptr_to_real = (uptr)addr;
41 return addr && (func == wrapper);
42}
43
44} // namespace __interception
45#endif // SANITIZER_AIX
lib/libtsan/interception/interception_aix.h deleted-36
...@@ -1,36 +0,0 @@
1//===-- interception_aix.h --------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is a part of AddressSanitizer, an address sanity checker.
10//
11// AIX-specific interception methods.
12//===----------------------------------------------------------------------===//
13
14#if SANITIZER_AIX
15
16# if !defined(INCLUDED_FROM_INTERCEPTION_LIB)
17# error \
18 "interception_aix.h should be included from interception library only"
19# endif
20
21# ifndef INTERCEPTION_AIX_H
22# define INTERCEPTION_AIX_H
23
24namespace __interception {
25bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
26 uptr wrapper);
27} // namespace __interception
28
29# define INTERCEPT_FUNCTION_AIX(func) \
30 ::__interception::InterceptFunction( \
31 #func, (::__interception::uptr *)&REAL(func), \
32 (::__interception::uptr) & (func), \
33 (::__interception::uptr) & WRAP(func))
34
35# endif // INTERCEPTION_AIX_H
36#endif // SANITIZER_AIX
lib/libunwind/src/Unwind_AIXExtras.cpp deleted-63
...@@ -1,63 +0,0 @@
1//===--------------------- Unwind_AIXExtras.cpp -------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//
8//===----------------------------------------------------------------------===//
9
10// This file is only used for AIX.
11#if defined(_AIX)
12
13#include "config.h"
14#include "libunwind_ext.h"
15#include <sys/debug.h>
16
17namespace libunwind {
18// getFuncNameFromTBTable
19// Get the function name from its traceback table.
20char *getFuncNameFromTBTable(uintptr_t Pc, uint16_t &NameLen,
21 unw_word_t *Offset) {
22 uint32_t *p = reinterpret_cast<uint32_t *>(Pc);
23 *Offset = 0;
24
25 // Keep looking forward until a word of 0 is found. The traceback
26 // table starts at the following word.
27 while (*p)
28 p++;
29 tbtable *TBTable = reinterpret_cast<tbtable *>(p + 1);
30
31 if (!TBTable->tb.name_present)
32 return NULL;
33
34 // Get to the name of the function.
35 p = reinterpret_cast<uint32_t *>(&TBTable->tb_ext);
36
37 // Skip field parminfo if it exists.
38 if (TBTable->tb.fixedparms || TBTable->tb.floatparms)
39 p++;
40
41 // If the tb_offset field exists, get the offset from the start of
42 // the function to pc. Skip the field.
43 if (TBTable->tb.has_tboff) {
44 unw_word_t StartIp =
45 reinterpret_cast<uintptr_t>(TBTable) - *p - sizeof(uint32_t);
46 *Offset = Pc - StartIp;
47 p++;
48 }
49
50 // Skip field hand_mask if it exists.
51 if (TBTable->tb.int_hndl)
52 p++;
53
54 // Skip fields ctl_info and ctl_info_disp if they exist.
55 if (TBTable->tb.has_ctl) {
56 p += 1 + *p;
57 }
58
59 NameLen = *(reinterpret_cast<uint16_t *>(p));
60 return reinterpret_cast<char *>(p) + sizeof(uint16_t);
61}
62} // namespace libunwind
63#endif // defined(_AIX)
lib/std/Target.zig+6-51
...@@ -24,7 +24,6 @@ pub const Os = struct {...@@ -24,7 +24,6 @@ pub const Os = struct {
24 hermit,24 hermit,
25 managarm,25 managarm,
2626
27 aix,
28 haiku,27 haiku,
29 hurd,28 hurd,
30 illumos,29 illumos,
...@@ -32,7 +31,6 @@ pub const Os = struct {...@@ -32,7 +31,6 @@ pub const Os = struct {
32 plan9,31 plan9,
33 rtems,32 rtems,
34 serenity,33 serenity,
35 zos,
3634
37 dragonfly,35 dragonfly,
38 freebsd,36 freebsd,
...@@ -174,9 +172,7 @@ pub const Os = struct {...@@ -174,9 +172,7 @@ pub const Os = struct {
174 .fuchsia,172 .fuchsia,
175 .hermit,173 .hermit,
176174
177 .aix,
178 .rtems,175 .rtems,
179 .zos,
180176
181 .dragonfly,177 .dragonfly,
182 .freebsd,178 .freebsd,
...@@ -418,12 +414,6 @@ pub const Os = struct {...@@ -418,12 +414,6 @@ pub const Os = struct {
418 },414 },
419 },415 },
420416
421 .aix => .{
422 .semver = .{
423 .min = .{ .major = 7, .minor = 2, .patch = 5 },
424 .max = .{ .major = 7, .minor = 3, .patch = 3 },
425 },
426 },
427 .hurd => .{417 .hurd => .{
428 .hurd = .{418 .hurd = .{
429 .range = .{419 .range = .{
...@@ -494,12 +484,6 @@ pub const Os = struct {...@@ -494,12 +484,6 @@ pub const Os = struct {
494 .max = .{ .major = 6, .minor = 1, .patch = 0 },484 .max = .{ .major = 6, .minor = 1, .patch = 0 },
495 },485 },
496 },486 },
497 .zos => .{
498 .semver = .{
499 .min = .{ .major = 2, .minor = 5, .patch = 0 },
500 .max = .{ .major = 3, .minor = 1, .patch = 0 },
501 },
502 },
503487
504 .dragonfly => .{488 .dragonfly => .{
505 .semver = .{489 .semver = .{
...@@ -825,7 +809,6 @@ pub const Abi = enum {...@@ -825,7 +809,6 @@ pub const Abi = enum {
825 => .eabi,809 => .eabi,
826 else => .none,810 else => .none,
827 },811 },
828 .aix => if (arch == .powerpc) .eabihf else .none,
829 .haiku => switch (arch) {812 .haiku => switch (arch) {
830 .arm,813 .arm,
831 .powerpc,814 .powerpc,
...@@ -917,7 +900,6 @@ pub const Abi = enum {...@@ -917,7 +900,6 @@ pub const Abi = enum {
917 .managarm,900 .managarm,
918 .plan9,901 .plan9,
919 .serenity,902 .serenity,
920 .zos,
921 .dragonfly,903 .dragonfly,
922 .driverkit,904 .driverkit,
923 .macos,905 .macos,
...@@ -1006,8 +988,6 @@ pub const ObjectFormat = enum {...@@ -1006,8 +988,6 @@ pub const ObjectFormat = enum {
1006 coff,988 coff,
1007 /// The Executable and Linkable Format used by many Unixes.989 /// The Executable and Linkable Format used by many Unixes.
1008 elf,990 elf,
1009 /// The Generalized Object File Format used by z/OS.
1010 goff,
1011 /// The Intel HEX format for storing binary code in ASCII text.991 /// The Intel HEX format for storing binary code in ASCII text.
1012 hex,992 hex,
1013 /// The Mach object format used by macOS and other Apple platforms.993 /// The Mach object format used by macOS and other Apple platforms.
...@@ -1020,8 +1000,6 @@ pub const ObjectFormat = enum {...@@ -1020,8 +1000,6 @@ pub const ObjectFormat = enum {
1020 spirv,1000 spirv,
1021 /// The WebAssembly binary format.1001 /// The WebAssembly binary format.
1022 wasm,1002 wasm,
1023 /// The eXtended Common Object File Format used by AIX.
1024 xcoff,
10251003
1026 // LLVM tags deliberately omitted:1004 // LLVM tags deliberately omitted:
1027 // - dxcontainer1005 // - dxcontainer
...@@ -1030,7 +1008,7 @@ pub const ObjectFormat = enum {...@@ -1030,7 +1008,7 @@ pub const ObjectFormat = enum {
1030 return switch (of) {1008 return switch (of) {
1031 .c => ".c",1009 .c => ".c",
1032 .coff => ".obj",1010 .coff => ".obj",
1033 .elf, .goff, .macho, .wasm, .xcoff => ".o",1011 .elf, .macho, .wasm => ".o",
1034 .hex => ".ihex",1012 .hex => ".ihex",
1035 .plan9 => arch.plan9Ext(),1013 .plan9 => arch.plan9Ext(),
1036 .raw => ".bin",1014 .raw => ".bin",
...@@ -1040,11 +1018,9 @@ pub const ObjectFormat = enum {...@@ -1040,11 +1018,9 @@ pub const ObjectFormat = enum {
10401018
1041 pub fn default(os_tag: Os.Tag, arch: Cpu.Arch) ObjectFormat {1019 pub fn default(os_tag: Os.Tag, arch: Cpu.Arch) ObjectFormat {
1042 return switch (os_tag) {1020 return switch (os_tag) {
1043 .aix => .xcoff,
1044 .driverkit, .ios, .macos, .tvos, .visionos, .watchos => .macho,1021 .driverkit, .ios, .macos, .tvos, .visionos, .watchos => .macho,
1045 .plan9 => .plan9,1022 .plan9 => .plan9,
1046 .uefi, .windows => .coff,1023 .uefi, .windows => .coff,
1047 .zos => .goff,
1048 else => switch (arch) {1024 else => switch (arch) {
1049 .spirv32, .spirv64 => .spirv,1025 .spirv32, .spirv64 => .spirv,
1050 .wasm32, .wasm64 => .wasm,1026 .wasm32, .wasm64 => .wasm,
...@@ -2030,10 +2006,7 @@ pub const Cpu = struct {...@@ -2030,10 +2006,7 @@ pub const Cpu = struct {
2030 .riscv32, .riscv32be => &riscv.cpu.baseline_rv32,2006 .riscv32, .riscv32be => &riscv.cpu.baseline_rv32,
2031 .riscv64, .riscv64be => &riscv.cpu.baseline_rv64,2007 .riscv64, .riscv64be => &riscv.cpu.baseline_rv64,
2032 // gcc/clang do not have a generic s390x model.2008 // gcc/clang do not have a generic s390x model.
2033 .s390x => switch (os.tag) {2009 .s390x => &s390x.cpu.arch8,
2034 .zos => &s390x.cpu.arch10,
2035 else => &s390x.cpu.arch8,
2036 },
2037 .sparc => &sparc.cpu.v9, // glibc does not work with 'plain' v8.2010 .sparc => &sparc.cpu.v9, // glibc does not work with 'plain' v8.
2038 .x86 => &x86.cpu.pentium4,2011 .x86 => &x86.cpu.pentium4,
2039 .x86_64 => switch (os.tag) {2012 .x86_64 => switch (os.tag) {
...@@ -2162,7 +2135,6 @@ pub inline fn isWasiLibC(target: *const Target) bool {...@@ -2162,7 +2135,6 @@ pub inline fn isWasiLibC(target: *const Target) bool {
2162/// syscall interface, for example.2135/// syscall interface, for example.
2163pub fn requiresLibC(target: *const Target) bool {2136pub fn requiresLibC(target: *const Target) bool {
2164 return switch (target.os.tag) {2137 return switch (target.os.tag) {
2165 .aix,
2166 .illumos,2138 .illumos,
2167 .driverkit,2139 .driverkit,
2168 .macos,2140 .macos,
...@@ -2189,7 +2161,6 @@ pub fn requiresLibC(target: *const Target) bool {...@@ -2189,7 +2161,6 @@ pub fn requiresLibC(target: *const Target) bool {
2189 .fuchsia,2161 .fuchsia,
2190 .managarm,2162 .managarm,
2191 .ps3,2163 .ps3,
2192 .zos,
2193 .rtems,2164 .rtems,
2194 .cuda,2165 .cuda,
2195 .nvcl,2166 .nvcl,
...@@ -2347,10 +2318,8 @@ pub const DynamicLinker = struct {...@@ -2347,10 +2318,8 @@ pub const DynamicLinker = struct {
2347 .hermit,2318 .hermit,
2348 .managarm, // Needs to be double-checked.2319 .managarm, // Needs to be double-checked.
23492320
2350 .aix,
2351 .plan9,2321 .plan9,
2352 .rtems,2322 .rtems,
2353 .zos,
23542323
2355 .uefi,2324 .uefi,
2356 .windows,2325 .windows,
...@@ -2759,10 +2728,8 @@ pub const DynamicLinker = struct {...@@ -2759,10 +2728,8 @@ pub const DynamicLinker = struct {
2759 .contiki,2728 .contiki,
2760 .hermit,2729 .hermit,
27612730
2762 .aix,
2763 .plan9,2731 .plan9,
2764 .rtems,2732 .rtems,
2765 .zos,
27662733
2767 .uefi,2734 .uefi,
2768 .windows,2735 .windows,
...@@ -2916,7 +2883,7 @@ pub fn stackAlignment(target: *const Target) u16 {...@@ -2916,7 +2883,7 @@ pub fn stackAlignment(target: *const Target) u16 {
2916 // can't handle that level of nuance yet.2883 // can't handle that level of nuance yet.
2917 .powerpc64,2884 .powerpc64,
2918 .powerpc64le,2885 .powerpc64le,
2919 => if (target.os.tag == .linux or target.os.tag == .aix) return 16,2886 => if (target.os.tag == .linux) return 16,
2920 .riscv32,2887 .riscv32,
2921 .riscv32be,2888 .riscv32be,
2922 .riscv64,2889 .riscv64,
...@@ -3112,7 +3079,6 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {...@@ -3112,7 +3079,6 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {
3112 .fuchsia,3079 .fuchsia,
3113 .hermit,3080 .hermit,
31143081
3115 .aix,
3116 .haiku,3082 .haiku,
3117 .hurd,3083 .hurd,
3118 .illumos,3084 .illumos,
...@@ -3120,7 +3086,6 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {...@@ -3120,7 +3086,6 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {
3120 .plan9,3086 .plan9,
3121 .rtems,3087 .rtems,
3122 .serenity,3088 .serenity,
3123 .zos,
31243089
3125 .freebsd,3090 .freebsd,
3126 .dragonfly,3091 .dragonfly,
...@@ -3175,7 +3140,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {...@@ -3175,7 +3140,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {
3175 .muslx32,3140 .muslx32,
3176 => return 64,3141 => return 64,
3177 else => switch (target.os.tag) {3142 else => switch (target.os.tag) {
3178 .aix, .freebsd, .netbsd, .openbsd => return 64,3143 .freebsd, .netbsd, .openbsd => return 64,
3179 else => return 128,3144 else => return 128,
3180 },3145 },
3181 },3146 },
...@@ -3191,7 +3156,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {...@@ -3191,7 +3156,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {
3191 .muslx32,3156 .muslx32,
3192 => return 64,3157 => return 64,
3193 else => switch (target.os.tag) {3158 else => switch (target.os.tag) {
3194 .aix, .freebsd, .openbsd => return 64,3159 .freebsd, .openbsd => return 64,
3195 else => return 128,3160 else => return 128,
3196 },3161 },
3197 },3162 },
...@@ -3361,13 +3326,6 @@ pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 {...@@ -3361,13 +3326,6 @@ pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 {
3361 .int, .uint, .long, .ulong => return 2,3326 .int, .uint, .long, .ulong => return 2,
3362 else => {},3327 else => {},
3363 },3328 },
3364 .powerpc, .powerpcle, .powerpc64, .powerpc64le => switch (target.os.tag) {
3365 .aix => switch (c_type) {
3366 .double, .longdouble => return 4,
3367 else => {},
3368 },
3369 else => {},
3370 },
3371 .wasm32, .wasm64 => switch (target.os.tag) {3329 .wasm32, .wasm64 => switch (target.os.tag) {
3372 .emscripten => switch (c_type) {3330 .emscripten => switch (c_type) {
3373 .longdouble => return 8,3331 .longdouble => return 8,
...@@ -3666,10 +3624,7 @@ pub fn cCallingConvention(target: *const Target) ?std.builtin.CallingConvention...@@ -3666,10 +3624,7 @@ pub fn cCallingConvention(target: *const Target) ?std.builtin.CallingConvention
3666 else3624 else
3667 .{ .powerpc64_elf = .{} },3625 .{ .powerpc64_elf = .{} },
3668 .powerpc64le => .{ .powerpc64_elf_v2 = .{} },3626 .powerpc64le => .{ .powerpc64_elf_v2 = .{} },
3669 .powerpc, .powerpcle => switch (target.os.tag) {3627 .powerpc, .powerpcle => .{ .powerpc_sysv = .{} },
3670 .aix => .{ .powerpc_aix = .{} },
3671 else => .{ .powerpc_sysv = .{} },
3672 },
3673 .wasm32, .wasm64 => .{ .wasm_mvp = .{} },3628 .wasm32, .wasm64 => .{ .wasm_mvp = .{} },
3674 .arc, .arceb => .{ .arc_sysv = .{} },3629 .arc, .arceb => .{ .arc_sysv = .{} },
3675 .avr => .avr_gnu,3630 .avr => .avr_gnu,
lib/std/Target/powerpc.zig-30
...@@ -7,10 +7,6 @@ const CpuModel = std.Target.Cpu.Model;...@@ -7,10 +7,6 @@ const CpuModel = std.Target.Cpu.Model;
7pub const Feature = enum {7pub const Feature = enum {
8 @"64bit",8 @"64bit",
9 @"64bitregs",9 @"64bitregs",
10 aix,
11 aix_shared_lib_tls_model_opt,
12 aix_small_local_dynamic_tls,
13 aix_small_local_exec_tls,
14 allow_unaligned_fp_access,10 allow_unaligned_fp_access,
15 altivec,11 altivec,
16 booke,12 booke,
...@@ -61,7 +57,6 @@ pub const Feature = enum {...@@ -61,7 +57,6 @@ pub const Feature = enum {
61 longcall,57 longcall,
62 mfocrf,58 mfocrf,
63 mma,59 mma,
64 modern_aix_as,
65 msync,60 msync,
66 paired_vector_memops,61 paired_vector_memops,
67 partword_atomics,62 partword_atomics,
...@@ -110,26 +105,6 @@ pub const all_features = blk: {...@@ -110,26 +105,6 @@ pub const all_features = blk: {
110 .description = "Enable 64-bit registers usage for ppc32 [beta]",105 .description = "Enable 64-bit registers usage for ppc32 [beta]",
111 .dependencies = featureSet(&[_]Feature{}),106 .dependencies = featureSet(&[_]Feature{}),
112 };107 };
113 result[@intFromEnum(Feature.aix)] = .{
114 .llvm_name = "aix",
115 .description = "AIX OS",
116 .dependencies = featureSet(&[_]Feature{}),
117 };
118 result[@intFromEnum(Feature.aix_shared_lib_tls_model_opt)] = .{
119 .llvm_name = "aix-shared-lib-tls-model-opt",
120 .description = "Tune TLS model at function level in shared library loaded with the main program (for 64-bit AIX only)",
121 .dependencies = featureSet(&[_]Feature{}),
122 };
123 result[@intFromEnum(Feature.aix_small_local_dynamic_tls)] = .{
124 .llvm_name = "aix-small-local-dynamic-tls",
125 .description = "Produce a faster local-dynamic TLS sequence for this function for 64-bit AIX",
126 .dependencies = featureSet(&[_]Feature{}),
127 };
128 result[@intFromEnum(Feature.aix_small_local_exec_tls)] = .{
129 .llvm_name = "aix-small-local-exec-tls",
130 .description = "Produce a TOC-free local-exec TLS sequence for this function for 64-bit AIX",
131 .dependencies = featureSet(&[_]Feature{}),
132 };
133 result[@intFromEnum(Feature.allow_unaligned_fp_access)] = .{108 result[@intFromEnum(Feature.allow_unaligned_fp_access)] = .{
134 .llvm_name = "allow-unaligned-fp-access",109 .llvm_name = "allow-unaligned-fp-access",
135 .description = "CPU does not trap on unaligned FP access",110 .description = "CPU does not trap on unaligned FP access",
...@@ -446,11 +421,6 @@ pub const all_features = blk: {...@@ -446,11 +421,6 @@ pub const all_features = blk: {
446 .power9_altivec,421 .power9_altivec,
447 }),422 }),
448 };423 };
449 result[@intFromEnum(Feature.modern_aix_as)] = .{
450 .llvm_name = "modern-aix-as",
451 .description = "AIX system assembler is modern enough to support new mnes",
452 .dependencies = featureSet(&[_]Feature{}),
453 };
454 result[@intFromEnum(Feature.msync)] = .{424 result[@intFromEnum(Feature.msync)] = .{
455 .llvm_name = "msync",425 .llvm_name = "msync",
456 .description = "Has only the msync instruction instead of sync",426 .description = "Has only the msync instruction instead of sync",
lib/std/builtin.zig+1-4
...@@ -1031,10 +1031,7 @@ pub const VaList = switch (builtin.cpu.arch) {...@@ -1031,10 +1031,7 @@ pub const VaList = switch (builtin.cpu.arch) {
1031 .alpha => VaListAlpha,1031 .alpha => VaListAlpha,
1032 .arm, .armeb, .thumb, .thumbeb => VaListArm,1032 .arm, .armeb, .thumb, .thumbeb => VaListArm,
1033 .hexagon => if (builtin.target.abi.isMusl()) VaListHexagon else *u8,1033 .hexagon => if (builtin.target.abi.isMusl()) VaListHexagon else *u8,
1034 .powerpc, .powerpcle => switch (builtin.os.tag) {1034 .powerpc, .powerpcle => VaListPowerPc,
1035 .aix => *u8,
1036 else => VaListPowerPc,
1037 },
1038 .s390x => VaListS390x,1035 .s390x => VaListS390x,
1039 .sh, .sheb => VaListSh, // This is wrong for `sh_renesas`: https://github.com/ziglang/zig/issues/24692#issuecomment-31507798291036 .sh, .sheb => VaListSh, // This is wrong for `sh_renesas`: https://github.com/ziglang/zig/issues/24692#issuecomment-3150779829
1040 .x86_64 => switch (builtin.os.tag) {1037 .x86_64 => switch (builtin.os.tag) {
lib/std/debug.zig+1-1
...@@ -68,7 +68,7 @@ else switch (std.Target.ObjectFormat.default(native_os, native_arch)) {...@@ -68,7 +68,7 @@ else switch (std.Target.ObjectFormat.default(native_os, native_arch)) {
68 else => @import("debug/SelfInfo/Elf.zig"),68 else => @import("debug/SelfInfo/Elf.zig"),
69 },69 },
70 .macho => @import("debug/SelfInfo/MachO.zig"),70 .macho => @import("debug/SelfInfo/MachO.zig"),
71 .goff, .plan9, .spirv, .wasm, .xcoff => void,71 .plan9, .spirv, .wasm => void,
72 .c, .hex, .raw => unreachable,72 .c, .hex, .raw => unreachable,
73};73};
7474
lib/std/zig.zig+1-1
...@@ -169,7 +169,7 @@ pub fn binNameAlloc(allocator: Allocator, options: BinNameOptions) error{OutOfMe...@@ -169,7 +169,7 @@ pub fn binNameAlloc(allocator: Allocator, options: BinNameOptions) error{OutOfMe
169 },169 },
170 .Obj => return std.fmt.allocPrint(allocator, "{s}.obj", .{root_name}),170 .Obj => return std.fmt.allocPrint(allocator, "{s}.obj", .{root_name}),
171 },171 },
172 .elf, .goff, .xcoff => switch (options.output_mode) {172 .elf => switch (options.output_mode) {
173 .Exe => return allocator.dupe(u8, root_name),173 .Exe => return allocator.dupe(u8, root_name),
174 .Lib => {174 .Lib => {
175 switch (options.link_mode orelse .static) {175 switch (options.link_mode orelse .static) {
lib/zig.h+1-9
...@@ -87,9 +87,7 @@...@@ -87,9 +87,7 @@
87#define zig_big_endian 187#define zig_big_endian 1
88#endif88#endif
8989
90#if defined(_AIX)90#if defined(__MACH__)
91#define zig_aix
92#elif defined(__MACH__)
93#define zig_darwin91#define zig_darwin
94#elif defined(__DragonFly__)92#elif defined(__DragonFly__)
95#define zig_dragonfly93#define zig_dragonfly
...@@ -119,20 +117,14 @@...@@ -119,20 +117,14 @@
119#define zig_wasi117#define zig_wasi
120#elif defined(_WIN32)118#elif defined(_WIN32)
121#define zig_windows119#define zig_windows
122#elif defined(__MVS__)
123#define zig_zos
124#endif120#endif
125121
126#if defined(zig_windows)122#if defined(zig_windows)
127#define zig_coff123#define zig_coff
128#elif defined(__ELF__)124#elif defined(__ELF__)
129#define zig_elf125#define zig_elf
130#elif defined(zig_zos)
131#define zig_goff
132#elif defined(zig_darwin)126#elif defined(zig_darwin)
133#define zig_macho127#define zig_macho
134#elif defined(zig_aix)
135#define zig_xcoff
136#endif128#endif
137129
138#define zig_concat(lhs, rhs) lhs##rhs130#define zig_concat(lhs, rhs) lhs##rhs
src/Compilation/Config.zig+1-1
...@@ -492,7 +492,7 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -492,7 +492,7 @@ pub fn resolve(options: Options) ResolveError!Config {
492 if (root_strip and !options.any_non_stripped) break :b .strip;492 if (root_strip and !options.any_non_stripped) break :b .strip;
493 if (options.debug_format) |x| break :b x;493 if (options.debug_format) |x| break :b x;
494 break :b switch (target.ofmt) {494 break :b switch (target.ofmt) {
495 .elf, .goff, .macho, .wasm, .xcoff => .{ .dwarf = .@"32" },495 .elf, .macho, .wasm => .{ .dwarf = .@"32" },
496 .coff => .code_view,496 .coff => .code_view,
497 .c => switch (target.os.tag) {497 .c => switch (target.os.tag) {
498 .windows, .uefi => .code_view,498 .windows, .uefi => .code_view,
src/codegen/llvm.zig+3-21
...@@ -179,9 +179,6 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8...@@ -179,9 +179,6 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8
179 try llvm_triple.append('-');179 try llvm_triple.append('-');
180180
181 try llvm_triple.appendSlice(switch (target.os.tag) {181 try llvm_triple.appendSlice(switch (target.os.tag) {
182 .aix,
183 .zos,
184 => "ibm",
185 .driverkit,182 .driverkit,
186 .ios,183 .ios,
187 .macos,184 .macos,
...@@ -214,10 +211,8 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8...@@ -214,10 +211,8 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8
214 .openbsd => "openbsd",211 .openbsd => "openbsd",
215 .illumos => "solaris",212 .illumos => "solaris",
216 .windows, .uefi => "windows",213 .windows, .uefi => "windows",
217 .zos => "zos",
218 .haiku => "haiku",214 .haiku => "haiku",
219 .rtems => "rtems",215 .rtems => "rtems",
220 .aix => "aix",
221 .cuda => "cuda",216 .cuda => "cuda",
222 .nvcl => "nvcl",217 .nvcl => "nvcl",
223 .amdhsa => "amdhsa",218 .amdhsa => "amdhsa",
...@@ -382,13 +377,9 @@ pub fn dataLayout(target: *const std.Target) []const u8 {...@@ -382,13 +377,9 @@ pub fn dataLayout(target: *const std.Target) []const u8 {
382 else => "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",377 else => "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
383 },378 },
384 .m68k => "E-m:e-p:32:16:32-i8:8:8-i16:16:16-i32:16:32-n8:16:32-a:0:16-S16",379 .m68k => "E-m:e-p:32:16:32-i8:8:8-i16:16:16-i32:16:32-n8:16:32-a:0:16-S16",
385 .powerpc => if (target.os.tag == .aix)380 .powerpc => "E-m:e-p:32:32-Fn32-i64:64-n32",
386 "E-m:a-p:32:32-Fi32-i64:64-n32"
387 else
388 "E-m:e-p:32:32-Fn32-i64:64-n32",
389 .powerpcle => "e-m:e-p:32:32-Fn32-i64:64-n32",381 .powerpcle => "e-m:e-p:32:32-Fn32-i64:64-n32",
390 .powerpc64 => switch (target.os.tag) {382 .powerpc64 => switch (target.os.tag) {
391 .aix => "E-m:a-Fi64-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512",
392 .linux => if (target.abi.isMusl())383 .linux => if (target.abi.isMusl())
393 "E-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512"384 "E-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512"
394 else385 else
...@@ -425,10 +416,7 @@ pub fn dataLayout(target: *const std.Target) []const u8 {...@@ -425,10 +416,7 @@ pub fn dataLayout(target: *const std.Target) []const u8 {
425 "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128",416 "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
426 .sparc => "E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64",417 .sparc => "E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64",
427 .sparc64 => "E-m:e-i64:64-i128:128-n32:64-S128",418 .sparc64 => "E-m:e-i64:64-i128:128-n32:64-S128",
428 .s390x => if (target.os.tag == .zos)419 .s390x => "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64",
429 "E-m:l-p1:32:32-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
430 else
431 "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64",
432 .x86 => if (target.os.tag == .windows or target.os.tag == .uefi) switch (target.abi) {420 .x86 => if (target.os.tag == .windows or target.os.tag == .uefi) switch (target.abi) {
433 .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",421 .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",
434 .gnu => if (target.ofmt == .coff)422 .gnu => if (target.ofmt == .coff)
...@@ -517,7 +505,7 @@ fn codeModel(model: std.builtin.CodeModel, target: *const std.Target) CodeModel...@@ -517,7 +505,7 @@ fn codeModel(model: std.builtin.CodeModel, target: *const std.Target) CodeModel
517 .extreme, .large => .large,505 .extreme, .large => .large,
518 .kernel => .kernel,506 .kernel => .kernel,
519 .medany => if (target.cpu.arch.isRISCV()) .medium else .large,507 .medany => if (target.cpu.arch.isRISCV()) .medium else .large,
520 .medium => if (target.os.tag == .aix) .large else .medium,508 .medium => .medium,
521 .medmid => .medium,509 .medmid => .medium,
522 .normal, .medlow, .small => .small,510 .normal, .medlow, .small => .small,
523 .tiny => .tiny,511 .tiny => .tiny,
...@@ -12828,12 +12816,6 @@ fn backendSupportsF128(target: *const std.Target) bool {...@@ -12828,12 +12816,6 @@ fn backendSupportsF128(target: *const std.Target) bool {
12828 // https://github.com/llvm/llvm-project/issues/4183812816 // https://github.com/llvm/llvm-project/issues/41838
12829 .sparc,12817 .sparc,
12830 => false,12818 => false,
12831 // https://github.com/llvm/llvm-project/issues/101545
12832 .powerpc,
12833 .powerpcle,
12834 .powerpc64,
12835 .powerpc64le,
12836 => target.os.tag != .aix,
12837 .arm,12819 .arm,
12838 .armeb,12820 .armeb,
12839 .thumb,12821 .thumb,
src/dev.zig-4
...@@ -104,8 +104,6 @@ pub const Env = enum {...@@ -104,8 +104,6 @@ pub const Env = enum {
104 .wasm_linker,104 .wasm_linker,
105 .spirv_linker,105 .spirv_linker,
106 .plan9_linker,106 .plan9_linker,
107 .goff_linker,
108 .xcoff_linker,
109 => true,107 => true,
110 .cc_command,108 .cc_command,
111 .translate_c_command,109 .translate_c_command,
...@@ -293,8 +291,6 @@ pub const Feature = enum {...@@ -293,8 +291,6 @@ pub const Feature = enum {
293 wasm_linker,291 wasm_linker,
294 spirv_linker,292 spirv_linker,
295 plan9_linker,293 plan9_linker,
296 goff_linker,
297 xcoff_linker,
298};294};
299295
300/// Makes the code following the call to this function unreachable if `feature` is disabled.296/// Makes the code following the call to this function unreachable if `feature` is disabled.
src/libs/libcxx.zig+1-10
...@@ -79,9 +79,6 @@ const libcxx_base_files = [_][]const u8{...@@ -79,9 +79,6 @@ const libcxx_base_files = [_][]const u8{
79 "src/stdexcept.cpp",79 "src/stdexcept.cpp",
80 "src/string.cpp",80 "src/string.cpp",
81 "src/strstream.cpp",81 "src/strstream.cpp",
82 "src/support/ibm/mbsnrtowcs.cpp",
83 "src/support/ibm/wcsnrtombs.cpp",
84 "src/support/ibm/xlocale_zos.cpp",
85 "src/support/win32/locale_win32.cpp",82 "src/support/win32/locale_win32.cpp",
86 "src/support/win32/support.cpp",83 "src/support/win32/support.cpp",
87 "src/system_error.cpp",84 "src/system_error.cpp",
...@@ -203,8 +200,6 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!...@@ -203,8 +200,6 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
203 continue;200 continue;
204 if (std.mem.startsWith(u8, cxx_src, "src/support/win32/") and target.os.tag != .windows)201 if (std.mem.startsWith(u8, cxx_src, "src/support/win32/") and target.os.tag != .windows)
205 continue;202 continue;
206 if (std.mem.startsWith(u8, cxx_src, "src/support/ibm/") and target.os.tag != .zos)
207 continue;
208203
209 var cflags = std.array_list.Managed([]const u8).init(arena);204 var cflags = std.array_list.Managed([]const u8).init(arena);
210205
...@@ -223,11 +218,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!...@@ -223,11 +218,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
223 try cflags.append("-fvisibility=hidden");218 try cflags.append("-fvisibility=hidden");
224 try cflags.append("-fvisibility-inlines-hidden");219 try cflags.append("-fvisibility-inlines-hidden");
225220
226 if (target.os.tag == .zos) {221 try cflags.append("-faligned-allocation");
227 try cflags.append("-fno-aligned-allocation");
228 } else {
229 try cflags.append("-faligned-allocation");
230 }
231222
232 try cflags.append("-nostdinc++");223 try cflags.append("-nostdinc++");
233 try cflags.append("-std=c++23");224 try cflags.append("-std=c++23");
src/libs/libtsan.zig-1
...@@ -480,7 +480,6 @@ const sanitizer_symbolizer_sources = [_][]const u8{...@@ -480,7 +480,6 @@ const sanitizer_symbolizer_sources = [_][]const u8{
480};480};
481481
482const interception_sources = [_][]const u8{482const interception_sources = [_][]const u8{
483 "interception_aix.cpp",
484 "interception_linux.cpp",483 "interception_linux.cpp",
485 "interception_mac.cpp",484 "interception_mac.cpp",
486 "interception_win.cpp",485 "interception_win.cpp",
src/libs/libunwind.zig-1
...@@ -198,6 +198,5 @@ const unwind_src_list = [_][]const u8{...@@ -198,6 +198,5 @@ const unwind_src_list = [_][]const u8{
198 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-wasm.c",198 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-wasm.c",
199 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersRestore.S",199 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersRestore.S",
200 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersSave.S",200 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersSave.S",
201 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind_AIXExtras.cpp",
202 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "gcc_personality_v0.c",201 "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "gcc_personality_v0.c",
203};202};
src/link.zig+4-18
...@@ -574,9 +574,9 @@ pub const File = struct {...@@ -574,9 +574,9 @@ pub const File = struct {
574 const gpa = comp.gpa;574 const gpa = comp.gpa;
575 switch (base.tag) {575 switch (base.tag) {
576 .lld => assert(base.file == null),576 .lld => assert(base.file == null),
577 .elf, .macho, .wasm, .goff, .xcoff => {577 .elf, .macho, .wasm => {
578 if (base.file != null) return;578 if (base.file != null) return;
579 dev.checkAny(&.{ .coff_linker, .elf_linker, .macho_linker, .plan9_linker, .wasm_linker, .goff_linker, .xcoff_linker });579 dev.checkAny(&.{ .coff_linker, .elf_linker, .macho_linker, .plan9_linker, .wasm_linker });
580 const emit = base.emit;580 const emit = base.emit;
581 if (base.child_pid) |pid| {581 if (base.child_pid) |pid| {
582 if (builtin.os.tag == .windows) {582 if (builtin.os.tag == .windows) {
...@@ -681,8 +681,8 @@ pub const File = struct {...@@ -681,8 +681,8 @@ pub const File = struct {
681 }681 }
682 }682 }
683 },683 },
684 .macho, .wasm, .goff, .xcoff => if (base.file) |f| {684 .macho, .wasm => if (base.file) |f| {
685 dev.checkAny(&.{ .coff_linker, .macho_linker, .plan9_linker, .wasm_linker, .goff_linker, .xcoff_linker });685 dev.checkAny(&.{ .coff_linker, .macho_linker, .plan9_linker, .wasm_linker });
686 f.close();686 f.close();
687 base.file = null;687 base.file = null;
688688
...@@ -825,7 +825,6 @@ pub const File = struct {...@@ -825,7 +825,6 @@ pub const File = struct {
825 switch (base.tag) {825 switch (base.tag) {
826 .lld => unreachable,826 .lld => unreachable,
827 .spirv => {},827 .spirv => {},
828 .goff, .xcoff => {},
829 .plan9 => unreachable,828 .plan9 => unreachable,
830 .elf2, .coff2 => {},829 .elf2, .coff2 => {},
831 inline else => |tag| {830 inline else => |tag| {
...@@ -973,7 +972,6 @@ pub const File = struct {...@@ -973,7 +972,6 @@ pub const File = struct {
973 .c => unreachable,972 .c => unreachable,
974 .spirv => unreachable,973 .spirv => unreachable,
975 .wasm => unreachable,974 .wasm => unreachable,
976 .goff, .xcoff => unreachable,
977 .plan9 => unreachable,975 .plan9 => unreachable,
978 inline else => |tag| {976 inline else => |tag| {
979 dev.check(tag.devFeature());977 dev.check(tag.devFeature());
...@@ -996,7 +994,6 @@ pub const File = struct {...@@ -996,7 +994,6 @@ pub const File = struct {
996 .c => unreachable,994 .c => unreachable,
997 .spirv => unreachable,995 .spirv => unreachable,
998 .wasm => unreachable,996 .wasm => unreachable,
999 .goff, .xcoff => unreachable,
1000 .plan9 => unreachable,997 .plan9 => unreachable,
1001 inline else => |tag| {998 inline else => |tag| {
1002 dev.check(tag.devFeature());999 dev.check(tag.devFeature());
...@@ -1013,7 +1010,6 @@ pub const File = struct {...@@ -1013,7 +1010,6 @@ pub const File = struct {
1013 .c => unreachable,1010 .c => unreachable,
1014 .spirv => unreachable,1011 .spirv => unreachable,
1015 .wasm => unreachable,1012 .wasm => unreachable,
1016 .goff, .xcoff => unreachable,
1017 .plan9 => unreachable,1013 .plan9 => unreachable,
1018 inline else => |tag| {1014 inline else => |tag| {
1019 dev.check(tag.devFeature());1015 dev.check(tag.devFeature());
...@@ -1034,8 +1030,6 @@ pub const File = struct {...@@ -1034,8 +1030,6 @@ pub const File = struct {
1034 .plan9 => unreachable,1030 .plan9 => unreachable,
10351031
1036 .spirv,1032 .spirv,
1037 .goff,
1038 .xcoff,
1039 => {},1033 => {},
10401034
1041 inline else => |tag| {1035 inline else => |tag| {
...@@ -1171,8 +1165,6 @@ pub const File = struct {...@@ -1171,8 +1165,6 @@ pub const File = struct {
1171 wasm,1165 wasm,
1172 spirv,1166 spirv,
1173 plan9,1167 plan9,
1174 goff,
1175 xcoff,
1176 lld,1168 lld,
11771169
1178 pub fn Type(comptime tag: Tag) type {1170 pub fn Type(comptime tag: Tag) type {
...@@ -1184,8 +1176,6 @@ pub const File = struct {...@@ -1184,8 +1176,6 @@ pub const File = struct {
1184 .c => C,1176 .c => C,
1185 .wasm => Wasm,1177 .wasm => Wasm,
1186 .spirv => SpirV,1178 .spirv => SpirV,
1187 .goff => Goff,
1188 .xcoff => Xcoff,
1189 .lld => Lld,1179 .lld => Lld,
1190 .plan9 => comptime unreachable,1180 .plan9 => comptime unreachable,
1191 };1181 };
...@@ -1200,8 +1190,6 @@ pub const File = struct {...@@ -1200,8 +1190,6 @@ pub const File = struct {
1200 .plan9 => .plan9,1190 .plan9 => .plan9,
1201 .c => .c,1191 .c => .c,
1202 .spirv => .spirv,1192 .spirv => .spirv,
1203 .goff => .goff,
1204 .xcoff => .xcoff,
1205 .hex => @panic("TODO implement hex object format"),1193 .hex => @panic("TODO implement hex object format"),
1206 .raw => @panic("TODO implement raw object format"),1194 .raw => @panic("TODO implement raw object format"),
1207 };1195 };
...@@ -1284,8 +1272,6 @@ pub const File = struct {...@@ -1284,8 +1272,6 @@ pub const File = struct {
1284 pub const MachO = @import("link/MachO.zig");1272 pub const MachO = @import("link/MachO.zig");
1285 pub const SpirV = @import("link/SpirV.zig");1273 pub const SpirV = @import("link/SpirV.zig");
1286 pub const Wasm = @import("link/Wasm.zig");1274 pub const Wasm = @import("link/Wasm.zig");
1287 pub const Goff = @import("link/Goff.zig");
1288 pub const Xcoff = @import("link/Xcoff.zig");
1289 pub const Dwarf = @import("link/Dwarf.zig");1275 pub const Dwarf = @import("link/Dwarf.zig");
1290};1276};
12911277
src/link/Elf2.zig-1
...@@ -418,7 +418,6 @@ fn create(...@@ -418,7 +418,6 @@ fn create(
418 .freestanding, .other => .STANDALONE,418 .freestanding, .other => .STANDALONE,
419 .netbsd => .NETBSD,419 .netbsd => .NETBSD,
420 .illumos => .SOLARIS,420 .illumos => .SOLARIS,
421 .aix => .AIX,
422 .freebsd, .ps4 => .FREEBSD,421 .freebsd, .ps4 => .FREEBSD,
423 .openbsd => .OPENBSD,422 .openbsd => .OPENBSD,
424 .cuda => .CUDA,423 .cuda => .CUDA,
src/link/Goff.zig deleted-112
...@@ -1,112 +0,0 @@
1//! Stub linker support for GOFF based on LLVM.
2
3const Goff = @This();
4
5const std = @import("std");
6const builtin = @import("builtin");
7
8const Allocator = std.mem.Allocator;
9const assert = std.debug.assert;
10const log = std.log.scoped(.link);
11const Path = std.Build.Cache.Path;
12
13const Zcu = @import("../Zcu.zig");
14const InternPool = @import("../InternPool.zig");
15const Compilation = @import("../Compilation.zig");
16const codegen = @import("../codegen.zig");
17const link = @import("../link.zig");
18const trace = @import("../tracy.zig").trace;
19const build_options = @import("build_options");
20
21base: link.File,
22
23pub fn createEmpty(
24 arena: Allocator,
25 comp: *Compilation,
26 emit: Path,
27 options: link.File.OpenOptions,
28) !*Goff {
29 const target = &comp.root_mod.resolved_target.result;
30 const use_lld = build_options.have_llvm and comp.config.use_lld;
31 const use_llvm = comp.config.use_llvm;
32
33 assert(use_llvm); // Caught by Compilation.Config.resolve.
34 assert(!use_lld); // Caught by Compilation.Config.resolve.
35 assert(target.os.tag == .zos); // Caught by Compilation.Config.resolve.
36
37 const goff = try arena.create(Goff);
38 goff.* = .{
39 .base = .{
40 .tag = .goff,
41 .comp = comp,
42 .emit = emit,
43 .zcu_object_basename = emit.sub_path,
44 .gc_sections = options.gc_sections orelse false,
45 .print_gc_sections = options.print_gc_sections,
46 .stack_size = options.stack_size orelse 0,
47 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
48 .file = null,
49 .build_id = options.build_id,
50 },
51 };
52
53 return goff;
54}
55
56pub fn open(
57 arena: Allocator,
58 comp: *Compilation,
59 emit: Path,
60 options: link.File.OpenOptions,
61) !*Goff {
62 const target = &comp.root_mod.resolved_target.result;
63 assert(target.ofmt == .goff);
64 return createEmpty(arena, comp, emit, options);
65}
66
67pub fn deinit(self: *Goff) void {
68 _ = self;
69}
70
71pub fn updateFunc(
72 self: *Goff,
73 pt: Zcu.PerThread,
74 func_index: InternPool.Index,
75 mir: *const codegen.AnyMir,
76) link.File.UpdateNavError!void {
77 _ = self;
78 _ = pt;
79 _ = func_index;
80 _ = mir;
81 unreachable; // we always use llvm
82}
83
84pub fn updateNav(self: *Goff, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void {
85 _ = self;
86 _ = pt;
87 _ = nav;
88 unreachable; // we always use llvm
89}
90
91pub fn updateExports(
92 self: *Goff,
93 pt: Zcu.PerThread,
94 exported: Zcu.Exported,
95 export_indices: []const Zcu.Export.Index,
96) !void {
97 _ = self;
98 _ = pt;
99 _ = exported;
100 _ = export_indices;
101 unreachable; // we always use llvm
102}
103
104pub fn flush(self: *Goff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
105 if (build_options.skip_non_native and builtin.object_format != .goff)
106 @panic("Attempted to compile for object format that was disabled by build configuration");
107
108 _ = self;
109 _ = arena;
110 _ = tid;
111 _ = prog_node;
112}
src/link/Lld.zig-1
...@@ -348,7 +348,6 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void {...@@ -348,7 +348,6 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void {
348 object_files.items.ptr,348 object_files.items.ptr,
349 object_files.items.len,349 object_files.items.len,
350 switch (target.os.tag) {350 switch (target.os.tag) {
351 .aix => .AIXBIG,
352 .windows => .COFF,351 .windows => .COFF,
353 else => if (target.os.tag.isDarwin()) .DARWIN else .GNU,352 else => if (target.os.tag.isDarwin()) .DARWIN else .GNU,
354 },353 },
src/link/Xcoff.zig deleted-112
...@@ -1,112 +0,0 @@
1//! Stub linker support for GOFF based on LLVM.
2
3const Xcoff = @This();
4
5const std = @import("std");
6const builtin = @import("builtin");
7
8const Allocator = std.mem.Allocator;
9const assert = std.debug.assert;
10const log = std.log.scoped(.link);
11const Path = std.Build.Cache.Path;
12
13const Zcu = @import("../Zcu.zig");
14const InternPool = @import("../InternPool.zig");
15const Compilation = @import("../Compilation.zig");
16const codegen = @import("../codegen.zig");
17const link = @import("../link.zig");
18const trace = @import("../tracy.zig").trace;
19const build_options = @import("build_options");
20
21base: link.File,
22
23pub fn createEmpty(
24 arena: Allocator,
25 comp: *Compilation,
26 emit: Path,
27 options: link.File.OpenOptions,
28) !*Xcoff {
29 const target = &comp.root_mod.resolved_target.result;
30 const use_lld = build_options.have_llvm and comp.config.use_lld;
31 const use_llvm = comp.config.use_llvm;
32
33 assert(use_llvm); // Caught by Compilation.Config.resolve.
34 assert(!use_lld); // Caught by Compilation.Config.resolve.
35 assert(target.os.tag == .aix); // Caught by Compilation.Config.resolve.
36
37 const xcoff = try arena.create(Xcoff);
38 xcoff.* = .{
39 .base = .{
40 .tag = .xcoff,
41 .comp = comp,
42 .emit = emit,
43 .zcu_object_basename = emit.sub_path,
44 .gc_sections = options.gc_sections orelse false,
45 .print_gc_sections = options.print_gc_sections,
46 .stack_size = options.stack_size orelse 0,
47 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
48 .file = null,
49 .build_id = options.build_id,
50 },
51 };
52
53 return xcoff;
54}
55
56pub fn open(
57 arena: Allocator,
58 comp: *Compilation,
59 emit: Path,
60 options: link.File.OpenOptions,
61) !*Xcoff {
62 const target = &comp.root_mod.resolved_target.result;
63 assert(target.ofmt == .xcoff);
64 return createEmpty(arena, comp, emit, options);
65}
66
67pub fn deinit(self: *Xcoff) void {
68 _ = self;
69}
70
71pub fn updateFunc(
72 self: *Xcoff,
73 pt: Zcu.PerThread,
74 func_index: InternPool.Index,
75 mir: *const codegen.AnyMir,
76) link.File.UpdateNavError!void {
77 _ = self;
78 _ = pt;
79 _ = func_index;
80 _ = mir;
81 unreachable; // we always use llvm
82}
83
84pub fn updateNav(self: *Xcoff, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void {
85 _ = self;
86 _ = pt;
87 _ = nav;
88 unreachable; // we always use llvm
89}
90
91pub fn updateExports(
92 self: *Xcoff,
93 pt: Zcu.PerThread,
94 exported: Zcu.Exported,
95 export_indices: []const Zcu.Export.Index,
96) !void {
97 _ = self;
98 _ = pt;
99 _ = exported;
100 _ = export_indices;
101 unreachable; // we always use llvm
102}
103
104pub fn flush(self: *Xcoff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
105 if (build_options.skip_non_native and builtin.object_format != .xcoff)
106 @panic("Attempted to compile for object format that was disabled by build configuration");
107
108 _ = self;
109 _ = arena;
110 _ = tid;
111 _ = prog_node;
112}
src/target.zig-2
...@@ -155,13 +155,11 @@ pub fn hasLlvmSupport(target: *const std.Target, ofmt: std.Target.ObjectFormat)...@@ -155,13 +155,11 @@ pub fn hasLlvmSupport(target: *const std.Target, ofmt: std.Target.ObjectFormat)
155155
156 .coff,156 .coff,
157 .elf,157 .elf,
158 .goff,
159 .hex,158 .hex,
160 .macho,159 .macho,
161 .spirv,160 .spirv,
162 .raw,161 .raw,
163 .wasm,162 .wasm,
164 .xcoff,
165 => {},163 => {},
166 }164 }
167165
test/llvm_targets.zig-3
...@@ -175,7 +175,6 @@ const targets = [_]std.Target.Query{...@@ -175,7 +175,6 @@ const targets = [_]std.Target.Query{
175 .{ .cpu_arch = .nvptx64, .os_tag = .cuda, .abi = .none },175 .{ .cpu_arch = .nvptx64, .os_tag = .cuda, .abi = .none },
176 .{ .cpu_arch = .nvptx64, .os_tag = .nvcl, .abi = .none },176 .{ .cpu_arch = .nvptx64, .os_tag = .nvcl, .abi = .none },
177177
178 .{ .cpu_arch = .powerpc, .os_tag = .aix, .abi = .eabihf },
179 .{ .cpu_arch = .powerpc, .os_tag = .freestanding, .abi = .eabi },178 .{ .cpu_arch = .powerpc, .os_tag = .freestanding, .abi = .eabi },
180 .{ .cpu_arch = .powerpc, .os_tag = .freestanding, .abi = .eabihf },179 .{ .cpu_arch = .powerpc, .os_tag = .freestanding, .abi = .eabihf },
181 .{ .cpu_arch = .powerpc, .os_tag = .haiku, .abi = .eabi },180 .{ .cpu_arch = .powerpc, .os_tag = .haiku, .abi = .eabi },
...@@ -196,7 +195,6 @@ const targets = [_]std.Target.Query{...@@ -196,7 +195,6 @@ const targets = [_]std.Target.Query{
196 .{ .cpu_arch = .powerpcle, .os_tag = .freestanding, .abi = .eabi },195 .{ .cpu_arch = .powerpcle, .os_tag = .freestanding, .abi = .eabi },
197 .{ .cpu_arch = .powerpcle, .os_tag = .freestanding, .abi = .eabihf },196 .{ .cpu_arch = .powerpcle, .os_tag = .freestanding, .abi = .eabihf },
198197
199 .{ .cpu_arch = .powerpc64, .os_tag = .aix, .abi = .none },
200 .{ .cpu_arch = .powerpc64, .os_tag = .freebsd, .abi = .none },198 .{ .cpu_arch = .powerpc64, .os_tag = .freebsd, .abi = .none },
201 .{ .cpu_arch = .powerpc64, .os_tag = .freestanding, .abi = .none },199 .{ .cpu_arch = .powerpc64, .os_tag = .freestanding, .abi = .none },
202 .{ .cpu_arch = .powerpc64, .os_tag = .linux, .abi = .gnu },200 .{ .cpu_arch = .powerpc64, .os_tag = .linux, .abi = .gnu },
...@@ -239,7 +237,6 @@ const targets = [_]std.Target.Query{...@@ -239,7 +237,6 @@ const targets = [_]std.Target.Query{
239 .{ .cpu_arch = .s390x, .os_tag = .freestanding, .abi = .none },237 .{ .cpu_arch = .s390x, .os_tag = .freestanding, .abi = .none },
240 .{ .cpu_arch = .s390x, .os_tag = .linux, .abi = .gnu },238 .{ .cpu_arch = .s390x, .os_tag = .linux, .abi = .gnu },
241 .{ .cpu_arch = .s390x, .os_tag = .linux, .abi = .none },239 .{ .cpu_arch = .s390x, .os_tag = .linux, .abi = .none },
242 // .{ .cpu_arch = .s390x, .os_tag = .zos, .abi = .none },
243240
244 .{ .cpu_arch = .sparc, .os_tag = .freestanding, .abi = .none },241 .{ .cpu_arch = .sparc, .os_tag = .freestanding, .abi = .none },
245 .{ .cpu_arch = .sparc, .os_tag = .linux, .abi = .gnu },242 .{ .cpu_arch = .sparc, .os_tag = .linux, .abi = .gnu },
tools/update_cpu_features.zig+22
...@@ -1051,6 +1051,28 @@ const targets = [_]ArchTarget{...@@ -1051,6 +1051,28 @@ const targets = [_]ArchTarget{
1051 .name = "PowerPC",1051 .name = "PowerPC",
1052 .td_name = "PPC",1052 .td_name = "PPC",
1053 },1053 },
1054 .feature_overrides = &.{
1055 .{
1056 .llvm_name = "aix",
1057 .omit = true,
1058 },
1059 .{
1060 .llvm_name = "aix-shared-lib-tls-model-opt",
1061 .omit = true,
1062 },
1063 .{
1064 .llvm_name = "aix-small-local-dynamic-tls",
1065 .omit = true,
1066 },
1067 .{
1068 .llvm_name = "aix-small-local-exec-tls",
1069 .omit = true,
1070 },
1071 .{
1072 .llvm_name = "modern-aix-as",
1073 .omit = true,
1074 },
1075 },
1054 .omit_cpus = &.{1076 .omit_cpus = &.{
1055 "ppc32",1077 "ppc32",
1056 },1078 },