cosmopolitan/third_party/libunwind/assembly.h
Justine Tunney c9152b6f14
Release Cosmopolitan v3.8.0
This change switches c++ exception handling from sjlj to standard dwarf.
It's needed because clang for aarch64 doesn't support sjlj. It turns out
that libunwind had a bare-metal configuration that made this easy to do.

This change gets the new experimental cosmocc -mclang flag in a state of
working so well that it can now be used to build all of llamafile and it
goes 3x faster in terms of build latency, without trading away any perf.

The int_fast16_t and int_fast32_t types are now always defined as 32-bit
in the interest of having more abi consistency between cosmocc -mgcc and
-mclang mode.
2024-08-30 20:14:07 -07:00

303 lines
10 KiB
C

/* ===-- assembly.h - libUnwind assembler support macros -------------------===
*
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
* See https://llvm.org/LICENSE.txt for license information.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
* ===----------------------------------------------------------------------===
*
* This file defines macros for use in libUnwind assembler source.
* This file is not part of the interface of this library.
*
* ===----------------------------------------------------------------------===
*/
#ifndef UNWIND_ASSEMBLY_H
#define UNWIND_ASSEMBLY_H
#if defined(__linux__) && defined(__CET__)
#include <cet.h>
#define _LIBUNWIND_CET_ENDBR _CET_ENDBR
#else
#define _LIBUNWIND_CET_ENDBR
#endif
#if defined(__powerpc64__)
#define SEPARATOR ;
#define PPC64_OFFS_SRR0 0
#define PPC64_OFFS_CR 272
#define PPC64_OFFS_XER 280
#define PPC64_OFFS_LR 288
#define PPC64_OFFS_CTR 296
#define PPC64_OFFS_VRSAVE 304
#define PPC64_OFFS_FP 312
#define PPC64_OFFS_V 824
#elif defined(__APPLE__) && defined(__aarch64__)
#define SEPARATOR %%
#elif defined(__riscv)
# define RISCV_ISIZE (__riscv_xlen / 8)
# define RISCV_FOFFSET (RISCV_ISIZE * 32)
# if defined(__riscv_flen)
# define RISCV_FSIZE (__riscv_flen / 8)
# endif
# if __riscv_xlen == 64
# define ILOAD ld
# define ISTORE sd
# elif __riscv_xlen == 32
# define ILOAD lw
# define ISTORE sw
# else
# error "Unsupported __riscv_xlen"
# endif
# if defined(__riscv_flen)
# if __riscv_flen == 64
# define FLOAD fld
# define FSTORE fsd
# elif __riscv_flen == 32
# define FLOAD flw
# define FSTORE fsw
# else
# error "Unsupported __riscv_flen"
# endif
# endif
# define SEPARATOR ;
#else
#define SEPARATOR ;
#endif
#if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF == 1) && \
!defined(_AIX)
#define PPC64_OPD1 .section .opd,"aw",@progbits SEPARATOR
#define PPC64_OPD2 SEPARATOR \
.p2align 3 SEPARATOR \
.quad .Lfunc_begin0 SEPARATOR \
.quad .TOC.@tocbase SEPARATOR \
.quad 0 SEPARATOR \
.text SEPARATOR \
.Lfunc_begin0:
#else
#define PPC64_OPD1
#define PPC64_OPD2
#endif
#if defined(__aarch64__)
#if defined(__ARM_FEATURE_GCS_DEFAULT) && defined(__ARM_FEATURE_BTI_DEFAULT)
// Set BTI, PAC, and GCS gnu property bits
#define GNU_PROPERTY 7
// We indirectly branch to __libunwind_Registers_arm64_jumpto from
// __unw_phase2_resume, so we need to use bti jc.
#define AARCH64_BTI bti jc
#elif defined(__ARM_FEATURE_GCS_DEFAULT)
// Set GCS gnu property bit
#define GNU_PROPERTY 4
#elif defined(__ARM_FEATURE_BTI_DEFAULT)
// Set BTI and PAC gnu property bits
#define GNU_PROPERTY 3
#define AARCH64_BTI bti c
#endif
#ifdef GNU_PROPERTY
.pushsection ".note.gnu.property", "a" SEPARATOR \
.balign 8 SEPARATOR \
.long 4 SEPARATOR \
.long 0x10 SEPARATOR \
.long 0x5 SEPARATOR \
.asciz "GNU" SEPARATOR \
.long 0xc0000000 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ \
.long 4 SEPARATOR \
.long GNU_PROPERTY SEPARATOR \
.long 0 SEPARATOR \
.popsection SEPARATOR
#endif
#endif
#if !defined(AARCH64_BTI)
#define AARCH64_BTI
#endif
#if !defined(__aarch64__)
#ifdef __ARM_FEATURE_PAC_DEFAULT
.eabi_attribute Tag_PAC_extension, 2
.eabi_attribute Tag_PACRET_use, 1
#endif
#ifdef __ARM_FEATURE_BTI_DEFAULT
.eabi_attribute Tag_BTI_extension, 1
.eabi_attribute Tag_BTI_use, 1
#endif
#endif
#define GLUE2(a, b) a ## b
#define GLUE(a, b) GLUE2(a, b)
#define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)
#if defined(__APPLE__)
#define SYMBOL_IS_FUNC(name)
#define HIDDEN_SYMBOL(name) .private_extern name
#if defined(_LIBUNWIND_HIDE_SYMBOLS)
#define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name)
#else
#define EXPORT_SYMBOL(name)
#endif
#define WEAK_ALIAS(name, aliasname) \
.globl SYMBOL_NAME(aliasname) SEPARATOR \
EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
#define NO_EXEC_STACK_DIRECTIVE
#elif defined(__ELF__)
#if defined(__arm__)
#define SYMBOL_IS_FUNC(name) .type name,%function
#else
#define SYMBOL_IS_FUNC(name) .type name,@function
#endif
#define HIDDEN_SYMBOL(name) .hidden name
#if defined(_LIBUNWIND_HIDE_SYMBOLS)
#define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name)
#else
#define EXPORT_SYMBOL(name)
#endif
#define WEAK_SYMBOL(name) .weak name
#if defined(__hexagon__)
#define WEAK_ALIAS(name, aliasname) \
EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
.equiv SYMBOL_NAME(aliasname), SYMBOL_NAME(name)
#else
#define WEAK_ALIAS(name, aliasname) \
EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
#endif
#if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
defined(__linux__)
#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits
#else
#define NO_EXEC_STACK_DIRECTIVE
#endif
#elif defined(_WIN32)
#define SYMBOL_IS_FUNC(name) \
.def name SEPARATOR \
.scl 2 SEPARATOR \
.type 32 SEPARATOR \
.endef
#define EXPORT_SYMBOL2(name) \
.section .drectve,"yn" SEPARATOR \
.ascii "-export:", #name, "\0" SEPARATOR \
.text
#if defined(_LIBUNWIND_HIDE_SYMBOLS)
#define EXPORT_SYMBOL(name)
#else
#define EXPORT_SYMBOL(name) EXPORT_SYMBOL2(name)
#endif
#define HIDDEN_SYMBOL(name)
#if defined(__MINGW32__)
#define WEAK_ALIAS(name, aliasname) \
.globl SYMBOL_NAME(aliasname) SEPARATOR \
EXPORT_SYMBOL(aliasname) SEPARATOR \
SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
#else
#define WEAK_ALIAS3(name, aliasname) \
.section .drectve,"yn" SEPARATOR \
.ascii "-alternatename:", #aliasname, "=", #name, "\0" SEPARATOR \
.text
#define WEAK_ALIAS2(name, aliasname) \
WEAK_ALIAS3(name, aliasname)
#define WEAK_ALIAS(name, aliasname) \
EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR \
WEAK_ALIAS2(SYMBOL_NAME(name), SYMBOL_NAME(aliasname))
#endif
#define NO_EXEC_STACK_DIRECTIVE
#elif defined(__sparc__)
#elif defined(_AIX)
#if defined(__powerpc64__)
#define VBYTE_LEN 8
#define CSECT_ALIGN 3
#else
#define VBYTE_LEN 4
#define CSECT_ALIGN 2
#endif
// clang-format off
#define DEFINE_LIBUNWIND_FUNCTION_AND_WEAK_ALIAS(name, aliasname) \
.csect .text[PR], 2 SEPARATOR \
.csect .name[PR], 2 SEPARATOR \
.globl name[DS] SEPARATOR \
.globl .name[PR] SEPARATOR \
.align 4 SEPARATOR \
.csect name[DS], CSECT_ALIGN SEPARATOR \
aliasname: \
.vbyte VBYTE_LEN, .name[PR] SEPARATOR \
.vbyte VBYTE_LEN, TOC[TC0] SEPARATOR \
.vbyte VBYTE_LEN, 0 SEPARATOR \
.weak aliasname SEPARATOR \
.weak .aliasname SEPARATOR \
.csect .name[PR], 2 SEPARATOR \
.aliasname: \
#define WEAK_ALIAS(name, aliasname)
#define NO_EXEC_STACK_DIRECTIVE
// clang-format on
#else
#error Unsupported target
#endif
#if defined(_AIX)
// clang-format off
#define DEFINE_LIBUNWIND_FUNCTION(name) \
.globl name[DS] SEPARATOR \
.globl .name SEPARATOR \
.align 4 SEPARATOR \
.csect name[DS], CSECT_ALIGN SEPARATOR \
.vbyte VBYTE_LEN, .name SEPARATOR \
.vbyte VBYTE_LEN, TOC[TC0] SEPARATOR \
.vbyte VBYTE_LEN, 0 SEPARATOR \
.csect .text[PR], 2 SEPARATOR \
.name:
// clang-format on
#else
#define DEFINE_LIBUNWIND_FUNCTION(name) \
.globl SYMBOL_NAME(name) SEPARATOR \
HIDDEN_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \
SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \
PPC64_OPD1 \
SYMBOL_NAME(name): \
PPC64_OPD2 \
AARCH64_BTI
#endif
#if defined(__arm__)
#if !defined(__ARM_ARCH)
#define __ARM_ARCH 4
#endif
#if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5
#define ARM_HAS_BX
#endif
#ifdef ARM_HAS_BX
#define JMP(r) bx r
#else
#define JMP(r) mov pc, r
#endif
#endif /* __arm__ */
#if defined(__powerpc__)
#define PPC_LEFT_SHIFT(index) << (index)
#endif
#endif /* UNWIND_ASSEMBLY_H */