__libc_start_main.c 1.8 KB

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