From 7c7da3927aa09f8de9ceaf1eff8af5fe1cde3bf4 Mon Sep 17 00:00:00 2001 From: Phil Ramsey Date: Thu, 16 Jan 2025 00:24:14 +0000 Subject: [PATCH 1/3] i#7185 Add missing AArch64 system register enums (#7189) Add decoding support for the following AArch64 registers: CONTEXTIDR_EL1 ELR_EL1 SPSR_EL1 TPIDR_EL1 Also add some missing tests for other AArch64 registers. Fixes: #7185 --- core/ir/aarch64/codec.c | 8 ++++++++ core/ir/aarch64/encode.c | 9 +++++++-- core/ir/opnd_api.h | 12 ++++++++---- core/ir/opnd_shared.c | 2 +- suite/tests/api/dis-a64.txt | 21 +++++++++++++++++++++ suite/tests/api/ir_aarch64_v80.c | 12 ++++++++++-- 6 files changed, 55 insertions(+), 9 deletions(-) diff --git a/core/ir/aarch64/codec.c b/core/ir/aarch64/codec.c index bfec2a92262..d1d21a57db2 100644 --- a/core/ir/aarch64/codec.c +++ b/core/ir/aarch64/codec.c @@ -283,6 +283,10 @@ decode_sysreg(uint imm15) { reg_t sysreg; switch (imm15) { + case 0x4681: sysreg = DR_REG_CONTEXTIDR_EL1; break; + case 0x4201: sysreg = DR_REG_ELR_EL1; break; + case 0x4200: sysreg = DR_REG_SPSR_EL1; break; + case 0x4684: sysreg = DR_REG_TPIDR_EL1; break; case 0x4000: sysreg = DR_REG_MIDR_EL1; break; case 0x4005: sysreg = DR_REG_MPIDR_EL1; break; case 0x4006: sysreg = DR_REG_REVIDR_EL1; break; @@ -419,6 +423,10 @@ encode_sysreg(OUT uint *imm15, opnd_t opnd) { if (opnd_is_reg(opnd)) { switch (opnd_get_reg(opnd)) { + case DR_REG_CONTEXTIDR_EL1: *imm15 = 0x4681; break; + case DR_REG_ELR_EL1: *imm15 = 0x4201; break; + case DR_REG_SPSR_EL1: *imm15 = 0x4200; break; + case DR_REG_TPIDR_EL1: *imm15 = 0x4684; break; case DR_REG_MIDR_EL1: *imm15 = 0x4000; break; case DR_REG_MPIDR_EL1: *imm15 = 0x4005; break; case DR_REG_REVIDR_EL1: *imm15 = 0x4006; break; diff --git a/core/ir/aarch64/encode.c b/core/ir/aarch64/encode.c index 2b270a76a81..64497fffa28 100644 --- a/core/ir/aarch64/encode.c +++ b/core/ir/aarch64/encode.c @@ -122,7 +122,7 @@ const char *const reg_names[] = { "id_aa64pfr0_el1", "id_aa64mmfr1_el1", "id_aa64dfr0_el1", "id_aa64zfr0_el1", "id_aa64pfr1_el1", "id_aa64mmfr2_el1", "midr_el1", "mpidr_el1", "revidr_el1", - "fpmr", + "fpmr", "contextidr_el1", "elr_el1", "spsr_el1", "tpidr_el1" }; @@ -203,7 +203,8 @@ const reg_id_t dr_reg_fixer[] = { REG_NULL, DR_REG_ID_AA64DFR0_EL1, DR_REG_ID_AA64ZFR0_EL1, DR_REG_ID_AA64PFR1_EL1, DR_REG_ID_AA64MMFR2_EL1, DR_REG_MIDR_EL1, DR_REG_MPIDR_EL1, DR_REG_REVIDR_EL1, - DR_REG_FPMR, + DR_REG_FPMR, DR_REG_CONTEXTIDR_EL1, DR_REG_ELR_EL1, DR_REG_SPSR_EL1, + DR_REG_TPIDR_EL1 }; /* Maps real ISA registers to their corresponding virtual DR_ISA_REGDEPS register. @@ -392,6 +393,10 @@ const reg_id_t d_r_reg_id_to_virtual[] = { DR_REG_VIRT208, /* DR_REG_REVIDR_EL1 */ DR_REG_VIRT209, /* DR_REG_FPMR */ + DR_REG_VIRT210, /* DR_REG_CONTEXTIDR_EL1 */ + DR_REG_VIRT211, /* DR_REG_ELR_EL1 */ + DR_REG_VIRT212, /* DR_REG_SPSR_EL1 */ + DR_REG_VIRT213, /* DR_REG_TPIDR_EL1 */ }; /* clang-format on */ diff --git a/core/ir/opnd_api.h b/core/ir/opnd_api.h index d9e61a848be..3b04c7b8f37 100644 --- a/core/ir/opnd_api.h +++ b/core/ir/opnd_api.h @@ -1061,6 +1061,10 @@ enum { DR_REG_MPIDR_EL1, /**< The "mpidr_el1" register. */ DR_REG_REVIDR_EL1, /**< The "revidr_el1" register. */ DR_REG_FPMR, /**< The "fpmr" register. */ + DR_REG_CONTEXTIDR_EL1, /**< The "contextidr_el1" register. */ + DR_REG_ELR_EL1, /**< The "elr_el1" register. */ + DR_REG_SPSR_EL1, /**< The "spsr_el1" register. */ + DR_REG_TPIDR_EL1, /**< The "tpidr_el1" register. */ # endif /* Aliases below here: */ @@ -1117,12 +1121,12 @@ enum { /** Thread Pointer/ID Register, Read-Only, EL0. */ DR_REG_TPIDRRO_EL0 = DR_REG_TPIDRURO, /* ARMv7 Thread Registers */ - DR_REG_CP15_C13_2 = DR_REG_TPIDRURW, /**< User Read/Write Thread ID Register */ - DR_REG_CP15_C13_3 = DR_REG_TPIDRURO, /**< User Read-Only Thread ID Register */ + DR_REG_CP15_C13_2 = DR_REG_TPIDRURW, /**< User Read/Write Thread ID Register */ + DR_REG_CP15_C13_3 = DR_REG_TPIDRURO, /**< User Read-Only Thread ID Register */ # ifdef AARCH64 - DR_REG_LAST_VALID_ENUM = DR_REG_FPMR, /**< Last valid register enum */ - DR_REG_LAST_ENUM = DR_REG_FPMR, /**< Last value of register enums */ + DR_REG_LAST_VALID_ENUM = DR_REG_TPIDR_EL1, /**< Last valid register enum */ + DR_REG_LAST_ENUM = DR_REG_TPIDR_EL1, /**< Last value of register enums */ # else DR_REG_LAST_VALID_ENUM = DR_REG_TPIDRURO, /**< Last valid register enum */ DR_REG_LAST_ENUM = DR_REG_TPIDRURO, /**< Last value of register enums */ diff --git a/core/ir/opnd_shared.c b/core/ir/opnd_shared.c index 11ae3eb0dc7..54165b41c66 100644 --- a/core/ir/opnd_shared.c +++ b/core/ir/opnd_shared.c @@ -2782,7 +2782,7 @@ reg_get_size(reg_id_t reg) } if ((reg >= DR_REG_P0 && reg <= DR_REG_P15) || reg == DR_REG_FFR) return OPSZ_SVE_PREDLEN_BYTES; - if (reg >= DR_REG_CNTVCT_EL0 && reg <= DR_REG_FPMR) + if (reg >= DR_REG_CNTVCT_EL0 && reg <= DR_REG_TPIDR_EL1) return OPSZ_8; if (reg >= DR_REG_NZCV && reg <= DR_REG_FPSR) return OPSZ_8; diff --git a/suite/tests/api/dis-a64.txt b/suite/tests/api/dis-a64.txt index 6b14ee8a9f3..6f0a27872e3 100644 --- a/suite/tests/api/dis-a64.txt +++ b/suite/tests/api/dis-a64.txt @@ -31743,6 +31743,10 @@ d5380000 : mrs x0, midr_el1 : mrs %midr_el1 -> %x0 d53800a0 : mrs x0, mpidr_el1 : mrs %mpidr_el1 -> %x0 d53800c0 : mrs x0, revidr_el1 : mrs %revidr_el1 -> %x0 d53b4440 : mrs x0, fpmr : mrs %fpmr -> %x0 +d538d020 : mrs x0, contextidr_el1 : mrs %contextidr_el1 -> %x0 +d5384020 : mrs x0, elr_el1 : mrs %elr_el1 -> %x0 +d5384000 : mrs x0, spsr_el1 : mrs %spsr_el1 -> %x0 +d538d080 : mrs x0, tpidr_el1 : mrs %tpidr_el1 -> %x0 # MSR , # (MSR-I-SI_system) d50040bf : msr SPSel, #0x0 : msr %spsel $0x00 @@ -31886,6 +31890,23 @@ d51beffe : msr pmccfiltr_el0, x30 : msr %x30 -> %pmccfiltr d51c431e : msr spsr_irq, x30 : msr %x30 -> %spsr_irq d51c433e : msr spsr_abt, x30 : msr %x30 -> %spsr_abt d51c4360 : msr spsr_fiq, x0 : msr %x0 -> %spsr_fiq +d5180600 : msr x0, id_aa64isar0_el1 : msr %x0 -> %id_aa64isar0_el1 +d5180620 : msr x0, id_aa64isar1_el1 : msr %x0 -> %id_aa64isar1_el1 +d5180640 : msr x0, id_aa64isar2_el1 : msr %x0 -> %id_aa64isar2_el1 +d5180400 : msr x0, id_aa64pfr0_el1 : msr %x0 -> %id_aa64pfr0_el1 +d5180720 : msr x0, id_aa64mmfr1_el1 : msr %x0 -> %id_aa64mmfr1_el1 +d5180500 : msr x0, id_aa64dfr0_el1 : msr %x0 -> %id_aa64dfr0_el1 +d5180480 : msr x0, id_aa64zfr0_el1 : msr %x0 -> %id_aa64zfr0_el1 +d5180420 : msr x0, id_aa64pfr1_el1 : msr %x0 -> %id_aa64pfr1_el1 +d5180740 : msr x0, id_aa64mmfr2_el1 : msr %x0 -> %id_aa64mmfr2_el1 +d5180000 : msr x0, midr_el1 : msr %x0 -> %midr_el1 +d51800a0 : msr x0, mpidr_el1 : msr %x0 -> %mpidr_el1 +d51800c0 : msr x0, revidr_el1 : msr %x0 -> %revidr_el1 +d51b4440 : msr x0, fpmr : msr %x0 -> %fpmr +d518d020 : msr x0, contextidr_el1 : msr %x0 -> %contextidr_el1 +d5184020 : msr x0, elr_el1 : msr %x0 -> %elr_el1 +d5184000 : msr x0, spsr_el1 : msr %x0 -> %spsr_el1 +d518d080 : msr x0, tpidr_el1 : msr %x0 -> %tpidr_el1 # MSUB , , , (MSUB-R.RRR-32A_dp_3src) 1b028c20 : msub w0, w1, w2, w3 : msub %w1 %w2 %w3 -> %w0 diff --git a/suite/tests/api/ir_aarch64_v80.c b/suite/tests/api/ir_aarch64_v80.c index ead9b88160e..a259c6381db 100644 --- a/suite/tests/api/ir_aarch64_v80.c +++ b/suite/tests/api/ir_aarch64_v80.c @@ -139,6 +139,10 @@ static const reg_id_t systemreg[] = { DR_REG_MIDR_EL1, DR_REG_MPIDR_EL1, DR_REG_REVIDR_EL1, + DR_REG_CONTEXTIDR_EL1, + DR_REG_ELR_EL1, + DR_REG_SPSR_EL1, + DR_REG_TPIDR_EL1, }; static const size_t sysreg_count = sizeof(systemreg) / sizeof(systemreg[0]); @@ -197,7 +201,9 @@ TEST_INSTR(mrs) "mrs %id_aa64dfr0_el1 -> %x22", "mrs %id_aa64zfr0_el1 -> %x23", "mrs %id_aa64pfr1_el1 -> %x24", "mrs %id_aa64mmfr2_el1 -> %x25", "mrs %midr_el1 -> %x26", "mrs %mpidr_el1 -> %x27", - "mrs %revidr_el1 -> %x28" + "mrs %revidr_el1 -> %x28", "mrs %contextidr_el1 -> %x29", + "mrs %elr_el1 -> %x30", "mrs %spsr_el1 -> %x0", + "mrs %tpidr_el1 -> %x1" /* clang-format on */ ); switch (systemreg[i]) { @@ -278,7 +284,9 @@ TEST_INSTR(msr) "msr %x22 -> %id_aa64dfr0_el1", "msr %x23 -> %id_aa64zfr0_el1", "msr %x24 -> %id_aa64pfr1_el1", "msr %x25 -> %id_aa64mmfr2_el1", "msr %x26 -> %midr_el1", "msr %x27 -> %mpidr_el1", - "msr %x28 -> %revidr_el1" + "msr %x28 -> %revidr_el1", "msr %x29 -> %contextidr_el1", + "msr %x30 -> %elr_el1", "msr %x0 -> %spsr_el1", + "msr %x1 -> %tpidr_el1" /* clang-format on */ ); switch (systemreg[i]) { From 6d1e5447be1e2259dcff0689da6101d80fda68bd Mon Sep 17 00:00:00 2001 From: Enrico Deiana Date: Wed, 15 Jan 2025 17:37:24 -0800 Subject: [PATCH 2/3] i#6662 public traces: fix doc formatting (#7188) Fixes new line issues after bullet point lists for better readability. Fixes citation, for which the title wasn't being displayed correctly. Issue #6662 --- clients/drcachesim/docs/drcachesim.dox.in | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/clients/drcachesim/docs/drcachesim.dox.in b/clients/drcachesim/docs/drcachesim.dox.in index 68f344631e5..45cc5bb5265 100644 --- a/clients/drcachesim/docs/drcachesim.dox.in +++ b/clients/drcachesim/docs/drcachesim.dox.in @@ -1084,17 +1084,19 @@ All markers of the original trace are present, except for: - #dynamorio::drmemtrace::TRACE_MARKER_TYPE_SYSCALL_TRACE_END - #dynamorio::drmemtrace::TRACE_MARKER_TYPE_SYSCALL_FAILED - #dynamorio::drmemtrace::TRACE_MARKER_TYPE_SIGNAL_NUMBER + Which have been removed. + Because tracing overhead results into inflated context switches, the #dynamorio::drmemtrace::TRACE_MARKER_TYPE_CPU_ID values have been modified to "unknown CPU" to avoid confusion. We recommend users to use our scheduler (see \ref sec_drcachesim_sched) for a realistic schedule of a trace's threads. -Also, we preserved the following markers: + +Also, we preserved the following markers, but only for SYS_futex functions: - #dynamorio::drmemtrace::TRACE_MARKER_TYPE_FUNC_ID - #dynamorio::drmemtrace::TRACE_MARKER_TYPE_FUNC_ARG - #dynamorio::drmemtrace::TRACE_MARKER_TYPE_FUNC_RETVAL - #dynamorio::drmemtrace::TRACE_MARKER_TYPE_FUNC_RETADDR -But only for SYS_futex functions. Finally, every trace has a v2p.textproto file associated to it, which provides a plausible virtual to physical mapping of the virtual addresses present in a trace @@ -1109,14 +1111,14 @@ These traces are supported starting from DynamoRIO 11.3. The Google Workload Traces can be downloaded from: - - [Google workload trace folder](https://console.cloud.google.com/storage/browser/external-traces-v2) +- [Google workload trace folder](https://console.cloud.google.com/storage/browser/external-traces-v2) Directory structure: -- \verbatim - workload_name/ - ..memtrace.zip - v2p.textproto - \endverbatim +\verbatim +workload_name/ + ..memtrace.zip + v2p.textproto +\endverbatim \section sec_google_help Getting Help and Reporting Bugs @@ -1156,8 +1158,8 @@ You can contribute to the project in many ways: If you would like to cite this work, you can use the following BibTeX entry: \verbatim -@misc{ Google_Workload_Traces_Version_2, - title = {{Google Workload Traces Version 2}}, +@misc{Google_Workload_Traces_Version_2, + title = {Google Workload Traces Version 2}, howpublished = {\url{https://console.cloud.google.com/storage/browser/external-traces-v2}}, note = {Accessed: yyyy-mm-dd} } From 359868c7c61ebde085bf4454a7278cade8a2f789 Mon Sep 17 00:00:00 2001 From: ath0 Date: Thu, 16 Jan 2025 11:31:20 +0900 Subject: [PATCH 3/3] i#5383: Fix macOS preload on a64 (#7170) This fixes several build and runtime issues under macOS on ARM64 on macOS 14.4.1 (Sonoma). - `FEATURE_PAUTH` is now detected on macOS using a sysctl (capability MSRs cannot be read in userspace on M3 at least). - In the preload library and os.c, `_init` needs `__attribute__((constructor))` to be run by dyld. - `PLATFORM_SUPPORTS_SCATTER_GATHER` is broken, disabled for now on a64 macOS. - Fixed sigcontext/mcontext conversion which assumes old `simd` size and was failing on an assert. Known issues that remain: - VM allocation frequently but nondeterministically fails reachability constraints. `-vm_size 500M` seems to fix this. #7171 adds this flag to tests on macOS+ARM64. Another option is to make this the default on macOS+ARM64. - Sometimes some bookkeeping asserts in `vmh_exit` are reached upon process exit. The end result is that the `bbcount` tool works on a simple toy program on macOS, in debug mode, without hitting any asserts: ``` bin64/drrun -debug -vm_size 500M -c api/bin/libbbcount.dylib -- ./main ``` Issue #5383 --- core/arch/aarch64/proc.c | 90 ++++++++++++++++++++++++++-------------- core/iox.h | 2 - core/unix/os.c | 4 +- core/unix/os_public.h | 10 +++++ core/unix/preload.c | 3 +- core/unix/signal_macos.c | 26 ++++++++++-- ext/drx/drx.c | 3 +- 7 files changed, 98 insertions(+), 40 deletions(-) diff --git a/core/arch/aarch64/proc.c b/core/arch/aarch64/proc.c index 0c875822936..945ec9bdbdf 100644 --- a/core/arch/aarch64/proc.c +++ b/core/arch/aarch64/proc.c @@ -36,12 +36,44 @@ #include "arch.h" #include "instr.h" +#if defined(MACOS) +# include +#endif + static int num_simd_saved; static int num_simd_registers; static int num_svep_registers; static int num_ffr_registers; static int num_opmask_registers; +#define GET_FEAT_REG(FEATURE) (feature_reg_idx_t)((((ushort)FEATURE) & 0x3F00) >> 8) +#define GET_FEAT_NIBPOS(FEATURE) ((((ushort)FEATURE) & 0x00F0) >> 4) +#define GET_FEAT_VAL(FEATURE) (((ushort)FEATURE) & 0x000F) +#define GET_FEAT_NSFLAG(FEATURE) ((((ushort)FEATURE) & 0x8000) >> 15) +#define GET_FEAT_EXACT_MATCH(FEATURE) ((((ushort)FEATURE) & 0x4000) >> 14) + +void +proc_set_feature(feature_bit_t feature_bit, bool enable) +{ + uint64 *freg_val = cpu_info.features.isa_features; + ushort feat_nibble = GET_FEAT_NIBPOS(feature_bit); + bool feat_nsflag = GET_FEAT_NSFLAG(feature_bit); + uint64 feat_val = GET_FEAT_VAL(feature_bit); + + feature_reg_idx_t feat_reg = GET_FEAT_REG(feature_bit); + freg_val += feat_reg; + + /* Clear the current feature state. */ + *freg_val &= ~(0xFULL << (feat_nibble * 4)); + if (enable) { + /* Write the feature value into the feature nibble. */ + *freg_val |= feat_val << (feat_nibble * 4); + } else if (feat_nsflag) { + /* If the not-set flag is 0xF, then that needs manually setting. */ + *freg_val |= 0xF << (feat_nibble * 4); + } +} + #ifndef DR_HOST_NOT_TARGET # define NUM_FEATURE_REGISTERS (sizeof(features_t) / sizeof(uint64)) @@ -86,7 +118,7 @@ read_feature_regs(uint64 isa_features[]) : "x0"); } -# if !defined(MACOS) // TODO i#5383: Get this working on Mac. */ +# if !defined(MACOS) static void get_processor_specific_info(void) { @@ -146,6 +178,32 @@ get_processor_specific_info(void) dr_set_vector_length(256); # endif } +# else /* defined(MACOS) */ + +/* On macOS, MRS appears to be restricted. We'll use sysctl's instead. + * XXX i#5383: Add remaining features from other sysctls. + */ +static void +get_processor_specific_info(void) +{ + memset(&cpu_info.features, 0, sizeof(cpu_info.features)); + +# define SET_FEAT_IF_SYSCTL_EQ(FEATURE, SYSCTL, TY, VAL) \ + TY FEATURE##_tmp; \ + size_t FEATURE##_tmp_buflen = sizeof(FEATURE##_tmp); \ + if (sysctlbyname(SYSCTL, &FEATURE##_tmp, &FEATURE##_tmp_buflen, NULL, 0) == \ + -1) { \ + ASSERT_CURIOSITY(false && SYSCTL " sysctl failed"); \ + SYSLOG_INTERNAL_WARNING("Failed to read " SYSCTL " sysctl"); \ + } else if (FEATURE##_tmp_buflen == sizeof(FEATURE##_tmp)) { \ + if (FEATURE##_tmp == VAL) { \ + proc_set_feature(FEATURE, true); \ + } \ + } + + SET_FEAT_IF_SYSCTL_EQ(FEATURE_PAUTH, "hw.optional.arm.FEAT_PAuth", uint32_t, 1); + SET_FEAT_IF_SYSCTL_EQ(FEATURE_FPAC, "hw.optional.arm.FEAT_FPAC", uint32_t, 1); +} # endif # define LOG_FEATURE(feature) \ @@ -172,7 +230,6 @@ proc_init_arch(void) } #ifndef DR_HOST_NOT_TARGET -# if !defined(MACOS) // TODO i#5383: Get this working on Mac. */ get_processor_specific_info(); DOLOG(1, LOG_TOP, { @@ -247,38 +304,9 @@ proc_init_arch(void) cpu_info.features.isa_features[AA64MMFR2]); LOG_FEATURE(FEATURE_LSE2); }); -# endif #endif } -#define GET_FEAT_REG(FEATURE) (feature_reg_idx_t)((((ushort)FEATURE) & 0x3F00) >> 8) -#define GET_FEAT_NIBPOS(FEATURE) ((((ushort)FEATURE) & 0x00F0) >> 4) -#define GET_FEAT_VAL(FEATURE) (((ushort)FEATURE) & 0x000F) -#define GET_FEAT_NSFLAG(FEATURE) ((((ushort)FEATURE) & 0x8000) >> 15) -#define GET_FEAT_EXACT_MATCH(FEATURE) ((((ushort)FEATURE) & 0x4000) >> 14) - -void -proc_set_feature(feature_bit_t feature_bit, bool enable) -{ - uint64 *freg_val = cpu_info.features.isa_features; - ushort feat_nibble = GET_FEAT_NIBPOS(feature_bit); - bool feat_nsflag = GET_FEAT_NSFLAG(feature_bit); - uint64 feat_val = GET_FEAT_VAL(feature_bit); - - feature_reg_idx_t feat_reg = GET_FEAT_REG(feature_bit); - freg_val += feat_reg; - - /* Clear the current feature state. */ - *freg_val &= ~(0xFULL << (feat_nibble * 4)); - if (enable) { - /* Write the feature value into the feature nibble. */ - *freg_val |= feat_val << (feat_nibble * 4); - } else if (feat_nsflag) { - /* If the not-set flag is 0xF, then that needs manually setting. */ - *freg_val |= 0xF << (feat_nibble * 4); - } -} - void enable_all_test_cpu_features() { diff --git a/core/iox.h b/core/iox.h index e9f4ee2728a..c0329c228ab 100644 --- a/core/iox.h +++ b/core/iox.h @@ -706,9 +706,7 @@ TNAME(d_r_vsnprintf)(TCHAR *s, size_t max, const TCHAR *fmt, va_list ap) c++; } else { const TCHAR *cstart = c; - int nbytes = 0; while (*c && *c != _T('%')) { - nbytes++; c++; } while (cstart < c) { diff --git a/core/unix/os.c b/core/unix/os.c index 9d9becdb14f..500814b024f 100644 --- a/core/unix/os.c +++ b/core/unix/os.c @@ -784,7 +784,7 @@ static init_fn_t #else /* If we're a normal shared object, then we override _init. */ -int +INITIALIZER_ATTRIBUTES int _init(int argc, char **argv, char **envp) { # ifdef ANDROID @@ -1143,6 +1143,8 @@ get_application_name_helper(bool ignore_cache, bool full_path) #else /* OSX kernel puts full app exec path above envp */ char *c, **env = our_environ; + ASSERT(our_environ != NULL && + "our_environ is not set in get_application_name_helper"); do { env++; } while (*env != NULL); diff --git a/core/unix/os_public.h b/core/unix/os_public.h index 84899bcec88..f19036ad658 100644 --- a/core/unix/os_public.h +++ b/core/unix/os_public.h @@ -242,4 +242,14 @@ typedef kernel_sigcontext_t sigcontext_t; # define SC_RETURN_REG SC_A0 #endif /* X86/ARM */ +/* XXX i#5383: macOS 14.4 on ARM64 _init does not seem to get called + * without __attribute__((constructor)) but it inexplicably breaks tests if + * we add this flag on X86. So we add it only on ARM64 for now. + */ +#if defined(MACOS) && defined(AARCH64) +# define INITIALIZER_ATTRIBUTES __attribute__((constructor)) +#else +# define INITIALIZER_ATTRIBUTES +#endif + #endif /* _OS_PUBLIC_H_ 1 */ diff --git a/core/unix/preload.c b/core/unix/preload.c index 934e71546fe..48fb62e83ca 100644 --- a/core/unix/preload.c +++ b/core/unix/preload.c @@ -50,6 +50,7 @@ #include "configure.h" #include "globals_shared.h" #include "../config.h" +#include "os_public.h" #include /* for getpid */ #include @@ -137,7 +138,7 @@ take_over(const char *pname) return true; } -int +INITIALIZER_ATTRIBUTES int #if INIT_BEFORE_LIBC _init(int argc, char *arg0, ...) { diff --git a/core/unix/signal_macos.c b/core/unix/signal_macos.c index db6d1c35750..a8b05ee687c 100644 --- a/core/unix/signal_macos.c +++ b/core/unix/signal_macos.c @@ -157,8 +157,17 @@ sigcontext_to_mcontext_simd(priv_mcontext_t *mc, sig_full_cxt_t *sc_full) return; mc->fpsr = fpc->__fpsr; mc->fpcr = fpc->__fpcr; - ASSERT(sizeof(mc->simd) == sizeof(fpc->__v)); - memcpy(&mc->simd, &fpc->__v, sizeof(mc->simd)); + if (proc_has_feature(FEATURE_SVE)) { + /* XXX i#5383: SVE and SVE2 support for MACOS still missing. + */ + ASSERT_NOT_IMPLEMENTED(false); + } else { + /* ARM_NEON64 case. + */ + for (int i = 0; i < proc_num_simd_registers(); i++) { + memcpy(&mc->simd[i].q, &fpc->__v[i], sizeof(mc->simd->q)); + } + } #elif defined(X86) /* We assume that _STRUCT_X86_FLOAT_STATE* matches exactly the first * half of _STRUCT_X86_AVX_STATE*, and similarly for AVX and AVX512. @@ -200,8 +209,17 @@ mcontext_to_sigcontext_simd(sig_full_cxt_t *sc_full, priv_mcontext_t *mc) return; fpc->__fpsr = mc->fpsr; fpc->__fpcr = mc->fpcr; - ASSERT(sizeof(mc->simd) == sizeof(fpc->__v)); - memcpy(&fpc->__v, &mc->simd, sizeof(mc->simd)); + if (proc_has_feature(FEATURE_SVE)) { + /* XXX i#5383: SVE and SVE2 support for MACOS still missing. + */ + ASSERT_NOT_IMPLEMENTED(false); + } else { + /* ARM_NEON64 case. + */ + ASSERT((sizeof(mc->simd->q) * proc_num_simd_registers()) == sizeof(fpc->__v)); + for (int i = 0; i < proc_num_simd_registers(); i++) + memcpy(&fpc->__v[i], &mc->simd[i].q, sizeof(fpc->__v[i])); + } #elif defined(X86) sigcontext_t *sc = sc_full->sc; int i; diff --git a/ext/drx/drx.c b/ext/drx/drx.c index f5b9d25dd1b..2037fd5cbe0 100644 --- a/ext/drx/drx.c +++ b/ext/drx/drx.c @@ -71,7 +71,8 @@ # define IF_WINDOWS_ELSE(x, y) (y) #endif -#if defined(X86) || defined(AARCH64) +/* XXX i#5383: PLATFORM_SUPPORTS_SCATTER_GATHER is broken on aarch64 macOS. */ +#if (defined(X86) || defined(AARCH64)) && !(defined(MACOS) && defined(AARCH64)) # define PLATFORM_SUPPORTS_SCATTER_GATHER #endif