Advertisement
Madmouse

My LIBC replacement in its unfinished state

Nov 20th, 2015
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.01 KB | None | 0 0
  1.  
  2. #include <madlib.h>
  3.  
  4. ///!!!!!!!!!!!!!!!!!!!!!!!!! SPECIAL LIBC MAGIX !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  5. extern void (*__preinit_array_start []) (int, char **, char **);
  6. extern void (*__preinit_array_end []) (int, char **, char **);
  7. extern void (*__init_array_start []) (int, char **, char **);
  8. extern void (*__init_array_end []) (int, char **, char **);
  9. extern void (*__fini_array_start []) (void);
  10. extern void (*__fini_array_end []) (void);
  11.  
  12. extern void _init (void);
  13. extern void _fini (void);
  14.  
  15. char** __environ;
  16. int errno;
  17.  
  18.  
  19. void __libc_csu_fini(int e)
  20. {
  21. #if defined(DEBUG)
  22.     puts(__FUNCTION__);
  23. #endif
  24.     size_t i = __fini_array_end - __fini_array_start;
  25.     while(i-- > 0)
  26.         (*__fini_array_start[i])();
  27.     _fini();
  28.     exit(e);
  29. }
  30.  
  31.  
  32. void __libc_init(int argc, char** argv, char** envp)
  33. {
  34.     const size_t size = __preinit_array_end - __preinit_array_start;
  35.     size_t i;
  36.     for(i = 0; i < size; i++)
  37.         (*__preinit_array_start[i])(argc, argv, envp);
  38. }
  39.  
  40. void __libc_init_first(int argc, char** argv, char** envp)
  41. {
  42. #if defined(DEBUG)
  43.     puts(__FUNCTION__);
  44. #endif
  45.     __environ = envp;
  46.     __libc_init(argc, argv, envp);
  47. }
  48.  
  49. void __libc_csu_init(int argc, char** argv, char** envp)
  50. {
  51. #if defined(DEBUG)
  52.     puts(__FUNCTION__);
  53. #endif
  54.     _init();
  55.    
  56.     size_t i;
  57.     const size_t size = __init_array_end - __init_array_start;
  58.     for(i = 0; i < size; i++)
  59.         (*__init_array_start[i])(argc, argv, envp);
  60. }
  61.  
  62.  
  63. void __attribute__((noreturn)) __libc_start_main(
  64.     int (*main) (int, char**, char**),
  65.     int argc, char** ubp_av,
  66.     void (*init) (int, char**, char**),
  67.     void (*fini) (int),
  68.     void (*rtld_fini) (void),
  69.     void (*stack_end))
  70. {
  71. #if defined(DEBUG)
  72.     puts(__FUNCTION__);
  73. #endif
  74.     char** argv = (char**) ubp_av;
  75.     char** envp = &argv[argc + 1];
  76.     int ret;
  77.  
  78.     char* ld_show_auxv = envpv(envp, "LD_SHOW_AUXV");
  79.     if(ld_show_auxv != NULL && ld_show_auxv[0] == '1')
  80.     {
  81.         char** p = envp;
  82.         while(*p++ != NULL);
  83. #if defined(__x86_64__)
  84.         Elf64_auxv_t* auxv;
  85.         for(auxv = (Elf64_auxv_t*) p; auxv->a_type != AT_NULL; auxv++)
  86. #elif defined(__i386__)
  87.         Elf32_auxv_t* auxv;
  88.         for(auxv = (Elf32_auxv_t*) p; auxv->a_type != AT_NULL; auxv++)
  89. #elif defined(__arm__)
  90.         Elf32_auxv_t* auxv;
  91.         for(auxv = (Elf32_auxv_t*) p; auxv->a_type != AT_NULL; auxv++)
  92. #endif
  93.         {
  94.             switch(auxv->a_type)
  95.             {
  96.                 case AT_IGNORE:
  97.                     break;
  98.                 case AT_EXECFD:
  99.                     printf("AT_EXECFD:\t%i\n", (int) auxv->a_un.a_val);
  100.                     break;
  101.                 case AT_PHDR:
  102.                     printf("AT_PHDR:\t%i\n", (int) auxv->a_un.a_val);
  103.                     break;
  104.                 case AT_PHENT:
  105.                     printf("AT_PHENT:\t%i\n", (int) auxv->a_un.a_val);
  106.                     break;
  107.                 case AT_PHNUM:
  108.                     printf("AT_PHNUM:\t%i\n", (int) auxv->a_un.a_val);
  109.                     break;
  110.                 case AT_PAGESZ:
  111.                     printf("AT_PAGESZ:\t%i\n", (int) auxv->a_un.a_val);
  112.                     break;
  113.                 case AT_BASE:
  114.                     printf("AT_BASE:\t%i\n", (int) auxv->a_un.a_val);
  115.                     break;
  116.                 case AT_FLAGS:
  117.                     printf("AT_FLAGS:\t%i\n", (int) auxv->a_un.a_val);
  118.                     break;
  119.                 case AT_ENTRY:
  120.                     printf("AT_ENTRY:\t%i\n", (int) auxv->a_un.a_val);
  121.                     break;
  122.                 case AT_NOTELF:
  123.                     printf("AT_NOTELF:\t%i\n", (int) auxv->a_un.a_val);
  124.                     break;
  125.                 case AT_UID:
  126.                     printf("AT_UID:\t\t%i\n", (int) auxv->a_un.a_val);
  127.                     break;
  128.                 case AT_EUID:
  129.                     printf("AT_EUID:\t%i\n", (int) auxv->a_un.a_val);
  130.                     break;
  131.                 case AT_GID:
  132.                     printf("AT_GID:\t\t%i\n", (int) auxv->a_un.a_val);
  133.                     break;
  134.                 case AT_EGID:
  135.                     printf("AT_EGID:\t%i\n", (int) auxv->a_un.a_val);
  136.                     break;
  137.                 case AT_CLKTCK:
  138.                     printf("AT_CLKTCK:\t%i\n", (int) auxv->a_un.a_val);
  139.                     break;
  140.                 case AT_PLATFORM:
  141.                     printf("AT_PLATFORM:\t%s\n", (char*) auxv->a_un.a_val);
  142.                     break;
  143.                 case AT_HWCAP:
  144.                     printf("AT_hwcap:\t%i\n", (int) auxv->a_un.a_val);
  145.                     break;
  146.                 case AT_FPUCW:
  147.                     printf("AT_FPUCW:\t%i\n", (int) auxv->a_un.a_val);
  148.                     break;
  149.                 case AT_DCACHEBSIZE:
  150.                     printf("AT_DCACHEBSIZE:\t%i\n", (int) auxv->a_un.a_val);
  151.                     break;
  152.                 case AT_ICACHEBSIZE:
  153.                     printf("AT_ICACHEBSIZE:\t%i\n", (int) auxv->a_un.a_val);
  154.                     break;
  155.                 case AT_UCACHEBSIZE:
  156.                     printf("AT_UCACHEBSIZE:\t%i\n", (int) auxv->a_un.a_val);
  157.                     break;
  158.                 case AT_IGNOREPPC:
  159.                     printf("AT_IGNOREPPC:\t%i\n", (int) auxv->a_un.a_val);
  160.                     break;
  161.                 case AT_SECURE:
  162.                     printf("AT_SECURE:\t%i\n", (int) auxv->a_un.a_val);
  163.                     break;
  164.                 case AT_BASE_PLATFORM:
  165.                     printf("AT_BASE_PLATFORM:\t%s\n", (char*) auxv->a_un.a_val);
  166.                     break;
  167.                 case AT_RANDOM:
  168.                     printf("AT_RANDOM:\t%i\n", (int) auxv->a_un.a_val);
  169.                     break;
  170.                 case AT_HWCAP2:
  171.                     printf("AT_HWCAP2:\t%i\n", (int) auxv->a_un.a_val);
  172.                     break;
  173.                 case AT_EXECFN:
  174.                     printf("AT_EXECFN:\t%s\n", (char*) auxv->a_un.a_val);
  175.                     break;
  176.                 case AT_SYSINFO:
  177.                     printf("AT_SYSINFO:\t%i\n", (int) auxv->a_un.a_val);
  178.                     break;
  179.                 case AT_SYSINFO_EHDR:
  180.                     printf("AT_SYSINFO_EHDR:\t%i\n", (int) auxv->a_un.a_val);
  181.                     break;
  182.                 case AT_L1I_CACHESHAPE:
  183.                     printf("AT_L1I_CACHESHAPE:\t%i\n", (int) auxv->a_un.a_val);
  184.                     break;
  185.                 case AT_L1D_CACHESHAPE:
  186.                     printf("AT_L1D_CACHESHAPE:\t%i\n", (int) auxv->a_un.a_val);
  187.                     break;
  188.                 case AT_L2_CACHESHAPE:
  189.                     printf("AT_L2_CACHESHAPE:\t%i\n", (int) auxv->a_un.a_val);
  190.                     break;
  191.                 case AT_L3_CACHESHAPE:
  192.                     printf("AT_L3_CACHESHAPE:\t%i\n", (int) auxv->a_un.a_val);
  193.                     break;
  194.                 default:
  195.                     break;
  196.             }
  197.         }
  198.  
  199.     }
  200.     __libc_init_first(argc, argv, envp);
  201.     init(argc, argv, envp);
  202.  
  203.     ret = main(argc, argv, envp);
  204.     fini(ret);
  205.     __builtin_unreachable();
  206. }
  207.  
  208. // This prints an "Assertion failed" message and aborts.
  209. void __attribute__((noreturn)) __assert_fail (
  210.     const char* __assertion, const char* __file,
  211.     unsigned int __line, const char* __function)
  212. {
  213.     printf("%s:%i: %s: Assertion (%s) failed.\n", __file, __line, __function, __assertion);
  214.     exit(-1);
  215.     __builtin_unreachable();
  216. }
  217.  
  218. // Likewise, but prints the error text for ERRNUM.
  219. void __attribute__((noreturn)) __assert_perror_fail(
  220.     int __errnum, const char* __file,
  221.     unsigned int __line, const char* __function)
  222. {
  223.     printf("Errnum: %i -> %s:%i:%s\n", __errnum, __file, __line, __function);
  224.     exit(-1);
  225.     __builtin_unreachable();
  226. }
  227.  
  228.  
  229. // The following is not at all used here but needed for standard compliance.
  230. void __attribute__((noreturn)) __assert(
  231.     const char* __assertion,
  232.     const char* __file, int __line)
  233. {
  234.     printf("%s:%i: Assertion (%s) failed.\n", __file, __line, __assertion);
  235.     exit(-1);
  236.     __builtin_unreachable();
  237. }
  238.  
  239.  
  240. ///!!!!!!!!!!!!!!!!!!!!!!!!!!! SYSCALL STUFF !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  241. long int syscall(size_t size, ...)
  242. {
  243.     va_list argp;
  244.     long int*  a[7];
  245.     size_t i;
  246.    
  247.     va_start(argp, size);
  248.     for(i = 0;i <= size && size <= 7;i++)
  249.         a[i] = (long int*) va_arg(argp, long int);
  250.     va_end(argp);
  251.  
  252. #if defined(__x86_64__)
  253.     register uint64_t ret asm("rax");
  254.     asm(".intel_syntax noprefix\n"
  255.         "push %6\n"
  256.         "push %5\n"
  257.         "push %4\n"
  258.         "push %3\n"
  259.         "push %2\n"
  260.         "push %1\n"
  261.         "push %0\n"
  262.         "pop rax\n"
  263.         "pop rdi\n"
  264.         "pop rsi\n"
  265.         "pop rdx\n"
  266.         "pop r10\n"
  267.         "pop r8\n"
  268.         "pop r9\n"
  269.     "syscall\n"
  270.     ::"g"((uint64_t) a[0]),
  271.             "g"((uint64_t) a[1]),
  272.             "g"((uint64_t) a[2]),
  273.             "g"((uint64_t) a[3]),
  274.             "g"((uint64_t) a[4]),
  275.             "g"((uint64_t) a[5]),
  276.             "g"((uint64_t) a[6])
  277.     );
  278.  
  279. #elif defined(__i386__)
  280.     register uint32_t ret asm("eax");
  281.     asm(".intel_syntax noprefix\n"
  282.         "push %5\n"
  283.         "push %4\n"
  284.         "push %3\n"
  285.         "push %2\n"
  286.         "push %1\n"
  287.         "push %0\n"
  288.         "pop eax\n"
  289.         "pop ebx\n"
  290.         "pop ecx\n"
  291.         "pop edx\n"
  292.         "pop esi\n"
  293.         "pop edi\n"
  294.     "int 0x80\n"
  295.     ::"g"((uint32_t) a[0]),
  296.         "g"((uint32_t) a[1]),
  297.         "g"((uint32_t) a[2]),
  298.         "g"((uint32_t) a[3]),
  299.         "g"((uint32_t) a[4]),
  300.         "g"((uint32_t) a[5])
  301.     );
  302.  
  303. #elif defined(__arm__)
  304.  
  305. #else
  306. #   error "Architecture not supported."
  307. #endif
  308.     return (errno = ret) >= 0 ? ret : -1;
  309. }
  310.  
  311. ///!!!!!!!!!!!!!!!!!!!!!!!!!!! SYSCALL FUNCTIONS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  312.  
  313.  
  314. void __attribute__((noreturn)) exit(int e)
  315. {
  316.     syscall(1, SYS_EXIT, e);
  317.     __builtin_unreachable();
  318. }
  319.  
  320. int brk(void* addr)
  321. {
  322.  
  323. }
  324.  
  325. void* sbrk(intptr_t increment)
  326. {
  327.  
  328. }
  329.  
  330. int unlink(const char* pathname)
  331. {
  332.     return syscall(1, SYS_UNLINK, pathname);
  333. }
  334.  
  335. int unlinkat(int dirfd, const char* pathname, int flags)
  336. {
  337.     return syscall(3, SYS_UNLINKAT, dirfd, pathname, flags);
  338. }
  339.  
  340. int rmdir(const char* pathname)
  341. {
  342.     return syscall(1, SYS_RMDIR, pathname);
  343. }
  344.  
  345.  
  346. ///!!!!!!!!!!!!!!!!!!!!!!!!!!! MEMORY AND I/O !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  347. void* malloc(size_t size)
  348. {
  349.     void* p = sbrk(0);
  350.     void* request = sbrk(size);
  351.     if(request == (void*) -1)
  352.         return NULL;
  353.     assert(p == request); // Not thread safe.
  354.     return p;
  355. }
  356. void free(void* ptr);
  357.  
  358. void* calloc(size_t nmemb, size_t size);
  359. void* realloc(void* ptr, size_t size);
  360.  
  361. void* memset(void* s, int c, size_t n)
  362. {
  363.     unsigned char* p = (unsigned char*) s;
  364.     for(;n > 0;n--)
  365.         p[n - 1] = (unsigned char) c;
  366.     return s;
  367. }
  368.  
  369. void* memcpy(void* dest, const void* src, size_t n)
  370. {
  371.     unsigned char* a = (unsigned char*) dest;
  372.     const unsigned char* b = (const unsigned char*) src;
  373.     int i;
  374.     for(i = 0;i < n;i++) a[i] = b[i];
  375.     return dest;
  376. }
  377.  
  378.  
  379.  
  380. int strcmp(const char* s1, const char* s2)
  381. {
  382.     int i,c;
  383.     if((c = strlen(s1) - strlen(s2)) != 0)
  384.         return c;
  385.     for(i = 0;i < strlen(s1);i++)
  386.         if(s1[i] != s2[i])
  387.             return -1;
  388.     return 0;
  389. }
  390.  
  391. size_t strlen(const char* s)
  392. {
  393.     size_t size = 0;
  394.     for(;s[size] != 0;size++);
  395.     return size;
  396. }
  397.  
  398. char* envpv(char** envp, char* key)
  399. {
  400.     int i,c;
  401.     for(i = 0;envp[i] != NULL;i++)
  402.         for(c = 0;envp[i][c] != NULL;c++)
  403.             if(envp[i][c] == '=')
  404.             {
  405.                 char k[c + 1];
  406.                 char* v = (char*) envp[i] + c + 1;
  407.                 memset(k, 0, sizeof(k));
  408.                 memcpy(k, envp[i], c);
  409.                 if(strcmp(key, k) == 0)
  410.                     return v;
  411.                 break;
  412.             }
  413.     return NULL;
  414. }
  415.  
  416. int putch(char c)
  417. {
  418.     char s[1] = {c};
  419.     return syscall(3, SYS_WRITE, 0, s, 1);
  420. }
  421.  
  422. int puts(const char* s)
  423. {
  424.     if(s == NULL) return -1;
  425.     int ret = syscall(3, SYS_WRITE, 0, s, strlen(s));
  426.     syscall(3, SYS_WRITE, 0, "\n", 1);
  427.     return ret;
  428. }
  429.  
  430. char *getline(char* __s, int __size);
  431. char *gets(char* __s);
  432. char getch(void);
  433.  
  434.  
  435. int printf(const char* format, ...)
  436. {
  437.     va_list argp;
  438.     char* p;
  439.     int i, c, ip, ccount;
  440.     va_start(argp, format);
  441.     for(i = 0;format[i] != NULL;i++)
  442.     {
  443.         switch(format[i])
  444.         {
  445.             case '%':
  446.                 i++;
  447.                 switch(format[i])
  448.                 {
  449.                     case 's':
  450.                         p = (char*) va_arg(argp, char*);
  451.                         for(c = 0;p[c] != NULL;c++)
  452.                             putch(p[c]);
  453.                             ccount++;
  454.                         continue;
  455.                     case 'i':
  456.                         ip = (int) va_arg(argp, int);
  457.                         ccount += printf(itoa(ip));
  458.                         continue;
  459.                     case '%':
  460.                         putch('%');
  461.                         ccount++;
  462.                         continue;
  463.                 }
  464.                 continue;
  465.             default:
  466.                 putch(format[i]);
  467.                 ccount++;
  468.                 continue;
  469.         }
  470.     }
  471.     va_end(argp);
  472.     return ccount;
  473. }
  474. int fprintf(FILE* stream, const char* format, ...);
  475. int sprintf(char* str, const char* format, ...);
  476. int snprintf(char* str, size_t size, const char *format, ...);
  477.  
  478.  
  479.  
  480.  
  481. ///!!!!!!!!!!!!!!!!!!!!!!!!!!! CONVERTION FUNCTIONS !!!!!!!!!!!!!!!!!!!!!!!!!!!!
  482. void reverse(char* s)
  483. {
  484.     int i, j;
  485.     char c;
  486.     for(i = 0, j = strlen(s) - 1; i<j; i++, j--)
  487.     {
  488.         c = s[i];
  489.         s[i] = s[j];
  490.         s[j] = c;
  491.     }
  492. }
  493. char* itoa(int n)
  494. {
  495.     int i, sign, size;
  496.     for(i=0;i > 0;i/=10)size++;
  497.     char s[size]; // make realistic when fixing
  498.     if ((sign = n) < 0)
  499.         n = -n;
  500.     i = 0;
  501.     do
  502.     {   // generate digits in reverse order
  503.         s[i++] = n % 10 + '0';
  504.     } while ((n /= 10) > 0);
  505.     if (sign < 0)
  506.         s[i++] = '-';
  507.     s[i] = '\0';
  508.     reverse(s);
  509.     return s;
  510. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement