├── adir └── as ├── bdir ├── as └── ld ├── src ├── misc │ ├── __xtiny_errno.s │ ├── __xtiny_environ.s │ ├── strdup.c │ ├── strstr.c │ ├── abort.s │ ├── getenv.c │ └── atexit.s ├── libgcc │ ├── misc.obj │ │ ├── _clz.o │ │ ├── _clzdi2.o │ │ ├── _clzsi2.o │ │ ├── _cmpdi2.o │ │ ├── _ctors.o │ │ ├── _ctzdi2.o │ │ ├── _ctzsi2.o │ │ ├── _divdi3.o │ │ ├── _divtc3.o │ │ ├── _ffsdi2.o │ │ ├── _ffssi2.o │ │ ├── _moddi3.o │ │ ├── _muldi3.o │ │ ├── _negdi2.o │ │ ├── __gcc_bcmp.o │ │ ├── _ashldi3.o │ │ ├── _ashrdi3.o │ │ ├── _lshrdi3.o │ │ ├── _paritydi2.o │ │ ├── _paritysi2.o │ │ ├── _ucmpdi2.o │ │ ├── _udivdi3.o │ │ ├── _umoddi3.o │ │ ├── _clear_cache.o │ │ ├── _udiv_w_sdiv.o │ │ ├── _udivmoddi4.o │ │ └── _popcount_tab.o │ └── withgot.exclude_obj │ │ ├── _absvdi2.o │ │ ├── _absvsi2.o │ │ ├── _addvdi3.o │ │ ├── _addvsi3.o │ │ ├── _divdc3.o │ │ ├── _divsc3.o │ │ ├── _divxc3.o │ │ ├── _fixdfdi.o │ │ ├── _fixsfdi.o │ │ ├── _fixxfdi.o │ │ ├── _muldc3.o │ │ ├── _mulsc3.o │ │ ├── _mulvdi3.o │ │ ├── _mulvsi3.o │ │ ├── _mulxc3.o │ │ ├── _negvdi2.o │ │ ├── _negvsi2.o │ │ ├── _powidf2.o │ │ ├── _powisf2.o │ │ ├── _powixf2.o │ │ ├── _subvdi3.o │ │ ├── _subvsi3.o │ │ ├── _fixunsdfdi.o │ │ ├── _fixunsdfsi.o │ │ ├── _fixunssfdi.o │ │ ├── _fixunssfsi.o │ │ ├── _fixunsxfdi.o │ │ ├── _fixunsxfsi.o │ │ ├── _floatdidf.o │ │ ├── _floatdisf.o │ │ ├── _floatdixf.o │ │ ├── _popcountdi2.o │ │ └── _popcountsi2.o ├── malloc │ ├── calloc.c │ ├── __forward_malloc_free.c │ ├── realloc_grow.c │ ├── __forward_malloc.c │ └── __xtiny_lite_malloc.c ├── string │ ├── strlen.s │ ├── memset.s │ ├── memcpy.s │ ├── strrchr.s │ ├── strcpy.s │ ├── memcmp.s │ ├── strchr.s │ ├── memchr.s │ ├── strcat.s │ ├── memccpy.s │ ├── strcasecmp.s │ ├── strncmp.s │ ├── strncpy.s │ ├── strcmp.s │ └── string_decl.h ├── ctype │ ├── isdigit.s │ ├── isalpha.s │ ├── isspace.s │ └── isxdigit.s ├── start │ ├── __xtiny_exit.S │ ├── _start.S │ └── _start_noctors.s └── c.sh ├── as.xtiny ├── ld.xtiny ├── lib__xtiny.a ├── examples ├── start_exit.c ├── start_exit0.c ├── abort.c ├── hellot.c ├── long_long_divide.c ├── hellow1.c ├── gcs.c ├── bss.c ├── hellowr.c ├── hello.c ├── _start.c ├── cdtors.c ├── trymalloc.c ├── test_stat.c ├── addrnd.c ├── hellowr.nasm ├── trampoline_linux_i386.nasm ├── helloo.nasm ├── compressible.c └── multi_trampoline.c ├── lib__xtiny_exit.a ├── test └── ctype_test.c ├── lib__xtiny_start_if.a ├── lib__xtiny_start_in.a ├── lib__xtiny_start_nf.a ├── lib__xtiny_start_nn.a ├── .gitignore ├── stdarginc.c ├── xtiny_noctors.scr ├── xtiny.scr ├── README.txt ├── xtiny └── include └── xtiny.h /adir/as: -------------------------------------------------------------------------------- 1 | ../as.xtiny -------------------------------------------------------------------------------- /bdir/as: -------------------------------------------------------------------------------- 1 | ../as.xtiny -------------------------------------------------------------------------------- /bdir/ld: -------------------------------------------------------------------------------- 1 | ../xtiny -------------------------------------------------------------------------------- /src/misc/__xtiny_errno.s: -------------------------------------------------------------------------------- 1 | .comm __xtiny_errno,4,4 2 | -------------------------------------------------------------------------------- /src/misc/__xtiny_environ.s: -------------------------------------------------------------------------------- 1 | .comm __xtiny_environ,4,4 2 | -------------------------------------------------------------------------------- /as.xtiny: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/as.xtiny -------------------------------------------------------------------------------- /ld.xtiny: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/ld.xtiny -------------------------------------------------------------------------------- /lib__xtiny.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/lib__xtiny.a -------------------------------------------------------------------------------- /examples/start_exit.c: -------------------------------------------------------------------------------- 1 | #include 2 | void _start() { exit(42); } 3 | -------------------------------------------------------------------------------- /examples/start_exit0.c: -------------------------------------------------------------------------------- 1 | #include 2 | void _start() { exit(0); } 3 | -------------------------------------------------------------------------------- /lib__xtiny_exit.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/lib__xtiny_exit.a -------------------------------------------------------------------------------- /test/ctype_test.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/test/ctype_test.c -------------------------------------------------------------------------------- /examples/abort.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void _start() { 4 | abort(); 5 | } 6 | -------------------------------------------------------------------------------- /lib__xtiny_start_if.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/lib__xtiny_start_if.a -------------------------------------------------------------------------------- /lib__xtiny_start_in.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/lib__xtiny_start_in.a -------------------------------------------------------------------------------- /lib__xtiny_start_nf.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/lib__xtiny_start_nf.a -------------------------------------------------------------------------------- /lib__xtiny_start_nn.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/lib__xtiny_start_nn.a -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_clz.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_clz.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_clzdi2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_clzdi2.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_clzsi2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_clzsi2.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_cmpdi2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_cmpdi2.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_ctors.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_ctors.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_ctzdi2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_ctzdi2.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_ctzsi2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_ctzsi2.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_divdi3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_divdi3.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_divtc3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_divtc3.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_ffsdi2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_ffsdi2.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_ffssi2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_ffssi2.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_moddi3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_moddi3.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_muldi3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_muldi3.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_negdi2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_negdi2.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/__gcc_bcmp.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/__gcc_bcmp.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_ashldi3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_ashldi3.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_ashrdi3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_ashrdi3.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_lshrdi3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_lshrdi3.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_paritydi2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_paritydi2.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_paritysi2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_paritysi2.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_ucmpdi2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_ucmpdi2.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_udivdi3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_udivdi3.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_umoddi3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_umoddi3.o -------------------------------------------------------------------------------- /examples/hellot.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void _start() { 4 | puts("Hello, World!"); 5 | exit(0); 6 | } 7 | -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_clear_cache.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_clear_cache.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_udiv_w_sdiv.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_udiv_w_sdiv.o -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_udivmoddi4.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_udivmoddi4.o -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | a.out 3 | examples/addrnd 4 | src/obj 5 | src/*/*.o 6 | src/lib__*.a 7 | src/include 8 | src/xtiny 9 | -------------------------------------------------------------------------------- /src/libgcc/misc.obj/_popcount_tab.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/misc.obj/_popcount_tab.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_absvdi2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_absvdi2.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_absvsi2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_absvsi2.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_addvdi3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_addvdi3.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_addvsi3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_addvsi3.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_divdc3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_divdc3.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_divsc3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_divsc3.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_divxc3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_divxc3.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_fixdfdi.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_fixdfdi.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_fixsfdi.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_fixsfdi.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_fixxfdi.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_fixxfdi.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_muldc3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_muldc3.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_mulsc3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_mulsc3.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_mulvdi3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_mulvdi3.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_mulvsi3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_mulvsi3.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_mulxc3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_mulxc3.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_negvdi2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_negvdi2.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_negvsi2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_negvsi2.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_powidf2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_powidf2.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_powisf2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_powisf2.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_powixf2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_powixf2.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_subvdi3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_subvdi3.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_subvsi3.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_subvsi3.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_fixunsdfdi.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_fixunsdfdi.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_fixunsdfsi.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_fixunsdfsi.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_fixunssfdi.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_fixunssfdi.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_fixunssfsi.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_fixunssfsi.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_fixunsxfdi.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_fixunsxfdi.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_fixunsxfsi.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_fixunsxfsi.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_floatdidf.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_floatdidf.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_floatdisf.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_floatdisf.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_floatdixf.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_floatdixf.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_popcountdi2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_popcountdi2.o -------------------------------------------------------------------------------- /src/libgcc/withgot.exclude_obj/_popcountsi2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pts/pts-xtiny/HEAD/src/libgcc/withgot.exclude_obj/_popcountsi2.o -------------------------------------------------------------------------------- /stdarginc.c: -------------------------------------------------------------------------------- 1 | /* xtiny helper file to find the compiler-specific #include directory, 2 | * when compiled with -E. 3 | */ 4 | #include 5 | -------------------------------------------------------------------------------- /examples/long_long_divide.c: -------------------------------------------------------------------------------- 1 | int main(int argc, char **argv) { 2 | long long x = argc; 3 | (void)argv; 4 | return x * x * x % 1234567890; 5 | } 6 | -------------------------------------------------------------------------------- /examples/hellow1.c: -------------------------------------------------------------------------------- 1 | #include 2 | void _start() { 3 | static const char msg[15] = "Hello, World!\n"; 4 | (void)!write(1, msg, sizeof msg); 5 | exit(0); 6 | } 7 | -------------------------------------------------------------------------------- /examples/gcs.c: -------------------------------------------------------------------------------- 1 | __attribute__((constructor)) void myctorgcs(void) {} 2 | 3 | extern void magic(void); 4 | void callmagic(void) { magic(); } 5 | int uanswer = 42; 6 | /*int main(void) { return 0; }*/ 7 | 8 | -------------------------------------------------------------------------------- /src/malloc/calloc.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void *__xtiny_malloc0(size_t); 4 | 5 | void *calloc(size_t m, size_t n) { 6 | if (n && m > (size_t)-1/n) { 7 | errno = ENOMEM; 8 | return 0; 9 | } 10 | return __xtiny_malloc0(n * m); 11 | } 12 | -------------------------------------------------------------------------------- /src/misc/strdup.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void *__xtiny_malloc(size_t size); 4 | 5 | char *strdup(const char *s) { 6 | const size_t l = strlen(s) + 1; 7 | char *d = __xtiny_malloc(l); 8 | if (!d) return NULL; 9 | return memcpy(d, s, l); 10 | } 11 | -------------------------------------------------------------------------------- /src/misc/strstr.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char *strstr(const char *h, const char *n) { 4 | size_t nlen; 5 | const char c = *n++; 6 | if (!c) return (char*)h; 7 | nlen = strlen(n); 8 | while ((h = strchr(h, c)) && 0 != memcmp(++h, n, nlen)) {} 9 | return (char*)h; 10 | } 11 | -------------------------------------------------------------------------------- /src/string/strlen.s: -------------------------------------------------------------------------------- 1 | /* From gcc-4.6.3. */ 2 | .align 0 3 | .globl strlen 4 | .type strlen, @function 5 | strlen: 6 | pushl %edi 7 | movl 8(%esp), %edi 8 | xorl %eax, %eax 9 | orl $-1, %ecx 10 | repnz scasb 11 | popl %edi 12 | notl %ecx 13 | leal -1(%ecx), %eax 14 | ret 15 | .size strlen, .-strlen 16 | -------------------------------------------------------------------------------- /src/malloc/__forward_malloc_free.c: -------------------------------------------------------------------------------- 1 | /* __forward_malloc(...) never frees. */ 2 | void __forward_malloc_free(void *ptr) { (void)ptr; } 3 | /* This can result in link error: multiple definition of free, 4 | * if the program also defines it. 5 | */ 6 | void __xtiny_free(void *ptr) __attribute__((alias("__forward_malloc_free"))); 7 | -------------------------------------------------------------------------------- /src/string/memset.s: -------------------------------------------------------------------------------- 1 | /* From gcc-4.6.3. */ 2 | .align 0 3 | .globl memset 4 | .type memset, @function 5 | memset: 6 | pushl %edi 7 | movl 8(%esp), %edx 8 | movb 12(%esp), %al 9 | movl 16(%esp), %ecx 10 | movl %edx, %edi 11 | rep stosb 12 | movl %edx, %eax 13 | popl %edi 14 | ret 15 | .size memset, .-memset 16 | -------------------------------------------------------------------------------- /src/string/memcpy.s: -------------------------------------------------------------------------------- 1 | /* From gcc-4.6.3. */ 2 | .align 0 3 | .globl memcpy 4 | .type memcpy, @function 5 | memcpy: 6 | pushl %edi 7 | pushl %esi 8 | movl 12(%esp), %eax 9 | movl 16(%esp), %esi 10 | movl 20(%esp), %ecx 11 | movl %eax, %edi 12 | rep movsb 13 | popl %esi 14 | popl %edi 15 | ret 16 | .size memcpy, .-memcpy 17 | -------------------------------------------------------------------------------- /examples/bss.c: -------------------------------------------------------------------------------- 1 | #ifdef __XTINY__ 2 | #include 3 | #else 4 | #include 5 | #include 6 | #endif 7 | 8 | char buf[43]; 9 | 10 | #ifdef __XTINY__ 11 | void _start() { 12 | #else 13 | int main() { 14 | #endif 15 | static const char msg[15] = "Hello, World!\n"; 16 | (void)!write(1, msg, sizeof msg); 17 | (void)!read(0, buf, sizeof buf); 18 | exit(0); 19 | } 20 | -------------------------------------------------------------------------------- /src/misc/abort.s: -------------------------------------------------------------------------------- 1 | .text 2 | .globl abort 3 | .type abort, @function 4 | abort: 5 | /* pushl %ebx */ 6 | movl $20, %eax /* __NR_getpid */ 7 | int $0x80 8 | xchgl %eax, %ebx 9 | movl $37, %eax /* __NR_kill */ 10 | movl $6, %ecx /* SIGABRT */ 11 | int $0x80 12 | /* popl %ebx */ 13 | /* No need to ret, doesn't return (with the default handler): ret */ 14 | .size abort, .-abort 15 | -------------------------------------------------------------------------------- /src/string/strrchr.s: -------------------------------------------------------------------------------- 1 | /* From dietlibc-0.33. */ 2 | .align 0 3 | .globl strrchr 4 | .type strrchr,@function 5 | 6 | strrchr: 7 | movl 0x4(%esp), %edx 8 | movb 0x8(%esp), %cl 9 | xorl %eax, %eax 10 | .Lloop: 11 | cmpb %cl, (%edx) 12 | jnz .Ltest0 13 | movl %edx, %eax 14 | .Ltest0: 15 | cmpb $0,(%edx) 16 | jz .Lret 17 | incl %edx 18 | jmp .Lloop 19 | .Lret: 20 | ret 21 | .size strrchr, .-strrchr 22 | -------------------------------------------------------------------------------- /src/string/strcpy.s: -------------------------------------------------------------------------------- 1 | /* From dietlibc-0.33. */ 2 | .align 0 3 | .global strcpy 4 | .type strcpy,@function 5 | strcpy: 6 | pushl %esi 7 | pushl %edi 8 | 9 | movl 12(%esp), %edx 10 | movl 16(%esp), %esi 11 | movl %edx, %edi 12 | cld 13 | 14 | .Lloop: 15 | lodsb 16 | stosb 17 | orb %al, %al 18 | jnz .Lloop 19 | 20 | popl %edi 21 | popl %esi 22 | movl %edx,%eax 23 | ret 24 | .size strcpy, .-strcpy 25 | -------------------------------------------------------------------------------- /src/malloc/realloc_grow.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void *__xtiny_malloc(size_t size); 4 | void __xtiny_free(void *ptr); 5 | 6 | void *realloc_grow(void *ptr, size_t old_size, size_t new_size) { 7 | if (new_size > old_size) { 8 | void *new_ptr = __xtiny_malloc(new_size); 9 | if (new_ptr) memcpy(new_ptr, ptr, old_size); 10 | __xtiny_free(ptr); 11 | ptr = new_ptr; 12 | } 13 | return ptr; 14 | } 15 | -------------------------------------------------------------------------------- /src/string/memcmp.s: -------------------------------------------------------------------------------- 1 | /* From dietlibc-0.33. */ 2 | .align 0 3 | .global memcmp 4 | .type memcmp,function 5 | memcmp: 6 | pushl %esi 7 | pushl %edi 8 | xorl %eax,%eax 9 | movl %esp,%ecx 10 | movl 12(%ecx),%esi 11 | movl 16(%ecx),%edi 12 | movl 20(%ecx),%ecx 13 | jecxz .Lout 14 | cld 15 | rep cmpsb 16 | jz .Lout 17 | sbbl %eax,%eax 18 | orl $1,%eax 19 | .Lout: 20 | popl %edi 21 | popl %esi 22 | ret 23 | .size memcmp,.-memcmp 24 | -------------------------------------------------------------------------------- /src/string/strchr.s: -------------------------------------------------------------------------------- 1 | /* From dietlibc-0.33. */ 2 | .align 0 3 | .type strchr,@function 4 | .global strchr 5 | .weak index 6 | .type index,@function 7 | 8 | index: 9 | strchr: 10 | movl 4(%esp),%ecx 11 | movb 8(%esp),%dl 12 | .Lloop: 13 | movb (%ecx),%al 14 | cmpb %al,%dl 15 | jz .Lfound 16 | incl %ecx 17 | testb %al,%al 18 | jnz .Lloop 19 | xorl %ecx,%ecx 20 | .Lfound: 21 | movl %ecx,%eax 22 | ret 23 | .size strchr, .-strchr 24 | -------------------------------------------------------------------------------- /examples/hellowr.c: -------------------------------------------------------------------------------- 1 | #ifdef __XTINY__ 2 | #include 3 | #else 4 | #include 5 | #include 6 | #endif 7 | 8 | #ifdef __XTINY__ 9 | void _start() { 10 | #else 11 | int main() { 12 | #endif 13 | static const char msg[15] = "Hello, World!\n"; 14 | int i = sizeof msg, got; 15 | while (i > 0) { 16 | got = write(1, msg, sizeof msg); 17 | if (got <= 0) break; 18 | i -= got; 19 | } 20 | exit(0); 21 | } 22 | -------------------------------------------------------------------------------- /src/string/memchr.s: -------------------------------------------------------------------------------- 1 | .align 0 2 | .globl memchr 3 | .type memchr, @function 4 | memchr: 5 | pushl %edi 6 | movl 16(%esp), %ecx 7 | xorl %eax, %eax 8 | testl %ecx, %ecx 9 | je .L2 10 | movl 8(%esp), %edx 11 | movl 12(%esp), %eax 12 | movl %edx, %edi 13 | /* cld */ 14 | repne scasb 15 | je .L1 16 | xor %edi, %edi 17 | incl %edi 18 | .L1: decl %edi 19 | movl %edi, %eax 20 | .L2: 21 | popl %edi 22 | ret 23 | .size memchr, .-memchr 24 | -------------------------------------------------------------------------------- /src/misc/getenv.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char *getenv(const char *name) { 4 | const char *p; 5 | for (p = name; *p != '\0' && *p != '='; ++p) {} 6 | if (environ && *name != '\0' && *p != '=') { 7 | char **e; 8 | const size_t len = p - name; 9 | for (e = environ; 10 | *e && (0 != memcmp(*e, name, len) || e[0][len] != '='); 11 | ++e) {} 12 | if (*e) return *e + len + 1; 13 | } 14 | return NULL; 15 | } 16 | -------------------------------------------------------------------------------- /src/string/strcat.s: -------------------------------------------------------------------------------- 1 | /* From dietlibc-0.33. */ 2 | .align 0 3 | .global strcat 4 | .type strcat,@function 5 | strcat: 6 | pushl %edi 7 | pushl %esi 8 | 9 | movl 12(%esp), %edi 10 | movl 16(%esp), %esi 11 | 12 | pushl %edi 13 | 14 | cld 15 | xorl %eax, %eax 16 | xorl %ecx, %ecx 17 | decl %ecx 18 | repne scasb 19 | decl %edi 20 | 21 | .Lloop: 22 | lodsb 23 | stosb 24 | testb %al, %al 25 | jnz .Lloop 26 | 27 | popl %eax 28 | popl %esi 29 | popl %edi 30 | ret 31 | .size strcat, .-strcat 32 | -------------------------------------------------------------------------------- /src/ctype/isdigit.s: -------------------------------------------------------------------------------- 1 | /* by pts@fazekas.hu at Fri Nov 25 02:32:23 CET 2022 */ 2 | 3 | .section .note.GNU-stack,"",@progbits 4 | .text 5 | 6 | /* This is hand-written, and it is shorter than code generated by GCC 6.3.0. */ 7 | .globl isdigit 8 | .type isdigit, @function 9 | isdigit: /* __attribute__((regparm(1))) int isdigit(int c); */ 10 | subb $48, %al 11 | cmpb $10, %al 12 | sbbl %eax, %eax 13 | negl %eax 14 | ret 15 | .size isdigit, .-isdigit 16 | /* Test: int c; for (c = -1; c <= 255; ++c) { if (isdigit(c) != (c >= '0' && c <= '9')) goto fail; } */ 17 | -------------------------------------------------------------------------------- /src/string/memccpy.s: -------------------------------------------------------------------------------- 1 | /* From dietlibc-0.33 */ 2 | .align 0 3 | .global memccpy 4 | .type memccpy,@function 5 | memccpy: 6 | pushl %esi 7 | pushl %edi 8 | 9 | movl %esp, %ecx 10 | movl 0x0c(%ecx), %edi 11 | movl 0x10(%ecx), %esi 12 | movl 0x14(%ecx), %edx 13 | movl 0x18(%ecx), %ecx 14 | cld 15 | jecxz .Lerr 16 | .Lloop: 17 | lodsb 18 | stosb 19 | cmp %al, %dl 20 | jz .Lout 21 | decl %ecx 22 | jnz .Lloop 23 | .Lerr: 24 | xorl %edi, %edi 25 | .Lout: 26 | movl %edi, %eax 27 | popl %edi 28 | popl %esi 29 | ret 30 | .Lende: 31 | .size memccpy,.Lende-memccpy 32 | -------------------------------------------------------------------------------- /src/ctype/isalpha.s: -------------------------------------------------------------------------------- 1 | /* by pts@fazekas.hu at Fri Nov 25 02:32:23 CET 2022 */ 2 | 3 | .section .note.GNU-stack,"",@progbits 4 | .text 5 | 6 | /* This is hand-written, and it is shorter than code generated by GCC 6.3.0. */ 7 | .globl isalpha 8 | .type isalpha, @function 9 | isalpha: /* __attribute__((regparm(1))) int isalpha(int c); */ 10 | orb $32, %al 11 | subb $97, %al 12 | cmpb $26, %al 13 | sbbl %eax, %eax 14 | negl %eax 15 | ret 16 | .size isalpha, .-isalpha 17 | /* Test: int c; for (c = -1; c <= 255; ++c) { if (isalpha(c) != ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) goto fail; } */ 18 | -------------------------------------------------------------------------------- /src/misc/atexit.s: -------------------------------------------------------------------------------- 1 | .text 2 | .globl atexit 3 | .type atexit, @function 4 | atexit: 5 | cmpl $ __xtiny_atexit_ret, __xtiny_atexit_hook 6 | jne .L4 7 | movl %eax, __xtiny_atexit_hook 8 | xorl %eax, %eax 9 | ret 10 | .L4: 11 | orl $-1, %eax 12 | .type __xtiny_atexit_ret, @function 13 | __xtiny_atexit_ret: 14 | ret 15 | .size __xtiny_atexit_ret, .- __xtiny_atexit_ret 16 | .size atexit, .-atexit 17 | 18 | /*.globl __xtiny_atexit_hook*/ 19 | .section .fini_array,"aw" 20 | .align 4 21 | .type __xtiny_atexit_hook, @object 22 | .size __xtiny_atexit_hook, 4 23 | __xtiny_atexit_hook: 24 | .long __xtiny_atexit_ret 25 | -------------------------------------------------------------------------------- /src/ctype/isspace.s: -------------------------------------------------------------------------------- 1 | /* by pts@fazekas.hu at Fri Nov 25 02:32:23 CET 2022 */ 2 | 3 | .section .note.GNU-stack,"",@progbits 4 | .text 5 | 6 | /* This is hand-written, and it is shorter than code generated by GCC 6.3.0. */ 7 | .globl isspace 8 | .type isspace, @function 9 | isspace: /* __attribute__((regparm(1))) int isspace(int c); */ 10 | subb $9, %al 11 | cmpb $13-9+1, %al 12 | jc 1f 13 | subb $32-9, %al 14 | cmpb $1, %al 15 | 1: sbbl %eax, %eax 16 | negl %eax 17 | ret 18 | .size isspace, .-isspace 19 | /* Test: int c; for (c = -1; c <= 255; ++c) { if (isspace(c) != ((c >= '\t' && c <= '\r') || c == ' ')) goto fail; } */ 20 | -------------------------------------------------------------------------------- /src/string/strcasecmp.s: -------------------------------------------------------------------------------- 1 | /* From dietlibc-0.33. */ 2 | .align 0 3 | .global strcasecmp 4 | .type strcasecmp,@function 5 | 6 | strcasecmp: 7 | pushl %esi 8 | movl 0x8(%esp), %esi 9 | movl 0xc(%esp), %edx 10 | xorl %eax, %eax 11 | xorl %ecx, %ecx 12 | cld 13 | .Lloop: 14 | lodsb 15 | movb (%edx), %cl 16 | incl %edx 17 | or %al, %al 18 | jz .Lfinifirst 19 | cmp $'A', %al 20 | jnge .Lcmp 21 | cmp $'z', %al 22 | jg .Lcmp 23 | or $0x20, %al 24 | or $0x20, %cl 25 | .Lcmp: 26 | subl %ecx, %eax 27 | jz .Lloop 28 | .Lret: 29 | popl %esi 30 | ret 31 | .Lfinifirst: 32 | subl %ecx, %eax 33 | jmp .Lret 34 | 35 | .size strcasecmp,.-strcasecmp 36 | -------------------------------------------------------------------------------- /src/string/strncmp.s: -------------------------------------------------------------------------------- 1 | /* From dietlibc-0.33. */ 2 | .align 0 3 | .global strncmp 4 | .type strncmp,function 5 | strncmp: 6 | pushl %esi 7 | pushl %edi 8 | movl %esp,%ecx 9 | movl 12(%ecx),%esi 10 | movl 16(%ecx),%edi 11 | movl 20(%ecx),%ecx 12 | jecxz .Lequal 13 | .Lloop: 14 | movzbl (%esi),%eax 15 | movzbl (%edi),%edx 16 | incl %esi 17 | incl %edi 18 | /* !equal ? */ 19 | subl %edx,%eax 20 | jnz .Lout 21 | /* end of c-string ? */ 22 | test %edx,%edx 23 | jz .Lequal 24 | /* do loop */ 25 | decl %ecx 26 | jnz .Lloop 27 | 28 | .Lequal: 29 | xorl %eax,%eax 30 | .Lout: 31 | popl %edi 32 | popl %esi 33 | ret 34 | .size strncmp,.-strncmp 35 | -------------------------------------------------------------------------------- /examples/hello.c: -------------------------------------------------------------------------------- 1 | /* $ xtiny gcc -s -O2 -W -Wall -Wextra -o hello.xtiny hello.c 2 | * $ xstatic gcc -s -O2 -W -Wall -Wextra -o hello.xstatic hello.c 3 | * $ gcc -m32 -s -O2 -W -Wall -Wextra -o hello.dynamic hello.c 4 | * $ ls -ld hello.{xstatic,xtiny,dynamic} 5 | * -rwxr-xr-x 1 pts eng 5540 Feb 9 17:50 hello.dynamic 6 | * -rwxr-xr-x 1 pts pts 7340 Feb 9 17:49 hello.xstatic 7 | * -rwxr-xr-x 1 pts pts 234 Feb 9 17:49 hello.xtiny 8 | */ 9 | 10 | #ifdef __XTINY__ 11 | #include 12 | #else 13 | #include 14 | #endif 15 | 16 | int main(int argc, char **argv) { 17 | (void)argc; (void)argv; 18 | puts("Hello, World!"); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /src/ctype/isxdigit.s: -------------------------------------------------------------------------------- 1 | /* by pts@fazekas.hu at Fri Nov 25 02:32:23 CET 2022 */ 2 | 3 | .section .note.GNU-stack,"",@progbits 4 | .text 5 | 6 | /* This is hand-written, and it is shorter than code generated by GCC 6.3.0. */ 7 | .globl isxdigit 8 | .type isxdigit, @function 9 | isxdigit: /* __attribute__((regparm(1))) int isxdigit(int c); */ 10 | subb $48, %al 11 | cmpb $10, %al 12 | jc 1f 13 | orb $32, %al 14 | subb $49, %al 15 | cmpb $6, %al 16 | 1: sbbl %eax, %eax 17 | negl %eax 18 | ret 19 | .size isxdigit, .-isxdigit 20 | /* Test: int c; for (c = -1; c <= 255; ++c) { if (isxdigit(c) != ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9'))) goto fail; } */ 21 | -------------------------------------------------------------------------------- /examples/_start.c: -------------------------------------------------------------------------------- 1 | #define __NR_sys_exit 1 2 | 3 | #define _syscall1_noreturn(name,type1,arg1) \ 4 | static __inline__ void __attribute__((noreturn)) name(type1 __##arg1) { \ 5 | long __res; \ 6 | __asm__ volatile ("int $0x80" \ 7 | : "=a" (__res) \ 8 | : "0" (__NR_##name),"b" ((long)(__##arg1))); \ 9 | __builtin_unreachable(); \ 10 | } 11 | 12 | _syscall1_noreturn(sys_exit,int,exitcode) 13 | 14 | extern int main(int argc, char **argv, char **envp); 15 | extern char **environ; 16 | 17 | /* Entry point of the program. Default: ld -e _start 18 | * On Linux i386: http://asm.sourceforge.net/articles/startup.html 19 | */ 20 | void _start(char *argv0) { 21 | char **a = &argv0; 22 | while (*a) a++; 23 | environ = a + 1; 24 | sys_exit(main(a - &argv0, &argv0, a + 1)); 25 | } 26 | -------------------------------------------------------------------------------- /src/string/strncpy.s: -------------------------------------------------------------------------------- 1 | /* From dietlibc-0.33. */ 2 | .align 0 3 | /* 4 | Copyright (C) 2002 Thomas M. Ogrisegg 5 | 6 | This is free software. You can redistribute and 7 | modify it under the terms of the GNU General Public 8 | Public License. 9 | 10 | strncpy.S 11 | i386 assembler implementation of strncpy(3) 12 | */ 13 | 14 | .globl strncpy 15 | .type strncpy,@function 16 | 17 | strncpy: 18 | pushl %esi 19 | pushl %edi 20 | movl %esp, %ecx 21 | movl 0x0c(%ecx), %edi 22 | movl 0x10(%ecx), %esi 23 | movl 0x14(%ecx), %ecx 24 | 25 | movl %edi, %edx 26 | cld 27 | .Lloop: 28 | dec %ecx 29 | js .Lout 30 | lodsb 31 | stosb 32 | or %al, %al 33 | jnz .Lloop 34 | repnz stosb 35 | .Lout: 36 | movl %edx, %eax 37 | popl %edi 38 | popl %esi 39 | ret 40 | .size strncpy, .-strncpy 41 | -------------------------------------------------------------------------------- /examples/cdtors.c: -------------------------------------------------------------------------------- 1 | #ifdef __XTINY__ 2 | #include 3 | #else 4 | #include 5 | #include 6 | #endif 7 | 8 | __attribute__((constructor)) void myctor1(void) { 9 | (void)!write(1, "MYCTOR1\n", 8); 10 | } 11 | 12 | __attribute__((constructor)) static void myctor2(void) { 13 | (void)!write(1, "MYCTOR2\n", 8); 14 | } 15 | 16 | __attribute__((destructor)) static void mydtor1(void) { 17 | (void)!write(1, "MYDTOR1\n", 8); 18 | } 19 | 20 | __attribute__((destructor)) static void mydtor2(void) { 21 | (void)!write(1, "MYDTOR2\n", 8); 22 | } 23 | 24 | static void myatexit(void) { 25 | (void)!write(1, "MYATEXIT\n", 9); 26 | } 27 | 28 | int main(int argc, char **argv) { 29 | (void)argc; (void)argv; 30 | (void)!write(1, "MAIN\n", 5); 31 | atexit(myatexit); 32 | return 0; /*(int)__init_array_start;*/ 33 | } 34 | -------------------------------------------------------------------------------- /src/string/strcmp.s: -------------------------------------------------------------------------------- 1 | /* From dietlibc-0.33. */ 2 | .align 0 3 | .global strcmp 4 | .type strcmp,@function 5 | .weak strcoll 6 | .type strcoll,@function 7 | 8 | strcoll: 9 | strcmp: 10 | movl 4(%esp), %ecx 11 | movl 8(%esp), %edx 12 | xorl %eax, %eax 13 | .Lloop: /* Schleifenanfang liegt genau auf Modulanfang + 0x10, damit alignbar */ 14 | movb (%ecx), %al 15 | cmpb (%edx), %al 16 | jnz .Ldiff 17 | incl %edx 18 | incl %ecx 19 | testb %al, %al 20 | jnz .Lloop 21 | ret 22 | .Ldiff: 23 | movzbl (%edx), %ecx 24 | subl %ecx, %eax /* (unsigned char)*p - (unsigned char)*q, so wie die Original libc */ 25 | ret /* und ohne Überlaufprobleme: */ 26 | /* (int) ((signed char)c - (signed char)d) != (int)(signed char) ((unsigned char)c - (unsigned char)d) */ 27 | /* c = x', d = 'e': left expression: -129, right expression: 127 */ 28 | .size strcmp, .-strcmp 29 | -------------------------------------------------------------------------------- /src/start/__xtiny_exit.S: -------------------------------------------------------------------------------- 1 | /* by pts@fazekas.hu at Sun Jan 29 20:56:18 CET 2017 */ 2 | .section .text.__xtiny_startexit 3 | .globl __xtiny_exit_with_fini 4 | .type __xtiny_exit_with_fini, @function 5 | /* Fall throuh here from _start.S after return from main(). */ 6 | __xtiny_exit_with_fini: /* Exit code passed in eax (regparm(1)). */ 7 | 8 | #ifdef DO_FINI_ARRAY 9 | /* This works only if .fini_array is not empty. */ 10 | push %eax /* __exitcode */ 11 | mov $__fini_array_end, %eax 12 | .Lfiniarycall: 13 | sub $4, %eax /* 3 bytes only. */ 14 | push %eax 15 | call *(%eax) 16 | pop %eax 17 | cmp $__fini_array_start, %eax 18 | jne .Lfiniarycall 19 | pop %eax /* __exitcode */ 20 | #endif 21 | 22 | .globl __xtiny_exit 23 | .type __xtiny_exit, @function 24 | __xtiny_exit: /* Exit code passed in eax (regparm(1)). */ 25 | .byte 0x93 26 | /* ^^^ 000000?? 93 xchg eax,ebx */ 27 | .byte 0x31, 0xC0 28 | /* ^^^ 000000?? 31C0 xor eax,eax */ 29 | .byte 0x40 30 | /* ^^^ 000000?? 40 inc eax */ 31 | .byte 0xCD, 0x80 32 | /* ^^^ 000000?? CD80 int 0x80 */ 33 | .size __xtiny_exit_with_fini, .-__xtiny_exit_with_fini 34 | .size __xtiny_exit, .-__xtiny_exit 35 | -------------------------------------------------------------------------------- /examples/trymalloc.c: -------------------------------------------------------------------------------- 1 | /* by pts@fazekas.hu at Mon Jan 30 15:18:46 CET 2017 */ 2 | #ifdef __XTINY__ 3 | #define NO_FREE 1 4 | #endif 5 | typedef unsigned long size_t; 6 | extern void *malloc(size_t size); 7 | extern void free(void *ptr); 8 | extern void *calloc(size_t nmemb, size_t size); 9 | extern void *realloc(void *ptr, size_t size); 10 | extern void abort(); 11 | 12 | int main(int argc, char **argv) { 13 | enum { N = 60000 }; /* TODO(pts): Why is 70000 too much for valgrind? */ 14 | char *p[N]; 15 | unsigned i; 16 | (void)argc; (void)argv; 17 | for (i = 0; i < N; ++i) { 18 | p[i] = malloc(33); 19 | p[i][0] = 'X'; 20 | p[i][32] = 'Y'; 21 | } 22 | #ifndef NO_FREE 23 | for (i = 0; i < N; ++i) { 24 | p[i] = realloc(p[i], 77); 25 | if (p[i][32] != 'Y') abort(); 26 | p[i][0] = 'A'; 27 | p[i][76] = 'B'; 28 | } 29 | #endif 30 | for (i = 0; i < N; ++i) { 31 | #ifndef NO_FREE 32 | free(p[i]); 33 | #endif 34 | p[i] = calloc(3, 11); 35 | if (p[i][0] != 0) abort(); 36 | if (p[i][32] != 0) abort(); 37 | p[i][32] = 'Z'; 38 | } 39 | #ifndef NO_FREE 40 | for (i = 0; i < N; ++i) { 41 | free(p[i]); 42 | } 43 | #endif 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /src/malloc/__forward_malloc.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* Another .o file must define these (with any size): 4 | * char __forward_malloc_heap[1200000000] __attribute__((aligned(8))); 5 | * char *__forward_malloc_heap_end = __forward_malloc_heap + sizeof __forward_malloc_heap; 6 | * 7 | * Please note that Linux allocates only as much physical memory as used. 8 | */ 9 | extern char __forward_malloc_heap[]; 10 | extern char *__forward_malloc_heap_end; 11 | char * __forward_malloc_heap_pos = __forward_malloc_heap; 12 | 13 | void *__forward_malloc(size_t size) { 14 | char *result; 15 | if ((ssize_t)size <= 0) goto err; /* Disallow 0, check for overflow. */ 16 | size += -size & 7; /* Align to 8-byte boundary. */ 17 | /* Report out-of-memory error. */ 18 | if (size > (size_t)(__forward_malloc_heap_end - 19 | __forward_malloc_heap_pos)) { err: 20 | errno = ENOMEM; 21 | return 0; 22 | } 23 | result = __forward_malloc_heap_pos; 24 | __forward_malloc_heap_pos += size; 25 | return result; 26 | } 27 | 28 | void *__xtiny_malloc(size_t size) __attribute__((alias("__forward_malloc"))); 29 | /* Blocks returned by __forward_malloc are always 0-initialized. */ 30 | void *__xtiny_malloc0(size_t size) __attribute__((alias("__forward_malloc"))); 31 | -------------------------------------------------------------------------------- /examples/test_stat.c: -------------------------------------------------------------------------------- 1 | /* by pts@fazekas.hu at Tue Feb 14 17:38:01 CET 2017 2 | * 3 | * xtiny gcc -W -Wall -Wextra -s -Os -o test_stat test_stat.c 4 | * xtiny gcc -D_FILE_OFFSET_BITS=64 -W -Wall -Wextra -s -Os -o test_stat test_stat.c 5 | * xstatic gcc -W -Wall -Wextra -s -Os -o test_stat.xstatic test_stat.c 6 | * xstatic gcc -D_FILE_OFFSET_BITS=64 -W -Wall -Wextra -s -Os -o test_stat.xstatic test_stat.c 7 | */ 8 | 9 | #ifdef __XTINY__ 10 | #include 11 | #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 12 | # define stat stat64 13 | # define lstat lstat64 14 | #endif 15 | #else 16 | #include 17 | #include 18 | #include 19 | #include 20 | #endif 21 | 22 | void printhex(const char *prefix, long long v) { 23 | static const char hextable[] = "0123456789abcdef"; 24 | char buf[80], *p, *q; 25 | const size_t prefix_size = strlen(prefix); 26 | if (prefix_size > 60) abort(); 27 | p = buf; 28 | memcpy(p, prefix, prefix_size); 29 | p += prefix_size; 30 | q = p + 16; 31 | while (q != p) { 32 | *--q = hextable[v & 15]; 33 | v >>= 4; 34 | } 35 | p += 16; 36 | *p++ = '\n'; 37 | *p = '\0'; 38 | (void)!write(1, buf, p - buf); 39 | } 40 | 41 | 42 | int main(int argc, char **argv) { 43 | (void)argc; 44 | for (++argv; *argv; ++argv) { 45 | struct stat st; 46 | (void)!write(1, *argv, strlen(*argv)); 47 | (void)!write(1, "\n", 1); 48 | #if 0 49 | st.__pad_end = 0xaabbccdd55667788ULL; 50 | #endif 51 | if (lstat(*argv, &st) != 0) { 52 | (void)write(1, " error\n", 8); 53 | } else { 54 | printhex(" st_dev: ", st.st_dev); 55 | printhex(" st_ino: ", st.st_ino); 56 | printhex(" st_mode: ", st.st_mode); 57 | printhex(" st_nlink: ", st.st_nlink); 58 | printhex(" st_uid: ", st.st_uid); 59 | printhex(" st_gid: ", st.st_gid); 60 | printhex(" st_rdev: ", st.st_rdev); 61 | printhex(" st_size: ", st.st_size); 62 | printhex(" st_blksize: ", st.st_blksize); 63 | printhex(" st_blocks: ", st.st_blocks); 64 | printhex(" st_atime: ", st.st_atime); 65 | printhex(" st_mtime: ", st.st_mtime); 66 | printhex(" st_ctime: ", st.st_ctime); 67 | } 68 | #if 0 69 | /* Verify canary. */ 70 | if (st.__pad_end != 0xaabbccdd55667788ULL) abort(); 71 | #endif 72 | } 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /src/start/_start.S: -------------------------------------------------------------------------------- 1 | /* by pts@fazekas.hu at Mon Oct 20 00:31:44 CEST 2014 */ 2 | /*.arch i386*/ 3 | .section .text.__xtiny_startexit 4 | .globl _start 5 | .type _start, @function 6 | _start: 7 | /* This is hand-optimized assembly code of 43 bytes for _start, 8 | * `gcc-4.6 -Os' generates 53 bytes. 9 | * 10 | * The addresses in the assembly dump below are relative to _start. 11 | * 12 | * Mostly equivalent to this: 13 | * 14 | * extern int main(int argc, char **argv, char **envp); 15 | * void _start(char *argv0) { 16 | * char **a=&argv0; 17 | * while (*a!=(char*)0) a++; 18 | * environ=(char const*const*)a+1; 19 | * exit(main(a-&argv0, &argv0, a+1)); 20 | * } 21 | */ 22 | .byte 0x8D, 0x5C, 0x24, 0x04 23 | /* ^^^ 00000000 8D5C2404 lea ebx,[esp+0x4] */ 24 | .byte 0x89, 0xDA 25 | /* ^^^ 00000004 89DA mov edx,ebx */ 26 | .byte 0x31, 0xC0 27 | /* ^^^ 00000006 31C0 xor eax,eax */ 28 | .byte 0x83, 0xC3, 0x04 29 | /* ^^^ 00000008 83C304 add ebx,byte +0x4 */ 30 | .byte 0x3B, 0x03 31 | /* ^^^ 0000000B 3B03 cmp eax,[ebx] */ 32 | .byte 0x75, 0xF9 33 | /* ^^^ 0000000D 75F9 jnz 0x8 */ 34 | .byte 0x8D, 0x4B, 0x04 35 | /* ^^^ 0000000F 8D4B04 lea ecx,[ebx+0x4] */ 36 | .byte 0x29, 0xD3 37 | /* ^^^ 00000012 29D3 sub ebx,edx */ 38 | .byte 0xC1, 0xEB, 0x02 39 | /* ^^^ 00000014 C1EB02 shr ebx,0x2 */ 40 | .byte 0x89, 0x0D 41 | .long __xtiny_environ 42 | /* ^^^ 00000017 890D???????? mov [__xtiny_environ],ecx */ 43 | .byte 0x51 44 | /* ^^^ 0000001D 51 push ecx */ 45 | .byte 0x52 46 | /* ^^^ 0000001E 52 push edx */ 47 | .byte 0x53 48 | /* ^^^ 0000001F 53 push ebx */ 49 | 50 | #ifdef DO_INIT_ARRAY 51 | /* by pts@fazekas.hu at Sun Jan 29 10:16:14 CET 2017 52 | * http://ptspts.blogspot.com/2014/01/how-to-run-custom-code-before-and-after.html 53 | */ 54 | /* This works only if .init_array is not empty. */ 55 | mov $__init_array_start, %eax 56 | .Linitarycall: 57 | push %eax 58 | call *(%eax) 59 | pop %eax 60 | add $4, %eax /* 3 bytes only. */ 61 | cmp $__init_array_end, %eax 62 | jne .Linitarycall 63 | #endif 64 | 65 | call main 66 | /* ^^^ 000000?? E8???????? call main */ 67 | /* Now eax has the exit code. */ 68 | /* Execution continues in __xtiny_exit.s. */ 69 | .size _start, .-_start 70 | /* Make __xtiny_exit undefined here, pull __xtiny_exit.s. */ 71 | .reloc 0, R_386_NONE, __xtiny_exit 72 | -------------------------------------------------------------------------------- /examples/addrnd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * addrnd.c: additive random stream generator 3 | * by pts@fazekas.hu at Wed Sep 12 21:31:41 CEST 2012 4 | * 5 | * This is a very fast random number generator, writing random bytes to 6 | * stdout. Takes the random seed from 220 bytes in the beginning of the 7 | * file specified in argv[1], or "/dev/urandom" as the default. 8 | * 9 | * Compilation with xtiny: xtiny gcc -W -Wall -Werror -o addrnd addrnd.c 10 | * 11 | * Compilation without xtiny: gcc -W -Wall -Werror -O2 -s -o addrnd addrnd.c 12 | * 13 | * Uses unpublished additive random generator algorithm by G.J. Mitchell and 14 | * D.P. Moore (1958), published as Algorithm A in subsection 3.2.2 of TAOCP. 15 | * See more here: https://en.wikipedia.org/wiki/Lagged_Fibonacci_generator , 16 | * it's used with parameters {j = 24, k = 55}. 17 | */ 18 | 19 | #ifdef __XTINY__ 20 | #include 21 | #else 22 | #include 23 | #include 24 | #include 25 | #include 26 | #define sys_exit _exit 27 | #endif 28 | 29 | /* The real abort() call adds more dependencies, e.g. on kill(). */ 30 | static __inline__ void __attribute__((__noreturn__)) my_abort(void) { 31 | _exit(104); /* This call is smaller than the inlined sys_exit(104) call. */ 32 | } 33 | 34 | int main(int argc, char **argv) { 35 | int fd; 36 | int32_t y[55]; 37 | int32_t w[8192]; /* 64K. */ 38 | int32_t *p; 39 | register int j, k; 40 | int i, m; 41 | (void)argc; 42 | fd = open(argv[1] != NULL ? argv[1] : "/dev/urandom", O_RDONLY, 0); 43 | if (fd < 0) my_abort(); 44 | /* By commenting out the next line, we can make the file 5 bytes smaller. */ 45 | y[0] = 0; /* Pacify gcc-4.4, it thinks y is used uninitialized. */ 46 | for (j = 0; j < 55 * 4; j += k) { /* Read 55 * 4 bytes of random seed. */ 47 | k = read(fd, j + (char*)y, 55 * 4 - j); 48 | if (k <= 0) my_abort(); 49 | } 50 | close(fd); 51 | for (j = 0; j < 55 && (y[j] & 1) == 0; ++j) {} 52 | if (j == 55) y[0] |= 1; /* Make sure not all numbers are even. */ 53 | 54 | j = 24; 55 | k = 55; 56 | for (;;) { 57 | for (p = w; p != w + sizeof w / sizeof w[0]; ++p) { /* Generate w. */ 58 | *p = y[k - 1] += y[j - 1]; 59 | if (--j == 0) j = 55; 60 | if (--k == 0) k = 55; 61 | } 62 | for (i = 0; i + 0U < sizeof w; i += m) { /* Write w to stdout. */ 63 | m = write(1, i + (char*)w, sizeof w - i); 64 | if (m <= 0) my_abort(); 65 | } 66 | } 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /examples/hellowr.nasm: -------------------------------------------------------------------------------- 1 | ; by pts@fazekas.hu at Mon Oct 20 15:38:20 CEST 2014 2 | ; 3 | ; Compile with: 4 | ; 5 | ; $ nasm -f bin -o hellowr hellowr.nasm && chmod +x hellowr 6 | ; 7 | ; or 8 | ; 9 | ; $ yasm -f bin -o hellowr hellowr.nasm && chmod +x hellowr 10 | ; 11 | ; The output will be 138 bytes, identical for nasm and yasm. 12 | ; 13 | ; Please note that `-f bin' is optional for both nasm and yasm. 14 | ; 15 | 16 | bits 32 17 | 18 | ; Based on: http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html 19 | org 0x08048000 20 | ehdr: ; Elf32_Ehdr 21 | db 0x7F, "ELF", 1, 1, 1 ; e_ident 22 | db 3 ; 0=SYSV 3=GNU/Linux 23 | dd 0, 0 24 | dw 2 ; e_type 25 | dw 3 ; e_machine 26 | dd 1 ; e_version 27 | dd _start ; e_entry 28 | dd phdr - $$ ; e_phoff 29 | dd 0 ; e_shoff 30 | dd 0 ; e_flags 31 | dw ehdrsize ; e_ehsize 32 | dw phdrsize ; e_phentsize 33 | dw 1 ; e_phnum 34 | dw 40 ; e_shentsize 35 | dw 0 ; e_shnum 36 | dw 0 ; e_shstrndx 37 | ehdrsize equ $ - ehdr 38 | phdr: ; Elf32_Phdr 39 | dd 1 ; p_type 40 | dd 0 ; p_offset 41 | dd $$ ; p_vaddr 42 | dd $$ ; p_paddr 43 | dd filesize ; p_filesz 44 | dd filesize ; p_memsz 45 | dd 7 ; p_flags ; (1=executable 2=writable 4=readable) 46 | dd 0x1000 ; p_align 47 | phdrsize equ $ - phdr 48 | 49 | ; This is hand-optimized assembly for a loop which calls write(2) until 50 | ; all the output is printend. 51 | _start: 52 | mov edx, msg_size 53 | mov ecx, msg 54 | .again: 55 | mov eax, 4 ; __NR_write == 4. 56 | xor ebx, ebx 57 | inc ebx ; STDOUT_FILENO == 1. 58 | int 0x80 59 | add ecx, eax 60 | neg eax 61 | add eax, edx 62 | jz .done ; Finished writing. 63 | cmp eax, edx 64 | xchg eax, edx 65 | jle .again ; Error writing. 66 | .done: 67 | xor eax, eax 68 | mov ebx, eax 69 | inc eax ; __NR_exit == 1. 70 | int 0x80 71 | msg: db 'Hello, World!', 10 72 | msg_size equ $ - msg 73 | 74 | filesize equ $ - $$ 75 | -------------------------------------------------------------------------------- /examples/trampoline_linux_i386.nasm: -------------------------------------------------------------------------------- 1 | ; by pts@fazekas.hu at Sun Oct 19 12:51:22 CEST 2014 2 | ; 3 | ; Compile with: 4 | ; 5 | ; $ nasm -f bin -o cgin.trampoline trampoline_linux_i386.nasm && chmod +x cgin.trampoline 6 | ; 7 | ; Based on the output of: 8 | ; 9 | ; $ gcc -S -masm=intel -m32 -W -Wall -Os -Wl,-z,norelro -Wl,--build-id=none -fno-ident -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-stack-protector -fomit-frame-pointer -mpreferred-stack-boundary=2 -falign-functions=1 -falign-jumps=1 -falign-loops=1 trampoline_linux_i386.c && cat trampoline_linux_i386.s 10 | ; 11 | bits 32 12 | 13 | ; Based on: http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html 14 | org 0x08048000 15 | ehdr: ; Elf32_Ehdr 16 | db 0x7F, "ELF", 1, 1, 1, 0 ; e_ident 17 | dd 0, 0 18 | dw 2 ; e_type 19 | dw 3 ; e_machine 20 | dd 1 ; e_version 21 | dd _start ; e_entry 22 | dd phdr - $$ ; e_phoff 23 | dd 0 ; e_shoff 24 | dd 0 ; e_flags 25 | dw ehdrsize ; e_ehsize 26 | dw phdrsize ; e_phentsize 27 | dw 1 ; e_phnum 28 | dw 40 ; e_shentsize 29 | dw 0 ; e_shnum 30 | dw 0 ; e_shstrndx 31 | ehdrsize equ $ - ehdr 32 | phdr: ; Elf32_Phdr 33 | dd 1 ; p_type 34 | dd 0 ; p_offset 35 | dd $$ ; p_vaddr 36 | dd $$ ; p_paddr 37 | dd filesize ; p_filesz 38 | dd filesize ; p_memsz 39 | dd 7 ; p_flags ; (1=executable 2=writable 4=readable) 40 | dd 0x1000 ; p_align 41 | phdrsize equ $ - phdr 42 | 43 | ; This is based on trampoline_linux_i386.c 44 | _start: 45 | push ebx 46 | lea edx, [esp+8] 47 | .L2: 48 | cmp DWORD [edx], 0 49 | lea edx, [edx+4] 50 | jne .L2 51 | xor ecx, ecx 52 | mov eax, 206 53 | mov ebx, ecx 54 | int 0x80 55 | mov eax, DWORD [esp+8] 56 | mov ecx, eax 57 | jmp .L4 58 | .L6: 59 | sub ebx, 46 60 | cmp bl, 1 61 | cmovbe ecx, eax 62 | inc eax 63 | .L4: 64 | mov bl, BYTE [eax] 65 | test bl, bl 66 | jne .L6 67 | mov BYTE [ecx], 0 68 | mov eax, 11 69 | mov ebx, DWORD [esp+8] 70 | lea ecx, [esp+8] 71 | int 0x80 72 | mov eax, 1 73 | mov ebx, 120 74 | int 0x80 75 | 76 | filesize equ $ - $$ 77 | -------------------------------------------------------------------------------- /examples/helloo.nasm: -------------------------------------------------------------------------------- 1 | ;; Based on: 2 | ;; hello.asm: Copyright (C) 2001 Brian Raiter 3 | ;; Licensed under the terms of the GNU General Public License, either 4 | ;; version 2 or (at your option) any later version. 5 | ;; 6 | ;; To build: (output is 63 bytes) 7 | ;; nasm -f bin -o helloo helloo.nasm && chmod +x helloo 8 | 9 | BITS 32 10 | 11 | org 0x05430000 12 | 13 | db 0x7F, "ELF" 14 | dd 1 15 | dd 0 16 | dd $$ 17 | dw 2 18 | dw 3 19 | dd _start 20 | dw _start - $$ 21 | _start: inc ebx ; 1 = stdout file descriptor 22 | add eax, strict dword 4 ; 4 = write system call number 23 | mov ecx, msg ; Point ecx at string 24 | mov dl, 14 ; Set edx to string length 25 | int 0x80 ; eax = write(ebx, ecx, edx) 26 | and eax, 0x10020 ; al = 0 if no error occurred 27 | xchg eax, ebx ; 1 = exit system call number 28 | int 0x80 ; exit(ebx) 29 | msg: db 'Hello, World!', 10 30 | 31 | ;; This is how the file looks when it is read as an (incomplete) ELF 32 | ;; header, beginning at offset 0: 33 | ;; 34 | ;; e_ident: db 0x7F, "ELF" ; required 35 | ;; db 1 ; 1 = ELFCLASS32 36 | ;; db 0 ; (garbage) 37 | ;; db 0 ; (garbage) 38 | ;; db 0 ; (garbage) 39 | ;; db 0x00, 0x00, 0x00, 0x00 ; (unused) 40 | ;; db 0x00, 0x00, 0x43, 0x05 41 | ;; e_type: dw 2 ; 2 = ET_EXE 42 | ;; e_machine: dw 3 ; 3 = EM_386 43 | ;; e_version: dd 0x0543001A ; (garbage) 44 | ;; e_entry: dd 0x0543001A ; program starts here 45 | ;; e_phoff: dd 4 ; phdrs located here 46 | ;; e_shoff: dd 0x430031B9 ; (garbage) 47 | ;; e_flags: dd 0xCD0DB205 ; (unused) 48 | ;; e_ehsize: dw 0x2580 ; (garbage) 49 | ;; e_phentsize: dw 0x20 ; phdr entry size 50 | ;; e_phnum: dw 1 ; one phdr in the table 51 | ;; e_shentsize: dw 0xCD93 ; (garbage) 52 | ;; e_shnum: dw 0x6880 ; (garbage) 53 | ;; e_shstrndx: dw 0x6C65 ; (garbage) 54 | ;; 55 | ;; This is how the file looks when it is read as a program header 56 | ;; table, beginning at offset 4: 57 | ;; 58 | ;; p_type: dd 1 ; 1 = PT_LOAD 59 | ;; p_offset: dd 0 ; read from top of file 60 | ;; p_vaddr: dd 0x05430000 ; load at this address 61 | ;; p_paddr: dd 0x00030002 ; (unused) 62 | ;; p_filesz: dd 0x0543001A ; too big, but ok 63 | ;; p_memsz: dd 0x0543001A ; equal to file size 64 | ;; p_flags: dd 4 ; 4 = PF_R 65 | ;; p_align: dd 0x430031B9 ; (garbage) 66 | ;; 67 | ;; Note that the top two bytes of the file's origin (0x43 0x05) 68 | ;; correspond to the instructions "inc ebx" and the first byte of "add 69 | ;; eax, IMM". 70 | ;; 71 | ;; The fields marked as unused are either specifically documented as 72 | ;; not being used, or not being used with 386-based implementations. 73 | ;; Some of the fields marked as containing garbage are not used when 74 | ;; loading and executing programs. Other fields containing garbage are 75 | ;; accepted because Linux currently doesn't examine then. 76 | -------------------------------------------------------------------------------- /src/start/_start_noctors.s: -------------------------------------------------------------------------------- 1 | /* by pts@fazekas.hu at Mon Oct 20 00:31:44 CEST 2014 */ 2 | /* _start_noctors.s not used by pts-xtiny directly. */ 3 | /*.arch i386*/ 4 | .section .text.__xtiny_startexit 5 | .globl _start 6 | .type _start, @function 7 | _start: 8 | /* This is hand-optimized assembly code of 43 bytes for _start, 9 | * `gcc-4.6 -Os' generates 53 bytes. 10 | * 11 | * The addresses in the assembly dump below are relative to _start. 12 | * 13 | * Mostly equivalent to this: 14 | * 15 | * extern int main(int argc, char **argv, char **envp); 16 | * void _start(char *argv0) { 17 | * char **a=&argv0; 18 | * while (*a!=(char*)0) a++; 19 | * environ=(char const*const*)a+1; 20 | * exit(main(a-&argv0, &argv0, a+1)); 21 | * } 22 | */ 23 | .byte 0x8D, 0x5C, 0x24, 0x04 24 | /* ^^^ 00000000 8D5C2404 lea ebx,[esp+0x4] */ 25 | .byte 0x89, 0xDA 26 | /* ^^^ 00000004 89DA mov edx,ebx */ 27 | .byte 0x31, 0xC0 28 | /* ^^^ 00000006 31C0 xor eax,eax */ 29 | .byte 0x83, 0xC3, 0x04 30 | /* ^^^ 00000008 83C304 add ebx,byte +0x4 */ 31 | .byte 0x3B, 0x03 32 | /* ^^^ 0000000B 3B03 cmp eax,[ebx] */ 33 | .byte 0x75, 0xF9 34 | /* ^^^ 0000000D 75F9 jnz 0x8 */ 35 | .byte 0x8D, 0x4B, 0x04 36 | /* ^^^ 0000000F 8D4B04 lea ecx,[ebx+0x4] */ 37 | .byte 0x29, 0xD3 38 | /* ^^^ 00000012 29D3 sub ebx,edx */ 39 | .byte 0xC1, 0xEB, 0x02 40 | /* ^^^ 00000014 C1EB02 shr ebx,0x2 */ 41 | .byte 0x89, 0x0D 42 | .long __xtiny_environ 43 | /* ^^^ 00000017 890D???????? mov [__xtiny_environ],ecx */ 44 | .byte 0x51 45 | /* ^^^ 0000001D 51 push ecx */ 46 | .byte 0x52 47 | /* ^^^ 0000001E 52 push edx */ 48 | .byte 0x53 49 | /* ^^^ 0000001F 53 push ebx */ 50 | 51 | call main 52 | /* ^^^ 000000?? E8???????? call main */ 53 | /* Now eax has the exit code. */ 54 | /* Execution continues in __xtiny_exit.s. */ 55 | .size _start, .-_start 56 | /* Make __xtiny_exit undefined here, pull __xtiny_exit.s. */ 57 | .reloc 0, R_386_NONE, __xtiny_exit 58 | /* by pts@fazekas.hu at Sun Jan 29 20:56:18 CET 2017 */ 59 | .section .text.__xtiny_startexit 60 | .globl __xtiny_exit_with_fini 61 | .type __xtiny_exit_with_fini, @function 62 | /* Fall throuh here from _start.S after return from main(). */ 63 | __xtiny_exit_with_fini: /* Exit code passed in eax (regparm(1)). */ 64 | 65 | .globl __xtiny_exit 66 | .type __xtiny_exit, @function 67 | __xtiny_exit: /* Exit code passed in eax (regparm(1)). */ 68 | .byte 0x93 69 | /* ^^^ 000000?? 93 xchg eax,ebx */ 70 | .byte 0x31, 0xC0 71 | /* ^^^ 000000?? 31C0 xor eax,eax */ 72 | .byte 0x40 73 | /* ^^^ 000000?? 40 inc eax */ 74 | .byte 0xCD, 0x80 75 | /* ^^^ 000000?? CD80 int 0x80 */ 76 | .size __xtiny_exit_with_fini, .-__xtiny_exit_with_fini 77 | .size __xtiny_exit, .-__xtiny_exit 78 | -------------------------------------------------------------------------------- /src/malloc/__xtiny_lite_malloc.c: -------------------------------------------------------------------------------- 1 | /* based on musl-1.1.16/src/malloc, but single-threaded */ 2 | 3 | #include 4 | #define BRK(n) sys_brk((void*)(n)) 5 | #undef weak_alias 6 | #define weak_alias(old, new) \ 7 | extern __typeof(old) new __attribute__((weak, alias(#old))) 8 | 9 | #define ALIGN 16 10 | 11 | /* This function returns true if the interval [old,new] 12 | * intersects the 'len'-sized interval below &libc.auxv 13 | * (interpreted as the main-thread stack) or below &b 14 | * (the current stack). It is used to defend against 15 | * buggy brk implementations that can cross the stack. */ 16 | 17 | static int traverses_stack_p(size_t old, size_t new) 18 | { 19 | const size_t len = 8<<20; 20 | size_t a, b; 21 | 22 | /* Typically the stack is at 0xbf?????? or 0xff?????? */ 23 | #ifndef __XTINY__ 24 | b = (size_t)libc.auxv; 25 | a = b > len ? b-len : 0; 26 | if (new>a && old len ? b-len : 0; 31 | if (new>a && old SIZE_MAX - 16 - h) goto err; 71 | h += n + align; 72 | while (h > g) { 73 | g += g >> 1; 74 | } 75 | if (g > SIZE_MAX - PAGE_SIZE + 1 - base_brkv) goto err; 76 | g += -g & (PAGE_SIZE-1); 77 | g += base_brkv; 78 | if (traverses_stack_p(brkv, g) || (size_t)BRK(g) != g) goto err; 79 | result = (void*)(heap_used += align); 80 | memset((void*)brkv, '\0', g - brkv); /* TODO(pts): Inline memset? */ 81 | brkv = g; 82 | heap_used += n; 83 | return result; 84 | 85 | err: 86 | errno = ENOMEM; 87 | return 0; 88 | } 89 | 90 | weak_alias(__xtiny_lite_malloc, __xtiny_malloc); 91 | weak_alias(__xtiny_lite_malloc, __xtiny_malloc0); 92 | 93 | #if 0 94 | void *malloc(size_t n) { 95 | return __xtiny_lite_malloc(n); 96 | } 97 | void *__malloc0(size_t n) { 98 | return __xtiny_lite_malloc(n); 99 | } 100 | #endif 101 | -------------------------------------------------------------------------------- /src/c.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash -- 2 | # by pts@fazekas.hu at Sun Jan 29 19:54:21 CET 2017 3 | # 4 | # If we ever need .c files: gcc -nostdlib -nostartfiles -nodefaultlibs 5 | # 6 | 7 | # It's important that _start.s is immediately followed by __xtiny_exit.s. 8 | START_FILES_S_IN_ORDER=' 9 | start/_start.S 10 | start/__xtiny_exit.S 11 | ' 12 | 13 | EXIT_FILES_S_IN_ORDER=' 14 | start/__xtiny_exit.S 15 | ' 16 | 17 | FILES_S_IN_ORDER=' 18 | misc/__xtiny_environ.s 19 | misc/__xtiny_errno.s 20 | misc/abort.s 21 | misc/atexit.s 22 | ctype/isalpha.s 23 | ctype/isdigit.s 24 | ctype/isspace.s 25 | ctype/isxdigit.s 26 | string/memccpy.s 27 | string/memchr.s 28 | string/memcmp.s 29 | string/memcpy.s 30 | string/memset.s 31 | string/strcasecmp.s 32 | string/strcat.s 33 | string/strchr.s 34 | string/strcmp.s 35 | string/strcpy.s 36 | string/strlen.s 37 | string/strncmp.s 38 | string/strncpy.s 39 | string/strrchr.s 40 | ' 41 | set -ex 42 | cd "${0%/*}" 43 | test -f string/memset.s 44 | rm -rf obj obj__* lib__*.a */*.o 45 | rm -f include xtiny 46 | 47 | GCCDETFLAGS=-frandom-seed=9853 48 | 49 | mkdir obj__xtiny 50 | cd obj__xtiny 51 | set -- $FILES_S_IN_ORDER 52 | gcc $GCCDETFLAGS -m32 -c "${@/#/../}" 53 | rm -f ../lib__xtiny.a 54 | set -- "${@#*/}" 55 | # Automatic ranlib. 56 | # Don't include libgcc/withgot.exclude_obj/*.o, because 57 | # they reference the _GLOBAL_OFFSET_TABLE_. 58 | # D: for deterministic mode, don't include timestamps etc. 59 | ar crD ../lib__xtiny.a "${@/%.*/.o}" ../libgcc/*.obj/*.o 60 | cd .. 61 | 62 | for VV in {i,n}{f,n}; do 63 | DEFINES= 64 | test "${VV:0:1}" = n || DEFINES="$DEFINES -DDO_INIT_ARRAY" 65 | test "${VV:1:1}" = n || DEFINES="$DEFINES -DDO_FINI_ARRAY" 66 | mkdir obj__xtiny_start_"$VV" 67 | cd obj__xtiny_start_"$VV" 68 | set -- $START_FILES_S_IN_ORDER 69 | gcc $GCCDETFLAGS -m32 -c $DEFINES "${@/#/../}" 70 | rm -f ../lib__xtiny_start_"$VV".a 71 | set -- "${@#*/}" 72 | # Automatic ranlib. 73 | ar crD ../lib__xtiny_start_"$VV".a "${@/%.*/.o}" 74 | cd .. 75 | done 76 | 77 | mkdir obj__xtiny_exit 78 | cd obj__xtiny_exit 79 | set -- $EXIT_FILES_S_IN_ORDER 80 | gcc -m32 -c "${@/#/../}" # No -DDO_INIT_ARRAY, no -DDO_FINI_ARRAY. 81 | rm -f ../lib__xtiny_exit.a 82 | set -- "${@#*/}" 83 | ar crD ../lib__xtiny_exit.a "${@/%.*/.o}" 84 | cd .. 85 | 86 | ln -s ../include 87 | 88 | cp ../xtiny ./xtiny 89 | cd malloc 90 | # calloc.c uses malloc. 91 | # realloc_grow.c uses malloc and free. 92 | C_FILES='__forward_malloc.c __forward_malloc_free.c __xtiny_lite_malloc.c calloc.c realloc_grow.c' 93 | # -- not production-ready yet. 94 | set -- $C_FILES 95 | rm -f *.o 96 | # SUXX: The number NNNN in heap_end.NNNN may still change. 97 | ../xtiny gcc $GCCDETFLAGS -s -O2 -W -Wall -Wextra -Werror -c "$@" 98 | ar crD ../lib__xtiny.a "${@/%.*/.o}" 99 | cd .. 100 | 101 | cp ../xtiny ./xtiny 102 | cd misc 103 | C_FILES=' 104 | strdup.c 105 | strstr.c 106 | getenv.c 107 | ' 108 | set -- $C_FILES 109 | rm -f *.o 110 | # SUXX: The number NNNN in heap_end.NNNN may still change. 111 | ../xtiny gcc $GCCDETFLAGS -s -O2 -W -Wall -Wextra -Werror -c "$@" 112 | ar crD ../lib__xtiny.a "${@/%.*/.o}" 113 | cd .. 114 | 115 | set +x 116 | echo "Install with: cp -a src/lib__*.a ./" 117 | : c.sh OK 118 | -------------------------------------------------------------------------------- /examples/compressible.c: -------------------------------------------------------------------------------- 1 | #ifdef __XTINY__ 2 | #include 3 | #else 4 | #include 5 | #include 6 | #endif 7 | const char buf[5120]="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"; 8 | #ifdef __XTINY__ 9 | void _start() { 10 | #else 11 | int main() { 12 | #endif 13 | (void)write(1, buf, sizeof buf); 14 | exit(0); 15 | } 16 | -------------------------------------------------------------------------------- /src/string/string_decl.h: -------------------------------------------------------------------------------- 1 | typedef unsigned int size_t; 2 | 3 | /* Have GCC __builtin_* for these: */ 4 | extern void *memchr(__const void *__s, int __c, size_t __n) __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) __attribute__((__nonnull__(1))); 5 | extern int memcmp(__const void *__s1, __const void *__s2, size_t __n) __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) __attribute__((__nonnull__(1, 2))); 6 | extern void *memcpy(void *__restrict __dest, __const void *__restrict __src, size_t __n) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2))); 7 | extern void *memset(void *__s, int __c, size_t __n) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1))); 8 | extern char *strcat(char *__restrict __dest, __const char *__restrict __src) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2))); 9 | extern char *strchr(__const char *__s, int __c) __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) __attribute__((__nonnull__(1))); 10 | extern int strcmp(__const char *__s1, __const char *__s2) __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) __attribute__((__nonnull__(1, 2))); 11 | extern char *strcpy(char *__restrict __dest, __const char *__restrict __src) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2))); 12 | extern size_t strcspn(__const char *__s, __const char *__reject) __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) __attribute__((__nonnull__(1, 2))); 13 | extern size_t strlen(__const char *__s) __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) __attribute__((__nonnull__(1))); 14 | extern char *strncat(char *__restrict __dest, __const char *__restrict __src, size_t __n) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2))); 15 | extern int strncmp(__const char *__s1, __const char *__s2, size_t __n) __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) __attribute__((__nonnull__(1, 2))); 16 | extern char *strncpy(char *__restrict __dest, __const char *__restrict __src, size_t __n) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2))); 17 | extern char *strpbrk(__const char *__s, __const char *__accept) __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) __attribute__((__nonnull__(1, 2))); 18 | extern char *strrchr(__const char *__s, int __c) __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) __attribute__((__nonnull__(1))); 19 | extern size_t strspn(__const char *__s, __const char *__accept) __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) __attribute__((__nonnull__(1, 2))); 20 | extern char *strstr(__const char *__haystack, __const char *__needle) __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) __attribute__((__nonnull__(1, 2))); 21 | 22 | /* No GCC __builtin_* for these: */ 23 | extern void *memmove(void *__dest, __const void *__src, size_t __n) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2))); 24 | extern void *memccpy(void *__restrict __dest, __const void *__restrict __src, int __c, size_t __n) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2))); 25 | extern int strcoll(__const char *__s1, __const char *__s2) __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) __attribute__((__nonnull__(1, 2))); 26 | extern size_t strxfrm(char *__restrict __dest, __const char *__restrict __src, size_t __n) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(2))); 27 | extern char *strdup(__const char *__s) __attribute__((__nothrow__, __leaf__)) __attribute__((__malloc__)) __attribute__((__nonnull__(1))); 28 | extern char *strndup(__const char *__string, size_t __n) __attribute__((__nothrow__, __leaf__)) __attribute__((__malloc__)) __attribute__((__nonnull__(1))); 29 | extern char *strtok(char *__restrict __s, __const char *__restrict __delim) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(2))); 30 | extern char *__strtok_r(char *__restrict __s, __const char *__restrict __delim, char **__restrict __save_ptr) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(2, 3))); 31 | extern char *strtok_r(char *__restrict __s, __const char *__restrict __delim, char **__restrict __save_ptr) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(2, 3))); 32 | extern size_t strnlen(__const char *__string, size_t __maxlen) __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) __attribute__((__nonnull__(1))); 33 | extern char *strerror(int __errnum) __attribute__((__nothrow__, __leaf__)); 34 | extern int strerror_r(int __errnum, char *__buf, size_t __buflen) __asm__("__xpg_strerror_r") __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(2))); 35 | extern void __bzero(void *__s, size_t __n) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1))); 36 | extern void bcopy(__const void *__src, void *__dest, size_t __n) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2))); 37 | extern void bzero(void *__s, size_t __n) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1))); 38 | extern int bcmp(__const void *__s1, __const void *__s2, size_t __n) __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) __attribute__((__nonnull__(1, 2))); 39 | extern char *index(__const char *__s, int __c) __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) __attribute__((__nonnull__(1))); 40 | extern char *rindex(__const char *__s, int __c) __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) __attribute__((__nonnull__(1))); 41 | extern int ffs(int __i) __attribute__((__nothrow__, __leaf__)) __attribute__((__const__)); 42 | extern int strcasecmp(__const char *__s1, __const char *__s2) __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) __attribute__((__nonnull__(1, 2))); 43 | extern int strncasecmp(__const char *__s1, __const char *__s2, size_t __n) __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) __attribute__((__nonnull__(1, 2))); 44 | extern char *strsep(char **__restrict __stringp, __const char *__restrict __delim) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2))); 45 | extern char *strsignal(int __sig) __attribute__((__nothrow__, __leaf__)); 46 | extern char *__stpcpy(char *__restrict __dest, __const char *__restrict __src) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2))); 47 | extern char *stpcpy(char *__restrict __dest, __const char *__restrict __src) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2))); 48 | extern char *__stpncpy(char *__restrict __dest, __const char *__restrict __src, size_t __n) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2))); 49 | extern char *stpncpy(char *__restrict __dest, __const char *__restrict __src, size_t __n) __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2))); 50 | -------------------------------------------------------------------------------- /xtiny_noctors.scr: -------------------------------------------------------------------------------- 1 | /* 2 | * xtiny.scr -- a GNU ld(1) linker script for emitting small ELF binaries for C programs 3 | * by pts@fazekas.hu at Sun Oct 19 13:06:04 CEST 2014 4 | * 5 | * * GNU ld(1) and a Linux i386 system is required 6 | * * Usage: gcc -m32 -Os -nostdlib -W,-T,tiny.scr src*.c 7 | * * C++ not supported (because of constructor etc. sections) 8 | * * You need to define your own _start function (not a _main). 9 | * * No need for ALIGN(4) on .data, .rodata, .bss etc., because indivitual .o 10 | * files already specify alignment for the variables they define. 11 | */ 12 | 13 | OUTPUT_FORMAT(binary) 14 | TARGET(elf32-i386) /* Input (.o) format. */ 15 | /* If we specify TARGET(elf32-little) instead of TARGET(elf32-i386), 16 | * and move -T earlier than the .o files in the cmdline, we'd get error: 17 | * ld: ....o: Relocations in generic ELF (EM: 3) 18 | */ 19 | ENTRY(_start) /* Without this _start won't be loaded from an .a file. */ 20 | 21 | SECTIONS { 22 | __myorg = 0x08048000; /* Moves only relocation offsets. */ 23 | . = __myorg; 24 | /* ABSOLUTE(.) is necessary instead of . inside a section for ld. */ 25 | __ehdr = ABSOLUTE(.); /* __ehdr: ; Elf32_Ehdr */ 26 | . : { 27 | BYTE(0x7F) BYTE(69) BYTE(76) BYTE(70) BYTE(1) BYTE(1) BYTE(1) 28 | /* ^^^ db 0x7F, "ELF", 1, 1, 1 ; 0 e_ident */ 29 | BYTE(3) /* 0=SYSV 3=GNU/Linux */ 30 | LONG(0) LONG(0) 31 | /* ^^^ times 8 db 0 */ 32 | SHORT(2) SHORT(3) 33 | /* ^^^ dw 2, 3 ; 16 e_type, e_machine */ 34 | LONG(1) 35 | /* ^^^ dd 1 ; 20 e_version */ 36 | LONG(_start) 37 | /* ^^^ dd _start ; 24 e_entry */ 38 | LONG(__phdr - __myorg) 39 | /* ^^^ dd __phdr - $$ ; 28 e_phoff */ 40 | LONG(0) 41 | /* ^^^ dd 0 ; 32 e_shoff */ 42 | LONG(0) 43 | /* ^^^ dd 0 ; 36 e_flags */ 44 | SHORT(__ehdrsize) SHORT(__phdrsize) 45 | /* ^^^ dw __ehdrsize, __phdrsize ; 40 e_ehsize, e_phentsize */ 46 | SHORT(1) SHORT(40) SHORT(0) SHORT(0) 47 | /* ^^^ dw 1, 40, 0, 0 ; e_phnum, e_shentsize, e_shnum, e_shstrndx */ 48 | __ehdrsize = ABSOLUTE(.) - __ehdr; /* __ehdrsize equ $ - __ehdr; */ 49 | __phdr = ABSOLUTE(.); /* ; Elf32_Phdr */ 50 | LONG(1) LONG(0) LONG(__myorg) LONG(__myorg) 51 | /* ^^^ dd 1, 0, $$, $$ ; p_type, p_offset, p_vaddr, p_paddr */ 52 | LONG(__p_filesz - __myorg) 53 | /* ^^^ dd __p_filesz - __myorg ; p_filesz */ 54 | LONG(__p_memsz - __myorg) 55 | /* ^^^ dd __p_memsz - __myorg ; p_memsz */ 56 | LONG(7) 57 | /* ^^^ dd 7 ; p_flags (1=executable 2=writable 4=readable) */ 58 | LONG(4) 59 | /* ^^^ dd 4 ; p_align, same as ld -N */ 60 | __phdrsize = ABSOLUTE(.) - __phdr; /* __phdrsize equ $ - __phdr */ 61 | /* _start is defined in _start.o (compiled from _start.s) in lib__xtiny.a */ 62 | } 63 | PROVIDE(__executable_start = ABSOLUTE(.)); 64 | .text : { 65 | *(.text) /* Contains all other functions. */ 66 | *(.text.unlikely .text.*_unlikely) 67 | *(.text.exit .text.exit.*) 68 | *(.text.startup .text.startup.*) 69 | *(.text.hot .text.hot.*) 70 | *(.text .stub .text.* .gnu.linkonce.t.*) 71 | *(.text.*) /* text.startup contains main(). */ 72 | } 73 | PROVIDE(__etext = ABSOLUTE(.)); 74 | PROVIDE(_etext = ABSOLUTE(.)); 75 | PROVIDE(etext = ABSOLUTE(.)); 76 | /* Thread Local Storage sections supported but not useful yet. 77 | * We don't print an error, because it's hard to create these accidentally. 78 | */ 79 | .tdata : /* ALIGN(4) SUBALIGN(4) */ { 80 | *(.tdata .tdata.* .gnu.linkonce.td.*) 81 | } 82 | .tbss : /* ALIGN(4) SUBALIGN(4) */ { 83 | *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) 84 | } 85 | /* We align .data, .rodata and .bss to 4-byte boundary for faster loads on 86 | * the data bus. 87 | */ 88 | .rodata : /* ALIGN(4) SUBALIGN(4) */ { 89 | *(.rodata .rodata.* .gnu.linkonce.r.*) 90 | } 91 | .rodata1 : /* ALIGN(4) SUBALIGN(4) */ { 92 | /* Never seen it, but mentioned in default.scr. */ 93 | *(.rodata1) 94 | } 95 | .data : /* ALIGN(4) SUBALIGN(4) */ { 96 | *(.data .data.* .gnu.linkonce.d.*) /* Example: int a = 1; */ 97 | } 98 | .data1 : /* ALIGN(4) SUBALIGN(4) */ { 99 | /* Never seen it, but mentioned in https://refspecs.linuxfoundation.org/LSB_2.1.0/LSB-Core-generic/LSB-Core-generic/specialsections.html */ 100 | *(.data1) 101 | } 102 | .init : ALIGN(4) SUBALIGN(4) { 103 | *(.init) 104 | ASSERT(0, "Old-style constructors (.init) are not supported."); 105 | } 106 | .fini : ALIGN(4) SUBALIGN(4) { 107 | *(.fini) 108 | ASSERT(0, "Old-style destructors (.fini) are not supported."); 109 | } 110 | .preinit_array : ALIGN(4) SUBALIGN(4) { 111 | *(.preinit_array) 112 | ASSERT(0, "Old-style constructors (.preinit_array) are not supported."); 113 | } 114 | .init_array : ALIGN(4) SUBALIGN(4) { 115 | *(.init_array.* .init_array) 116 | ASSERT(0, "New-style constructors (.init_array) are not supported."); 117 | } 118 | .fini_array : ALIGN(4) SUBALIGN(4) { 119 | *(.fini_array.* .fini_array) 120 | ASSERT(0, "New-style destructors (.fini_array) are not supported."); 121 | } 122 | .ctors : ALIGN(4) SUBALIGN(4) { 123 | *(.ctors.* .ctors) 124 | ASSERT(0, "New-style constructors (.ctors) are not supported."); 125 | } 126 | .dtors : ALIGN(4) SUBALIGN(4) { 127 | *(.dtors.* .dtors) 128 | ASSERT(0, "New-style destructors (.dtors) are not supported."); 129 | } 130 | __p_filesz = .; 131 | PROVIDE(edata = ABSOLUTE(.)); 132 | PROVIDE(_edata = ABSOLUTE(.)); 133 | PROVIDE(__edata = ABSOLUTE(.)); 134 | __bss_start = ABSOLUTE(.); 135 | /* For some reason the contents of this secion will be omitted from the 136 | * file. Probably because do real data bytes are added here. 137 | */ 138 | .bss : /* ALIGN(4) SUBALIGN(4) */ { 139 | /* errno is defined in __xtiny_errno.o in lib__xtiny.a. We could define it 140 | * here: `__xtiny_errno = ABSOLUTE(.); . += 4;', but that would make the 141 | * symbol unavailable when linking with gcc. Similarly for environ. 142 | */ 143 | *(.dynbss) 144 | *(.bss .bss.* .gnu.linkonce.b.*) /* Example: int a = 0; // 0 is special. */ 145 | *(COMMON) /* Example: int a; */ 146 | } 147 | . = ALIGN(32 / 8); /* For compatibility with ld -N. */ 148 | _end = .; PROVIDE (end = .); 149 | /DISCARD/ : /* ALIGN(1) SUBALIGN(1) */ { 150 | *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) 151 | *(.note.gnu.gold-version) /* Not in .o files, just to be sure. */ 152 | *(.note.gnu.build-id) /* Not in .o files, just to be sure. */ 153 | *(.note.ABI-tag) 154 | *(.eh_frame .eh_frame_hdr) /* CFI for the debugger (gdb). */ 155 | *(.jcr) /* Java class registrations. */ 156 | *(.got.plt) 157 | *(.comment) *(.note) 158 | *(.debug .line .debug_*) /* DWARF debug, by `gcc -g'. */ 159 | *(.stab .stabstr .stab.*) /* Stabs debug. */ 160 | /* No difference, link warnings still displayed. */ 161 | *(.gnu.warning .gnu.warning.*) 162 | *(.gnu.version*) 163 | } 164 | /* Without this block ld will append all such sections to the target 165 | * executable. We don't know how to handle them, so let's not append them. 166 | */ 167 | .unsupported : /* ALIGN(1) SUBALIGN(1) */ { 168 | *(*) 169 | ASSERT(0, "Found non-empty unsupported section in ELF inputs."); 170 | } 171 | __p_memsz = .; 172 | } 173 | -------------------------------------------------------------------------------- /examples/multi_trampoline.c: -------------------------------------------------------------------------------- 1 | #define DUMMY /* 2 | true <<'#if 00' #*/ 3 | /* 4 | * multi_trampoline.c: a chdir() + [chroot() + umask()] + setreuid() + execve() for a CGI, possibly setuid 5 | * by pts@fazekas.hu at Fri Jun 9 12:09:32 CEST 2006 6 | * pts-xtiny version at Sat Feb 11 09:17:41 CET 2017 7 | * 8 | * multi_trampoline.c is a parametric C program, which, when compiled, 9 | * executes a real program (usually a CGI script) in a specially prepared a 10 | * UNIX environment. The envioronment is specified when multi_trampoline.c 11 | * is compiled. The following aspects of the UNIX environment can be modified: 12 | * removal of environment variables from environ, 13 | * UID, GID, EUID, EGID, umask(), chdir(), chroot() and argv[0]. 14 | * The argv[] coming from the 15 | * invocation command line is preserved upon execution, except for argv[0] 16 | * which is replaced. It is safe to add a setuid/setgid bits of the executable 17 | * of multi_trampoline.c. initgroups() and setgroups() are not called, 18 | * because this works only as root. multi_trampoline.c contains 19 | * optimizations for Linux i386, so the generated executable will be statically 20 | * linked and very small. 21 | * 22 | * This is version multi_trampoline.c version 0.04. See also VERSION below. 23 | * 24 | * This program is free software; you can redistribute it and/or modify 25 | * it under the terms of the GNU General Public License as published by 26 | * the Free Software Foundation; either version 2 of the License, or 27 | * (at your option) any later version. 28 | * 29 | * This program is distributed in the hope that it will be useful, 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 32 | * GNU General Public License for more details. 33 | * 34 | * You should have received a copy of the GNU General Public License 35 | * along with this program; if not, write to the Free Software 36 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 37 | * 38 | * Usage: ./multi_trampoline.c