__libc_start_main.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #include <elf.h>
  2. #include <poll.h>
  3. #include <fcntl.h>
  4. #include <signal.h>
  5. #include "syscall.h"
  6. #include "atomic.h"
  7. #include "libc.h"
  8. void __init_tls(size_t *);
  9. static void dummy(void) {}
  10. weak_alias(dummy, _init);
  11. __attribute__((__weak__, __visibility__("hidden")))
  12. extern void (*const __init_array_start)(void), (*const __init_array_end)(void);
  13. static void dummy1(void *p) {}
  14. weak_alias(dummy1, __init_ssp);
  15. #define AUX_CNT 38
  16. void __init_libc(char **envp, char *pn)
  17. {
  18. size_t i, *auxv, aux[AUX_CNT] = { 0 };
  19. __environ = envp;
  20. for (i=0; envp[i]; i++);
  21. libc.auxv = auxv = (void *)(envp+i+1);
  22. for (i=0; auxv[i]; i+=2) if (auxv[i]<AUX_CNT) aux[auxv[i]] = auxv[i+1];
  23. __hwcap = aux[AT_HWCAP];
  24. __sysinfo = aux[AT_SYSINFO];
  25. libc.page_size = aux[AT_PAGESZ];
  26. if (!pn) pn = (void*)aux[AT_EXECFN];
  27. if (!pn) pn = "";
  28. __progname = __progname_full = pn;
  29. for (i=0; pn[i]; i++) if (pn[i]=='/') __progname = pn+i+1;
  30. __init_tls(aux);
  31. __init_ssp((void *)aux[AT_RANDOM]);
  32. if (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID]
  33. && !aux[AT_SECURE]) return;
  34. struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} };
  35. #ifdef SYS_poll
  36. __syscall(SYS_poll, pfd, 3, 0);
  37. #else
  38. __syscall(SYS_ppoll, pfd, 3, &(struct timespec){0}, 0, _NSIG/8);
  39. #endif
  40. for (i=0; i<3; i++) if (pfd[i].revents&POLLNVAL)
  41. if (__sys_open("/dev/null", O_RDWR)<0)
  42. a_crash();
  43. libc.secure = 1;
  44. }
  45. static void libc_start_init(void)
  46. {
  47. _init();
  48. uintptr_t a = (uintptr_t)&__init_array_start;
  49. for (; a<(uintptr_t)&__init_array_end; a+=sizeof(void(*)()))
  50. (*(void (**)())a)();
  51. }
  52. weak_alias(libc_start_init, __libc_start_init);
  53. int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv)
  54. {
  55. char **envp = argv+argc+1;
  56. __init_libc(envp, argv[0]);
  57. __libc_start_init();
  58. /* Pass control to the application */
  59. exit(main(argc, argv, envp));
  60. return 0;
  61. }