libcinit.cpp 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. /*
  2. * Copyright (c) 2018-2022, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/Types.h>
  7. #include <assert.h>
  8. #include <errno.h>
  9. #include <sys/auxv.h>
  10. #include <sys/internals.h>
  11. #include <unistd.h>
  12. [[gnu::weak]] char** __environ_value() asm("__environ_value");
  13. extern "C" {
  14. #ifdef NO_TLS
  15. int errno_storage;
  16. #else
  17. __thread int errno_storage;
  18. #endif
  19. bool __environ_is_malloced = false;
  20. bool __stdio_is_initialized = false;
  21. void* __auxiliary_vector = reinterpret_cast<void*>(explode_byte(0xe1));
  22. #ifndef _DYNAMIC_LOADER
  23. char** environ = reinterpret_cast<char**>(explode_byte(0xe2));
  24. uintptr_t __stack_chk_guard;
  25. #endif
  26. int* __errno_location()
  27. {
  28. return &errno_storage;
  29. }
  30. void __libc_init()
  31. {
  32. #ifndef _DYNAMIC_LOADER
  33. // We can only call magic functions until __stack_chk_guard is initialized.
  34. environ = __environ_value();
  35. #endif
  36. char** env;
  37. for (env = environ; *env; ++env)
  38. ;
  39. __auxiliary_vector = (void*)++env;
  40. #ifndef _DYNAMIC_LOADER
  41. for (auxv_t* entry = reinterpret_cast<auxv_t*>(__auxiliary_vector); entry->a_type != AT_NULL; ++entry)
  42. if (entry->a_type == AT_RANDOM)
  43. __stack_chk_guard = *(reinterpret_cast<u64*>(entry->a_un.a_ptr) + 1);
  44. // We include an additional hardening: zero the first byte of the stack guard to avoid leaking
  45. // or overwriting the stack guard with C-style string functions.
  46. __stack_chk_guard &= ~0xffULL;
  47. #endif
  48. __malloc_init();
  49. __stdio_init();
  50. }
  51. }