brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.6 KiB · 8b5f98f Raw
194 lines · c
1//===-- crtbegin.c - Start of constructors and destructors ----------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include <stddef.h>10 11#ifndef __has_feature12# define __has_feature(x) 013#endif14 15#if __has_feature(ptrauth_init_fini)16#include <ptrauth.h>17#endif18 19__attribute__((visibility("hidden"))) void *__dso_handle = &__dso_handle;20 21#ifdef EH_USE_FRAME_REGISTRY22__extension__ static void *const __EH_FRAME_LIST__[]23    __attribute__((section(".eh_frame"), aligned(sizeof(void *)))) = {};24 25extern void __register_frame_info(const void *, void *) __attribute__((weak));26extern void *__deregister_frame_info(const void *) __attribute__((weak));27#endif28 29#ifndef CRT_HAS_INITFINI_ARRAY30typedef void (*fp)(void);31 32static fp __CTOR_LIST__[]33    __attribute__((section(".ctors"), aligned(sizeof(fp)))) = {(fp)-1};34extern fp __CTOR_LIST_END__[];35#endif36 37extern void __cxa_finalize(void *) __attribute__((weak));38 39static void __attribute__((used)) __do_init(void) {40  static _Bool __initialized;41  if (__builtin_expect(__initialized, 0))42    return;43  __initialized = 1;44 45#ifdef EH_USE_FRAME_REGISTRY46  static struct { void *p[8]; } __object;47  if (__register_frame_info)48    __register_frame_info(__EH_FRAME_LIST__, &__object);49#endif50#ifndef CRT_HAS_INITFINI_ARRAY51  const size_t n = __CTOR_LIST_END__ - __CTOR_LIST__ - 1;52  for (size_t i = n; i >= 1; i--) __CTOR_LIST__[i]();53#endif54}55 56#ifdef CRT_HAS_INITFINI_ARRAY57# if __has_feature(ptrauth_init_fini)58// TODO: use __ptrauth-qualified pointers when they are supported on clang side59#  if __has_feature(ptrauth_init_fini_address_discrimination)60__attribute__((section(".init_array"), used)) static void *__init =61    ptrauth_sign_constant(&__do_init, ptrauth_key_init_fini_pointer,62                          ptrauth_blend_discriminator(63                              &__init, __ptrauth_init_fini_discriminator));64#  else65__attribute__((section(".init_array"), used)) static void *__init =66    ptrauth_sign_constant(&__do_init, ptrauth_key_init_fini_pointer,67                          __ptrauth_init_fini_discriminator);68#  endif69# elif __has_feature(ptrauth_calls)70#  ifdef __aarch64__71// If ptrauth_init_fini feature is not present, compiler emits raw unsigned72// pointers in .init_array. Use inline assembly to avoid implicit signing of73// __do_init function pointer with ptrauth_calls enabled.74__asm__(".pushsection .init_array,\"aw\",@init_array\n\t"75        ".xword __do_init\n\t"76        ".popsection");77#  else78#   error "ptrauth_calls is only supported for AArch64"79#  endif80# else81__attribute__((section(".init_array"),82               used)) static void (*__init)(void) = __do_init;83# endif84#elif defined(__i386__) || defined(__x86_64__)85__asm__(".pushsection .init,\"ax\",@progbits\n\t"86        "call __do_init\n\t"87        ".popsection");88#elif defined(__riscv)89__asm__(".pushsection .init,\"ax\",%progbits\n\t"90        "call __do_init\n\t"91        ".popsection");92#elif defined(__arm__) || defined(__aarch64__)93__asm__(".pushsection .init,\"ax\",%progbits\n\t"94        "bl __do_init\n\t"95        ".popsection");96#elif defined(__mips__)97__asm__(".pushsection .init,\"ax\",@progbits\n\t"98        "jal __do_init\n\t"99        ".popsection");100#elif defined(__powerpc__) || defined(__powerpc64__)101__asm__(".pushsection .init,\"ax\",@progbits\n\t"102        "bl __do_init\n\t"103        "nop\n\t"104        ".popsection");105#elif defined(__sparc__)106__asm__(".pushsection .init,\"ax\",@progbits\n\t"107        "call __do_init\n\t"108        ".popsection");109#else110#error "crtbegin without .init_fini array unimplemented for this architecture"111#endif // CRT_HAS_INITFINI_ARRAY112 113#ifndef CRT_HAS_INITFINI_ARRAY114static fp __DTOR_LIST__[]115    __attribute__((section(".dtors"), aligned(sizeof(fp)))) = {(fp)-1};116extern fp __DTOR_LIST_END__[];117#endif118 119static void __attribute__((used)) __do_fini(void) {120  static _Bool __finalized;121  if (__builtin_expect(__finalized, 0))122    return;123  __finalized = 1;124 125  if (__cxa_finalize)126    __cxa_finalize(__dso_handle);127 128#ifndef CRT_HAS_INITFINI_ARRAY129  const size_t n = __DTOR_LIST_END__ - __DTOR_LIST__ - 1;130  for (size_t i = 1; i <= n; i++) __DTOR_LIST__[i]();131#endif132#ifdef EH_USE_FRAME_REGISTRY133  if (__deregister_frame_info)134    __deregister_frame_info(__EH_FRAME_LIST__);135#endif136}137 138#ifdef CRT_HAS_INITFINI_ARRAY139# if __has_feature(ptrauth_init_fini)140// TODO: use __ptrauth-qualified pointers when they are supported on clang side141#  if __has_feature(ptrauth_init_fini_address_discrimination)142__attribute__((section(".fini_array"), used)) static void *__fini =143    ptrauth_sign_constant(&__do_fini, ptrauth_key_init_fini_pointer,144                          ptrauth_blend_discriminator(145                              &__fini, __ptrauth_init_fini_discriminator));146#  else147__attribute__((section(".fini_array"), used)) static void *__fini =148    ptrauth_sign_constant(&__do_fini, ptrauth_key_init_fini_pointer,149                          __ptrauth_init_fini_discriminator);150#  endif151# elif __has_feature(ptrauth_calls)152#  ifdef __aarch64__153// If ptrauth_init_fini feature is not present, compiler emits raw unsigned154// pointers in .fini_array. Use inline assembly to avoid implicit signing of155// __do_fini function pointer with ptrauth_calls enabled.156__asm__(".pushsection .fini_array,\"aw\",@fini_array\n\t"157        ".xword __do_fini\n\t"158        ".popsection");159#  else160#   error "ptrauth_calls is only supported for AArch64"161#  endif162# else163__attribute__((section(".fini_array"),164               used)) static void (*__fini)(void) = __do_fini;165# endif166#elif defined(__i386__) || defined(__x86_64__)167__asm__(".pushsection .fini,\"ax\",@progbits\n\t"168        "call __do_fini\n\t"169        ".popsection");170#elif defined(__arm__) || defined(__aarch64__)171__asm__(".pushsection .fini,\"ax\",%progbits\n\t"172        "bl __do_fini\n\t"173        ".popsection");174#elif defined(__mips__)175__asm__(".pushsection .fini,\"ax\",@progbits\n\t"176        "jal __do_fini\n\t"177        ".popsection");178#elif defined(__powerpc__) || defined(__powerpc64__)179__asm__(".pushsection .fini,\"ax\",@progbits\n\t"180        "bl __do_fini\n\t"181        "nop\n\t"182        ".popsection");183#elif defined(__riscv)184__asm__(".pushsection .fini,\"ax\",@progbits\n\t"185        "call __do_fini\n\t"186        ".popsection");187#elif defined(__sparc__)188__asm__(".pushsection .fini,\"ax\",@progbits\n\t"189        "call __do_fini\n\t"190        ".popsection");191#else192#error "crtbegin without .init_fini array unimplemented for this architecture"193#endif  // CRT_HAS_INIT_FINI_ARRAY194