├── .gitignore ├── LICENSE ├── Makefile ├── README ├── demo ├── Makefile ├── ldtest.c ├── test.c └── test2.c ├── ldelf ├── Makefile ├── launch.s ├── ldelf.c ├── load.c ├── start.S ├── syscalls.c └── systemcall.S ├── neatas ├── Makefile ├── neatas.c ├── out.c └── out.h ├── neatcc ├── Makefile ├── README ├── arm.c ├── arm.h ├── cpp.c ├── div.s ├── gen.c ├── int.c ├── mem.c ├── ncc.c ├── ncc.h ├── out.c ├── reg.c ├── tok.c ├── x64.c ├── x64.h ├── x86.c └── x86.h ├── neatdbg ├── Makefile ├── coredump.c ├── elfcore.h └── elfloc.c ├── neatld ├── Makefile ├── nld.1 └── nld.c ├── neatlibc ├── Makefile ├── README ├── arm │ ├── bits.s │ ├── lmem.s │ ├── start.s │ ├── string.s │ └── syscall.s ├── arpa │ └── inet.h ├── assert.h ├── atoi.c ├── ctype.c ├── ctype.h ├── dirent.c ├── dirent.h ├── elf.h ├── elks │ ├── LICENSE │ ├── asc_conv.c │ ├── ctime.c │ ├── getcwd.c │ └── tm_conv.c ├── errno.c ├── errno.h ├── fcntl.c ├── fcntl.h ├── inttypes.h ├── isatty.c ├── limits.h ├── linux │ ├── fb.h │ ├── types.h │ └── vt.h ├── localtime.c ├── malloc.c ├── memtst.c ├── mkstemp.c ├── poll.h ├── pwd.h ├── qsort.c ├── rand.c ├── regex.c ├── regex.h ├── scanf.c ├── setjmp.h ├── signal.c ├── signal.h ├── stdarg.c ├── stdarg.h ├── stddef.h ├── stdint.h ├── stdio.c ├── stdio.h ├── stdlib.c ├── stdlib.h ├── strftime.c ├── string.c ├── string.h ├── stringc.c ├── sys │ ├── ioctl.h │ ├── mman.h │ ├── stat.h │ ├── time.h │ ├── types.h │ └── wait.h ├── syscalls.h ├── termios.c ├── termios.h ├── time.c ├── time.h ├── unistd.c ├── unistd.h ├── utime.h ├── x64 │ ├── bits.s │ ├── launch.s │ ├── lmem.s │ ├── memtst.s │ ├── setjmp.s │ ├── start.s │ ├── string.s │ ├── syscall-Darwin.s │ └── syscall-Linux.s └── x86 │ ├── bits.s │ ├── lmem.s │ ├── memtst.s │ ├── setjmp.s │ ├── start.s │ ├── string.s │ └── syscall.s ├── neatrun ├── Makefile └── neatcc.c ├── sash ├── COPYING ├── COPYING.sash ├── Makefile ├── README ├── README.elks ├── cmd_dd.c ├── cmd_ed.c ├── cmd_grep.c ├── cmd_history.c ├── cmd_ls.c ├── cmd_tar.c ├── cmds.c ├── config.h ├── sash.c ├── sash.h └── utils.c └── test ├── Makefile ├── arm.s ├── b01.c ├── b02.c ├── b03.c ├── b04.c ├── b05.c ├── b06.c ├── b07.c ├── b08.c ├── b09.c ├── b10.c ├── b11.c ├── b12.c ├── b13.c ├── b14.c ├── b15.c ├── b16.c ├── b17.c ├── b18.c ├── b19.c ├── b20.c ├── b21.c ├── b22.c ├── t00.c ├── t01.c ├── t02.c ├── t03.c ├── t04.c ├── t05.c ├── t06.c ├── t07.c ├── t08.c ├── t09.c ├── t0a.c ├── t0b.c ├── t0c.c ├── t0d.c ├── t0e.c ├── t0f.c ├── t10.c ├── t11.c ├── t12.c ├── t13.c ├── t14.c ├── t15.c ├── t16.c ├── t17.c ├── t18.c ├── t19.c ├── t1a.c ├── t1b.c ├── t1c.c ├── t1d.c ├── t1e.c ├── t1f.c ├── t20.c ├── t21.c ├── t22.c ├── t23.c ├── t24.c ├── t25.c ├── t26.c ├── t27.c ├── t28.c ├── t29.c ├── t2a.c ├── t2b.c ├── t2c.c ├── t2d.c ├── t2e.c ├── t2f.c ├── t30.c ├── t31.c ├── t32.c ├── t33.c ├── t34.c ├── t35.c ├── t36.c ├── t37.c ├── t38.c ├── t39.c ├── t3a.c ├── t3b.c ├── t3c.c ├── t3d.c ├── t3e.c ├── t3f.c ├── t40.c ├── t41.c ├── t42.c ├── t43.c ├── t44.c ├── t45.c ├── t46.c ├── t47.c ├── t48.c ├── t49.c ├── t4a.c ├── t4b.c ├── t4c.c ├── t4d.c ├── t4e.c ├── t4f.c ├── t50.c ├── t51.c ├── t52.c ├── t53.c ├── t54.c ├── t55.c ├── t55.h ├── t56.c ├── t57.c ├── t58.c ├── t59.c ├── t5a.c ├── t5b.c ├── t5c.c ├── t5d.c ├── t5e.c ├── t5f.c ├── t60.c ├── t61.c ├── t62.c ├── t63.c ├── t64.c ├── t65.c ├── t66.c ├── t67.c ├── t68.c ├── t69.c ├── t6a.c ├── t6b.c ├── t6c.c ├── t6d.c ├── t6e.c ├── t6f.c ├── t70.c ├── t71.c ├── t72.c ├── t73.c ├── t74.c ├── t75.c ├── t76.c ├── t77.c ├── t78.c ├── t79.c ├── t7a.c ├── t7b.c ├── t7c.c ├── t7d.c ├── t7e.c ├── t7f.c ├── t80.c ├── t81.c ├── t82.c ├── t83.c ├── t84.c ├── t85.c ├── t86.c ├── t87.c ├── t88.c ├── t89.c ├── t8a.c ├── t8b.c ├── t8c.c ├── t8d.c ├── t8e.c ├── t8f.c ├── t90.c ├── t91.c ├── t92.c ├── t93.c ├── t94.c ├── t95.c ├── t96.c ├── t97.c ├── t98.c ├── t99.c ├── test.sh ├── x64.s └── x86.s /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | demo/test 3 | demo/test2 4 | ldelf/ldelf 5 | ldelf/load 6 | neatas/neatas 7 | neatcc/ncc 8 | neatdbg/coredump 9 | neatdbg/elfloc 10 | neatld/nld 11 | neatlibc/libc.a 12 | neatrun/neatcc 13 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # NCC top-level Makefile 2 | 3 | # output architecture: x64, x86, arm 4 | OUT = x64 5 | CC = cc 6 | 7 | BASE = $(PWD) 8 | #LOADER = $(BASE)/ldelf/ldelf 9 | #BOOTLDR = ../ldelf/ldelf 10 | LOADER = $(BASE)/ldelf/load 11 | BOOTLDR = ../ldelf/load 12 | export LOADER 13 | 14 | all: help 15 | 16 | help: 17 | @echo "NCC top-level makefile" 18 | @echo 19 | @echo " neat Compile the programs" 20 | @echo " sash Compile and run standalone shell" 21 | @echo " boot Compile neatcc using itself" 22 | @echo " test Run compiler tests" 23 | @echo " clean Remove the generated files" 24 | @echo 25 | 26 | neat: 27 | @cd ldelf && $(MAKE) 28 | # compiling the programs 29 | @cd neatcc && $(MAKE) OUT=$(OUT) CC="$(CC)" 30 | @cd neatld && $(MAKE) OUT=$(OUT) CC="$(CC)" 31 | @cd neatlibc && $(MAKE) OUT=$(OUT) CC=../neatcc/ncc 32 | # setting up neatrun/neatcc 33 | @cd neatrun && $(MAKE) OUT=$(OUT) NCC=$(BASE)/neatcc/ncc \ 34 | NLD=$(BASE)/neatld/nld NLC=$(BASE)/neatlibc all 35 | # compiling the rest 36 | @cd neatas && $(MAKE) OUT=$(OUT) 37 | @cd neatdbg && $(MAKE) OUT=$(OUT) 38 | # compiling demos and sash 39 | @cd sash && $(MAKE) 40 | @cd demo && $(MAKE) 41 | 42 | boot: 43 | # the previous version 44 | @cp neatrun/neatcc _neatcc 45 | # 0000000000 46 | @cd neatrun && $(MAKE) OUT=$(OUT) CC=../_neatcc \ 47 | NCC=../_ncc NLD=../_nld NLC=../neatlibc clean all 48 | @cp neatcc/ncc _ncc 49 | @cp neatld/nld _nld 50 | @cp neatrun/neatcc _neatcc 51 | # compiling the programs 52 | # 1111111111 53 | @cd neatcc && $(MAKE) OUT=$(OUT) CC="$(BOOTLDR) ../_neatcc" clean all 54 | # 2222222222 55 | @cd neatld && $(MAKE) OUT=$(OUT) CC="$(BOOTLDR) ../_neatcc" clean all 56 | # 3333333333 57 | @cd neatlibc && $(MAKE) OUT=$(OUT) CC="$(BOOTLDR) ../neatcc/ncc" clean all 58 | # setting up neatrun/neatcc 59 | # 4444444444 60 | @cd neatrun && $(MAKE) OUT=$(OUT) CC="$(BOOTLDR) ../_neatcc" NCC=$(BASE)/neatcc/ncc \ 61 | NLD=$(BASE)/neatld/nld NLC=$(BASE)/neatlibc clean all 62 | @rm _ncc _nld _neatcc 63 | # compiling the rest 64 | # 5555555555 65 | @cd neatas && $(MAKE) CC="$(BOOTLDR) ../neatrun/neatcc" OUT=$(OUT) clean all 66 | # 6666666666 67 | @cd neatdbg && $(MAKE) CC="$(BOOTLDR) ../neatrun/neatcc" OUT=$(OUT) clean all 68 | @echo DONE 69 | 70 | .PHONY: sash test libc demo 71 | sash: 72 | @cd sash && $(MAKE) 73 | $(LOADER) sash/sash 74 | 75 | libc: 76 | @cd neatlibc && $(MAKE) 77 | 78 | demo: 79 | @cd demo && $(MAKE) 80 | $(LOADER) demo/test 81 | 82 | test: 83 | @cd test && $(MAKE) 84 | 85 | clean: 86 | @cd neatcc && $(MAKE) clean 87 | @cd neatlibc && $(MAKE) clean 88 | @cd neatas && $(MAKE) clean 89 | @cd neatld && $(MAKE) clean 90 | @cd neatrun && $(MAKE) clean 91 | @cd neatdbg && $(MAKE) clean 92 | @cd ldelf && $(MAKE) clean 93 | @cd sash && $(MAKE) clean 94 | @cd demo && $(MAKE) clean 95 | @cd test && $(MAKE) clean 96 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | The NCC Project 2 | =============== 3 | 4 | NCC is an experimental project combining the amazing work of Ali Rudi's 5 | neatcc C compiler, neatld ELF linker, and neatlibc C library with an ELF 6 | loader for macOS, allowing tiny binaries to be created for direct execution 7 | on macOS or Linux, and eventually bare metal. 8 | 9 | This project is a combined fork of Ali's separate repos to eventually 10 | allow the system to be used as a library for extending the functionality 11 | of programs by compiling and linking into a running process, or used as 12 | a tiny self-compiling language system for bare metal. 13 | 14 | The C compiler supports a large subset of ANSI C, but most importantly 15 | lacks support for bitfields, inline assembly and floating point types. 16 | 17 | The compiler supports direct optimized compilation into ELF object 18 | files for Aarch64 and Intel x86-64, and uses a tiny linker to create 19 | static ELF binaries for macOS or Linux. Since the output format is 20 | ELF, macOS requires an ELF loader. The application code, data, heap 21 | and stack segments can be configured for execution in various parts 22 | of the 64-bit address space. 23 | 24 | The included C library is self-hosted and makes direct system calls 25 | to macOS or Linux, producing binaries with no dependencies on any 26 | shared libraries. Shared libraries are purposely not supported, for 27 | simplification of compiler output and speed. 28 | 29 | For now, the startup and syscall parts of the C library are assembled 30 | using nasm for x86-64, and the included neatas assembler for Aarch64. 31 | The compiler output itself is direct to ELF object, no need for assembly. 32 | 33 | 34 | BUILDING 35 | ======== 36 | 37 | Since development has just started and is being done on macOS, 38 | currently only macOS has been tested (that should change soon). 39 | 40 | To build for use on a hosted system: 41 | 42 | $ make neat # build neatcc, ncc, nld, neatas, libc.a and runs demo/test.c 43 | $ make test # run compiler test suite 44 | 45 | DIRECTORY STRUCTURE 46 | =================== 47 | 48 | neatrun/ Compiler driver 'neatcc' 49 | neatcc/ Compiler 'ncc' 50 | neatld/ Linker 'nld' 51 | neatas/ Aarch64 assembler 'neatas' 52 | neatlibc/ C startup and library for Linux and macOS 'start.o/libc.a' 53 | neatdbg/ Debug tools 54 | demo/ Demo programs 55 | test/ Compiler test suite 56 | ldelf/ ELF loader for non-ELF systems 57 | 58 | LICENSE 59 | ======= 60 | ISC License 61 | -------------------------------------------------------------------------------- /demo/Makefile: -------------------------------------------------------------------------------- 1 | CC = ../neatrun/neatcc 2 | LD = ../neatld/nld 3 | 4 | CFLAGS = -Wall -O2 5 | LDFLAGS = -p 6 | 7 | # ldtest load address must be below normal load address of 0x400000 (4MB) 8 | LOADADDR = -mc=0x200000 # 2MB 9 | 10 | 11 | ifeq ($(LOADER), ) 12 | #LOADER = ../ldelf/ldelf 13 | LOADER = ../ldelf/load 14 | endif 15 | 16 | all: test 17 | 18 | %.o: %.c 19 | $(CC) -c $(CFLAGS) $< 20 | 21 | test: test.o 22 | $(CC) -o $@ $^ $(LDFLAGS) 23 | $(LOADER) ./test 24 | 25 | test2: test2.o ttyname.o 26 | $(CC) -o $@ $^ $(LDFLAGS) 27 | $(LOADER) ./test2 these are args 28 | 29 | ldtest: ldtest.o 30 | $(CC) -o $@ $^ $(LDFLAGS) $(LOADADDR) 31 | $(LOADER) ./ldtest 32 | 33 | clean: 34 | rm -f *.o test test2 ldtest 35 | -------------------------------------------------------------------------------- /demo/ldtest.c: -------------------------------------------------------------------------------- 1 | ../ldelf/load.c -------------------------------------------------------------------------------- /demo/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int ac, char **av) 6 | { 7 | write(1, "NEATCC DEMO!\n", 13); 8 | while (ac-- > 0) 9 | printf("%s ", *av++); 10 | printf("\n"); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /demo/test2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | //int errno; 8 | #if 0 9 | int strlen(char *p) 10 | { 11 | int n = 0; 12 | while (*p++) 13 | n++; 14 | return n; 15 | } 16 | #endif 17 | 18 | static char *Utox(char *p, unsigned long x) { 19 | int i; 20 | if (x) { 21 | #if 0 22 | *p++ = '0'; 23 | *p++ = 'x'; 24 | i = (__builtin_clzl(x) ^ (sizeof(long) * 8 - 1)) + 1; 25 | i = (i + 3) & -4; 26 | #else 27 | i = 64; 28 | #endif 29 | do { 30 | if (i == 32) *p++ = '_'; 31 | *p++ = "0123456789abcdef"[(x >> (i -= 4)) & 15]; 32 | } while (i); 33 | } else { 34 | *p++ = '0'; 35 | } 36 | *p = 0; 37 | return p; 38 | } 39 | 40 | void foo(char *a, char *b, char *c, char *d, char *e) 41 | { 42 | //foo("a", "b", "c", "d", "e"); 43 | //foo(a, b, c, d, e); 44 | int (*fn)() = strlen; 45 | fn(); 46 | } 47 | 48 | int main(int argc, char **argv, char **envp) 49 | { 50 | #if 1 51 | int i; 52 | i = open("sdf", 0); 53 | printf("open %d errno %d\n", i, errno); 54 | printf("%s\n", "hello world!!"); 55 | printf("main = %lx\n", main); 56 | ttyname(1); 57 | for (i=0; i<32; i++) printf("malloc %lx\n", malloc(i & 1? 2048: 8192)); 58 | for (i=0; i < argc; i++) 59 | printf("'%s' (=%lx)\n", argv[i], argv[i]); 60 | while (*envp) { 61 | printf("'%s' (=%lx)\n", *envp, *envp); 62 | envp++; 63 | } 64 | printf("%lx\n", 0xFFFF88881234abcd); 65 | long x = 0xFFFF88881234abcd; 66 | char buf[21]; 67 | Utox(buf, x); 68 | write(1, buf, strlen(buf)); 69 | write(1, "\n", 1); 70 | printf("argc = %d @ 0x%lx\n", argc, &argc); 71 | write(1, "NEATCC!\n", 8); 72 | //printf("NEATCC!\n"); 73 | #endif 74 | #if 1 75 | //execle("../ldelf/ldelf", "../ldelf/ldelf", "./a.out", "a", "b", "C", 0, envp); 76 | if (fork() == 0) { 77 | execle("/bin/echo", "/bin/echo", "a", "b", "C", 0, envp); 78 | printf("EXEC failed\n"); 79 | _exit(0); 80 | } 81 | int st; 82 | wait(&st); 83 | printf("END\n"); 84 | #endif 85 | char buf[512]; 86 | struct stat sbuf; 87 | char buf2[512]; 88 | int fd = open("./a.out", 0); 89 | int i = fstat(fd, &sbuf); 90 | printf("stat %d\n", i); 91 | printf("st_dev %lx, st_ino %ld st_mode %o\n", 92 | sbuf.st_dev, sbuf.st_ino, sbuf.st_mode); 93 | printf("st_nlink %d uid %d gid %d rdev %x\n", sbuf.st_nlink, sbuf.st_uid, sbuf.st_gid, 94 | sbuf.st_rdev); 95 | printf("st_size %ld st_blocks %ld st_blksize %d \n", sbuf.st_size, sbuf.st_blocks, 96 | sbuf.st_blksize); 97 | ttyname(1); 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /ldelf/Makefile: -------------------------------------------------------------------------------- 1 | # elf loaders 2 | 3 | CC = cc 4 | CFLAGS = \ 5 | -Os \ 6 | -Wall \ 7 | -Wextra \ 8 | -pedantic-errors \ 9 | -fno-stack-check \ 10 | -fno-stack-protector \ 11 | 12 | LDFLAGS = \ 13 | -static \ 14 | -nostdlib \ 15 | -pagezero_size 0x100000 \ 16 | 17 | ifeq ($(shell uname), Darwin) 18 | LDFLAGS += -e xnustart 19 | endif 20 | 21 | LDELF = ldelf.o systemcall.o launch.o start.o 22 | LOAD = load.o syscalls.o systemcall.o launch.o start.o 23 | 24 | all: ldelf load 25 | 26 | %.o: %.c 27 | $(CC) -c $(CFLAGS) $< 28 | 29 | ldelf: $(LDELF) 30 | $(CC) -o $@ $(LDFLAGS) $(LDELF) 31 | 32 | load: $(LOAD) 33 | $(CC) -o $@ $(LDFLAGS) $(LOAD) 34 | 35 | clean: 36 | rm -f *.o ldelf load 37 | -------------------------------------------------------------------------------- /ldelf/launch.s: -------------------------------------------------------------------------------- 1 | /*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ 2 | │vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ 3 | ╞══════════════════════════════════════════════════════════════════════════════╡ 4 | │ Copyright 2023 Justine Alexandra Roberts Tunney │ 5 | │ │ 6 | │ Permission to use, copy, modify, and/or distribute this software for │ 7 | │ any purpose with or without fee is hereby granted, provided that the │ 8 | │ above copyright notice and this permission notice appear in all copies. │ 9 | │ │ 10 | │ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ 11 | │ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ 12 | │ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ 13 | │ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ 14 | │ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ 15 | │ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ 16 | │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ 17 | │ PERFORMANCE OF THIS SOFTWARE. │ 18 | ╚─────────────────────────────────────────────────────────────────────────────*/ 19 | 20 | // Calls _start() function of loaded program. 21 | // 22 | // When the program entrypoint is called, all registers shall be 23 | // cleared, with the exception of (1) %rdi will be equal to %rsp 24 | // on FreeBSD and (2) %cl will contain the detected host OS code 25 | // 26 | // We clear all the general registers we can to have some wiggle 27 | // room, to extend the behavior of this loader in the future. We 28 | // don't need to clear the XMM registers because your APE loader 29 | // should be compiled using gcc/clang's -mgeneral-regs-only flag 30 | // 31 | // @param rdi is passed through as-is 32 | // @param rsi is address of entrypoint (becomes zero) 33 | // @param rdx is stack pointer (becomes zero) 34 | // @param rcx is passed through as-is 35 | // @noreturn 36 | .section __TEXT,__text,regular,pure_instructions 37 | .p2align 4, 0x90 38 | .globl _Launch 39 | _Launch: 40 | xor %r8d,%r8d 41 | xor %r9d,%r9d 42 | xor %r10d,%r10d 43 | xor %r11d,%r11d 44 | xor %r12d,%r12d 45 | xor %r13d,%r13d 46 | xor %r14d,%r14d 47 | xor %r15d,%r15d 48 | mov %rdx,%rsp 49 | xor %edx,%edx 50 | push %rsi 51 | xor %esi,%esi 52 | xor %ebp,%ebp 53 | xor %ebx,%ebx 54 | xor %eax,%eax 55 | ret 56 | -------------------------------------------------------------------------------- /ldelf/start.S: -------------------------------------------------------------------------------- 1 | /*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ 2 | │vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ 3 | ╞══════════════════════════════════════════════════════════════════════════════╡ 4 | │ Copyright 2023 Justine Alexandra Roberts Tunney │ 5 | │ │ 6 | │ Permission to use, copy, modify, and/or distribute this software for │ 7 | │ any purpose with or without fee is hereby granted, provided that the │ 8 | │ above copyright notice and this permission notice appear in all copies. │ 9 | │ │ 10 | │ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ 11 | │ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ 12 | │ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ 13 | │ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ 14 | │ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ 15 | │ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ 16 | │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ 17 | │ PERFORMANCE OF THIS SOFTWARE. │ 18 | ╚─────────────────────────────────────────────────────────────────────────────*/ 19 | 20 | #define _HOSTXNU 8 21 | 22 | .globl xnustart 23 | .globl start 24 | xnustart: 25 | mov $_HOSTXNU,%dl // xnu's not unix! 26 | start: 27 | mov %rsp,%rsi // save real stack 28 | andq $-16,%rsp // force SSE alignment 29 | call _Main 30 | -------------------------------------------------------------------------------- /ldelf/systemcall.S: -------------------------------------------------------------------------------- 1 | /*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ 2 | │vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ 3 | ╞══════════════════════════════════════════════════════════════════════════════╡ 4 | │ Copyright 2023 Justine Alexandra Roberts Tunney │ 5 | │ │ 6 | │ Permission to use, copy, modify, and/or distribute this software for │ 7 | │ any purpose with or without fee is hereby granted, provided that the │ 8 | │ above copyright notice and this permission notice appear in all copies. │ 9 | │ │ 10 | │ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ 11 | │ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ 12 | │ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ 13 | │ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ 14 | │ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ 15 | │ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ 16 | │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ 17 | │ PERFORMANCE OF THIS SOFTWARE. │ 18 | ╚─────────────────────────────────────────────────────────────────────────────*/ 19 | 20 | // Invokes system call. 21 | // 22 | // long SystemCall(long rdi, long rsi, long rdx, long rcx_r10, long r8, long r9, 23 | // long arg7_8rsp, int ax_16rsp); 24 | // 25 | // This function has eight parameters. The first seven are for 26 | // arguments passed along to the system call. The eight is for 27 | // the magic number that indicates which system call is called 28 | // 29 | // The return value follows the Linux kernel convention, where 30 | // errors are returned as `-errno`. BSD systems are normalized 31 | // to follow this convention automatically. 32 | .section __TEXT,__text,regular,pure_instructions 33 | .p2align 4, 0x90 34 | .globl _SystemCall 35 | _SystemCall: 36 | mov %rcx,%r10 37 | mov 16(%rsp),%eax 38 | clc 39 | syscall 40 | jnc 1f 41 | neg %rax 42 | 1: ret 43 | 44 | .globl _SystemCallFork 45 | _SystemCallFork: 46 | mov %rdi,%rax 47 | clc 48 | syscall 49 | jnc 1f 50 | mov $-1,%rax 51 | ret 52 | 1: or %edx,%edx // EDX zero in parent 53 | jz 9f 54 | xor %rax,%rax 55 | 9: ret 56 | -------------------------------------------------------------------------------- /neatas/Makefile: -------------------------------------------------------------------------------- 1 | CC = cc 2 | CFLAGS = -Wall -Os 3 | LDFLAGS = 4 | 5 | all: neatas 6 | .c.o: 7 | $(CC) -c $(CFLAGS) $< 8 | neatas: neatas.o out.o 9 | $(CC) -o $@ $^ $(LDFLAGS) 10 | clean: 11 | rm -f neatas *.o 12 | -------------------------------------------------------------------------------- /neatas/out.h: -------------------------------------------------------------------------------- 1 | #define OUT_CS 0x0001 /* code segment symbol */ 2 | #define OUT_DS 0x0002 /* data segment symbol */ 3 | #define OUT_BSS 0x0004 /* bss segment symbol */ 4 | 5 | #define OUT_GLOB 0x0010 /* global symbol */ 6 | 7 | #define OUT_REL 0x0100 /* relative relocation */ 8 | #define OUT_REL24 0x0200 /* 24-bit relative relocation */ 9 | 10 | void out_init(int flags); 11 | 12 | void out_sym(char *name, int flags, int off, int len); 13 | void out_rel(char *name, int flags, int off); 14 | 15 | void out_write(int fd, char *cs, int cslen, char *ds, int dslen); 16 | -------------------------------------------------------------------------------- /neatcc/Makefile: -------------------------------------------------------------------------------- 1 | # output architecture: x64, x86, arm 2 | OUT = x64 3 | 4 | CC = cc 5 | CFLAGS = -Wall -O2 -DNEATCC_`echo $(OUT) | tr "[:lower:]" "[:upper:]"` 6 | LDFLAGS = 7 | 8 | OBJS = ncc.o tok.o out.o cpp.o gen.o int.o reg.o mem.o $(OUT).o 9 | 10 | all: ncc 11 | %.o: %.c ncc.h $(OUT).h 12 | $(CC) -c $(CFLAGS) $< 13 | ncc: $(OBJS) 14 | $(CC) -o $@ $(OBJS) $(LDFLAGS) 15 | clean: 16 | rm -f *.o ncc 17 | -------------------------------------------------------------------------------- /neatcc/README: -------------------------------------------------------------------------------- 1 | NEATCC 2 | ====== 3 | 4 | Neatcc is an ARM/x86(-64) C compiler. It supports a large subset of 5 | ANSI C but lacks some of its features, the most important of which are 6 | struct bitfields, inline assembly, and floating point types. 7 | -------------------------------------------------------------------------------- /neatcc/arm.h: -------------------------------------------------------------------------------- 1 | /* architecture-dependent header for ARM */ 2 | #define LONGSZ 4 /* word size */ 3 | #define I_ARCH "__arm__" 4 | 5 | #define N_REGS 16 /* number of registers */ 6 | #define N_TMPS 10 /* number of tmp registers */ 7 | #define N_ARGS 4 /* number of arg registers */ 8 | #define R_TMPS 0x03ff /* mask of tmp registers */ 9 | #define R_ARGS 0x000f /* mask of arg registers */ 10 | #define R_PERM 0x0ff0 /* mask of callee-saved registers */ 11 | 12 | /* special registers */ 13 | #define REG_FP 11 /* frame pointer register */ 14 | #define REG_SP 13 /* stack pointer register */ 15 | 16 | /* stack positions */ 17 | #define I_ARG0 (-16) /* offset of the first argument from FP */ 18 | #define I_LOC0 0 /* offset of the first local from FP */ 19 | -------------------------------------------------------------------------------- /neatcc/div.s: -------------------------------------------------------------------------------- 1 | @ ARM software division implementation 2 | @ These functions are assembled using neatas and are included in gen.c 3 | .global __udivdi3 4 | __udivdi3: 5 | mov r2, #0 6 | mov r3, #0 7 | 8 | @ zero divider 9 | tst r1, r1 10 | beq .end 11 | 12 | @ shift the operand 13 | .shl: 14 | movs r12, r1, LSL r2 15 | add r2, r2, #1 16 | bpl .shl 17 | 18 | mov r12, #1 19 | 20 | @ the main division algorithm 21 | .shr: 22 | subs r2, r2, #1 23 | bmi .end 24 | cmps r0, r1, LSL r2 25 | bcc .shr 26 | sub r0, r0, r1, LSL r2 27 | add r3, r3, r12, LSL r2 28 | b .shr 29 | .end: 30 | mov r1, r0 31 | mov r0, r3 32 | mov pc, lr 33 | 34 | .global __umoddi3 35 | __umoddi3: 36 | stmfd sp!, {lr} 37 | bl __udivdi3 38 | mov r0, r1 39 | ldmfd sp!, {pc} 40 | 41 | .global __divdi3 42 | __divdi3: 43 | stmfd sp!, {r4, r5, lr} 44 | 45 | mov r4, r0 46 | mov r5, r1 47 | 48 | @ handle negative operands 49 | tst r0, r0 50 | rsbmi r0, r0, #0 51 | tst r1, r1 52 | rsbmi r1, r1, #0 53 | 54 | bl __udivdi3 55 | 56 | @ result is negative 57 | teq r4, r5 58 | rsbmi r0, r0, #0 59 | tst r4, r4 60 | rsbmi r1, r1, #0 61 | 62 | ldmfd sp!, {r4, r5, pc} 63 | 64 | .global __moddi3 65 | __moddi3: 66 | stmfd sp!, {lr} 67 | bl __divdi3 68 | mov r0, r1 69 | ldmfd sp!, {pc} 70 | -------------------------------------------------------------------------------- /neatcc/mem.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "ncc.h" 6 | 7 | #define MEMSZ 512 8 | 9 | static void mem_extend(struct mem *mem) 10 | { 11 | char *s = mem->s; 12 | mem->sz = mem->sz ? mem->sz + mem->sz : MEMSZ; 13 | mem->s = malloc(mem->sz); 14 | if (mem->n) 15 | memcpy(mem->s, s, mem->n); 16 | free(s); 17 | } 18 | 19 | void mem_init(struct mem *mem) 20 | { 21 | memset(mem, 0, sizeof(*mem)); 22 | } 23 | 24 | void mem_done(struct mem *mem) 25 | { 26 | free(mem->s); 27 | memset(mem, 0, sizeof(*mem)); 28 | } 29 | 30 | void mem_cut(struct mem *mem, long pos) 31 | { 32 | mem->n = pos < mem->n ? pos : mem->n; 33 | } 34 | 35 | void mem_cpy(struct mem *mem, long off, void *buf, long len) 36 | { 37 | while (mem->n + off + len + 1 >= mem->sz) 38 | mem_extend(mem); 39 | memcpy(mem->s + off, buf, len); 40 | } 41 | 42 | void mem_put(struct mem *mem, void *buf, long len) 43 | { 44 | mem_cpy(mem, mem->n, buf, len); 45 | mem->n += len; 46 | } 47 | 48 | void mem_putc(struct mem *mem, int c) 49 | { 50 | if (mem->n + 2 >= mem->sz) 51 | mem_extend(mem); 52 | mem->s[mem->n++] = c; 53 | } 54 | 55 | void mem_putz(struct mem *mem, long sz) 56 | { 57 | while (mem->n + sz + 1 >= mem->sz) 58 | mem_extend(mem); 59 | memset(mem->s + mem->n, 0, sz); 60 | mem->n += sz; 61 | } 62 | 63 | /* return a pointer to mem's buffer; valid as long as mem is not modified */ 64 | void *mem_buf(struct mem *mem) 65 | { 66 | if (!mem->s) 67 | return ""; 68 | mem->s[mem->n] = '\0'; 69 | return mem->s; 70 | } 71 | 72 | long mem_len(struct mem *mem) 73 | { 74 | return mem->n; 75 | } 76 | 77 | void *mem_get(struct mem *mem) 78 | { 79 | void *ret; 80 | if (!mem->s) 81 | mem_extend(mem); 82 | ret = mem->s; 83 | mem_init(mem); 84 | return ret; 85 | } 86 | -------------------------------------------------------------------------------- /neatcc/x64.h: -------------------------------------------------------------------------------- 1 | /* architecture-dependent header for x86_64 */ 2 | #define LONGSZ 8 /* word size */ 3 | #define I_ARCH "__x86_64__" 4 | 5 | #define N_REGS 16 /* number of registers */ 6 | #define N_TMPS 14 /* number of tmp registers */ 7 | #define N_ARGS 6 /* number of arg registers */ 8 | #define R_TMPS 0xffcf /* mask of tmp registers */ 9 | #define R_ARGS 0x03c6 /* mask of arg registers */ 10 | #define R_PERM 0xf008 /* mask of callee-saved registers */ 11 | 12 | #define REG_FP 5 /* frame pointer register */ 13 | #define REG_SP 4 /* stack pointer register */ 14 | 15 | #define I_ARG0 (-16) /* offset of the first argument from FP */ 16 | #define I_LOC0 0 /* offset of the first local from FP */ 17 | 18 | #define X64_ABS_RL (OUT_RL32) /* x86_64 memory model */ 19 | -------------------------------------------------------------------------------- /neatcc/x86.h: -------------------------------------------------------------------------------- 1 | /* architecture-dependent header for x86 */ 2 | #define LONGSZ 4 /* word size */ 3 | #define I_ARCH "__i386__" 4 | 5 | #define N_REGS 8 /* number of registers */ 6 | #define N_TMPS 6 /* number of tmp registers */ 7 | #define N_ARGS 0 /* number of arg registers */ 8 | #define R_TMPS 0x00cf /* mask of tmp registers */ 9 | #define R_ARGS 0x0000 /* mask of arg registers */ 10 | #define R_PERM 0x00c8 /* mask of callee-saved registers */ 11 | 12 | #define REG_FP 5 /* frame pointer register */ 13 | #define REG_SP 4 /* stack pointer register */ 14 | 15 | #define I_ARG0 (-8) /* offset of the first argument from FP */ 16 | #define I_LOC0 0 /* offset of the first local from FP */ 17 | -------------------------------------------------------------------------------- /neatdbg/Makefile: -------------------------------------------------------------------------------- 1 | CC = cc 2 | CFLAGS = -O2 -Wall 3 | LDFLAGS = 4 | 5 | all: elfloc coredump 6 | %.o: %.c 7 | $(CC) -c $(CFLAGS) $< 8 | elfloc: elfloc.o 9 | $(CC) $(LDFLAGS) -o $@ elfloc.o 10 | coredump: coredump.o 11 | $(CC) $(LDFLAGS) -o $@ coredump.o 12 | clean: 13 | rm -f *.o elfloc coredump 14 | -------------------------------------------------------------------------------- /neatdbg/coredump.c: -------------------------------------------------------------------------------- 1 | /* 2 | * a simple elf core file backtrace viewer 3 | * 4 | * Copyright (C) 2010-2013 Ali Gholami Rudi 5 | * 6 | * This program is released under the Modified BSD license. 7 | */ 8 | #include "../neatlibc/elf.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "elfcore.h" 17 | 18 | /* simplified elf struct and macro names */ 19 | #ifdef __x86_64__ 20 | # define Elf_Phdr Elf64_Phdr 21 | # define Elf_Ehdr Elf64_Ehdr 22 | #else 23 | # define Elf_Phdr Elf32_Phdr 24 | # define Elf_Ehdr Elf32_Ehdr 25 | #endif 26 | 27 | #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) 28 | 29 | static long readlong(char *mem, unsigned long addr) 30 | { 31 | Elf_Ehdr *ehdr = (void *) mem; 32 | Elf_Phdr *phdr = (void *) (mem + ehdr->e_phoff); 33 | int i; 34 | for (i = 0; i < ehdr->e_phnum; i++) { 35 | unsigned long beg = phdr[i].p_vaddr; 36 | if (addr >= beg && addr < beg + phdr[i].p_filesz) { 37 | unsigned long diff = addr - beg; 38 | return *(long *) (mem + phdr[i].p_offset + diff); 39 | } 40 | } 41 | return 0; 42 | } 43 | 44 | static void dump_prstatus(char *mem, struct elf_prstatus *prs) 45 | { 46 | struct user_regs_struct *regs = (void *) &prs->pr_reg; 47 | unsigned long bp = regs->bp; 48 | printf("ip=%lx, sp=%lx, bp=%lx\n\n", regs->ip, regs->sp, regs->bp); 49 | printf("\t%lx: %lx\n", regs->ip, regs->bp); 50 | while (bp) { 51 | printf("\t%lx: %lx\n", 52 | readlong(mem, bp + sizeof(long)), readlong(mem, bp)); 53 | bp = readlong(mem, bp); 54 | } 55 | printf("\n"); 56 | } 57 | 58 | struct elfnote { 59 | int namesz; 60 | int descsz; 61 | int type; 62 | }; 63 | 64 | static void dumpnote(char *mem, char *note, int len) 65 | { 66 | struct elfnote *elfnote; 67 | char *end = note + len; 68 | while (note < end) { 69 | elfnote = (void *) note; 70 | note += sizeof(*elfnote); 71 | note += ALIGN(elfnote->namesz, 4); 72 | if (elfnote->type == NT_PRSTATUS) 73 | dump_prstatus(mem, (void *) note); 74 | note += ALIGN(elfnote->descsz, 4); 75 | } 76 | } 77 | 78 | static void dumpelf(char *mem) 79 | { 80 | Elf_Ehdr *ehdr = (void *) mem; 81 | Elf_Phdr *phdr = (void *) (mem + ehdr->e_phoff); 82 | if (ehdr->e_type == ET_CORE && phdr[0].p_type == PT_NOTE) 83 | dumpnote(mem, mem + phdr[0].p_offset, phdr[0].p_filesz); 84 | } 85 | 86 | static void die(char *msg) 87 | { 88 | perror(msg); 89 | exit(1); 90 | } 91 | 92 | static long filesize(int fd) 93 | { 94 | struct stat stat; 95 | fstat(fd, &stat); 96 | return stat.st_size; 97 | } 98 | 99 | int main(int argc, char **argv) 100 | { 101 | int fd; 102 | long size; 103 | void *mem; 104 | if (argc < 2) { 105 | printf("Usage: %s path\n", argv[0]); 106 | return 0; 107 | } 108 | fd = open(argv[1], O_RDONLY); 109 | if (fd == -1) 110 | die("open"); 111 | size = filesize(fd); 112 | mem = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); 113 | if (!mem) 114 | die("mmap"); 115 | dumpelf(mem); 116 | munmap(mem, size); 117 | close(fd); 118 | return 0; 119 | } 120 | -------------------------------------------------------------------------------- /neatdbg/elfcore.h: -------------------------------------------------------------------------------- 1 | /* register layout in coredumps */ 2 | #ifdef __x86_64__ 3 | struct user_regs_struct { 4 | unsigned long r15; 5 | unsigned long r14; 6 | unsigned long r13; 7 | unsigned long r12; 8 | unsigned long bp; 9 | unsigned long bx; 10 | unsigned long r11; 11 | unsigned long r10; 12 | unsigned long r9; 13 | unsigned long r8; 14 | unsigned long ax; 15 | unsigned long cx; 16 | unsigned long dx; 17 | unsigned long si; 18 | unsigned long di; 19 | unsigned long orig_ax; 20 | unsigned long ip; 21 | unsigned long cs; 22 | unsigned long flags; 23 | unsigned long sp; 24 | unsigned long ss; 25 | unsigned long fs_base; 26 | unsigned long gs_base; 27 | unsigned long ds; 28 | unsigned long es; 29 | unsigned long fs; 30 | unsigned long gs; 31 | }; 32 | #else 33 | struct user_regs_struct { 34 | unsigned long bx; 35 | unsigned long cx; 36 | unsigned long dx; 37 | unsigned long si; 38 | unsigned long di; 39 | unsigned long bp; 40 | unsigned long ax; 41 | unsigned long ds; 42 | unsigned long es; 43 | unsigned long fs; 44 | unsigned long gs; 45 | unsigned long orig_ax; 46 | unsigned long ip; 47 | unsigned long cs; 48 | unsigned long flags; 49 | unsigned long sp; 50 | unsigned long ss; 51 | }; 52 | #endif 53 | 54 | typedef unsigned long elf_greg_t; 55 | 56 | #define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) 57 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; 58 | 59 | struct elf_siginfo { 60 | int si_signo; /* signal number */ 61 | int si_code; /* extra code */ 62 | int si_errno; /* errno */ 63 | }; 64 | 65 | typedef elf_greg_t greg_t; 66 | typedef elf_gregset_t gregset_t; 67 | 68 | struct elf_prstatus { 69 | struct elf_siginfo pr_info; /* Info associated with signal */ 70 | short pr_cursig; /* Current signal */ 71 | unsigned long pr_sigpend; /* Set of pending signals */ 72 | unsigned long pr_sighold; /* Set of held signals */ 73 | pid_t pr_pid; 74 | pid_t pr_ppid; 75 | pid_t pr_pgrp; 76 | pid_t pr_sid; 77 | struct timeval pr_utime; /* User time */ 78 | struct timeval pr_stime; /* System time */ 79 | struct timeval pr_cutime; /* Cumulative user time */ 80 | struct timeval pr_cstime; /* Cumulative system time */ 81 | elf_gregset_t pr_reg; /* GP registers */ 82 | int pr_fpvalid; /* True if math co-processor being used. */ 83 | }; 84 | 85 | #define ELF_PRARGSZ (80) /* Number of chars for args */ 86 | 87 | struct elf_prpsinfo { 88 | char pr_state; /* numeric process state */ 89 | char pr_sname; /* char for pr_state */ 90 | char pr_zomb; /* zombie */ 91 | char pr_nice; /* nice val */ 92 | unsigned long pr_flag; /* flags */ 93 | uid_t pr_uid; 94 | gid_t pr_gid; 95 | pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; 96 | /* Lots missing */ 97 | char pr_fname[16]; /* filename of executable */ 98 | char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ 99 | }; 100 | -------------------------------------------------------------------------------- /neatld/Makefile: -------------------------------------------------------------------------------- 1 | CC = cc 2 | CFLAGS = -Wall -O2 3 | LDFLAGS = 4 | 5 | all: nld 6 | .c.o: 7 | $(CC) -c $(CFLAGS) $< 8 | nld: nld.o 9 | $(CC) $(LDFLAGS) -o $@ $^ 10 | clean: 11 | rm -f nld *.o 12 | -------------------------------------------------------------------------------- /neatld/nld.1: -------------------------------------------------------------------------------- 1 | .TH NEATLD 1 2 | .SH NAME 3 | neatld \- the neatld ARM/X86(-64) static linker 4 | .SH SYNOPSIS 5 | .B neatld 6 | [ 7 | .I options 8 | ] 9 | .I objfile ... 10 | .br 11 | .SH DESCRIPTION 12 | neatld links the given object and archive files into an executable 13 | file. The architecture of the output is determined based on the 14 | architecture of input files. Options are: 15 | .TP 16 | .BI -o " out" 17 | Write the output to the given file instead of 18 | .I a.out. 19 | .TP 20 | .BI -l lib 21 | Link with library 22 | .IR lib . 23 | .TP 24 | .BI -L libdir 25 | Search 26 | .IR libdir 27 | for finding libraries specified with 28 | .B -l. 29 | .TP 30 | .BI -s 31 | Do not include a symbol table. 32 | .TP 33 | .BI -m X=vaddr:laddr 34 | Set the virtual/load address of a section. 35 | .I X 36 | defines the section and can be 37 | .I c 38 | for code section, 39 | .I d 40 | for data section and 41 | .I b 42 | for BSS section. 43 | .IR laddr 44 | can be omitted, in which case it would be the same as 45 | .IR vaddr . 46 | .TP 47 | .BI -p 48 | Page-align sections. 49 | .TP 50 | .BI -e sym 51 | Entry point symbol. 52 | .SH "SEE ALSO" 53 | .IR neatcc (1), 54 | .IR neatas (1) 55 | -------------------------------------------------------------------------------- /neatlibc/Makefile: -------------------------------------------------------------------------------- 1 | # output architecture: x64, x86, arm 2 | OUT = x64 3 | 4 | # platform uname for syscalls 5 | PLATFORM=$(shell uname) 6 | 7 | # loader path for execve on macOS 8 | #LOADER=$(shell dirname $(shell pwd))/ldelf/ldelf 9 | LOADER=$(shell dirname $(shell pwd))/ldelf/load 10 | 11 | # default assemblers 12 | ASx64 = nasm -f elf64 -d$(PLATFORM) 13 | ASx86 = nasm -f elf 14 | ASarm = neatas 15 | 16 | CC = ../neatcc/ncc 17 | AS = $(AS$(OUT)) 18 | CFLAGS = -O2 -I. -DLOADER='"$(LOADER)"' 19 | 20 | all: start.o libc.a 21 | 22 | %.o: %.s 23 | $(AS) $^ >/dev/null 24 | %.o: %.c 25 | $(CC) -c -o $@ $(CFLAGS) $^ 26 | 27 | SSRC = $(filter-out $(OUT)/start.o $(wildcard $(OUT)/syscall*.s), $(wildcard $(OUT)/*.s)) 28 | SSRC += $(OUT)/syscall-$(shell uname).o 29 | SOBJS = $(patsubst %.s,%.o,$(SSRC)) 30 | COBJS = $(patsubst %.c,%.o,$(wildcard *.c)) 31 | COBJS += $(patsubst %.c,%.o,$(wildcard elks/*.c)) 32 | OBJS = $(COBJS) $(SOBJS) 33 | 34 | start.o: $(OUT)/start.o 35 | cp $(OUT)/start.o . 36 | 37 | libc.a: $(OBJS) 38 | #$(AR) rcs $@ $(OBJS) 39 | $(AR) rcs $@ `lorder $(OBJS) | tsort -q` 40 | 41 | load: ../ldelf/load.o 42 | 43 | clean: 44 | rm -f *.o *.a elks/*.o x86/*.o arm/*.o x64/*.o 45 | -------------------------------------------------------------------------------- /neatlibc/README: -------------------------------------------------------------------------------- 1 | NEATLIBC 2 | ======== 3 | 4 | Neatlibc is a small C standard library, supporting x86, x86_64, and 5 | 32-bit ARM architectures. Written mainly for bootstrapping neatcc, 6 | neatlibc does not implement many of the C standard library functions. 7 | Nonetheless, most of the programs available in its homepage 8 | (http://litcave.rudi.ir/) can be compiled with neatcc and neatlibc. 9 | 10 | To examine dynamic memory allocation in a program, you can define 11 | MEMTST macro before including stdlib.h header (only implemented for 12 | x86_64). It should report failed allocations, bad free() calls, and 13 | memory leaks. 14 | 15 | LICENCE 16 | ======= 17 | 18 | NEATLIBC C STANDARD LIBRARY 19 | 20 | Copyright (C) 2010-2020 Ali Gholami Rudi 21 | 22 | Permission to use, copy, modify, and/or distribute this software for any 23 | purpose with or without fee is hereby granted, provided that the above 24 | copyright notice and this permission notice appear in all copies. 25 | 26 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 27 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 28 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 29 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 30 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 31 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 32 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 33 | -------------------------------------------------------------------------------- /neatlibc/arm/bits.s: -------------------------------------------------------------------------------- 1 | 2 | .global htonl 3 | .global ntohl 4 | ntohl: 5 | htonl: 6 | eor r1, r0, r0, ror #16 7 | bic r1, r1, #0x00ff0000 8 | mov r0, r0, ror #8 9 | eor r0, r0, r1, lsr #8 10 | mov pc, lr 11 | 12 | .global htons 13 | .global ntohs 14 | ntohs: 15 | htons: 16 | mov r1, r0, lsr #8 17 | and r0, r0, #255 18 | and r1, r1, #255 19 | mov r0, r0, lsl #8 20 | orr r0, r0, r1 21 | mov pc, lr 22 | -------------------------------------------------------------------------------- /neatlibc/arm/lmem.s: -------------------------------------------------------------------------------- 1 | 2 | .global __memcpylong 3 | __memcpylong: 4 | mov r12, r0 5 | .loop: subs r2, r2, #4 6 | bmi .ret 7 | ldr r3, [r1], #4 8 | str r3, [r0], #4 9 | b .loop 10 | .ret: mov r0, r12 11 | mov pc, lr 12 | 13 | .global __memsetlong 14 | __memsetlong: 15 | mov r12, r0 16 | .loop: subs r2, r2, #4 17 | bmi .ret 18 | str r1, [r0], #4 19 | b .loop 20 | .ret: mov r0, r12 21 | mov pc, lr 22 | -------------------------------------------------------------------------------- /neatlibc/arm/start.s: -------------------------------------------------------------------------------- 1 | .extern environ 2 | .extern main 3 | .extern __neatlibc_exit 4 | 5 | .global _start 6 | _start: 7 | mov fp, #0 8 | ldr r0, [sp], #4 @ argc 9 | mov r1, sp @ argv 10 | add r2, r1, r0, lsl #2 11 | add r2, r2, #4 @ envp 12 | ldr r12, =environ 13 | str a3, [r12] 14 | 15 | bl main 16 | mov r4, r0 17 | bl __neatlibc_exit 18 | mov r0, r4 19 | 20 | mov r7, #1 21 | swi #0 22 | -------------------------------------------------------------------------------- /neatlibc/arm/string.s: -------------------------------------------------------------------------------- 1 | 2 | .global memcpy 3 | memcpy: 4 | mov r12, r0 5 | .loop: 6 | subs r2, r2, #1 7 | bmi .ret 8 | ldrb r3, [r1], #1 9 | strb r3, [r0], #1 10 | b .loop 11 | .ret: 12 | mov r0, r12 13 | mov pc, lr 14 | 15 | .global memset 16 | memset: 17 | mov r12, r0 18 | .loop: 19 | subs r2, r2, #1 20 | bmi .ret 21 | strb r1, [r0], #1 22 | b .loop 23 | .ret: 24 | mov r0, r12 25 | mov pc, lr 26 | 27 | .global memmove 28 | memmove: 29 | mov r12, r0 30 | cmp r0, r1 31 | ble .fw 32 | add r3, r1, r2 33 | cmp r0, r3 34 | bgt .fw 35 | 36 | @ copying the memory in reverse order 37 | add r0, r0, r2 38 | add r1, r1, r2 39 | .bw: 40 | subs r2, r2, #1 41 | bmi .ret 42 | ldrb r3, [r1, #-1]! 43 | strb r3, [r0, #-1]! 44 | b .bw 45 | .fw: 46 | subs r2, r2, #1 47 | bmi .ret 48 | ldrb r3, [r1], #1 49 | strb r3, [r0], #1 50 | b .fw 51 | .ret: 52 | mov r0, r12 53 | mov pc, lr 54 | 55 | .global memchr 56 | memchr: 57 | subs r2, r2, #1 58 | bmi .failed 59 | ldrb r3, [r0], #1 60 | cmp r3, r1 61 | bne memchr 62 | sub r0, r0, #1 63 | b .ret 64 | .failed: 65 | mov r0, #0 66 | .ret: 67 | mov pc, lr 68 | 69 | .global memrchr 70 | memrchr: 71 | mov r12, #0 72 | .loop: 73 | subs r2, r2, #1 74 | bmi .ret 75 | ldrb r3, [r0], #1 76 | cmp r3, r1 77 | subeq r12, r0, #1 78 | b .loop 79 | .ret: 80 | mov r0, r12 81 | mov pc, lr 82 | 83 | .global memcmp 84 | memcmp: 85 | subs r2, r2, #1 86 | bmi .match 87 | ldrb r3, [r0], #1 88 | ldrb r12, [r1], #1 89 | subs r3, r3, r12 90 | movne r0, r3 91 | bne .ret 92 | b memcmp 93 | .match: 94 | mov r0, #0 95 | .ret: 96 | mov pc, lr 97 | 98 | .global strlen 99 | strlen: 100 | mov r2, r0 101 | .loop: 102 | ldrb r1, [r0], #1 103 | tst r1, r1 104 | bne .loop 105 | sub r0, r0, r2 106 | sub r0, r0, #1 107 | mov pc, lr 108 | 109 | .global strchr 110 | strchr: 111 | ldrb r2, [r0], #1 112 | cmp r1, r2 113 | subeq r0, r0, #1 114 | beq .ret 115 | tst r2, r2 116 | bne strchr 117 | mov r0, #0 118 | .ret: 119 | mov pc, lr 120 | 121 | .global strrchr 122 | strrchr: 123 | mov r3, #0 124 | .loop: 125 | ldrb r2, [r0], #1 126 | cmp r1, r2 127 | subeq r3, r0, #1 128 | tst r2, r2 129 | bne .loop 130 | .ret: 131 | mov r0, r3 132 | mov pc, lr 133 | 134 | .global strcmp 135 | strcmp: 136 | ldrb r2, [r0], #1 137 | ldrb r3, [r1], #1 138 | cmp r2, #1 139 | cmpcs r2, r3 140 | beq strcmp 141 | sub r0, r2, r3 142 | mov pc, lr 143 | 144 | .global strcpy 145 | strcpy: 146 | mov r3, r0 147 | .loop: 148 | ldrb r2, [r1], #1 149 | strb r2, [r0], #1 150 | tst r2, r2 151 | bne .loop 152 | mov r0, r3 153 | .ret: 154 | mov pc, lr 155 | 156 | .global strncmp 157 | strncmp: 158 | mov r12, r2 159 | .loop: 160 | subs r12, r12, #1 161 | movmi r0, #0 162 | bmi .ret 163 | ldrb r2, [r0], #1 164 | ldrb r3, [r1], #1 165 | cmp r2, #1 166 | cmpcs r2, r3 167 | beq .loop 168 | sub r0, r2, r3 169 | .ret: 170 | mov pc, lr 171 | -------------------------------------------------------------------------------- /neatlibc/arpa/inet.h: -------------------------------------------------------------------------------- 1 | unsigned int htonl(unsigned int n); 2 | unsigned int ntohl(unsigned int n); 3 | unsigned short htons(unsigned short n); 4 | unsigned short ntohs(unsigned short n); 5 | -------------------------------------------------------------------------------- /neatlibc/assert.h: -------------------------------------------------------------------------------- 1 | #ifndef NDEBUG 2 | #define assert(expr) \ 3 | if (!(expr)) { \ 4 | __assertfailed(#expr); \ 5 | } 6 | #else 7 | #define assert(expr) 8 | #endif 9 | 10 | #define unassert(expr) \ 11 | if (!(expr)) { \ 12 | __assertfailed(#expr); \ 13 | } 14 | 15 | void __assertfailed(char *str); 16 | -------------------------------------------------------------------------------- /neatlibc/atoi.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int atoi(char *s) 7 | { 8 | int num = 0; 9 | int neg = 0; 10 | while (isspace(*s)) 11 | s++; 12 | if (*s == '-' || *s == '+') 13 | neg = *s++ == '-'; 14 | while ((unsigned) (*s - '0') <= 9u) 15 | num = num * 10 + *s++ - '0'; 16 | return neg ? -num : num; 17 | } 18 | 19 | long atol(char *s) 20 | { 21 | long num = 0; 22 | int neg = 0; 23 | while (isspace(*s)) 24 | s++; 25 | if (*s == '-' || *s == '+') 26 | neg = *s++ == '-'; 27 | while ((unsigned) (*s - '0') <= 9u) 28 | num = num * 10 + *s++ - '0'; 29 | return neg ? -num : num; 30 | } 31 | 32 | static int digit(char c, int base) 33 | { 34 | int d; 35 | if (c <= '9') { 36 | d = c - '0'; 37 | } else if (c <= 'Z') { 38 | d = 10 + c - 'A'; 39 | } else { 40 | d = 10 + c - 'a'; 41 | } 42 | return d < base ? d : -1; 43 | } 44 | 45 | long strtol(const char *s, char **endptr, int base) 46 | { 47 | int sgn = 1; 48 | int overflow = 0; 49 | long num; 50 | int dig; 51 | while (isspace(*s)) 52 | s++; 53 | if (*s == '-' || *s == '+') 54 | sgn = ',' - *s++; 55 | if (base == 0) { 56 | if (*s == '0') { 57 | if (s[1] == 'x' || s[1] == 'X') 58 | base = 16; 59 | else 60 | base = 8; 61 | } else { 62 | base = 10; 63 | } 64 | } 65 | if (base == 16 && *s == '0' && (s[1] == 'x' || s[1] == 'X')) 66 | s += 2; 67 | for (num = 0; (dig = digit(*s, base)) >= 0; s++) { 68 | if (num > LONG_MAX / base) 69 | overflow = 1; 70 | num *= base; 71 | if (num > LONG_MAX - dig) 72 | overflow = 1; 73 | num += dig; 74 | } 75 | if (endptr) 76 | *endptr = s; 77 | if (overflow) { 78 | num = sgn > 0 ? LONG_MAX : LONG_MIN; 79 | errno = ERANGE; 80 | } else { 81 | num *= sgn; 82 | } 83 | return num; 84 | } 85 | 86 | unsigned long strtoul(const char *s, char **endptr, int base) 87 | { 88 | int sgn = 1; 89 | int overflow = 0; 90 | unsigned long num; 91 | int dig; 92 | while (isspace(*s)) 93 | s++; 94 | if (*s == '-' || *s == '+') 95 | sgn = ',' - *s++; 96 | if (base == 0) { 97 | if (*s == '0') { 98 | if (s[1] == 'x' || s[1] == 'X') 99 | base = 16; 100 | else 101 | base = 8; 102 | } else { 103 | base = 10; 104 | } 105 | } 106 | if (base == 16 && *s == '0' && (s[1] == 'x' || s[1] == 'X')) 107 | s += 2; 108 | for (num = 0; (dig = digit(*s, base)) >= 0; s++) { 109 | if (num > (unsigned long) ULONG_MAX / base) 110 | overflow = 1; 111 | num *= base; 112 | if (num > (unsigned long) ULONG_MAX - dig) 113 | overflow = 1; 114 | num += dig; 115 | } 116 | if (endptr) 117 | *endptr = s; 118 | if (overflow) { 119 | num = ULONG_MAX; 120 | errno = ERANGE; 121 | } else { 122 | num *= sgn; 123 | } 124 | return num; 125 | } 126 | -------------------------------------------------------------------------------- /neatlibc/ctype.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int isascii(int c) 4 | { 5 | return (unsigned) c < 128u; 6 | } 7 | 8 | int isblank(int c) 9 | { 10 | return c == ' ' || c == '\t'; 11 | } 12 | 13 | int isalpha(int c) 14 | { 15 | return (unsigned) ((c | 0x20) - 'a') < 26u; 16 | } 17 | 18 | int isdigit(int c) 19 | { 20 | return (unsigned) (c - '0') < 10u; 21 | } 22 | 23 | int isalnum(int c) 24 | { 25 | return (unsigned) ((c | 0x20) - 'a') < 26u || 26 | (unsigned) (c - '0') < 10u; 27 | } 28 | 29 | int isspace(int c) 30 | { 31 | return (unsigned) (c - 9) < 5u || c == ' '; 32 | } 33 | 34 | int isupper(int c) 35 | { 36 | return (unsigned) (c - 'A') < 26u; 37 | } 38 | 39 | int islower(int c) 40 | { 41 | return (unsigned) (c - 'a') < 26u; 42 | } 43 | 44 | int tolower(int c) 45 | { 46 | return (unsigned) (c - 'A') < 26u ? c + ('a' - 'A') : c; 47 | } 48 | 49 | int toupper(int c) 50 | { 51 | return (unsigned) (c - 'a') < 26u ? c + ('A' - 'a') : c; 52 | } 53 | 54 | int isprint(int c) 55 | { 56 | return (c & 0x7f) >= 32 && c < 127; 57 | } 58 | 59 | int ispunct(int c) 60 | { 61 | return isprint(c) && !isalnum(c) && !isspace(c); 62 | } 63 | -------------------------------------------------------------------------------- /neatlibc/ctype.h: -------------------------------------------------------------------------------- 1 | #ifndef _CTYPE_H 2 | #define _CTYPE_H 3 | 4 | int isascii(int c); 5 | int isblank(int c); 6 | int isspace(int c); 7 | int isalpha(int c); 8 | int isdigit(int c); 9 | int isalnum(int c); 10 | int isupper(int c); 11 | int islower(int c); 12 | int isprint(int c); 13 | int ispunct(int c); 14 | 15 | int tolower(int c); 16 | int toupper(int c); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /neatlibc/dirent.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #ifdef __APPLE__ 9 | /* getdirentries file types */ 10 | #define DT_UNKNOWN 0 11 | #define DT_FIFO 1 12 | #define DT_CHR 2 13 | #define DT_DIR 4 14 | #define DT_BLK 6 15 | #define DT_REG 8 16 | #define DT_LNK 10 17 | #define DT_SOCK 12 18 | #define DT_WHT 14 19 | 20 | /* opendir flags */ 21 | #define DTF_HIDEW 0x0001 /* hide whiteout entries */ 22 | #define DTF_NODUP 0x0002 /* don't return duplicate names */ 23 | #define DTF_REWIND 0x0004 /* rewind after reading union stack */ 24 | #define __DTF_READALL 0x0008 /* everything has been read */ 25 | 26 | struct __dirent_dir { /* Darwin */ 27 | int fd; /* file descriptor associated with directory */ 28 | int dd_loc; /* offset in current buffer */ 29 | int dd_size; /* amount of data returned by getdirentries */ 30 | long dd_seek; /* magic cookie returned by getdirentries */ 31 | int dd_flags; /* flags for readdir (UNUSED) */ 32 | char dd_buf[2048]; 33 | }; 34 | #else 35 | struct __dirent_dir { /* Linux */ 36 | int fd; 37 | int buf_pos; 38 | int buf_end; 39 | char buf[2048]; 40 | }; 41 | #endif 42 | 43 | DIR *opendir(char *path) 44 | { 45 | DIR *dir; 46 | int fd; 47 | if ((fd = open(path, O_RDONLY | O_DIRECTORY)) < 0) 48 | return NULL; 49 | fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); 50 | if (!(dir = malloc(sizeof(*dir)))) { 51 | close(fd); 52 | return NULL; 53 | } 54 | memset(dir, 0, sizeof(*dir)); 55 | dir->fd = fd; 56 | return dir; 57 | } 58 | 59 | int closedir(DIR *dir) 60 | { 61 | int ret; 62 | ret = close(dir->fd); 63 | free(dir); 64 | return ret; 65 | } 66 | 67 | #ifdef __APPLE__ 68 | int getdirentries(int fd, char *buf, int nbytes, long *basep); 69 | 70 | struct dirent *readdir(DIR *dirp) 71 | { 72 | struct dirent *dp; 73 | 74 | for (;;) { 75 | if (dirp->dd_loc >= dirp->dd_size) { 76 | /*if (dirp->dd_flags & __DTF_READALL) 77 | return (NULL);*/ 78 | dirp->dd_loc = 0; 79 | } 80 | if (dirp->dd_loc == 0 /*&& !(dirp->dd_flags & __DTF_READALL)*/) { 81 | dirp->dd_size = getdirentries(dirp->fd, 82 | dirp->dd_buf, sizeof(dirp->dd_buf), &dirp->dd_seek); 83 | if (dirp->dd_size <= 0) 84 | return NULL; 85 | } 86 | dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc); 87 | /*printf("ino %lx reclen %d type %d namlen %d name %s\n", 88 | (long)dp->d_ino, dp->d_reclen, dp->d_type, dp->d_namlen, dp->d_name);*/ 89 | if ((int)dp & 03) /* bogus pointer check */ 90 | return NULL; 91 | if (dp->d_reclen <= 0 || dp->d_reclen > sizeof(dirp->dd_buf) + 1 - dirp->dd_loc) 92 | return NULL; 93 | dirp->dd_loc += dp->d_reclen; 94 | if (dp->d_ino == 0) 95 | continue; 96 | /*if (dp->d_type == DT_WHT && (dirp->dd_flags & DTF_HIDEW)) 97 | continue;*/ 98 | return dp; 99 | } 100 | } 101 | #else 102 | int getdents(int fd, struct dirent *de, size_t len); 103 | 104 | struct dirent *readdir(DIR *dir) 105 | { 106 | struct dirent *de; 107 | int len; 108 | if (dir->buf_pos >= dir->buf_end) { 109 | len = getdents(dir->fd, (void *) dir->buf, sizeof(dir->buf)); 110 | if (len <= 0) 111 | return NULL; 112 | dir->buf_pos = 0; 113 | dir->buf_end = len; 114 | } 115 | de = (void *) (dir->buf + dir->buf_pos); 116 | dir->buf_pos += de->d_reclen; 117 | return de; 118 | } 119 | #endif 120 | -------------------------------------------------------------------------------- /neatlibc/dirent.h: -------------------------------------------------------------------------------- 1 | typedef struct __dirent_dir DIR; 2 | 3 | #ifdef __APPLE__ 4 | #if 1 5 | struct dirent { /* getdirentries64 */ 6 | unsigned long d_ino; /* file number of entry */ 7 | unsigned long d_seekoff; 8 | unsigned short d_reclen; /* length of this record */ 9 | unsigned char d_namlen; /* length of string in d_name */ 10 | unsigned char d_type; /* file type, see below */ 11 | unsigned char d_namlen2; 12 | char d_name[255]; /* name must be no longer than this */ 13 | }; 14 | #else 15 | struct dirent { /* getdirentries */ 16 | unsigned int d_ino; /* file number of entry */ 17 | unsigned short d_reclen; /* length of this record */ 18 | unsigned char d_type; /* file type, see below */ 19 | unsigned char d_namlen; /* length of string in d_name */ 20 | char d_name[256]; /* name must be no longer than this */ 21 | }; 22 | #endif 23 | #else 24 | struct dirent { 25 | unsigned long d_ino; 26 | unsigned long d_off; 27 | unsigned short d_reclen; 28 | char d_name[256]; 29 | }; 30 | #endif 31 | 32 | DIR *opendir(char *path); 33 | int closedir(DIR *dir); 34 | struct dirent *readdir(DIR *dir); 35 | -------------------------------------------------------------------------------- /neatlibc/elks/LICENSE: -------------------------------------------------------------------------------- 1 | Files in this directory are from ELKS libc, which in turn may 2 | be from dev86 or glibc, and are licensed LGPL. 3 | -------------------------------------------------------------------------------- /neatlibc/elks/asc_conv.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | /* 4 | * Internal ascii conversion routine, avoid use of printf, it's a bit big! 5 | */ 6 | 7 | 8 | static void hit(char *buf, int val) 9 | { 10 | *buf = '0' + val%10; 11 | } 12 | 13 | void 14 | __asctime(char *buffer, const struct tm *ptm) 15 | { 16 | static char days[] = "SunMonTueWedThuFriSat"; 17 | static char mons[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; 18 | int year; 19 | 20 | /* 012345678901234567890123456 */ 21 | strcpy(buffer, "Err Err .. ..:..:.. ....\n"); 22 | if( (ptm->tm_wday >= 0) && (ptm->tm_wday <= 6) ) 23 | memcpy(buffer, days+3*(ptm->tm_wday), 3); 24 | 25 | if( (ptm->tm_mon >= 0) && (ptm->tm_mon <= 11) ) 26 | memcpy(buffer+4, mons+3*(ptm->tm_mon), 3); 27 | 28 | 29 | if (ptm->tm_mday < 10) 30 | buffer[8] = ' '; 31 | else hit(buffer+ 8, ptm->tm_mday/10); 32 | hit(buffer+ 9, ptm->tm_mday ); 33 | hit(buffer+11, ptm->tm_hour/10); 34 | hit(buffer+12, ptm->tm_hour ); 35 | hit(buffer+14, ptm->tm_min/10); 36 | hit(buffer+15, ptm->tm_min ); 37 | hit(buffer+17, ptm->tm_sec/10); 38 | hit(buffer+18, ptm->tm_sec ); 39 | 40 | year = ptm->tm_year + 1900; 41 | hit(buffer+20, year/1000); 42 | hit(buffer+21, year/100); 43 | hit(buffer+22, year/10); 44 | hit(buffer+23, year); 45 | } 46 | -------------------------------------------------------------------------------- /neatlibc/elks/ctime.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char * 5 | ctime(const time_t *timep) 6 | { 7 | time_t offt; 8 | struct tm tmb; 9 | struct timezone tz; 10 | static char cbuf[26]; 11 | 12 | gettimeofday((void*)0, &tz); 13 | 14 | if (!_tz_is_set) 15 | tzset(); 16 | tz.tz_minuteswest = timezone / 60; 17 | offt = -tz.tz_minuteswest*60L; 18 | 19 | /* tmb.tm_isdst = ? */ 20 | __tm_conv(&tmb, timep, offt); 21 | 22 | __asctime(cbuf, &tmb); 23 | 24 | return cbuf; 25 | } 26 | -------------------------------------------------------------------------------- /neatlibc/elks/getcwd.c: -------------------------------------------------------------------------------- 1 | /* getcwd.c */ 2 | 3 | #ifdef __APPLE__ 4 | #include 5 | #include 6 | 7 | char * 8 | getcwd(char *buf, int size) 9 | { 10 | int fd, n, ret; 11 | char path[256]; 12 | 13 | if ((fd = open(".", O_RDONLY | O_DIRECTORY)) < 0) 14 | return NULL; 15 | ret = fcntl(fd, F_GETPATH, path); 16 | close(fd); 17 | if (ret != -1) { 18 | n = strlen(path) + 1; 19 | if (n <= size) { 20 | memcpy(buf, path, n); 21 | return buf; 22 | } 23 | } 24 | return NULL; 25 | } 26 | #else 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | /* 36 | * These functions find the absolute path to the current working directory. 37 | * 38 | * They don't use malloc or large amounts of stack space. 39 | */ 40 | 41 | typedef ino_t u_ino_t; 42 | 43 | static char * path_buf; 44 | static size_t path_size; 45 | static dev_t root_dev; 46 | static u_ino_t root_ino; 47 | static struct stat st; 48 | 49 | /* routine to find the step back down */ 50 | static char * 51 | search_dir(dev_t this_dev, u_ino_t this_ino) 52 | { 53 | DIR * dp; 54 | struct dirent * d; 55 | char * ptr; 56 | size_t slen; 57 | int slow_search = 0; 58 | 59 | if( stat(path_buf, &st) < 0 ) return NULL; 60 | if( this_dev != st.st_dev ) slow_search = 1; 61 | 62 | slen = strlen(path_buf); 63 | ptr = path_buf + slen -1; 64 | if( *ptr != '/' ) 65 | { 66 | if( slen + 2 > path_size ) 67 | { 68 | errno = ERANGE; 69 | return NULL; 70 | } 71 | strcpy(++ptr, "/"); 72 | slen++; 73 | } 74 | slen++; 75 | 76 | printf("opendir %s\n", path_buf); 77 | dp = opendir(path_buf); 78 | if( dp == NULL ) return NULL; 79 | 80 | while( (d=readdir(dp)) != NULL ) 81 | { 82 | printf("search %-16s %16lx %16lx\n", d->d_name, this_ino, d->d_ino); 83 | if( slow_search || this_ino == d->d_ino ) 84 | { 85 | if( slen + strlen(d->d_name) > path_size ) 86 | { 87 | errno = ERANGE; 88 | return NULL; 89 | } 90 | strcpy(ptr+1, d->d_name); 91 | if( stat(path_buf, &st) < 0 ) 92 | continue; 93 | if( st.st_ino == this_ino && st.st_dev == this_dev ) 94 | { 95 | closedir(dp); 96 | return path_buf; 97 | } 98 | } 99 | } 100 | 101 | printf("Not found\n"); 102 | closedir(dp); 103 | errno = ENOENT; 104 | return NULL; 105 | } 106 | 107 | /* routine to go up the tree */ 108 | static char * 109 | recurser(void) 110 | { 111 | dev_t this_dev; 112 | u_ino_t this_ino; 113 | 114 | if( stat(path_buf, &st) < 0 ) return NULL; 115 | this_dev = st.st_dev; 116 | this_ino = st.st_ino; 117 | printf("%-16s this_ino %lx\n", path_buf, this_ino); 118 | if( this_dev == root_dev && this_ino == root_ino ) 119 | { 120 | printf("root_dev %lx root_ino %lx\n", root_dev, root_ino); 121 | strcpy(path_buf, "/"); 122 | return path_buf; 123 | } 124 | if( strlen(path_buf) + 4 > path_size ) 125 | { 126 | errno = ERANGE; 127 | return NULL; 128 | } 129 | strcat(path_buf, "/.."); 130 | if( recurser() == NULL ) return NULL; 131 | 132 | return search_dir(this_dev, this_ino); 133 | } 134 | 135 | char * 136 | getcwd(char *buf, int size) 137 | { 138 | path_buf = buf; 139 | path_size = size; 140 | 141 | if( size < 3 ) 142 | { 143 | errno = ERANGE; 144 | return NULL; 145 | } 146 | strcpy(path_buf, "."); 147 | 148 | if( stat("/", &st) < 0 ) { 149 | printf("stat fail: %d\n", errno); 150 | return NULL; 151 | } 152 | 153 | root_dev = st.st_dev; 154 | root_ino = st.st_ino; 155 | printf("root_dev %lx root_ino %lx\n", root_dev, root_ino); 156 | 157 | return recurser(); 158 | } 159 | #endif 160 | -------------------------------------------------------------------------------- /neatlibc/elks/tm_conv.c: -------------------------------------------------------------------------------- 1 | /* This is adapted from glibc */ 2 | /* Copyright (C) 1991, 1993 Free Software Foundation, Inc */ 3 | 4 | #define SECS_PER_HOUR 3600L 5 | #define SECS_PER_DAY 86400L 6 | 7 | #include 8 | 9 | static const char __mon_lengths[2][12] = 10 | { 11 | /* Normal years. */ 12 | { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, 13 | /* Leap years. */ 14 | { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } 15 | }; 16 | 17 | 18 | void 19 | __tm_conv(struct tm *tmbuf, const time_t *t, time_t offset) 20 | { 21 | long days, rem; 22 | int yday; 23 | register int y; 24 | register const char *ip; 25 | 26 | days = *t / SECS_PER_DAY; 27 | rem = *t - days * SECS_PER_DAY; 28 | rem += offset; 29 | while (rem < 0) 30 | { 31 | rem += SECS_PER_DAY; 32 | --days; 33 | } 34 | while (rem >= SECS_PER_DAY) 35 | { 36 | rem -= SECS_PER_DAY; 37 | ++days; 38 | } 39 | tmbuf->tm_hour = rem / SECS_PER_HOUR; 40 | rem -= tmbuf->tm_hour * SECS_PER_HOUR; 41 | tmbuf->tm_min = rem / 60; 42 | tmbuf->tm_sec = rem - tmbuf->tm_min * 60; 43 | /* January 1, 1970 was a Thursday. */ 44 | tmbuf->tm_wday = (4 + days) % 7; 45 | if (tmbuf->tm_wday < 0) 46 | tmbuf->tm_wday += 7; 47 | y = 1970; 48 | while (days >= (rem = __isleap(y) ? 366 : 365)) 49 | { 50 | ++y; 51 | days -= rem; 52 | } 53 | while (days < 0) 54 | { 55 | --y; 56 | days += __isleap(y) ? 366 : 365; 57 | } 58 | yday = days; 59 | tmbuf->tm_year = y - 1900; 60 | tmbuf->tm_yday = yday; 61 | ip = __mon_lengths[__isleap(y)]; 62 | for (y = 0; yday >= ip[y]; ++y) 63 | yday -= ip[y]; 64 | tmbuf->tm_mon = y; 65 | tmbuf->tm_mday = yday + 1; 66 | tmbuf->tm_isdst = -1; 67 | } 68 | -------------------------------------------------------------------------------- /neatlibc/errno.c: -------------------------------------------------------------------------------- 1 | #include "errno.h" 2 | 3 | char *sys_errlist[] = { 4 | [0] = "Invalid error number", 5 | [EPERM] = "Operation not permitted", 6 | [ENOENT] = "No such file or directory", 7 | [ESRCH] = "No such process", 8 | [EINTR] = "Interrupted system call", 9 | [EIO] = "I/O error", 10 | [ENXIO] = "No such device or address", 11 | [E2BIG] = "Argument list too long", 12 | [ENOEXEC] = "Exec format error", 13 | [EBADF] = "Bad file number", 14 | [ECHILD] = "No child processes", 15 | [EAGAIN] = "Operation would block", 16 | [ENOMEM] = "Out of memory", 17 | [EACCES] = "Permission denied", 18 | [EFAULT] = "Bad address", 19 | [ENOTBLK] = "Block device required", 20 | [EBUSY] = "Device or resource busy", 21 | [EEXIST] = "File exists", 22 | [EXDEV] = "Cross-device link", 23 | [ENODEV] = "No such device", 24 | [ENOTDIR] = "Not a directory", 25 | [EISDIR] = "Is a directory", 26 | [EINVAL] = "Invalid argument", 27 | [ENFILE] = "File table overflow", 28 | [EMFILE] = "Too many open files", 29 | [ENOTTY] = "Not a tty", 30 | [ETXTBSY] = "Text file busy", 31 | [EFBIG] = "File too large", 32 | [ENOSPC] = "No space left on device", 33 | [ESPIPE] = "Illegal seek", 34 | [EROFS] = "Read-only file system", 35 | [EMLINK] = "Too many links", 36 | [EPIPE] = "Broken pipe", 37 | [EDOM] = "Argument outside domain", 38 | [ERANGE] = "Result not representable", 39 | }; 40 | 41 | int sys_nerr = sizeof(sys_errlist) / sizeof(sys_errlist[0]); 42 | -------------------------------------------------------------------------------- /neatlibc/errno.h: -------------------------------------------------------------------------------- 1 | #ifndef _ERRNO_H 2 | #define _ERRNO_H 3 | 4 | extern int errno; 5 | extern char *sys_errlist[]; 6 | extern int sys_nerr; 7 | 8 | #define EPERM 1 /* Operation not permitted */ 9 | #define ENOENT 2 /* No such file or directory */ 10 | #define ESRCH 3 /* No such process */ 11 | #define EINTR 4 /* Interrupted system call */ 12 | #define EIO 5 /* I/O error */ 13 | #define ENXIO 6 /* No such device or address */ 14 | #define E2BIG 7 /* Argument list too long */ 15 | #define ENOEXEC 8 /* Exec format error */ 16 | #define EBADF 9 /* Bad file number */ 17 | #define ECHILD 10 /* No child processes */ 18 | #define EAGAIN 11 /* Try again */ 19 | #define ENOMEM 12 /* Out of memory */ 20 | #define EACCES 13 /* Permission denied */ 21 | #define EFAULT 14 /* Bad address */ 22 | #define ENOTBLK 15 /* Block device required */ 23 | #define EBUSY 16 /* Device or resource busy */ 24 | #define EEXIST 17 /* File exists */ 25 | #define EXDEV 18 /* Cross-device link */ 26 | #define ENODEV 19 /* No such device */ 27 | #define ENOTDIR 20 /* Not a directory */ 28 | #define EISDIR 21 /* Is a directory */ 29 | #define EINVAL 22 /* Invalid argument */ 30 | #define ENFILE 23 /* File table overflow */ 31 | #define EMFILE 24 /* Too many open files */ 32 | #define ENOTTY 25 /* Not a typewriter */ 33 | #define ETXTBSY 26 /* Text file busy */ 34 | #define EFBIG 27 /* File too large */ 35 | #define ENOSPC 28 /* No space left on device */ 36 | #define ESPIPE 29 /* Illegal seek */ 37 | #define EROFS 30 /* Read-only file system */ 38 | #define EMLINK 31 /* Too many links */ 39 | #define EPIPE 32 /* Broken pipe */ 40 | #define EDOM 33 /* Math argument out of domain of func */ 41 | #define ERANGE 34 /* Math result not representable */ 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /neatlibc/fcntl.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef __APPLE__ 4 | int creat(const char *path, int mode) 5 | { 6 | return open(path, O_CREAT | O_TRUNC | O_WRONLY, mode); 7 | } 8 | #endif 9 | -------------------------------------------------------------------------------- /neatlibc/fcntl.h: -------------------------------------------------------------------------------- 1 | #ifndef _FCNTL_H 2 | #define _FCNTL_H 3 | 4 | #define O_RDONLY 00000 5 | #define O_WRONLY 00001 6 | #define O_RDWR 00002 7 | #define O_ACCMODE 00003 8 | 9 | #ifdef __APPLE__ 10 | #define O_NONBLOCK 0x0004 /* no delay */ 11 | #define O_APPEND 0x0008 /* set append mode */ 12 | #define O_CREAT 0x0200 /* create if nonexistant */ 13 | #define O_TRUNC 0x0400 /* truncate to zero length */ 14 | #define O_EXCL 0x0800 /* error if already exists */ 15 | #define O_NOCTTY 0x20000 /* don't assign controlling terminal */ 16 | #define O_DIRECTORY 0x100000 17 | #define O_SYMLINK 0x200000 /* allow open of a symlink */ 18 | #define O_CLOEXEC 0x1000000 /* implicitly set FD_CLOEXEC */ 19 | 20 | /* fcntl(2) */ 21 | #define F_DUPFD 0 /* duplicate file descriptor */ 22 | #define F_GETFD 1 /* get file descriptor flags */ 23 | #define F_SETFD 2 /* set file descriptor flags */ 24 | #define F_GETFL 3 /* get file status flags */ 25 | #define F_SETFL 4 /* set file status flags */ 26 | #define F_GETOWN 5 /* get SIGIO/SIGURG proc/pgrp */ 27 | #define F_SETOWN 6 /* set SIGIO/SIGURG proc/pgrp */ 28 | #define F_GETLK 7 /* get record locking information */ 29 | #define F_SETLK 8 /* set record locking information */ 30 | #define F_SETLKW 9 /* F_SETLK; wait if blocked */ 31 | #define F_GETPATH 50 /* get full path of file descriptor */ 32 | 33 | #define FD_CLOEXEC 1 /* close-on-exec flag */ 34 | 35 | 36 | #else 37 | #define O_CREAT 00100 38 | #define O_EXCL 00200 39 | #define O_NOCTTY 00400 40 | #define O_TRUNC 01000 41 | #define O_APPEND 02000 42 | #define O_NONBLOCK 04000 43 | #define O_SYNC 0010000 44 | #define FASYNC 0020000 45 | #ifdef __arm__ 46 | #define O_DIRECTORY 0040000 47 | #define O_NOFOLLOW 0100000 48 | #define O_DIRECT 0200000 49 | #define O_LARGEFILE 0400000 50 | #else 51 | #define O_DIRECT 0040000 52 | #define O_LARGEFILE 0100000 53 | #define O_DIRECTORY 0200000 54 | #define O_NOFOLLOW 0400000 55 | #endif 56 | #define O_NOATIME 001000000 57 | 58 | #define F_DUPFD 0 59 | #define F_GETFD 1 60 | #define F_SETFD 2 61 | #define F_GETFL 3 62 | #define F_SETFL 4 63 | #define F_GETLK 5 64 | #define F_SETLK 6 65 | #define F_SETLKW 7 66 | #define F_SETOWN 8 67 | #define F_GETOWN 9 68 | #define F_SETSIG 10 69 | #define F_GETSIG 11 70 | 71 | #define FD_CLOEXEC 1 72 | 73 | #define F_RDLCK 0 74 | #define F_WRLCK 1 75 | #define F_UNLCK 2 76 | 77 | #endif 78 | 79 | int open(char *path, int flags, ...); 80 | int creat(char *path, int mode); 81 | int fcntl(int fd, int cmd, ...); 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /neatlibc/inttypes.h: -------------------------------------------------------------------------------- 1 | #include 2 | -------------------------------------------------------------------------------- /neatlibc/isatty.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int 5 | isatty(int fd) 6 | { 7 | struct termios dummy; 8 | 9 | return (!ioctl(fd, TCGETS, &dummy)); 10 | } 11 | -------------------------------------------------------------------------------- /neatlibc/limits.h: -------------------------------------------------------------------------------- 1 | #ifndef _LIMITS_H 2 | #define _LIMITS_H 3 | 4 | #define CHAR_BIT 8 5 | #define SCHAR_MIN -127 6 | #define SCHAR_MAX 127 7 | #define UCHAR_MAX 255u 8 | #define CHAR_MIN SCHAR_MIN 9 | #define CHAR_MAX SCHAR_MAX 10 | #define MB_LEN_MAX 4 11 | 12 | #define SHRT_MIN -32767 13 | #define SHRT_MAX 32767 14 | #define USHRT_MAX 65535u 15 | #define INT_MIN -2147483647 16 | #define INT_MAX 2147483647 17 | #define UINT_MAX 4294967295u 18 | 19 | #ifdef __x86_64__ 20 | #define LONG_MIN -9223372036854775807l 21 | #define LONG_MAX 9223372036854775807l 22 | #define ULONG_MAX 18446744073709551615l 23 | #else 24 | #define LONG_MIN -2147483647l 25 | #define LONG_MAX 2147483647l 26 | #define ULONG_MAX 4294967295ul 27 | #endif 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /neatlibc/linux/types.h: -------------------------------------------------------------------------------- 1 | typedef unsigned int __u32; 2 | typedef unsigned short __u16; 3 | typedef unsigned char __u8; 4 | -------------------------------------------------------------------------------- /neatlibc/linux/vt.h: -------------------------------------------------------------------------------- 1 | #ifndef _LINUX_VT_H 2 | #define _LINUX_VT_H 3 | 4 | #define VT_OPENQRY 0x5600 5 | #define VT_GETMODE 0x5601 6 | #define VT_SETMODE 0x5602 7 | #define VT_GETSTATE 0x5603 8 | #define VT_SENDSIG 0x5604 9 | #define VT_RELDISP 0x5605 10 | #define VT_ACTIVATE 0x5606 11 | #define VT_WAITACTIVE 0x5607 12 | #define VT_DISALLOCATE 0x5608 13 | #define VT_RESIZE 0x5609 14 | #define VT_RESIZEX 0x560A 15 | #define VT_LOCKSWITCH 0x560B 16 | #define VT_UNLOCKSWITCH 0x560C 17 | 18 | #define VT_AUTO 0x00 19 | #define VT_PROCESS 0x01 20 | #define VT_ACKACQ 0x02 21 | 22 | struct vt_mode { 23 | char mode; 24 | char waitv; 25 | short relsig; 26 | short acqsig; 27 | short frsig; 28 | }; 29 | 30 | struct vt_stat { 31 | unsigned short v_active; 32 | unsigned short v_signal; 33 | unsigned short v_state; 34 | }; 35 | 36 | struct vt_sizes { 37 | unsigned short v_rows; 38 | unsigned short v_cols; 39 | unsigned short v_scrollsize; 40 | }; 41 | 42 | struct vt_consize { 43 | unsigned short v_rows; 44 | unsigned short v_cols; 45 | unsigned short v_vlin; 46 | unsigned short v_clin; 47 | unsigned short v_vcol; 48 | unsigned short v_ccol; 49 | }; 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /neatlibc/localtime.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define isleap(y) (!((y) % 4) && ((y) % 100) || !((y) % 400)) 6 | #define SPD (24 * 60 * 60) 7 | 8 | int _tz_is_set; 9 | long timezone; 10 | 11 | void tzset(void) 12 | { 13 | struct timezone tz; 14 | gettimeofday(0, &tz); 15 | timezone = tz.tz_minuteswest * 60; 16 | _tz_is_set = 1; 17 | } 18 | 19 | static void tp2tm(struct tm *tm, time_t t) 20 | { 21 | static int dpm[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 22 | long days = t / SPD; 23 | long rem = t % SPD; 24 | int i; 25 | tm->tm_sec = rem % 60; 26 | rem /= 60; 27 | tm->tm_min = rem % 60; 28 | tm->tm_hour = rem / 60; 29 | tm->tm_wday = (4 + days) % 7; 30 | 31 | /* calculating yday and year */ 32 | for (i = 1970; days >= 365 + isleap(i); i++) 33 | days -= 365 + isleap(i); 34 | tm->tm_year = i - 1900; 35 | tm->tm_yday = days; 36 | 37 | /* calculating mday and mon */ 38 | tm->tm_mday = 1; 39 | if (isleap(i) && days == 59) 40 | tm->tm_mday++; 41 | if (isleap(i) && days >= 59) 42 | days--; 43 | for (i = 0; i < 11 && days >= dpm[i]; i++) 44 | days -= dpm[i]; 45 | tm->tm_mon = i; 46 | tm->tm_mday += days; 47 | } 48 | 49 | struct tm *localtime(time_t *t) 50 | { 51 | static struct tm tm; 52 | tzset(); 53 | tp2tm(&tm, *t - timezone); 54 | return &tm; 55 | } 56 | 57 | struct tm *gmtime(time_t *t) 58 | { 59 | static struct tm tm; 60 | tp2tm(&tm, *t); 61 | return &tm; 62 | } 63 | 64 | time_t mktime(struct tm *tm) 65 | { 66 | static int dpm[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 67 | int d = 0, s = 0; 68 | int i; 69 | s = tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec; 70 | for (i = 70; i < tm->tm_year; i++) 71 | d += 365 + isleap(1900 + i); 72 | tm->tm_yday = tm->tm_mday - 1; 73 | for (i = 0; i < tm->tm_mon; i++) 74 | tm->tm_yday += dpm[i]; 75 | d += tm->tm_yday; 76 | tzset(); 77 | return d * 24 * 3600 + s + timezone; 78 | } 79 | -------------------------------------------------------------------------------- /neatlibc/malloc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define PGSIZE 4096 7 | #define PGMASK (PGSIZE - 1) 8 | #define MSETMAX 4096 9 | #define MSETLEN (1 << 15) 10 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) 11 | 12 | /* placed at the beginning of regions for small allocations */ 13 | struct mset { 14 | int refs; /* number of allocations */ 15 | int size; /* remaining size */ 16 | }; 17 | 18 | /* placed before each small allocation */ 19 | struct mhdr { 20 | int moff; /* mset offset */ 21 | int size; /* allocation size */ 22 | }; 23 | 24 | static struct mset *pool; 25 | 26 | static long heaptop = 0x0000000080000000; /* 2G growing upwards */ 27 | 28 | static int mk_pool(void) 29 | { 30 | if (pool && !pool->refs) { 31 | pool->size = sizeof(*pool); 32 | return 0; 33 | } 34 | #ifdef __APPLE__ 35 | pool = mmap(heaptop, MSETLEN, PROT_READ | PROT_WRITE, 36 | MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 37 | #else 38 | pool = mmap(NULL, MSETLEN, PROT_READ | PROT_WRITE, 39 | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 40 | #endif 41 | if (pool == MAP_FAILED) { 42 | printf("pool malloc %lx, errno %d\n", pool, errno); 43 | pool = NULL; 44 | return 1; 45 | } 46 | heaptop += MSETLEN; 47 | if (heaptop & 0xFFFFFFFF00000000) printf("malloc addr > 32 bits\n"); 48 | pool->size = sizeof(*pool); 49 | pool->refs = 0; 50 | return 0; 51 | } 52 | 53 | void *malloc(long n) 54 | { 55 | void *m; 56 | if (!n) 57 | return NULL; 58 | if (n >= MSETMAX) { 59 | #ifdef __APPLE__ 60 | m = mmap(heaptop, n + PGSIZE, PROT_READ | PROT_WRITE, 61 | MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 62 | #else 63 | m = mmap(NULL, n + PGSIZE, PROT_READ | PROT_WRITE, 64 | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 65 | #endif 66 | if (m == MAP_FAILED) { 67 | printf("mmap malloc %lx, errno %d\n", m, errno); 68 | return NULL; 69 | } 70 | *(long *) m = n + PGSIZE; /* store length in the first page */ 71 | heaptop += (n + PGSIZE + PGSIZE - 1) & ~PGMASK; 72 | if (heaptop & 0xFFFFFFFF00000000) printf("malloc addr > 32 bits\n"); 73 | return m + PGSIZE; 74 | } 75 | if (!pool || pool->size + n + sizeof(struct mhdr) > MSETLEN) 76 | if (mk_pool()) 77 | return NULL; 78 | m = (void *) pool + pool->size; 79 | ((struct mhdr *) m)->moff = pool->size; 80 | ((struct mhdr *) m)->size = n; 81 | pool->refs++; 82 | pool->size += (n + sizeof(struct mhdr) + 7) & ~7; 83 | if (!((unsigned long) (pool + pool->size + sizeof(struct mhdr)) & PGMASK)) 84 | pool->size += sizeof(long); 85 | return m + sizeof(struct mhdr); 86 | } 87 | 88 | static long msize(void *v) 89 | { 90 | if ((unsigned long) v & PGMASK) 91 | return ((struct mhdr *) (v - sizeof(struct mhdr)))->size; 92 | return *(long *) (v - PGSIZE); 93 | } 94 | 95 | void free(void *v) 96 | { 97 | if (!v) 98 | return; 99 | if ((unsigned long) v & PGMASK) { 100 | struct mhdr *mhdr = v - sizeof(struct mhdr); 101 | struct mset *mset = (void *) mhdr - mhdr->moff; 102 | mset->refs--; 103 | if (!mset->refs && mset != pool) 104 | munmap(mset, MSETLEN); 105 | } else { 106 | munmap(v - PGSIZE, *(long *) (v - PGSIZE)); 107 | } 108 | } 109 | 110 | void *calloc(long n, long sz) 111 | { 112 | void *r = malloc(n * sz); 113 | if (r) 114 | memset(r, 0, n * sz); 115 | return r; 116 | } 117 | 118 | void *realloc(void *v, long sz) 119 | { 120 | void *r = malloc(sz); 121 | long osz = msize(v); 122 | /*printf("REALLOC %lx size %ld to %lx size %ld\n", v, osz, r, sz);*/ 123 | if (r && v) { 124 | memcpy(r, v, MIN(osz, sz)); 125 | free(v); 126 | } 127 | return r; 128 | } 129 | -------------------------------------------------------------------------------- /neatlibc/memtst.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define MTHASH(v) ((((long) v) >> 8) & 0xffff) 6 | #define MEMTSTSZ (1 << 18) 7 | #define MTHASHSZ (1 << 16) 8 | #define MTBTLEN 5 9 | 10 | struct memtst { 11 | long *mem; 12 | long n; 13 | long bt[MTBTLEN]; 14 | int freed; 15 | }; 16 | 17 | static struct memtst *memtst; /* memtst records */ 18 | static int memtst_n; /* number of items in memtst[] */ 19 | static int memtst_sz = MEMTSTSZ; 20 | static int *memtst_tail; /* hash table list tails */ 21 | static int *memtst_prev; /* hash table list previous items */ 22 | static int memtst_mcnt, memtst_fcnt; /* malloc() and free() count */ 23 | static long memtst_mmax; /* maximum memory used */ 24 | static long memtst_mcur; /* allocated memory */ 25 | static long memtst_mtot; /* total memory allocated */ 26 | 27 | static int memtst_full(void) 28 | { 29 | return memtst_n == memtst_sz; 30 | } 31 | 32 | static char *memtst_show(long *bt) 33 | { 34 | static char s[100]; 35 | snprintf(s, sizeof(s), "%8p %8p %8p %8p %8p", 36 | bt[0], bt[1], bt[2], bt[3], bt[4]); 37 | return s; 38 | } 39 | 40 | static void memtst_summary(void) 41 | { 42 | int i; 43 | fprintf(stderr, "memtst %d %d %ld", memtst_mcnt, memtst_fcnt, memtst_mtot); 44 | if (memtst_full()) { 45 | fprintf(stderr, "\nmemtst: increase MEMTSTSZ\n"); 46 | return; 47 | } 48 | fprintf(stderr, " %ld\n", memtst_mmax); 49 | for (i = 0; i < memtst_n; i++) { 50 | struct memtst *mt = &memtst[i]; 51 | if (!mt->freed) 52 | fprintf(stderr, "memtstleak %8p %8ld %s\n", 53 | mt->mem, mt->n, memtst_show(mt->bt)); 54 | } 55 | } 56 | 57 | static void memtst_init(void) 58 | { 59 | memtst = malloc(memtst_sz * sizeof(memtst[0])); 60 | memtst_prev = malloc(memtst_sz * sizeof(memtst_prev[0])); 61 | memtst_tail = malloc(MTHASHSZ * sizeof(memtst_tail[0])); 62 | memset(memtst_tail, 0xff, MTHASHSZ * sizeof(memtst_tail[0])); 63 | atexit(memtst_summary); 64 | } 65 | 66 | static void memtst_put(void *mem, int n, long *bt) 67 | { 68 | struct memtst *mt; 69 | if (!memtst) 70 | memtst_init(); 71 | if (memtst_full()) 72 | return; 73 | mt = &memtst[memtst_n]; 74 | mt->mem = mem; 75 | mt->n = n; 76 | memcpy(mt->bt, bt, sizeof(mt->bt)); 77 | memtst_prev[memtst_n] = memtst_tail[MTHASH(mem)]; 78 | memtst_tail[MTHASH(mem)] = memtst_n; 79 | memtst_n++; 80 | } 81 | 82 | static struct memtst *memtst_get(void *mem) 83 | { 84 | int idx; 85 | if (!memtst) 86 | return NULL; 87 | idx = memtst_tail[MTHASH(mem)]; 88 | while (idx >= 0) { 89 | struct memtst *mt = &memtst[idx]; 90 | if (!mt->freed && mt->mem == mem) 91 | return mt; 92 | idx = memtst_prev[idx]; 93 | } 94 | return NULL; 95 | } 96 | 97 | long memtst_back(int n); 98 | 99 | static void memtst_bt(long *bt) 100 | { 101 | bt[0] = memtst_back(1); 102 | bt[1] = memtst_back(2); 103 | bt[2] = memtst_back(3); 104 | bt[3] = memtst_back(4); 105 | bt[4] = memtst_back(5); 106 | } 107 | 108 | static void memtst_mcheck(void *v, long n, long *bt) 109 | { 110 | if (!v) 111 | fprintf(stderr, "memtstfail %8ld %s\n", n, memtst_show(bt)); 112 | else 113 | memtst_put(v, n, bt); 114 | if (v) { 115 | memtst_mcnt++; 116 | memtst_mcur += n; 117 | memtst_mtot += n; 118 | } 119 | if (memtst_mcur > memtst_mmax) 120 | memtst_mmax = memtst_mcur; 121 | } 122 | 123 | void *memtst_malloc(long n) 124 | { 125 | void *v = malloc(n); 126 | long bt[MTBTLEN]; 127 | memtst_bt(bt); 128 | memtst_mcheck(v, n, bt); 129 | return v; 130 | } 131 | 132 | static void memtst_fcheck(void *v, long *bt) 133 | { 134 | struct memtst *mt; 135 | memtst_fcnt++; 136 | mt = memtst_get(v); 137 | if (!mt && !memtst_full()) { 138 | fprintf(stderr, "memtstfree %8p %s\n", v, memtst_show(bt)); 139 | return; 140 | } 141 | if (mt) 142 | memtst_mcur -= mt->n; 143 | if (mt) 144 | mt->freed = 1; 145 | } 146 | 147 | void memtst_free(void *v) 148 | { 149 | long bt[MTBTLEN]; 150 | if (v) { 151 | memtst_bt(bt); 152 | memtst_fcheck(v, bt); 153 | free(v); 154 | } 155 | } 156 | 157 | void *memtst_calloc(long n, long sz) 158 | { 159 | void *r = calloc(n, sz); 160 | long bt[MTBTLEN]; 161 | memtst_bt(bt); 162 | memtst_mcheck(r, n * sz, bt); 163 | return r; 164 | } 165 | 166 | void *memtst_realloc(void *v, long sz) 167 | { 168 | void *r = realloc(v, sz); 169 | long bt[MTBTLEN]; 170 | memtst_bt(bt); 171 | memtst_mcheck(r, sz, bt); 172 | if (v) 173 | memtst_fcheck(v, bt); 174 | return r; 175 | } 176 | -------------------------------------------------------------------------------- /neatlibc/mkstemp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static int tmpid; 6 | static char *digs = "0123456789abcdef"; 7 | 8 | int mkstemp(char *t) 9 | { 10 | char *x = t + strlen(t) - 6; 11 | int fd; 12 | int i; 13 | if (strlen(t) < 6) 14 | return -1; 15 | for (i = 0; i < 6; i++) 16 | x[i] = '0'; 17 | while ((fd = open(t, O_RDWR | O_EXCL | O_CREAT, 0600)) == -1) { 18 | int n = ++tmpid; 19 | for (i = 0; i < 6; i++) { 20 | x[5 - i] = digs[n & 0x0f]; 21 | n <<= 4; 22 | } 23 | } 24 | unlink(t); 25 | return fd; 26 | } 27 | -------------------------------------------------------------------------------- /neatlibc/poll.h: -------------------------------------------------------------------------------- 1 | #define POLLIN 0x0001 2 | #define POLLPRI 0x0002 3 | #define POLLOUT 0x0004 4 | #define POLLERR 0x0008 5 | #define POLLHUP 0x0010 6 | #define POLLNVAL 0x0020 7 | #define POLLRDNORM 0x0040 8 | #define POLLRDBAND 0x0080 9 | #define POLLWRBAND 0x0200 10 | #define POLLMSG 0x0400 11 | #define POLLREMOVE 0x1000 12 | 13 | struct pollfd { 14 | int fd; 15 | short events; 16 | short revents; 17 | }; 18 | 19 | typedef unsigned int nfds_t; 20 | 21 | extern int poll(struct pollfd *ufds, nfds_t nfds, int timeout); 22 | -------------------------------------------------------------------------------- /neatlibc/pwd.h: -------------------------------------------------------------------------------- 1 | #define endpwent() /* FIXME not implemented */ 2 | #define endgrent() /* FIXME not implemented */ 3 | -------------------------------------------------------------------------------- /neatlibc/qsort.c: -------------------------------------------------------------------------------- 1 | /* based on musl libc's qsort.c */ 2 | #include 3 | #include 4 | 5 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) 6 | 7 | static void swap(char *a, char *b, int sz) 8 | { 9 | char tmp[256]; 10 | while (sz) { 11 | int l = MIN(sizeof(tmp), sz); 12 | memcpy(tmp, a, l); 13 | memcpy(a, b, l); 14 | memcpy(b, tmp, l); 15 | a += l; 16 | b += l; 17 | sz -= l; 18 | } 19 | } 20 | 21 | static void fix(char *a, int root, int n, int sz, int (*cmp)(void *, void *)) 22 | { 23 | while (2 * root <= n) { 24 | int max = 2 * root; 25 | if (max < n && cmp(a + max * sz, a + (max + 1) * sz) < 0) 26 | max++; 27 | if (max && cmp(a + root * sz, a + max * sz) < 0) { 28 | swap(a + root * sz, a + max * sz, sz); 29 | root = max; 30 | } else { 31 | break; 32 | } 33 | } 34 | } 35 | 36 | void qsort(void *a, int n, int sz, int (*cmp)(void *, void *)) 37 | { 38 | int i; 39 | 40 | if (!n) 41 | return; 42 | for (i = (n + 1) >> 1; i; i--) 43 | fix(a, i - 1, n - 1, sz, cmp); 44 | for (i = n - 1; i; i--) { 45 | swap(a, a + i * sz, sz); 46 | fix(a, 0, i - 1, sz, cmp); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /neatlibc/rand.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | static unsigned r; 4 | 5 | void srand(unsigned int seed) 6 | { 7 | r = seed; 8 | } 9 | 10 | int rand(void) 11 | { 12 | r = r * 1103515245 + 12345; 13 | return r & 0x7fffffff; 14 | } 15 | -------------------------------------------------------------------------------- /neatlibc/regex.h: -------------------------------------------------------------------------------- 1 | #define REG_EXTENDED 0x01 2 | #define REG_NOSUB 0x02 3 | #define REG_ICASE 0x04 4 | #define REG_NEWLINE 0x08 5 | #define REG_NOTBOL 0x10 6 | #define REG_NOTEOL 0x20 7 | 8 | typedef struct { 9 | long rm_so; 10 | long rm_eo; 11 | } regmatch_t; 12 | 13 | typedef struct regex *regex_t; 14 | 15 | int regcomp(regex_t *preg, char *regex, int cflags); 16 | int regexec(regex_t *preg, char *str, int nmatch, regmatch_t pmatch[], int eflags); 17 | int regerror(int errcode, regex_t *preg, char *errbuf, int errbuf_size); 18 | void regfree(regex_t *preg); 19 | -------------------------------------------------------------------------------- /neatlibc/scanf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | static int ic(FILE *fp) 8 | { 9 | int nr; 10 | if (fp->back != EOF) { 11 | int i = fp->back; 12 | fp->back = EOF; 13 | return i; 14 | } 15 | while (fp->fd >= 0 && fp->icur == fp->ilen) { 16 | int nr = read(fp->fd, fp->ibuf, fp->isize); 17 | if (nr <= 0) 18 | break; 19 | fp->ilen = nr; 20 | fp->icur = 0; 21 | } 22 | return fp->icur < fp->ilen ? (unsigned char) fp->ibuf[fp->icur++] : EOF; 23 | } 24 | 25 | void setbuf(FILE *fp, char *buf) 26 | { 27 | } 28 | 29 | int fgetc(FILE *fp) 30 | { 31 | return ic(fp); 32 | } 33 | 34 | int getchar(void) 35 | { 36 | return ic(stdin); 37 | } 38 | 39 | int ungetc(int c, FILE *fp) 40 | { 41 | if (fp->back == EOF) 42 | fp->back = c; 43 | return fp->back; 44 | } 45 | 46 | /* t is 1 for char, 2 for short, 4 for int, and 8 for long */ 47 | static int iint(FILE *fp, void *dst, int t, int wid) 48 | { 49 | long n = 0; 50 | int c; 51 | int neg = 0; 52 | c = ic(fp); 53 | if (c == '-') 54 | neg = 1; 55 | if ((c == '-' || c == '+') && wid-- > 0) 56 | c = ic(fp); 57 | if (!isdigit(c) || wid <= 0) { 58 | ungetc(c, fp); 59 | return 1; 60 | } 61 | do { 62 | n = n * 10 + c - '0'; 63 | } while (isdigit(c = ic(fp)) && --wid > 0); 64 | ungetc(c, fp); 65 | if (t == 8) 66 | *(long *) dst = neg ? -n : n; 67 | else if (t == 4) 68 | *(int *) dst = neg ? -n : n; 69 | else if (t == 2) 70 | *(short *) dst = neg ? -n : n; 71 | else 72 | *(char *) dst = neg ? -n : n; 73 | return 0; 74 | } 75 | 76 | static int istr(FILE *fp, char *dst, int wid) 77 | { 78 | char *d = dst; 79 | int c; 80 | while ((c = ic(fp)) != EOF && wid-- > 0 && !isspace(c)) 81 | *d++ = c; 82 | *d = '\0'; 83 | ungetc(c, fp); 84 | return d == dst; 85 | } 86 | 87 | int vfscanf(FILE *fp, char *fmt, va_list ap) 88 | { 89 | int ret = 0; 90 | int t, c; 91 | int wid = 1 << 20; 92 | while (*fmt) { 93 | while (isspace((unsigned char) *fmt)) 94 | fmt++; 95 | while (isspace(c = ic(fp))) 96 | ; 97 | ungetc(c, fp); 98 | while (*fmt && *fmt != '%' && !isspace((unsigned char) *fmt)) 99 | if (*fmt++ != ic(fp)) 100 | return ret; 101 | if (*fmt != '%') 102 | continue; 103 | fmt++; 104 | if (isdigit((unsigned char) *fmt)) { 105 | wid = 0; 106 | while (isdigit((unsigned char) *fmt)) 107 | wid = wid * 10 + *fmt++ - '0'; 108 | } 109 | t = sizeof(int); 110 | while (*fmt == 'l') { 111 | t = sizeof(long); 112 | fmt++; 113 | } 114 | while (*fmt == 'h') { 115 | t = t < sizeof(int) ? sizeof(char) : sizeof(short); 116 | fmt++; 117 | } 118 | switch (*fmt++) { 119 | case 'u': 120 | case 'd': 121 | if (iint(fp, va_arg(ap, long *), t, wid)) 122 | return ret; 123 | ret++; 124 | break; 125 | case 's': 126 | if (istr(fp, va_arg(ap, char *), wid)) 127 | return ret; 128 | ret++; 129 | break; 130 | } 131 | } 132 | return ret; 133 | } 134 | 135 | int fscanf(FILE *fp, char *fmt, ...) 136 | { 137 | va_list ap; 138 | int ret; 139 | va_start(ap, fmt); 140 | ret = vfscanf(fp, fmt, ap); 141 | va_end(ap); 142 | return ret; 143 | } 144 | 145 | int scanf(char *fmt, ...) 146 | { 147 | va_list ap; 148 | int ret; 149 | va_start(ap, fmt); 150 | ret = vfscanf(stdin, fmt, ap); 151 | va_end(ap); 152 | return ret; 153 | } 154 | 155 | int vsscanf(char *s, char *fmt, va_list ap) 156 | { 157 | FILE f = {-1, EOF}; 158 | f.ibuf = s; 159 | f.ilen = strlen(s); 160 | return vfscanf(&f, fmt, ap); 161 | } 162 | 163 | int sscanf(char *s, char *fmt, ...) 164 | { 165 | va_list ap; 166 | int ret; 167 | va_start(ap, fmt); 168 | ret = vsscanf(s, fmt, ap); 169 | va_end(ap); 170 | return ret; 171 | } 172 | 173 | char *fgets(char *s, int sz, FILE *fp) 174 | { 175 | int i = 0; 176 | int c; 177 | while (i + 1 < sz && (c = ic(fp)) != EOF) { 178 | s[i++] = c; 179 | if (c == '\n') 180 | break; 181 | } 182 | s[i] = '\0'; 183 | return i ? s : NULL; 184 | } 185 | 186 | long fread(void *v, long sz, long n, FILE *fp) 187 | { 188 | char *s = v; 189 | int i = n * sz; 190 | while (i-- > 0) 191 | if ((*s++ = ic(fp)) == EOF) 192 | return n * sz - i - 1; 193 | return n * sz; 194 | } 195 | -------------------------------------------------------------------------------- /neatlibc/setjmp.h: -------------------------------------------------------------------------------- 1 | typedef long jmp_buf[8]; 2 | 3 | int setjmp(jmp_buf env); 4 | void longjmp(jmp_buf env, int val); 5 | -------------------------------------------------------------------------------- /neatlibc/signal.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define SIG_BLOCK 0 4 | #define SIG_UNBLOCK 1 5 | #define SIG_SETMASK 2 6 | 7 | #define SA_NOCLDSTOP 1 8 | #define SA_NOCLDWAIT 2 9 | #define SA_SIGINFO 4 10 | #define SA_ONSTACK 0x08000000 11 | #define SA_RESTART 0x10000000 12 | #define SA_NODEFER 0x40000000 13 | #define SA_RESETHAND 0x80000000 14 | #define SA_RESTORER 0x04000000 15 | 16 | struct sigset_t { 17 | unsigned long __bits[128 / sizeof(long)]; 18 | }; 19 | typedef struct sigset_t sigset_t; 20 | 21 | struct sigaction { 22 | void (*sa_handler)(int); 23 | sigset_t sa_mask; 24 | int sa_flags; 25 | void (*sa_restorer)(void); 26 | }; 27 | 28 | int sigreturn(unsigned long n); 29 | 30 | struct ksa { 31 | void *handler; 32 | unsigned long flags; 33 | int (*restorer)(unsigned long n); 34 | sigset_t mask; 35 | }; 36 | 37 | int __sigaction(int sig, const struct sigaction *sa, struct sigaction *old) 38 | { 39 | struct ksa ksa, _ksa; 40 | if (sa) { 41 | ksa.handler = sa->sa_handler; 42 | ksa.flags = sa->sa_flags | SA_RESTORER; 43 | ksa.restorer = sigreturn; 44 | ksa.mask = sa->sa_mask; 45 | } 46 | if (sigaction(sig, sa ? (long) &ksa : 0, old ? (long) &_ksa : 0, 8)) 47 | return -1; 48 | if (old) { 49 | old->sa_handler = _ksa.handler; 50 | old->sa_flags = _ksa.flags; 51 | old->sa_mask = _ksa.mask; 52 | } 53 | return 0; 54 | } 55 | 56 | int sigaction(int sig, struct sigaction *sa, struct sigaction *old_sa); 57 | 58 | sighandler_t signal(int sig, sighandler_t func) 59 | { 60 | struct sigaction sa = {.sa_handler = func, .sa_flags = SA_RESTART}; 61 | if (__sigaction(sig, &sa, &sa) < 0) 62 | return SIG_ERR; 63 | return sa.sa_handler; 64 | } 65 | -------------------------------------------------------------------------------- /neatlibc/signal.h: -------------------------------------------------------------------------------- 1 | #define NSIG 32 2 | 3 | #define SIGHUP 1 4 | #define SIGINT 2 5 | #define SIGQUIT 3 6 | #define SIGILL 4 7 | #define SIGTRAP 5 8 | #define SIGABRT 6 9 | #define SIGIOT 6 10 | #define SIGFPE 8 11 | #define SIGKILL 9 12 | #define SIGSEGV 11 13 | #define SIGPIPE 13 14 | #define SIGALRM 14 15 | #define SIGTERM 15 16 | #define SIGUNUSED 31 17 | #define SIGBUS 7 18 | #define SIGUSR1 10 19 | #define SIGUSR2 12 20 | #define SIGSTKFLT 16 21 | #define SIGCHLD 17 22 | #define SIGCONT 18 23 | #define SIGSTOP 19 24 | #define SIGTSTP 20 25 | #define SIGTTIN 21 26 | #define SIGTTOU 22 27 | #define SIGURG 23 28 | #define SIGXCPU 24 29 | #define SIGXFSZ 25 30 | #define SIGVTALRM 26 31 | #define SIGPROF 27 32 | #define SIGWINCH 28 33 | #define SIGIO 29 34 | #define SIGPWR 30 35 | #define SIGSYS 31 36 | 37 | #define SIGCLD SIGCHLD 38 | #define SIGPOLL SIGIO 39 | 40 | typedef void (*sighandler_t)(int); 41 | 42 | #define SIG_ERR ((void (*)(int)) -1) 43 | #define SIG_DFL ((void (*)(int)) 0) 44 | #define SIG_IGN ((void (*)(int)) 1) 45 | #define SIG_HOLD ((void (*)(int)) 2) 46 | 47 | sighandler_t signal(int signum, sighandler_t action); 48 | int kill(int pid, int sig); 49 | int raise(int sig); 50 | -------------------------------------------------------------------------------- /neatlibc/stdarg.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) 4 | 5 | void *__va_arg(void **ap, int size) 6 | { 7 | void *ret = *ap; 8 | *ap += ALIGN(size, sizeof(long)); 9 | return ret; 10 | } 11 | -------------------------------------------------------------------------------- /neatlibc/stdarg.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDARG_H 2 | #define _STDARG_H 3 | 4 | typedef void *va_list; 5 | 6 | void *__va_arg(void **ap, int size); 7 | 8 | #define va_start(ap, last) ((ap) = ((void *) &(last)) + sizeof(long)) 9 | #define va_arg(ap, type) (*(type *) __va_arg(&(ap), sizeof(type))) 10 | #define va_end(ap) ((ap) = (void *) 0) 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /neatlibc/stddef.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDDEF_H 2 | #define _STDDEF_H 3 | 4 | #define NULL ((void *) 0) 5 | #define offsetof(type, field) ((int) (&((type *) 0)->field)) 6 | 7 | typedef unsigned long size_t; 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /neatlibc/stdint.h: -------------------------------------------------------------------------------- 1 | #ifndef _INTTYPES_H 2 | #define _INTTYPES_H 3 | 4 | typedef char int8_t; 5 | typedef short int16_t; 6 | typedef int int32_t; 7 | typedef unsigned char uint8_t; 8 | typedef unsigned short uint16_t; 9 | typedef unsigned int uint32_t; 10 | 11 | #ifdef __x86_64__ 12 | typedef unsigned long uint64_t; 13 | typedef long int64_t; 14 | #else 15 | typedef unsigned long long uint64_t; 16 | typedef long long int64_t; 17 | #endif 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /neatlibc/stdio.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define EOF (-1) 4 | #define putc(c, fp) (fputc(c, fp)) 5 | #define getc(fp) (fgetc(fp)) 6 | #define BUFSIZ (1024) 7 | 8 | typedef struct { 9 | int fd; 10 | int back; /* pushback buffer */ 11 | char *ibuf, *obuf; /* input/output buffer */ 12 | int isize, osize; /* ibuf size */ 13 | int ilen, olen; /* length of data in buf */ 14 | int iown, oown; /* free the buffer when finished */ 15 | int icur; /* current position in ibuf */ 16 | int ostat; 17 | } FILE; 18 | 19 | extern FILE *stdin; 20 | extern FILE *stdout; 21 | extern FILE *stderr; 22 | 23 | #define ferror(fp) (0) /* NYI */ 24 | #define feof(fp) (0) /* NYI */ 25 | #define clearerr(fp) (0) /* NYI */ 26 | #define fileno(fp) ((fp)->fd) 27 | 28 | FILE *fopen(char *path, char *mode); 29 | int fclose(FILE *fp); 30 | int fflush(FILE *fp); 31 | void setbuf(FILE *fp, char *buf); 32 | 33 | int fputc(int c, FILE *fp); 34 | int putchar(int c); 35 | int printf(char *fmt, ...); 36 | int vprintf(char *fmt, va_list ap); 37 | int fprintf(FILE *fp, char *fmt, ...); 38 | int sprintf(char *dst, char *fmt, ...); 39 | int vsprintf(char *dst, char *fmt, va_list ap); 40 | int vfprintf(FILE *fp, char *fmt, va_list ap); 41 | int snprintf(char *dst, int sz, char *fmt, ...); 42 | int vsnprintf(char *dst, int sz, char *fmt, va_list ap); 43 | int fputs(char *s, FILE *fp); 44 | int puts(char *s); 45 | 46 | int fgetc(FILE *fp); 47 | char *fgets(char *s, int sz, FILE *fp); 48 | int scanf(char *fmt, ...); 49 | int fscanf(FILE *fp, char *fmt, ...); 50 | int sscanf(char *s, char *fmt, ...); 51 | int vsscanf(char *s, char *fmt, va_list ap); 52 | int vfscanf(FILE *fp, char *fmt, va_list ap); 53 | int getchar(void); 54 | int ungetc(int c, FILE *fp); 55 | long fwrite(void *s, long sz, long n, FILE *fp); 56 | long fread(void *s, long sz, long n, FILE *fp); 57 | 58 | void perror(char *s); 59 | 60 | int rename(char *old, char *new); 61 | -------------------------------------------------------------------------------- /neatlibc/stdlib.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define ATEXIT_MAX 32 8 | 9 | int abs(int n) 10 | { 11 | return n >= 0 ? n : -n; 12 | } 13 | 14 | long labs(long n) 15 | { 16 | return n >= 0 ? n : -n; 17 | } 18 | 19 | char *getenv(char *name) 20 | { 21 | char **p = environ; 22 | int len = strlen(name); 23 | for (; *p; p++) 24 | if (!memcmp(name, *p, len) && (*p)[len] == '=') 25 | return *p + len + 1; 26 | return NULL; 27 | } 28 | 29 | int system(char *cmd) 30 | { 31 | char *argv[] = {"/bin/sh", "-c", cmd, NULL}; 32 | pid_t pid; 33 | int ret; 34 | pid = fork(); 35 | if (pid < 0) 36 | return -1; 37 | if (!pid) { 38 | execv(argv[0], argv); 39 | exit(1); 40 | } 41 | if (waitpid(pid, &ret, 0) != pid) 42 | return -1; 43 | return ret; 44 | } 45 | 46 | static void (*atexit_func[ATEXIT_MAX])(void); 47 | static int atexit_cnt; 48 | 49 | int atexit(void (*func)(void)) 50 | { 51 | if (atexit_cnt >= ATEXIT_MAX) 52 | return -1; 53 | atexit_func[atexit_cnt++] = func; 54 | return 0; 55 | } 56 | 57 | void __neatlibc_exit(void) 58 | { 59 | int i; 60 | for (i = 0; i < atexit_cnt; i++) 61 | atexit_func[i](); 62 | } 63 | 64 | void exit(int status) 65 | { 66 | __neatlibc_exit(); 67 | _exit(status); 68 | } 69 | -------------------------------------------------------------------------------- /neatlibc/stdlib.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define RAND_MAX 0x7fffffff 4 | 5 | void *malloc(long n); 6 | void free(void *m); 7 | void *calloc(long n, long sz); 8 | void *realloc(void *v, long sz); 9 | 10 | int atoi(char *s); 11 | long atol(char *s); 12 | long strtol(const char *s, char **endptr, int base); 13 | unsigned long strtoul(const char *s, char **endptr, int base); 14 | int abs(int n); 15 | long labs(long n); 16 | 17 | void exit(int status); 18 | void abort(void); 19 | int atexit(void (*func)(void)); 20 | 21 | char *getenv(char *name); 22 | void qsort(void *a, int n, int sz, int (*cmp)(void *, void *)); 23 | int mkstemp(char *t); 24 | int system(char *cmd); 25 | 26 | void srand(unsigned int seed); 27 | int rand(void); 28 | 29 | /* for examining heap memory allocation */ 30 | #ifdef MEMTST 31 | void *memtst_malloc(long n); 32 | void memtst_free(void *v); 33 | void *memtst_calloc(long n, long sz); 34 | void *memtst_realloc(void *v, long sz); 35 | #define malloc memtst_malloc 36 | #define free memtst_free 37 | #define calloc memtst_calloc 38 | #define realloc memtst_realloc 39 | #endif 40 | -------------------------------------------------------------------------------- /neatlibc/strftime.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | static char *wday_ab[] = { 7 | "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 8 | }; 9 | static char *wday[] = { 10 | "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" 11 | }; 12 | static char *mon_ab[] = { 13 | "Jan", "Feb", "Mar", "Apr", "May", "Jun", 14 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 15 | }; 16 | static char *mon[] = { 17 | "January", "February", "March", "April", "May", "June", 18 | "July", "August", "September", "October", "November", "December" 19 | }; 20 | 21 | static char *putstr(char *d, char *s) 22 | { 23 | while (*s) 24 | *d++ = *s++; 25 | return d; 26 | } 27 | 28 | static char *puti(char *s, unsigned long n, int wid, int zpad) 29 | { 30 | int i; 31 | for (i = wid - 1; i >= 0; i--) { 32 | if (!n) { 33 | if (!zpad && i < wid - 1) 34 | s[i] = ' '; 35 | else 36 | s[i] = '0'; 37 | } else { 38 | s[i] = '0' + n % 10; 39 | n /= 10; 40 | } 41 | } 42 | return s + wid; 43 | } 44 | 45 | static char *puttz(char *s) 46 | { 47 | int d = timezone / 60; 48 | if (d < 0) { 49 | *s++ = '+'; 50 | d = -d; 51 | } else { 52 | *s++ = '-'; 53 | } 54 | s = puti(s, d / 60, 2, 1); 55 | s = puti(s, d % 60, 2, 1); 56 | return s; 57 | } 58 | 59 | long strftime(char *s, long n, char *f, struct tm *tm) 60 | { 61 | int val; 62 | char *beg = s; 63 | char *e = s + n; 64 | while (s + 1 < e && *f) { 65 | int c = *f++; 66 | if (c != '%') { 67 | *s++ = c; 68 | continue; 69 | } 70 | c = *f++; 71 | switch (c) { 72 | case '%': 73 | *s++ = '%'; 74 | break; 75 | case 'a': 76 | s = putstr(s, wday_ab[tm->tm_wday]); 77 | break; 78 | case 'A': 79 | s = putstr(s, wday[tm->tm_wday]); 80 | break; 81 | case 'b': 82 | case 'h': 83 | s = putstr(s, mon_ab[tm->tm_mon]); 84 | break; 85 | case 'B': 86 | s = putstr(s, mon[tm->tm_mon]); 87 | break; 88 | case 'c': 89 | s += strftime(s, e - s, "%b %a %d %k:%M:%S %Z %Y", tm); 90 | break; 91 | case 'C': 92 | s = puti(s, (1900 + tm->tm_year) / 100, 2, 1); 93 | break; 94 | case 'd': 95 | s = puti(s, tm->tm_mday, 2, 1); 96 | break; 97 | case 'D': 98 | s += strftime(s, e - s, "%m/%d/%y", tm); 99 | break; 100 | case 'e': 101 | s = puti(s, tm->tm_mday, 2, 0); 102 | break; 103 | case 'F': 104 | s += strftime(s, e - s, "%Y/%m/%d", tm); 105 | break; 106 | case 'H': 107 | s = puti(s, tm->tm_hour, 2, 1); 108 | break; 109 | case 'I': 110 | val = tm->tm_hour > 12 ? tm->tm_hour - 12 : tm->tm_hour; 111 | s = puti(s, val ? val : 12, 2, 1); 112 | break; 113 | case 'j': 114 | s = puti(s, tm->tm_yday + 1, 3, 1); 115 | break; 116 | case 'k': 117 | s = puti(s, tm->tm_hour, 2, 1); 118 | break; 119 | case 'm': 120 | s = puti(s, tm->tm_mon + 1, 2, 1); 121 | break; 122 | case 'M': 123 | s = puti(s, tm->tm_min, 2, 1); 124 | break; 125 | case 'n': 126 | *s++ = '\n'; 127 | break; 128 | case 'p': 129 | s = putstr(s, tm->tm_hour >= 12 ? "PM" : "AM"); 130 | break; 131 | case 'P': 132 | s = putstr(s, tm->tm_hour >= 12 ? "pm" : "am"); 133 | break; 134 | case 'r': 135 | s += strftime(s, e - s, "%I:%M:%S %p", tm); 136 | break; 137 | case 'R': 138 | s += strftime(s, e - s, "%H:%M", tm); 139 | break; 140 | case 'S': 141 | s = puti(s, tm->tm_sec, 2, 1); 142 | break; 143 | case 't': 144 | *s++ = '\t'; 145 | break; 146 | case 'T': 147 | s += strftime(s, e - s, "%H:%M:%S", tm); 148 | break; 149 | case 'u': 150 | s = puti(s, tm->tm_wday ? tm->tm_wday : 7, 1, 0); 151 | break; 152 | case 'w': 153 | s = puti(s, tm->tm_wday, 1, 0); 154 | break; 155 | case 'x': 156 | s += strftime(s, e - s, "%b %a %d", tm); 157 | break; 158 | case 'X': 159 | s += strftime(s, e - s, "%k:%M:%S", tm); 160 | break; 161 | case 'y': 162 | s = puti(s, tm->tm_year % 100, 2, 1); 163 | break; 164 | case 'Y': 165 | s = puti(s, 1900 + tm->tm_year, 4, 1); 166 | break; 167 | case 'z': 168 | s = puttz(s); 169 | break; 170 | default: 171 | break; 172 | } 173 | } 174 | *s = '\0'; 175 | return s - beg; 176 | } 177 | -------------------------------------------------------------------------------- /neatlibc/string.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LONG01 (0x01010101ul | (0x01010101ul << (sizeof(long) * 8 - 32))) 4 | #define LONG80 (0x80808080ul | (0x80808080ul << (sizeof(long) * 8 - 32))) 5 | #define LONGOFF(s) ((unsigned long) s & (sizeof(long) - 1)) 6 | #define HASZERO(x) (((x) - LONG01) & ~(x) & LONG80) 7 | 8 | void *__memchr_c(void *src, int c, long n) 9 | { 10 | unsigned char *s = src; 11 | c = (unsigned char) c; 12 | unsigned long k = LONG01 * c; 13 | while (LONGOFF(s) && n && *s != c) 14 | s++, n--; 15 | if (n && *s != c) { 16 | unsigned long *w = (void *) s; 17 | while (n >= sizeof(long) && !HASZERO(*w ^ k)) 18 | w++, n -= sizeof(long); 19 | s = (void *) w; 20 | } 21 | while (n && *s != c) 22 | s++, n--; 23 | return n ? (void *) s : 0; 24 | } 25 | 26 | /* based on musl libc */ 27 | char *strncat(char *d, char *s, size_t n) 28 | { 29 | char *a = d; 30 | d += strlen(d); 31 | while (n && *s) { 32 | n--; 33 | *d++ = *s++; 34 | } 35 | *d++ = 0; 36 | return a; 37 | } 38 | -------------------------------------------------------------------------------- /neatlibc/string.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void *memcpy(void *dst, void *src, long n); 4 | void *memmove(void *dst, void *src, long n); 5 | void *memset(void *s, int v, long n); 6 | void *memchr(void *s, int c, long n); 7 | void *memrchr(void *s, int c, long n); 8 | int memcmp(char *s1, char *s2, long n); 9 | 10 | char *strcpy(char *dst, char *src); 11 | char *strchr(char *s, int c); 12 | char *strrchr(char *s, int c); 13 | long strlen(char *s); 14 | int strcmp(char *s1, char *s2); 15 | 16 | char *strncpy(char *d, char *s, long n); 17 | char *strcat(char *d, char *s); 18 | int strncmp(char *d, char *s, long n); 19 | char *strstr(char *s, char *r); 20 | 21 | char *strdup(const char *s); 22 | 23 | /* faster implementations */ 24 | #define memchr(s, c, n) __memchr_c(s, c, n) 25 | 26 | void *__memchr_c(void *s, int c, long n); 27 | 28 | /* C versions */ 29 | char *strncat(char *d, char *s, size_t n); 30 | -------------------------------------------------------------------------------- /neatlibc/stringc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char *strncpy(char *d, char *s, long n) 5 | { 6 | int len = strlen(s); 7 | if (len > n) 8 | len = n; 9 | memcpy(d, s, len); 10 | memset(d + len, 0, n - len); 11 | return d; 12 | } 13 | 14 | char *strcat(char *d, char *s) 15 | { 16 | strcpy(d + strlen(d), s); 17 | return d; 18 | } 19 | 20 | char *strstr(char *s, char *r) 21 | { 22 | int len = strlen(r); 23 | if (!len) 24 | return s; 25 | while (s) { 26 | if (!memcmp(s, r, len)) 27 | return s; 28 | s = strchr(s + 1, *r); 29 | } 30 | return NULL; 31 | } 32 | 33 | char *strdup(const char *s) 34 | { 35 | size_t n = strlen(s) + 1; 36 | char *res = malloc(n); 37 | if (res) 38 | memcpy(res, s, n); 39 | return res; 40 | } 41 | -------------------------------------------------------------------------------- /neatlibc/sys/ioctl.h: -------------------------------------------------------------------------------- 1 | 2 | #ifdef __APPLE__ 3 | /* sys/ioccom.h */ 4 | #define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */ 5 | #define IOC_VOID 0x20000000 6 | #define IOC_OUT 0x40000000 /* copy parameters out */ 7 | #define IOC_IN 0x80000000 /* copy parameters in */ 8 | #define IOC_INOUT (IOC_IN|IOC_OUT)/* copy paramters in and out */ 9 | #define _IOC(inout, group, num, len) \ 10 | (inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num)) 11 | #define _IO(g, n) _IOC(IOC_VOID, (g), (n), 0) 12 | #define _IOR(g, n, t) _IOC(IOC_OUT, (g), (n), sizeof(t)) 13 | #define _IOW(g, n, t) _IOC(IOC_IN, (g), (n), sizeof(t)) 14 | #define _IOWR(g, n, t) _IOC(IOC_INOUT, (g), (n), sizeof(t)) 15 | 16 | /* sys/ttycom.h */ 17 | #define TIOCGETA _IOR('t', 19, struct termios) /* get termios struct */ 18 | #define TIOCSETA _IOW('t', 20, struct termios) /* set termios struct */ 19 | #define TIOCSETAW _IOW('t', 21, struct termios) /* drain output, set */ 20 | #define TIOCSETAF _IOW('t', 22, struct termios) /* drn out, fls in, set */ 21 | 22 | /* compatibility defines */ 23 | #define TCGETS TIOCGETA 24 | #define TCSETS TIOCSETA 25 | #define TCSETSW TIOCSETAW 26 | #define TCSETSF TIOCSETAF 27 | 28 | #else 29 | 30 | #define TCGETS 0x5401 31 | #define TCSETS 0x5402 32 | #define TCSETSW 0x5403 33 | #define TCSETSF 0x5404 34 | #define TCGETA 0x5405 35 | #define TCSETA 0x5406 36 | #define TCSETAW 0x5407 37 | #define TCSETAF 0x5408 38 | #define TCSBRK 0x5409 39 | #define TCXONC 0x540A 40 | #define TCFLSH 0x540B 41 | #define TIOCEXCL 0x540C 42 | #define TIOCNXCL 0x540D 43 | #define TIOCSCTTY 0x540E 44 | #define TIOCGPGRP 0x540F 45 | #define TIOCSPGRP 0x5410 46 | #define TIOCOUTQ 0x5411 47 | #define TIOCSTI 0x5412 48 | #define TIOCGWINSZ 0x5413 49 | #define TIOCSWINSZ 0x5414 50 | #define TIOCMGET 0x5415 51 | #define TIOCMBIS 0x5416 52 | #define TIOCMBIC 0x5417 53 | #define TIOCMSET 0x5418 54 | #define TIOCGSOFTCAR 0x5419 55 | #define TIOCSSOFTCAR 0x541A 56 | #define FIONREAD 0x541B 57 | #define TIOCINQ FIONREAD 58 | #define TIOCLINUX 0x541C 59 | #define TIOCCONS 0x541D 60 | #define TIOCGSERIAL 0x541E 61 | #define TIOCSSERIAL 0x541F 62 | #define TIOCPKT 0x5420 63 | #define FIONBIO 0x5421 64 | #define TIOCNOTTY 0x5422 65 | #define TIOCSETD 0x5423 66 | #define TIOCGETD 0x5424 67 | #define TCSBRKP 0x5425 68 | #define TIOCTTYGSTRUCT 0x5426 69 | #define TIOCSBRK 0x5427 70 | #define TIOCCBRK 0x5428 71 | #define TIOCGSID 0x5429 72 | #define TIOCGPTN 0x80045430 73 | #define TIOCSPTLCK 0x40045431 74 | 75 | /* socket-level I/O control calls. */ 76 | #define FIOSETOWN 0x8901 77 | #define SIOCSPGRP 0x8902 78 | #define FIOGETOWN 0x8903 79 | #define SIOCGPGRP 0x8904 80 | #define SIOCATMARK 0x8905 81 | #define SIOCGSTAMP 0x8906 82 | 83 | #endif 84 | 85 | int ioctl(int fd, int cmd, ...); 86 | -------------------------------------------------------------------------------- /neatlibc/sys/mman.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_MMAN_H 2 | #define _SYS_MMAN_H 3 | 4 | #define PROT_NONE 0x0 5 | #define PROT_READ 0x1 6 | #define PROT_WRITE 0x2 7 | #define PROT_EXEC 0x4 8 | 9 | #define MAP_SHARED 0x01 10 | #define MAP_PRIVATE 0x02 11 | #define MAP_FIXED 0x10 /* Interpret addr exactly */ 12 | 13 | #ifdef __APPLE__ 14 | #define MAP_ANONYMOUS 0x1000 /* don't use a file */ 15 | #else 16 | #define MAP_ANONYMOUS 0x20 /* don't use a file */ 17 | #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ 18 | #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ 19 | #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ 20 | #define MAP_LOCKED 0x2000 /* pages are locked */ 21 | #define MAP_NORESERVE 0x4000 /* don't check for reservations */ 22 | #define MAP_POPULATE 0x8000 23 | #endif 24 | 25 | #define MAP_ANON MAP_ANONYMOUS 26 | #define MAP_FILE 0 27 | #define MAP_FAILED ((void *) -1) 28 | 29 | void *mmap(void *addr, int len, int prot, int flags, int fd, int offset); 30 | int munmap(void *addr, int len); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /neatlibc/sys/time.h: -------------------------------------------------------------------------------- 1 | struct timeval { 2 | long tv_sec; 3 | long tv_usec; 4 | }; 5 | 6 | struct timezone { 7 | int tz_minuteswest; 8 | int tz_dsttime; 9 | }; 10 | 11 | int gettimeofday(struct timeval *tv, struct timezone *tz); 12 | 13 | #ifdef __APPLE__ 14 | int utimes(char *path, struct timeval times[2]); 15 | #endif 16 | -------------------------------------------------------------------------------- /neatlibc/sys/types.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_TYPES_H 2 | #define _SYS_TYPES_H 3 | 4 | #include 5 | 6 | typedef uint32_t dev_t; 7 | typedef uint16_t gid_t; 8 | typedef uint16_t mode_t; 9 | typedef uint16_t nlink_t; 10 | typedef uint16_t uid_t; 11 | typedef uint64_t ino_t; 12 | typedef uint32_t uid32_t; 13 | typedef uint32_t gid32_t; 14 | typedef int32_t pid_t; 15 | 16 | typedef long ssize_t; 17 | typedef long time_t; 18 | typedef long useconds_t; 19 | typedef signed long off_t; 20 | typedef long fpos_t; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /neatlibc/sys/wait.h: -------------------------------------------------------------------------------- 1 | #define WNOHANG 0x00000001 2 | #define WUNTRACED 0x00000002 3 | 4 | #define WSTOPPED 0x00000002 5 | #define WEXITED 0x00000004 6 | #define WCONTINUED 0x01000000 7 | 8 | #define WEXITSTATUS(s) (((s) & 0xff00) >> 8) 9 | #define WTERMSIG(s) ((s) & 0x7f) 10 | #define WSTOPSIG(s) WEXITSTATUS(s) 11 | #define WCOREDUMP(s) ((s) & 0x80) 12 | #define WIFEXITED(s) (WTERMSIG(s) == 0) 13 | #define WIFSTOPPED(s) (((s) & 0xff) == 0x7f) 14 | #define WIFSIGNALED(s) (!WIFEXITED(s) && !WIFSTOPPED(s)) 15 | #define WIFCONTINUED(s) ((s) == 0xffff) 16 | 17 | int wait(int *status); 18 | int waitpid(int pid, int *status, int options); 19 | -------------------------------------------------------------------------------- /neatlibc/syscalls.h: -------------------------------------------------------------------------------- 1 | /* system call wrappers for static NCC and host binaries */ 2 | 3 | #ifdef __neatcc__ 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define StrLen strlen 10 | #define StrCmp strcmp 11 | #define StrCpy strcpy 12 | #define MemMove memmove 13 | #define Bzero(d,n) memset(d,0,n) 14 | #define Open open 15 | #define Close close 16 | #define Pread pread 17 | #define Read read 18 | #define Write write 19 | #define Mmap mmap 20 | #define WaitPid waitpid 21 | #define Fork fork 22 | #define Exit _exit 23 | #define __builtin_memcpy(d,s,n) memcpy(d,s,n) 24 | #define __builtin_va_list va_list 25 | #define __builtin_va_start va_start 26 | #define __builtin_va_arg va_arg 27 | #define __builtin_va_end va_end 28 | #define __builtin_unreachable() 29 | 30 | #else 31 | long *InitAPE(long di, long *sp, char dl); 32 | __attribute__((__noreturn__)) void Exit(int rc); 33 | long StrLen(const char *s); 34 | char *StrCpy(char *d, const char *s); 35 | int StrCmp(const char *l, const char *r); 36 | void Bzero(void *a, unsigned long n); 37 | void *MemMove(void *a, const void *b, unsigned long n); 38 | int Open(const char *path, int flags, int mode); 39 | int Close(int fd); 40 | long Read(int fd, void *data, unsigned long size); 41 | long Write(int fd, const void *data, unsigned long size); 42 | long Pread(int fd, void *data, unsigned long size, long off); 43 | long Mmap(void *addr, unsigned long size, int prot, int flags, int fd, long off); 44 | long Fork(void); 45 | long WaitPid(int pid, int *status, int options); 46 | #endif 47 | 48 | void Launch(void *rdi, long entry, void *sp, int rcx) __attribute__((__noreturn__)); 49 | -------------------------------------------------------------------------------- /neatlibc/termios.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int tcgetattr(int fd, struct termios *term) 6 | { 7 | return ioctl(fd, TCGETS, term); 8 | } 9 | 10 | int tcsetattr(int fd, int actions, struct termios* term) 11 | { 12 | switch (actions) { 13 | case TCSANOW: 14 | return ioctl(fd, TCSETS , term); 15 | case TCSADRAIN: 16 | return ioctl(fd, TCSETSW, term); 17 | case TCSAFLUSH: 18 | return ioctl(fd, TCSETSF, term); 19 | } 20 | errno = EINVAL; 21 | return -1; 22 | } 23 | 24 | void cfmakeraw(struct termios *t) 25 | { 26 | t->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | 27 | INLCR | IGNCR | ICRNL | IXON); 28 | t->c_oflag &= ~OPOST; 29 | t->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); 30 | t->c_cflag &= ~(CSIZE | PARENB); 31 | t->c_cflag |= CS8; 32 | t->c_cc[VMIN] = 1; 33 | t->c_cc[VTIME] = 0; 34 | } 35 | -------------------------------------------------------------------------------- /neatlibc/termios.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct winsize { 4 | unsigned short ws_row; 5 | unsigned short ws_col; 6 | unsigned short ws_xpixel; 7 | unsigned short ws_ypixel; 8 | }; 9 | 10 | #ifdef __APPLE__ 11 | struct termios { 12 | unsigned long c_iflag; 13 | unsigned long c_oflag; 14 | unsigned long c_cflag; 15 | unsigned long c_lflag; 16 | unsigned char c_cc[20]; 17 | unsigned long c_ispeed; 18 | unsigned long c_ospeed; 19 | }; 20 | #else 21 | struct termios { 22 | unsigned c_iflag; 23 | unsigned c_oflag; 24 | unsigned c_cflag; 25 | unsigned c_lflag; 26 | unsigned char c_line; 27 | unsigned char c_cc[19]; 28 | }; 29 | #endif 30 | 31 | /* c_cc characters */ 32 | #define VINTR 0 33 | #define VQUIT 1 34 | #define VERASE 2 35 | #define VKILL 3 36 | #define VEOF 4 37 | #define VTIME 5 38 | #define VMIN 6 39 | #define VSWTC 7 40 | #define VSTART 8 41 | #define VSTOP 9 42 | #define VSUSP 10 43 | #define VEOL 11 44 | #define VREPRINT 12 45 | #define VDISCARD 13 46 | #define VWERASE 14 47 | #define VLNEXT 15 48 | #define VEOL2 16 49 | 50 | /* c_iflag bits */ 51 | #define IGNBRK 0000001 52 | #define BRKINT 0000002 53 | #define IGNPAR 0000004 54 | #define PARMRK 0000010 55 | #define INPCK 0000020 56 | #define ISTRIP 0000040 57 | #define INLCR 0000100 58 | #define IGNCR 0000200 59 | #define ICRNL 0000400 60 | #define IUCLC 0001000 61 | #define IXON 0002000 62 | #define IXANY 0004000 63 | #define IXOFF 0010000 64 | #define IMAXBEL 0020000 65 | #define IUTF8 0040000 66 | 67 | /* c_oflag bits */ 68 | #define OPOST 0000001 69 | #define OLCUC 0000002 70 | #define ONLCR 0000004 71 | #define OCRNL 0000010 72 | #define ONOCR 0000020 73 | #define ONLRET 0000040 74 | #define OFILL 0000100 75 | #define OFDEL 0000200 76 | #define NLDLY 0000400 77 | #define NL0 0000000 78 | #define NL1 0000400 79 | #define CRDLY 0003000 80 | #define CR0 0000000 81 | #define CR1 0001000 82 | #define CR2 0002000 83 | #define CR3 0003000 84 | #define TABDLY 0014000 85 | #define TAB0 0000000 86 | #define TAB1 0004000 87 | #define TAB2 0010000 88 | #define TAB3 0014000 89 | #define XTABS 0014000 90 | #define BSDLY 0020000 91 | #define BS0 0000000 92 | #define BS1 0020000 93 | #define VTDLY 0040000 94 | #define VT0 0000000 95 | #define VT1 0040000 96 | #define FFDLY 0100000 97 | #define FF0 0000000 98 | #define FF1 0100000 99 | 100 | /* c_cflag bit meaning */ 101 | #define CBAUD 0010017 102 | #define B0 0000000 103 | #define B50 0000001 104 | #define B75 0000002 105 | #define B110 0000003 106 | #define B134 0000004 107 | #define B150 0000005 108 | #define B200 0000006 109 | #define B300 0000007 110 | #define B600 0000010 111 | #define B1200 0000011 112 | #define B1800 0000012 113 | #define B2400 0000013 114 | #define B4800 0000014 115 | #define B9600 0000015 116 | #define B19200 0000016 117 | #define B38400 0000017 118 | #define EXTA B19200 119 | #define EXTB B38400 120 | #define CSIZE 0000060 121 | #define CS5 0000000 122 | #define CS6 0000020 123 | #define CS7 0000040 124 | #define CS8 0000060 125 | #define CSTOPB 0000100 126 | #define CREAD 0000200 127 | #define PARENB 0000400 128 | #define PARODD 0001000 129 | #define HUPCL 0002000 130 | #define CLOCAL 0004000 131 | #define CBAUDEX 0010000 132 | #define B57600 0010001 133 | #define B115200 0010002 134 | #define B230400 0010003 135 | #define B460800 0010004 136 | #define B500000 0010005 137 | #define B576000 0010006 138 | #define B921600 0010007 139 | #define B1000000 0010010 140 | #define B1152000 0010011 141 | #define B1500000 0010012 142 | #define B2000000 0010013 143 | #define B2500000 0010014 144 | #define B3000000 0010015 145 | #define B3500000 0010016 146 | #define B4000000 0010017 147 | #define CIBAUD 002003600000 148 | #define CMSPAR 010000000000 149 | #define CRTSCTS 020000000000 150 | 151 | #define ISIG 0000001 152 | #define ICANON 0000002 153 | #define XCASE 0000004 154 | #define ECHO 0000010 155 | #define ECHOE 0000020 156 | #define ECHOK 0000040 157 | #define ECHONL 0000100 158 | #define NOFLSH 0000200 159 | #define ECHOCTL 0001000 160 | #define ECHOPRT 0002000 161 | #define ECHOKE 0004000 162 | 163 | #define TOSTOP 0000400 164 | #define FLUSHO 0010000 165 | #define IEXTEN 0100000 166 | 167 | #define TCSANOW 0 168 | #define TCSADRAIN 1 169 | #define TCSAFLUSH 2 170 | 171 | int tcgetattr(int fd, struct termios *term); 172 | int tcsetattr(int fd, int actions, struct termios *term); 173 | -------------------------------------------------------------------------------- /neatlibc/time.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifdef __APPLE__ 6 | time_t time(time_t *tloc) 7 | { 8 | struct timeval tv; 9 | 10 | if (gettimeofday(&tv, NULL) < 0) 11 | return -1; 12 | 13 | if (tloc) 14 | *tloc = tv.tv_sec; 15 | 16 | return tv.tv_sec; 17 | } 18 | 19 | int utime(char *path, struct utimbuf *times) 20 | { 21 | struct timeval tv[2], *tvp; 22 | 23 | if (times) { 24 | tv[0].tv_sec = times->actime; 25 | tv[1].tv_sec = times->modtime; 26 | tv[0].tv_usec = tv[1].tv_usec = 0; 27 | tvp = tv; 28 | } else 29 | tvp = NULL; 30 | return utimes(path, tvp); 31 | } 32 | #endif 33 | -------------------------------------------------------------------------------- /neatlibc/time.h: -------------------------------------------------------------------------------- 1 | #ifndef _TIME_H 2 | #define _TIME_H 3 | 4 | #include 5 | 6 | struct timespec { 7 | long tv_sec; 8 | long tv_nsec; 9 | }; 10 | 11 | int nanosleep(struct timespec *req, struct timespec *rem); 12 | 13 | struct tm { 14 | int tm_sec; 15 | int tm_min; 16 | int tm_hour; 17 | int tm_mday; 18 | int tm_mon; 19 | int tm_year; 20 | int tm_wday; 21 | int tm_yday; 22 | int tm_isdst; 23 | long tm_gmtoff; 24 | char *tm_zone; 25 | }; 26 | 27 | time_t time(time_t *timep); 28 | long strftime(char *s, long len, char *fmt, struct tm *tm); 29 | struct tm *localtime(time_t *timep); 30 | struct tm *gmtime(time_t *timep); 31 | 32 | extern long timezone; 33 | extern int _tz_is_set; 34 | void tzset(void); 35 | 36 | #define __isleap(year) \ 37 | ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) 38 | void __tm_conv(struct tm *tmbuf, const time_t *timep, time_t offset); 39 | void __asctime(char *buffer, const struct tm *ptm); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /neatlibc/unistd.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #ifndef __APPLE__ 10 | int sleep(int n) 11 | { 12 | struct timespec req = {n, 0}; 13 | struct timespec rem; 14 | if (nanosleep(&req, &rem)) 15 | return rem.tv_sec; 16 | return 0; 17 | } 18 | #endif 19 | 20 | #define EXECARGS (1 << 7) 21 | 22 | int _execve(char *path, char *argv[], char *envp[]); 23 | 24 | int execve(char *path, char *argv[], char *envp[]) 25 | { 26 | #ifdef __APPLE__ 27 | int fd; 28 | char *argv2[EXECARGS]; 29 | 30 | fd = open(path, 0); 31 | if (fd >= 0) { 32 | char **p = argv, **q = argv2; 33 | char buf[2]; 34 | if (read(fd, buf, 2) == 2 && buf[0] == 0x7f && buf[1] == 0x45) { 35 | path = LOADER; //FIXME remove hard path 36 | printf("+elf %s ", path); 37 | *q++ = path; 38 | while ((*q++ = *p++) != 0) 39 | printf("%s ", q[-1]); 40 | printf("\n"); 41 | argv = argv2; 42 | } 43 | close(fd); 44 | } 45 | #endif 46 | return _execve(path, argv, envp); 47 | } 48 | 49 | int execle(char *path, ...) 50 | { 51 | va_list ap; 52 | char **envp; 53 | int argc = 0; 54 | char *argv[EXECARGS]; 55 | va_start(ap, path); 56 | while (argc + 1 < EXECARGS && (argv[argc] = va_arg(ap, char *))) 57 | argc++; 58 | envp = va_arg(ap, char **); 59 | va_end(ap); 60 | argv[argc] = NULL; 61 | execve(path, argv, envp); 62 | return -1; 63 | } 64 | 65 | int execl(char *path, ...) 66 | { 67 | va_list ap; 68 | int argc = 0; 69 | char *argv[EXECARGS]; 70 | va_start(ap, path); 71 | while (argc + 1 < EXECARGS && (argv[argc] = va_arg(ap, char *))) 72 | argc++; 73 | va_end(ap); 74 | argv[argc] = NULL; 75 | execve(path, argv, environ); 76 | return -1; 77 | } 78 | 79 | int execvp(char *cmd, char *argv[]) 80 | { 81 | char path[512]; 82 | char *p = getenv("PATH"); 83 | if (strchr(cmd, '/')) 84 | return execve(cmd, argv, environ); 85 | if (!p) 86 | p = "/bin"; 87 | while (*p) { 88 | char *s = path; 89 | while (*p && *p != ':') 90 | *s++ = *p++; 91 | if (s != path) 92 | *s++ = '/'; 93 | strcpy(s, cmd); 94 | execve(path, argv, environ); 95 | if (*p == ':') 96 | p++; 97 | } 98 | return -1; 99 | } 100 | 101 | int execv(char *path, char *argv[]) 102 | { 103 | return execve(path, argv, environ); 104 | } 105 | 106 | int wait(int *status) 107 | { 108 | return waitpid(-1, status, 0); 109 | } 110 | 111 | long pread(int fd, void *buf, long n, long offset) 112 | { 113 | long ret, old; 114 | int e; 115 | 116 | old = lseek(fd, offset, SEEK_CUR); 117 | if (lseek(fd, offset, SEEK_SET) == -1) 118 | return -1; 119 | ret = read(fd, buf, n); 120 | e = errno; 121 | lseek(fd, old, SEEK_CUR); 122 | errno = e; 123 | return ret; 124 | } 125 | 126 | int raise(int sig) 127 | { 128 | return kill(getpid(), sig); 129 | } 130 | 131 | void abort(void) 132 | { 133 | raise(SIGABRT); 134 | while (1) 135 | ; 136 | } 137 | 138 | #define errmsg(str) write(2, str, sizeof(str) - 1) 139 | #define errstr(str) write(2, str, strlen(str)) 140 | 141 | void __assertfailed(char *str) 142 | { 143 | errmsg("assertion \""); 144 | errstr(str); 145 | errmsg("\" failed\n"); 146 | abort(); 147 | } 148 | -------------------------------------------------------------------------------- /neatlibc/unistd.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* access() flags */ 5 | #define R_OK 4 6 | #define W_OK 2 7 | #define X_OK 1 8 | #define F_OK 0 9 | 10 | int access(char *name, int type); 11 | int unlink(char *path); 12 | 13 | extern char **environ; 14 | 15 | int isatty(int fd); 16 | int close(int fd); 17 | long write(int fd, void *buf, long n); 18 | long read(int fd, void *buf, long n); 19 | long pread(int fd, void *buf, long n, long offset); 20 | 21 | /* lseek() whence */ 22 | #define SEEK_SET 0 23 | #define SEEK_CUR 1 24 | #define SEEK_END 2 25 | 26 | long lseek(int fd, long offset, int whence); 27 | 28 | int pipe(int fds[2]); 29 | int dup(int fd); 30 | int dup2(int fd, int fd2); 31 | 32 | int fork(void); 33 | int vfork(void); /* FIXME same as fork */ 34 | int getpid(void); 35 | int getppid(void); 36 | 37 | int execve(char *path, char *argv[], char *envp[]); 38 | int execl(char *path, ...); 39 | int execle(char *path, ...); 40 | int execvp(char *file, char *argv[]); 41 | int execv(char *path, char *argv[]); 42 | 43 | void _exit(int status); 44 | 45 | int sleep(int n); 46 | 47 | /* standard file descriptors */ 48 | #define STDIN_FILENO 0 49 | #define STDOUT_FILENO 1 50 | #define STDERR_FILENO 2 51 | 52 | int symlink(char *path1, char *path2); 53 | ssize_t readlink(char *path, char *buf, size_t bufsize); 54 | -------------------------------------------------------------------------------- /neatlibc/utime.h: -------------------------------------------------------------------------------- 1 | #ifndef _UTIME_H 2 | #define _UTIME_H 3 | 4 | #include 5 | 6 | struct utimbuf { 7 | time_t actime; 8 | time_t modtime; 9 | }; 10 | 11 | int utime(char *path, struct utimbuf *times); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /neatlibc/x64/bits.s: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | global htonl 5 | global ntohl 6 | htonl: 7 | ntohl: 8 | mov eax, edi 9 | xchg al, ah 10 | ror eax, 16 11 | xchg al, ah 12 | ret 13 | 14 | global htons 15 | global ntohs 16 | htons: 17 | ntohs: 18 | mov eax, edi 19 | ror ax, 8 20 | ret 21 | -------------------------------------------------------------------------------- /neatlibc/x64/launch.s: -------------------------------------------------------------------------------- 1 | ; void Launch(long rdi, long entry, long sp, long rcx) 2 | ; Reset stack pointer and jump to loaded program entry 3 | ; 4 | ; rdi is passed through as-is 5 | ; rsi is address of entrypoint (becomes zero) 6 | ; rdx is stack pointer (becomes zero) 7 | ; rcx is passed through as-is 8 | 9 | global Launch 10 | Launch: 11 | xor r8,r8 12 | xor r9,r9 13 | xor r10,r10 14 | xor r11,r11 15 | xor r12,r12 16 | xor r13,r13 17 | xor r14,r14 18 | xor r15,r15 19 | mov rsp,rdx 20 | xor edx,edx 21 | push rsi 22 | xor esi,esi 23 | xor ebp,ebp 24 | xor ebx,ebx 25 | xor eax,eax 26 | ret 27 | -------------------------------------------------------------------------------- /neatlibc/x64/lmem.s: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | global __memcpylong 5 | __memcpylong: 6 | mov rax, rdi 7 | mov rcx, rdx 8 | shr ecx, 3 9 | cld 10 | rep movsq 11 | ret 12 | 13 | global __memsetlong 14 | __memsetlong: 15 | mov rcx, rdx 16 | mov rax, rsi 17 | mov rdx, rdi 18 | shr ecx, 3 19 | cld 20 | rep stosq 21 | mov rax, rdx 22 | ret 23 | -------------------------------------------------------------------------------- /neatlibc/x64/memtst.s: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | global memtst_back 5 | memtst_back: 6 | mov rax, rbp 7 | bt_up: cmp rdi, 0 8 | jle bt_out 9 | test rax, rax 10 | jz bt_out 11 | mov rax, [rax] 12 | dec rdi 13 | jmp bt_up 14 | bt_out: test rax, rax 15 | jz bt_ret 16 | add rax, 8 17 | mov rax, [rax] 18 | bt_ret: ret 19 | -------------------------------------------------------------------------------- /neatlibc/x64/setjmp.s: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | global setjmp 5 | setjmp: 6 | mov [rdi + 0 * 8], rbx 7 | mov [rdi + 1 * 8], rbp 8 | mov [rdi + 2 * 8], r12 9 | mov [rdi + 3 * 8], r13 10 | mov [rdi + 4 * 8], r14 11 | mov [rdi + 5 * 8], r15 12 | lea rdx, [rsp + 8] 13 | mov [rdi + 6 * 8], rdx 14 | mov rdx, [rsp] 15 | mov [rdi + 7 * 8], rdx 16 | xor rax, rax 17 | ret 18 | 19 | global longjmp 20 | longjmp: 21 | mov rbx, [rdi + 0 * 8] 22 | mov rbp, [rdi + 1 * 8] 23 | mov r12, [rdi + 2 * 8] 24 | mov r13, [rdi + 3 * 8] 25 | mov r14, [rdi + 4 * 8] 26 | mov r15, [rdi + 5 * 8] 27 | mov rsp, [rdi + 6 * 8] 28 | mov rdx, [rdi + 7 * 8] 29 | mov eax, 1 30 | test esi, esi 31 | cmovne eax, esi 32 | jmp rdx 33 | -------------------------------------------------------------------------------- /neatlibc/x64/start.s: -------------------------------------------------------------------------------- 1 | ;default rel ; default generate rip-relative code 2 | 3 | extern main 4 | ;extern __neatlibc_exit 5 | extern _exit 6 | global _start:function 7 | _start: 8 | xor rbp, rbp 9 | pop rdi ; argc 10 | mov rsi, rsp ; argv 11 | push rdi 12 | lea rdx, [rsi + rdi * 8 + 8]; envp 13 | mov [environ], rdx 14 | and rsp, -16 ; align rsp 15 | 16 | call main 17 | mov rbx, rax 18 | ;call __neatlibc_exit 19 | mov rdi, rbx 20 | call _exit 21 | 22 | SECTION .data 23 | global environ:object 24 | environ:dq 0 25 | -------------------------------------------------------------------------------- /neatlibc/x64/string.s: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | global memcpy 5 | memcpy: 6 | mov rax, rdi 7 | mov rcx, rdx 8 | cld 9 | rep movsb 10 | ret 11 | 12 | global memmove 13 | memmove: 14 | mov rcx, rdx 15 | cmp rdi, rsi 16 | jng .usual 17 | mov rax, rsi 18 | add rax, rcx 19 | cmp rdi, rax 20 | jg .usual 21 | 22 | mov rax, rdi 23 | std 24 | add rsi, rcx 25 | add rdi, rcx 26 | dec rsi 27 | dec rdi 28 | rep movsb 29 | ret 30 | .usual: 31 | mov rax, rdi 32 | cld 33 | rep movsb 34 | ret 35 | 36 | global memset 37 | memset: 38 | mov rcx, rdx 39 | mov rax, rsi 40 | mov rdx, rdi 41 | cld 42 | rep stosb 43 | mov rax, rdx 44 | ret 45 | 46 | global memchr 47 | memchr: 48 | mov rax, rsi 49 | mov rcx, rdx 50 | test rcx, rcx 51 | jz .failed 52 | cld 53 | repnz scasb 54 | jne .failed 55 | mov rax, rdi 56 | dec rax 57 | ret 58 | .failed: 59 | xor eax, eax 60 | ret 61 | 62 | global memcmp 63 | memcmp: 64 | xor eax, eax 65 | mov rcx, rdx 66 | jecxz .ret 67 | 68 | cld 69 | rep cmpsb 70 | jz .ret 71 | xor eax, eax 72 | mov al, [rdi - 1] 73 | xor ecx, ecx 74 | mov cl, [rsi - 1] 75 | sub eax, ecx 76 | .ret: 77 | ret 78 | 79 | global strlen 80 | strlen: 81 | xor eax, eax 82 | mov rcx, -1 83 | cld 84 | repnz scasb 85 | mov rax, rcx 86 | not rax 87 | dec rax 88 | ret 89 | 90 | global memrchr 91 | memrchr: 92 | mov eax, esi 93 | mov rcx, rdx 94 | add rdi, rcx 95 | dec rdi 96 | test rcx, rcx 97 | jz .failed 98 | std 99 | repnz scasb 100 | jne .failed 101 | mov rax, rdi 102 | inc rax 103 | ret 104 | .failed: 105 | xor eax, eax 106 | ret 107 | 108 | global strchr 109 | strchr: 110 | .loop: 111 | mov al, [rdi] 112 | cmp al, sil 113 | jz .done 114 | inc rdi 115 | test al, al 116 | jnz .loop 117 | xor edi, edi 118 | .done: 119 | mov rax, rdi 120 | ret 121 | 122 | global strcmp 123 | strcmp: 124 | xor eax, eax 125 | .loop: 126 | mov al, [rdi] 127 | cmp al, [rsi] 128 | jnz .ret 129 | inc rdi 130 | inc rsi 131 | test al, al 132 | jnz .loop 133 | ret 134 | .ret: 135 | movzx rcx, byte [rsi] 136 | sub rax, rcx 137 | ret 138 | 139 | global strcpy 140 | strcpy: 141 | mov rdx, rdi 142 | cld 143 | .loop: 144 | lodsb 145 | stosb 146 | or al, al 147 | jnz .loop 148 | mov rax, rdx 149 | ret 150 | 151 | global strrchr 152 | strrchr: 153 | xor edx, edx 154 | dec rdi 155 | .loop: 156 | inc rdi 157 | mov al, [rdi] 158 | test al, al 159 | jz .done 160 | cmp al, sil 161 | jnz .loop 162 | mov rdx, rdi 163 | jmp .loop 164 | .done: 165 | mov rax, rdx 166 | ret 167 | 168 | global strncmp 169 | strncmp: 170 | xor eax, eax 171 | .loop: 172 | test rdx, rdx 173 | jz .failed 174 | mov al, [rdi] 175 | cmp al, [rsi] 176 | jnz .ret 177 | inc rsi 178 | inc rdi 179 | dec rdx 180 | test al, al 181 | jnz .loop 182 | .failed: 183 | xor eax, eax 184 | ret 185 | .ret: 186 | movzx ecx, byte [rsi] 187 | sub eax, ecx 188 | ret 189 | -------------------------------------------------------------------------------- /neatlibc/x86/bits.s: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | global htonl 5 | global ntohl 6 | htonl: 7 | ntohl: 8 | mov eax, [esp+4] 9 | xchg al, ah 10 | ror eax, 16 11 | xchg al, ah 12 | ret 13 | 14 | global htons 15 | global ntohs 16 | htons: 17 | ntohs: 18 | mov eax, [esp+4] 19 | ror ax, 8 20 | ret 21 | -------------------------------------------------------------------------------- /neatlibc/x86/lmem.s: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | global __memcpylong 5 | __memcpylong: 6 | push esi 7 | push edi 8 | mov edi, [esp+12] 9 | mov esi, [esp+16] 10 | mov ecx, [esp+20] 11 | mov eax, edi 12 | shr ecx, 2 13 | cld 14 | rep movsd 15 | pop edi 16 | pop esi 17 | ret 18 | 19 | global __memsetlong 20 | __memsetlong: 21 | push edi 22 | mov edi, [esp+8] 23 | mov eax, [esp+12] 24 | mov ecx, [esp+16] 25 | mov edx, edi 26 | shr ecx, 2 27 | cld 28 | rep stosd 29 | pop edi 30 | mov eax, edx 31 | ret 32 | -------------------------------------------------------------------------------- /neatlibc/x86/memtst.s: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | global memtst_back 5 | memtst_back: 6 | mov eax, ebp 7 | mov ecx, [esp+4] 8 | bt_up: cmp ecx, 0 9 | jle bt_out 10 | test eax, eax 11 | jz bt_out 12 | mov eax, [eax] 13 | dec ecx 14 | jmp bt_up 15 | bt_out: test eax, eax 16 | jz bt_ret 17 | mov eax, [eax+4] 18 | bt_ret: ret 19 | -------------------------------------------------------------------------------- /neatlibc/x86/setjmp.s: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | global setjmp 5 | setjmp: 6 | mov eax, [esp + 4] 7 | mov [eax + 0 * 4], ebx 8 | mov [eax + 1 * 4], esi 9 | mov [eax + 2 * 4], edi 10 | mov [eax + 3 * 4], ebp 11 | lea ecx, [esp + 4] 12 | mov [eax + 4 * 4], ecx 13 | mov ecx, [esp] 14 | mov [eax + 5 * 4], ecx 15 | xor eax, eax 16 | ret 17 | 18 | global longjmp 19 | longjmp: 20 | mov edx, [esp + 4] 21 | mov eax, [esp + 8] 22 | mov ebx, [edx + 0 * 4] 23 | mov esi, [edx + 1 * 4] 24 | mov edi, [edx + 2 * 4] 25 | mov ebp, [edx + 3 * 4] 26 | mov ecx, [edx + 4 * 4] 27 | mov esp, ecx 28 | mov ecx, [edx + 5 * 4] 29 | test eax, eax 30 | jnz nz 31 | mov eax, 1 32 | nz: 33 | jmp ecx 34 | -------------------------------------------------------------------------------- /neatlibc/x86/start.s: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | extern environ 5 | 6 | extern main 7 | extern __neatlibc_exit 8 | global _start 9 | _start: 10 | xor ebp, ebp 11 | pop ecx 12 | mov edx, esp 13 | push ecx 14 | 15 | lea eax, [edx + ecx * 4 + 4] 16 | mov [environ], eax 17 | 18 | push eax 19 | push edx 20 | push ecx 21 | call main 22 | mov ebx, eax 23 | call __neatlibc_exit 24 | mov eax, 0x1 25 | int 0x80 26 | -------------------------------------------------------------------------------- /neatlibc/x86/string.s: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | global memcpy 5 | memcpy: 6 | push esi 7 | push edi 8 | mov edi, [esp+12] 9 | mov esi, [esp+16] 10 | mov ecx, [esp+20] 11 | mov eax, edi 12 | cld 13 | rep movsb 14 | pop edi 15 | pop esi 16 | ret 17 | 18 | global memmove 19 | memmove: 20 | push esi 21 | push edi 22 | mov edi, [esp+12] 23 | mov esi, [esp+16] 24 | mov ecx, [esp+20] 25 | cmp edi, esi 26 | jng .usual 27 | mov eax, esi 28 | add eax, ecx 29 | cmp edi, eax 30 | jg .usual 31 | 32 | mov eax, edi 33 | std 34 | add esi, ecx 35 | add edi, ecx 36 | dec esi 37 | dec edi 38 | rep movsb 39 | jmp .ret 40 | .usual: 41 | mov eax, edi 42 | cld 43 | rep movsb 44 | .ret: 45 | pop edi 46 | pop esi 47 | ret 48 | 49 | global memset 50 | memset: 51 | push edi 52 | mov edi, [esp+8] 53 | mov eax, [esp+12] 54 | mov ecx, [esp+16] 55 | mov edx, edi 56 | cld 57 | rep stosb 58 | pop edi 59 | mov eax, edx 60 | ret 61 | 62 | global memchr 63 | memchr: 64 | mov eax, [esp+8] 65 | mov ecx, [esp+12] 66 | push edi 67 | mov edi, [esp+8] 68 | test ecx, ecx 69 | jz .failed 70 | cld 71 | repnz scasb 72 | jne .failed 73 | mov eax, edi 74 | dec eax 75 | jmp .ret 76 | .failed: 77 | xor eax, eax 78 | .ret: 79 | pop edi 80 | ret 81 | 82 | global memcmp 83 | memcmp: 84 | push esi 85 | push edi 86 | xor eax, eax 87 | mov esi, [esp+12] 88 | mov edi, [esp+16] 89 | mov ecx, [esp+20] 90 | jecxz .ret 91 | 92 | cld 93 | rep cmpsb 94 | jz .ret 95 | sbb eax, eax 96 | or eax, 1 97 | .ret: 98 | pop edi 99 | pop esi 100 | ret 101 | 102 | global strlen 103 | strlen: 104 | push edi 105 | mov edi, [esp+8] 106 | xor eax, eax 107 | mov ecx, -1 108 | cld 109 | repnz scasb 110 | mov eax, ecx 111 | not eax 112 | dec eax 113 | pop edi 114 | ret 115 | 116 | global memrchr 117 | memrchr: 118 | mov eax, [esp+8] 119 | mov ecx, [esp+12] 120 | push edi 121 | mov edi, [esp+8] 122 | add edi, ecx 123 | dec edi 124 | test ecx, ecx 125 | jz .failed 126 | std 127 | repnz scasb 128 | jne .failed 129 | mov eax, edi 130 | inc eax 131 | jmp .ret 132 | .failed: 133 | xor eax, eax 134 | .ret: 135 | pop edi 136 | ret 137 | 138 | global strchr 139 | strchr: 140 | mov ecx, [esp+4] 141 | mov edx, [esp+8] 142 | .loop: 143 | mov al, [ecx] 144 | cmp al, dl 145 | jz .done 146 | inc ecx 147 | test al, al 148 | jnz .loop 149 | xor ecx, ecx 150 | .done: 151 | mov eax, ecx 152 | ret 153 | 154 | global strcmp 155 | strcmp: 156 | mov ecx, [esp+4] 157 | mov edx, [esp+8] 158 | xor eax, eax 159 | .loop: 160 | mov al, [ecx] 161 | cmp al, [edx] 162 | jnz .ret 163 | inc edx 164 | inc ecx 165 | test al, al 166 | jnz .loop 167 | ret 168 | .ret: 169 | movzx ecx, byte [edx] 170 | sub eax, ecx 171 | ret 172 | 173 | global strcpy 174 | strcpy: 175 | push edi 176 | push esi 177 | mov edx, [esp+12] 178 | mov esi, [esp+16] 179 | mov edi, edx 180 | cld 181 | .loop: 182 | lodsb 183 | stosb 184 | or al, al 185 | jnz .loop 186 | pop esi 187 | pop edi 188 | mov eax, edx 189 | ret 190 | 191 | global strrchr 192 | strrchr: 193 | push edi 194 | mov edi, [esp+8] 195 | mov ecx, [esp+12] 196 | xor edx, edx 197 | dec edi 198 | .loop: 199 | inc edi 200 | mov al, [edi] 201 | test al, al 202 | jz .done 203 | cmp al, cl 204 | jnz .loop 205 | mov edx, edi 206 | jmp .loop 207 | .done: 208 | mov eax, edx 209 | pop edi 210 | ret 211 | 212 | global strncmp 213 | strncmp: 214 | mov ecx, [esp+4] 215 | mov edx, [esp+8] 216 | xor eax, eax 217 | push edi 218 | mov edi, [esp+16] 219 | .loop: 220 | test edi, edi 221 | jz .failed 222 | mov al, [ecx] 223 | cmp al, [edx] 224 | jnz .ret 225 | inc edx 226 | inc ecx 227 | dec edi 228 | test al, al 229 | jnz .loop 230 | .failed: 231 | xor eax, eax 232 | pop edi 233 | ret 234 | .ret: 235 | movzx ecx, byte [edx] 236 | sub eax, ecx 237 | pop edi 238 | ret 239 | -------------------------------------------------------------------------------- /neatrun/Makefile: -------------------------------------------------------------------------------- 1 | NCC = "/path/to/neatcc/ncc" 2 | NLD = "/path/to/neatld/nld" 3 | NLC = "/path/to/neatlibc/" 4 | 5 | CC = cc 6 | CFLAGS = -DNCC=\"$(NCC)\" -DNLD=\"$(NLD)\" -DNLC=\"$(NLC)\" 7 | LDFLAGS = 8 | 9 | all: neatcc 10 | 11 | %.o: %.c 12 | $(CC) $(CFLAGS) -c $< 13 | neatcc: neatcc.o 14 | $(CC) -o $@ neatcc.o $(LDFLAGS) 15 | clean: 16 | rm -f *.o neatcc 17 | -------------------------------------------------------------------------------- /neatrun/neatcc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define MAXARGS 512 8 | #define LDOPTS "lLsgmpe" /* neatld options */ 9 | #define CCOPTS "cIOEDW" /* neatcc options */ 10 | #define AROPTS "IDOlLome" /* options with an argument */ 11 | 12 | static void die(char *msg) 13 | { 14 | write(2, msg, strlen(msg)); 15 | exit(1); 16 | } 17 | 18 | void display(char *str, char **args) 19 | { 20 | printf("%s", str); 21 | while (*args) { 22 | printf("%s ", *args++); 23 | } 24 | printf("\n"); 25 | } 26 | 27 | int main(int argc, char *argv[], char *envp[]) 28 | { 29 | char *ccargs[MAXARGS]; /* neatcc options */ 30 | char *ldargs[MAXARGS]; /* neatld options */ 31 | int opt[MAXARGS]; /* opt[i] is one if argv[i] is an option */ 32 | int optarg[MAXARGS]; /* argv[i + 1] is an argument of argv[i] */ 33 | int ccargc = 0; /* number of neatcc options */ 34 | int ldargc = 0; /* number of neatld options */ 35 | int nold = 0; /* compile only */ 36 | int i; 37 | 38 | /*display("NEATCC ARGS: ", argv);*/ 39 | if (argc < 2) 40 | die("neatcc: ncc/nld wrapper\n"); 41 | /* looking for options that prevent linking + initialize opt[] and optarg[] */ 42 | for (i = 1; i < argc; i++) { 43 | opt[i] = argv[i][0] == '-' ? argv[i][1] : 0; 44 | optarg[i] = opt[i] > 0 && strchr(AROPTS, opt[i]) && !argv[i][2]; 45 | nold = nold || opt[i] == 'c' || opt[i] == 'E'; 46 | } 47 | /* initialize compiler options */ 48 | ccargs[ccargc++] = NCC; 49 | ccargs[ccargc++] = "-Dfloat=long"; 50 | ccargs[ccargc++] = "-Ddouble=long"; 51 | ccargs[ccargc++] = "-D__extension__="; 52 | ccargs[ccargc++] = "-I" NLC; 53 | for (i = 1; i < argc; i += 1 + optarg[i]) { 54 | if (opt[i] && (strchr(CCOPTS, opt[i]) || (nold && opt[i] == 'o'))) { 55 | ccargs[ccargc++] = argv[i]; 56 | if (optarg[i]) 57 | ccargs[ccargc++] = argv[i + 1]; 58 | } 59 | } 60 | /* invoke neatcc for every .c file */ 61 | for (i = 1; i < argc; i += 1 + optarg[i]) { 62 | char *arg = argv[i]; 63 | char *end = strchr(arg, '\0'); 64 | if (!opt[i] && arg + 2 < end && end[-2] == '.' && end[-1] == 'c') { 65 | int st; 66 | ccargs[ccargc] = arg; 67 | ccargs[ccargc + 1] = NULL; 68 | display("+", ccargs); 69 | if (fork() == 0) { 70 | execve(ccargs[0], ccargs, envp); 71 | die("neatcc: could not find ncc\n"); 72 | return 1; 73 | } 74 | if (wait(&st) < 0 || WEXITSTATUS(st)) 75 | return 1; 76 | end[-1] = 'o'; /* for linker */ 77 | } 78 | } 79 | /* invoke neatld */ 80 | if (!nold) { 81 | ldargs[ldargc++] = NLD; 82 | for (i = 1; i < argc; i += 1 + optarg[i]) { 83 | if (!opt[i] || !strchr(CCOPTS, opt[i])) { 84 | ldargs[ldargc++] = argv[i]; 85 | if (optarg[i]) 86 | ldargs[ldargc++] = argv[i + 1]; 87 | } 88 | } 89 | ldargs[ldargc++] = NLC "/start.o"; 90 | ldargs[ldargc++] = NLC "/libc.a"; 91 | ldargs[ldargc] = NULL; 92 | display("+", ldargs); 93 | execve(ldargs[0], ldargs, envp); 94 | die("neatcc: could not find nld\n"); 95 | } 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /sash/COPYING.sash: -------------------------------------------------------------------------------- 1 | Portions of this code were extracted from the sash 2.1 program, 2 | which has the following copyright: 3 | 4 | Copyright (c) 1998 by David I. Bell 5 | Permission is granted to use, distribute, or modify this source, 6 | provided that this copyright notice remains intact. 7 | 8 | This message is included in accordance with David Bell's wishes. These terms 9 | are compatible with the GNU GPL contained in COPYING. 10 | -------------------------------------------------------------------------------- /sash/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for sash 2 | 3 | CC = ../neatrun/neatcc 4 | LD = ../neatrun/neatcc 5 | CFLAGS += -O2 6 | xCFLAGS += -Os -Wno-implicit-int -Wall 7 | 8 | OBJS = sash.o cmds.o cmd_dd.o cmd_ed.o cmd_grep.o cmd_ls.o cmd_tar.o utils.o cmd_history.o 9 | #LDFLAGS = -lc 10 | 11 | all: sash 12 | 13 | sash: $(OBJS) ../neatlibc/libc.a 14 | $(LD) $(LDFLAGS) -o sash $(OBJS) $(LDLIBS) 15 | 16 | clean: 17 | rm -f core sash $(OBJS) 18 | 19 | $(OBJS): sash.h config.h 20 | -------------------------------------------------------------------------------- /sash/README: -------------------------------------------------------------------------------- 1 | April 14, 1993 2 | 3 | This is release 1.0 of sash, my stand-alone shell for Linux. 4 | 5 | The purpose of this program is to make replacing of shared libraries 6 | easy and safe. It does this by firstly being linked statically, and 7 | secondly by including many of the standard utilities within itself. 8 | Read the sash.1 documentation for more details. 9 | 10 | Type "make install" to build and install the program and man page. 11 | 12 | David I. Bell 13 | dbell@pdact.pd.necisa.oz.au 14 | -------------------------------------------------------------------------------- /sash/README.elks: -------------------------------------------------------------------------------- 1 | This is a slightly modified version of sash which works under ELKS. 2 | 3 | - Chad 4 | ----------------------------------------------------------------------- 5 | 30th April 1997 6 | Added config.h to configure in the various built in commands. This is 7 | essentially so that 8 | 9 | a) a simple shell without builtins 10 | 11 | b) a medium size shell with some useful builtins, but not too much bulk 12 | 13 | c) a full stand alone shell with all the high level features 14 | 15 | can all be built from the one source tree. 16 | Just edit config.h and comment out the #defines for the builtins you don't 17 | want. 18 | 19 | 8th May 1997 20 | Added stand_alone/ subdirectory which contains stand alone versions of 21 | almost all the builtin commands. These can be used in association with a 22 | sash compiled without these commands, or with any other shell. 23 | 24 | To install take a root disk with init and login from the elkscmd/initlogin 25 | directory in the bin directory. Install sash as /bin/sh, and copy the 26 | binaries from the stand-alone directory into the bin directory of the disk. 27 | 28 | - Alistair Riddoch 29 | -------------------------------------------------------------------------------- /sash/cmd_grep.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1993 by David I. Bell 3 | * Permission is granted to use, distribute, or modify this source, 4 | * provided that this copyright notice remains intact. 5 | * 6 | * The "grep" built-in command. 7 | */ 8 | 9 | #include "sash.h" 10 | #ifdef CMD_GREP 11 | 12 | #include 13 | 14 | 15 | static BOOL search(); 16 | 17 | 18 | void 19 | do_grep(argc, argv) 20 | char **argv; 21 | { 22 | FILE *fp; 23 | char *word; 24 | char *name; 25 | char *cp; 26 | BOOL tellname; 27 | BOOL ignorecase; 28 | BOOL tellline; 29 | long line; 30 | char buf[BUFSIZ]; 31 | 32 | ignorecase = FALSE; 33 | tellline = FALSE; 34 | 35 | argc--; 36 | argv++; 37 | 38 | if (**argv == '-') { 39 | argc--; 40 | cp = *argv++; 41 | 42 | while (*++cp) switch (*cp) { 43 | case 'i': 44 | ignorecase = TRUE; 45 | break; 46 | 47 | case 'n': 48 | tellline = TRUE; 49 | break; 50 | 51 | default: 52 | fprintf(stderr, "Unknown option\n"); 53 | return; 54 | } 55 | } 56 | 57 | word = *argv++; 58 | argc--; 59 | 60 | tellname = (argc > 1); 61 | 62 | while (argc-- > 0) { 63 | name = *argv++; 64 | 65 | fp = fopen(name, "r"); 66 | if (fp == NULL) { 67 | perror(name); 68 | continue; 69 | } 70 | 71 | line = 0; 72 | 73 | while (fgets(buf, sizeof(buf), fp)) { 74 | if (intflag) { 75 | fclose(fp); 76 | return; 77 | } 78 | 79 | line++; 80 | 81 | cp = &buf[strlen(buf) - 1]; 82 | if (*cp != '\n') 83 | fprintf(stderr, "%s: Line too long\n", name); 84 | 85 | if (search(buf, word, ignorecase)) { 86 | if (tellname) 87 | printf("%s: ", name); 88 | if (tellline) 89 | printf("%ld: ", line); 90 | 91 | fputs(buf, stdout); 92 | } 93 | } 94 | 95 | if (ferror(fp)) 96 | perror(name); 97 | 98 | fclose(fp); 99 | } 100 | } 101 | 102 | 103 | /* 104 | * See if the specified word is found in the specified string. 105 | */ 106 | static BOOL 107 | search(string, word, ignorecase) 108 | char *string; 109 | char *word; 110 | BOOL ignorecase; 111 | { 112 | char *cp1; 113 | char *cp2; 114 | int len; 115 | int lowfirst; 116 | int ch1; 117 | int ch2; 118 | 119 | len = strlen(word); 120 | 121 | if (!ignorecase) { 122 | while (TRUE) { 123 | string = strchr(string, word[0]); 124 | if (string == NULL) 125 | return FALSE; 126 | 127 | if (memcmp(string, word, len) == 0) 128 | return TRUE; 129 | 130 | string++; 131 | } 132 | } 133 | 134 | /* 135 | * Here if we need to check case independence. 136 | * Do the search by lower casing both strings. 137 | */ 138 | lowfirst = *word; 139 | if (isupper(lowfirst)) 140 | lowfirst = tolower(lowfirst); 141 | 142 | while (TRUE) { 143 | while (*string && (*string != lowfirst) && 144 | (!isupper(*string) || (tolower(*string) != lowfirst))) 145 | string++; 146 | 147 | if (*string == '\0') 148 | return FALSE; 149 | 150 | cp1 = string; 151 | cp2 = word; 152 | 153 | do { 154 | if (*cp2 == '\0') 155 | return TRUE; 156 | 157 | ch1 = *cp1++; 158 | if (isupper(ch1)) 159 | ch1 = tolower(ch1); 160 | 161 | ch2 = *cp2++; 162 | if (isupper(ch2)) 163 | ch2 = tolower(ch2); 164 | 165 | } while (ch1 == ch2); 166 | 167 | string++; 168 | } 169 | } 170 | 171 | #endif /* CMD_GREP */ 172 | 173 | /* END CODE */ 174 | -------------------------------------------------------------------------------- /sash/config.h: -------------------------------------------------------------------------------- 1 | /* Config file for sash. 2 | * Comment out #define for commands you do not require 3 | */ 4 | 5 | #define WILDCARDS 6 | #define BUILTINS /* unset to build a very small shell for 256K systems */ 7 | 8 | #ifdef BUILTINS 9 | #define CMD_ALIAS /* 1048 bytes. Includes unalias */ 10 | //#define CMD_CHGRP /* 2164 bytes */ 11 | #define CMD_CHMOD /* 260 bytes */ 12 | //#define CMD_CHOWN /* 2080 bytes */ 13 | #define CMD_CMP /* 904 bytes */ 14 | #define CMD_CP /* 1108 bytes */ 15 | #define CMD_DD /* 2524 bytes */ 16 | #define CMD_ECHO /* 264 bytes */ 17 | #define CMD_ED /* 8300 bytes */ 18 | #define CMD_GREP /* 144 bytes */ 19 | #define CMD_HELP /* 88 bytes */ 20 | #define CMD_KILL /* 532 bytes */ 21 | #define CMD_LN /* 716 bytes */ 22 | #define CMD_LS /* 7092 bytes */ 23 | #define CMD_MKDIR /* 140 bytes */ 24 | #define CMD_MKNOD /* 516 bytes */ 25 | #define CMD_MORE /* 608 bytes */ 26 | //#define CMD_MOUNT /* 600 bytes. Includes umount */ 27 | #define CMD_MV /* 1272 bytes */ 28 | #define CMD_PRINTENV /* 260 bytes */ 29 | #define CMD_PROMPT /* */ 30 | #define CMD_PWD /* 928 bytes */ 31 | #define CMD_RM /* 140 bytes */ 32 | #define CMD_RMDIR /* 140 bytes */ 33 | //#define CMD_SETENV /* 129 bytes */ 34 | #define CMD_SOURCE /* bytes */ 35 | #define CMD_SYNC /* 80 bytes */ 36 | #define CMD_TAR /* 5576 bytes */ 37 | #define CMD_TOUCH /* 236 bytes */ 38 | #define CMD_UMASK /* 272 bytes */ 39 | #define CMD_HISTORY 40 | #endif 41 | 42 | #ifdef CMD_CP 43 | #define FUNC_COPYFILE 44 | #define FUNC_ISADIR 45 | #define FUNC_BUILDNAME 46 | #endif 47 | 48 | #ifdef CMD_MV 49 | #define FUNC_COPYFILE 50 | #define FUNC_ISADIR 51 | #define FUNC_BUILDNAME 52 | #endif 53 | 54 | #ifdef CMD_LN 55 | #define FUNC_ISADIR 56 | #define FUNC_BUILDNAME 57 | #endif 58 | 59 | #ifdef CMD_LS 60 | #define FUNC_MODESTRING 61 | #define FUNC_TIMESTRING 62 | #endif 63 | 64 | #ifdef CMD_TAR 65 | #define FUNC_MODESTRING 66 | #define FUNC_TIMESTRING 67 | #endif 68 | -------------------------------------------------------------------------------- /sash/sash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1993 by David I. Bell 3 | * Permission is granted to use, distribute, or modify this source, 4 | * provided that this copyright notice remains intact. 5 | * 6 | * Definitions for stand-alone shell for system maintainance for Linux. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "config.h" 19 | 20 | #define PATHLEN 256 21 | #define CMDLEN 128 22 | #define MAXARGS 256 23 | #define ALIASALLOC 20 24 | #define STDIN 0 25 | #define STDOUT 1 26 | #define MAXSOURCE 10 27 | #define CFGFILE "sashrc" 28 | 29 | #ifndef isblank 30 | #define isblank(ch) (((ch) == ' ') || ((ch) == '\t')) 31 | #endif 32 | 33 | #define isquote(ch) (((ch) == '"') || ((ch) == '\'')) 34 | #define isdecimal(ch) (((ch) >= '0') && ((ch) <= '9')) 35 | #define isoctal(ch) (((ch) >= '0') && ((ch) <= '7')) 36 | 37 | extern char **environ; 38 | 39 | typedef int BOOL; 40 | 41 | #ifndef FALSE 42 | #define FALSE ((BOOL) 0) 43 | #define TRUE ((BOOL) 1) 44 | #endif 45 | 46 | extern void do_alias(), do_cd(), do_exec(), do_exit(), do_prompt(); 47 | extern void do_source(), do_umask(), do_unalias(), do_help(), do_ln(); 48 | extern void do_cp(), do_mv(), do_rm(), do_chmod(), do_mkdir(), do_rmdir(); 49 | extern void do_mknod(), do_chown(), do_chgrp(), do_sync(), do_printenv(); 50 | extern void do_more(), do_cmp(), do_touch(), do_ls(), do_dd(), do_tar(); 51 | extern void do_mount(), do_umount(), do_setenv(), do_pwd(), do_echo(); 52 | extern void do_kill(), do_grep(), do_ed(), do_history(); 53 | 54 | 55 | extern char *buildname(); 56 | extern char *modestring(mode_t mode); 57 | extern char *timestring(time_t t); 58 | extern BOOL isadir(); 59 | extern BOOL copyfile(); 60 | extern BOOL match(); 61 | extern BOOL makestring(); 62 | extern BOOL makeargs(); 63 | extern int expandwildcards(); 64 | extern int namesort(); 65 | extern char *getchunk(); 66 | extern void freechunks(); 67 | 68 | extern BOOL intflag; 69 | 70 | /* END CODE */ 71 | -------------------------------------------------------------------------------- /test/Makefile: -------------------------------------------------------------------------------- 1 | # output architecture: x64, x86, arm 2 | OUT = x64 3 | 4 | # platform uname for syscalls 5 | PLATFORM=$(shell uname) 6 | 7 | CC = ../neatcc/ncc # the neatcc binary 8 | LD = ../neatld/nld # the neatld binary 9 | 10 | # default assemblers 11 | ASx64 = nasm -f elf64 -d$(PLATFORM) 12 | ASx86 = nasm -f elf 13 | ASarm = neatas 14 | 15 | AS = $(AS$(OUT)) 16 | 17 | all: $(OUT).o \ 18 | b01.x b02.x b03.x b04.x b05.x b06.x b07.x b08.x b09.x b10.x \ 19 | b11.x b12.x b13.x b14.x b15.x b16.x b17.x b18.x b19.x b20.x \ 20 | b21.x b22.x \ 21 | t00.x t01.x t02.x t03.x t04.x t05.x t06.x t07.x \ 22 | t08.x t09.x t0a.x t0b.x t0c.x t0d.x t0e.x t0f.x \ 23 | t10.x t11.x t12.x t13.x t14.x t15.x t16.x t17.x \ 24 | t18.x t19.x t1a.x t1b.x t1c.x t1d.x t1e.x t1f.x \ 25 | t20.x t21.x t22.x t23.x t24.x t25.x t26.x t27.x \ 26 | t28.x t29.x t2a.x t2b.x t2c.x t2d.x t2e.x t2f.x \ 27 | t30.x t31.x t32.x t33.x t34.x t35.x t36.x t37.x \ 28 | t38.x t39.x t3a.x t3b.x t3c.x t3d.x t3e.x t3f.x \ 29 | t40.x t41.x t42.x t43.x t44.x t45.x t46.x t47.x \ 30 | t48.x t49.x t4a.x t4b.x t4c.x t4d.x t4e.x t4f.x \ 31 | t50.x t51.x t52.x t53.x t54.x t55.x t56.x t57.x \ 32 | t58.x t59.x t5a.x t5b.x t5c.x t5d.x t5e.x t5f.x \ 33 | t60.x t61.x t62.x t63.x t64.x t65.x t66.x t67.x \ 34 | t68.x t69.x t6a.x t6b.x t6c.x t6d.x t6e.x t6f.x \ 35 | t70.x t71.x t72.x t73.x t74.x t75.x t76.x t77.x \ 36 | t78.x t79.x t7a.x t7b.x t7c.x t7d.x t7e.x t7f.x \ 37 | t80.x t81.x t82.x t83.x t84.x t85.x t86.x t87.x \ 38 | t88.x t89.x t8a.x t8b.x t8c.x t8d.x t8e.x t8f.x \ 39 | t90.x t91.x t92.x t93.x t94.x t95.x t96.x t97.x \ 40 | t98.x t99.x 41 | ./test.sh 42 | 43 | .SECONDARY: 44 | %.o: %.s 45 | $(AS) $^ -o $@ 46 | %.o: %.c 47 | $(CC) -c $< 48 | %.x: %.o $(OUT).o 49 | $(LD) -o $@ $^ 50 | clean: 51 | rm -f *.o t??.x b??.x 52 | -------------------------------------------------------------------------------- /test/arm.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | .extern main 3 | _start: 4 | mov fp, #0 5 | ldr r0, [sp], #4 6 | mov r1, sp 7 | add r2, r1, r0, lsl #2 8 | add r2, r2, #4 9 | bl main 10 | mov r7, #1 11 | swi #0 12 | -------------------------------------------------------------------------------- /test/b01.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return 1; 4 | } 5 | -------------------------------------------------------------------------------- /test/b02.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return 2; 4 | } 5 | -------------------------------------------------------------------------------- /test/b03.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int i; 4 | i = 3; 5 | return i; 6 | } 7 | -------------------------------------------------------------------------------- /test/b04.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int i = 4; 4 | return i; 5 | } 6 | -------------------------------------------------------------------------------- /test/b05.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | if (0) 4 | return 4; 5 | return 5; 6 | } 7 | -------------------------------------------------------------------------------- /test/b06.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int i = 0x12345678; 4 | return i - 0x12345672; 5 | } 6 | -------------------------------------------------------------------------------- /test/b07.c: -------------------------------------------------------------------------------- 1 | int g(void) 2 | { 3 | return 7; 4 | } 5 | 6 | int main(void) 7 | { 8 | return g(); 9 | } 10 | -------------------------------------------------------------------------------- /test/b08.c: -------------------------------------------------------------------------------- 1 | int g(int i) 2 | { 3 | return i; 4 | } 5 | 6 | int main(void) 7 | { 8 | return g(8); 9 | } 10 | -------------------------------------------------------------------------------- /test/b09.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return h(9); 4 | } 5 | 6 | int h(int i) 7 | { 8 | return i; 9 | } 10 | -------------------------------------------------------------------------------- /test/b10.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return 1 + 10 - 1; 4 | } 5 | -------------------------------------------------------------------------------- /test/b11.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a = 3; 4 | int b = 2; 5 | a = a + 1; 6 | b = b + a; 7 | return a + b + 1; 8 | } 9 | -------------------------------------------------------------------------------- /test/b12.c: -------------------------------------------------------------------------------- 1 | int g(int p1, int p2, int p3, int p4, int p5, int p6) 2 | { 3 | return p1 + p2 + p3 + p4 + p5 + p6; 4 | } 5 | 6 | int main(void) 7 | { 8 | return g(7, 1, 1, 1, 1, 1); 9 | } 10 | -------------------------------------------------------------------------------- /test/b13.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a = 12; 4 | int *b; 5 | b = &a; 6 | *b = *b + 1; 7 | return *b; 8 | } 9 | -------------------------------------------------------------------------------- /test/b14.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a = 1; 4 | int b = 0; 5 | return a ? 13 + (b ? 0 : 1) : 0; 6 | } 7 | -------------------------------------------------------------------------------- /test/b15.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a[3]; 4 | a[0] = 1; 5 | *(a + a[0]) = 2; 6 | a[2] = 12; 7 | a[1] = (a + 3) - (a + 1); 8 | return *a + a[1] + *(a + 2); 9 | } 10 | -------------------------------------------------------------------------------- /test/b16.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int result; 4 | if (2 < 1) 5 | result = 30; 6 | else 7 | result = 10; 8 | return result + (1 < 2 ? 6 : 40); 9 | } 10 | -------------------------------------------------------------------------------- /test/b17.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a = 7; 4 | int b = a++; 5 | return a++ + ++b + 1; 6 | } 7 | -------------------------------------------------------------------------------- /test/b18.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int result = 0; 4 | int i; 5 | for (i = 0; i < 7; i++) 6 | result = result + i; 7 | return result - 3; 8 | } 9 | -------------------------------------------------------------------------------- /test/b19.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a = 10; 4 | int b; 5 | b = a-- + 1; 6 | return --b + a--; 7 | } 8 | -------------------------------------------------------------------------------- /test/b20.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a = 10; 4 | int b = 20; 5 | return (a * b) / 10 - 2 + 9 % 7; 6 | } 7 | -------------------------------------------------------------------------------- /test/b21.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a = 10; 4 | int b = 10; 5 | int c = 20; 6 | if (a < b) 7 | return 0; 8 | if (a != b) 9 | return 1; 10 | if (a == c) 11 | return 2; 12 | if (a > c) 13 | return 3; 14 | if (!a) 15 | return 4; 16 | return (a + b) != c ? 0 : 21; 17 | } 18 | -------------------------------------------------------------------------------- /test/b22.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a = 1 << 4; 4 | int b = 22 >> 2; 5 | return a + b + 1 << 0; 6 | } 7 | -------------------------------------------------------------------------------- /test/t00.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return 0; 4 | } 5 | -------------------------------------------------------------------------------- /test/t01.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | char a[10]; 4 | long sum = 0; 5 | int i; 6 | for (i = 0; i < 10; i++) 7 | a[i] = i; 8 | for (i = 0; i < 10; i++) 9 | sum = sum + a[i]; 10 | return (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9) != sum; 11 | } 12 | -------------------------------------------------------------------------------- /test/t02.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a = 1; 4 | int b = 7; 5 | a += 5; 6 | a += 5; 7 | a -= b; 8 | return a != 4; 9 | } 10 | -------------------------------------------------------------------------------- /test/t03.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a = 1; 4 | int b = -a + -a; 5 | return (a + b + -2) != -3; 6 | } 7 | -------------------------------------------------------------------------------- /test/t04.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a = 8; 4 | int b = 4; 5 | return (a & (b | 15)) != a; 6 | } 7 | -------------------------------------------------------------------------------- /test/t05.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int ret = 0; 4 | int a = 10; 5 | int b = 10 + (1 < 2); 6 | if (a < b && a == 10) 7 | ret++; 8 | if (a == b || a == 11) 9 | ret += 10; 10 | if (a == b || a == 10) 11 | ret++; 12 | return (ret + !0) != 3; 13 | } 14 | -------------------------------------------------------------------------------- /test/t06.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a = 0x100 | 0x001; 4 | int b = 'a'; 5 | return !(b == 'a' && a == 0x101); 6 | } 7 | -------------------------------------------------------------------------------- /test/t07.c: -------------------------------------------------------------------------------- 1 | int a; 2 | 3 | int g(void) 4 | { 5 | return a; 6 | } 7 | 8 | int main(void) 9 | { 10 | a += 2; 11 | return a != g() || a != 2 ? 1 : 0; 12 | } 13 | -------------------------------------------------------------------------------- /test/t08.c: -------------------------------------------------------------------------------- 1 | int mstrcmp(char *s, char *r) 2 | { 3 | while (*s && *s == *r) 4 | s++, r++; 5 | return *s - *r; 6 | } 7 | 8 | int main(void) 9 | { 10 | if (!mstrcmp("abc", "123")) 11 | return 1; 12 | if (!mstrcmp("123", "abc")) 13 | return 2; 14 | if (mstrcmp("abc", "abc")) 15 | return 3; 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /test/t09.c: -------------------------------------------------------------------------------- 1 | int mstrcmp(char *s, char *r) 2 | { 3 | while (*s && *s == *r) 4 | s++, r++; 5 | return *s - *r; 6 | } 7 | 8 | int main(void) 9 | { 10 | char *s1 = "abc"; 11 | char *s2 = "123"; 12 | char *s3 = "abc"; 13 | if (!mstrcmp(s1, s2)) 14 | return 1; 15 | if (!mstrcmp(s2, s3)) 16 | return 2; 17 | if (mstrcmp(s1, s3)) 18 | return 3; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /test/t0a.c: -------------------------------------------------------------------------------- 1 | int a[10]; 2 | 3 | int *g(void) 4 | { 5 | return a; 6 | } 7 | 8 | int main(void) 9 | { 10 | int i; 11 | for (i = 0; i < 10; i++) 12 | a[i] = i; 13 | return g()[3] != 3; 14 | } 15 | -------------------------------------------------------------------------------- /test/t0b.c: -------------------------------------------------------------------------------- 1 | struct t { 2 | int a; 3 | int b; 4 | int c; 5 | }; 6 | 7 | int main(void) 8 | { 9 | struct t t; 10 | t.a = 2; 11 | t.b = t.a + 3; 12 | t.c = t.a + t.b; 13 | return t.c != 7; 14 | } 15 | -------------------------------------------------------------------------------- /test/t0c.c: -------------------------------------------------------------------------------- 1 | struct t { 2 | int a; 3 | int b; 4 | int c; 5 | }; 6 | 7 | void g(struct t *tp) 8 | { 9 | tp->a = 2; 10 | } 11 | 12 | int main(void) 13 | { 14 | struct t t; 15 | struct t *tp = &t; 16 | g(tp); 17 | tp->b = tp->a + 3; 18 | tp->c = tp->a + t.b; 19 | return tp->c != 7; 20 | } 21 | -------------------------------------------------------------------------------- /test/t0d.c: -------------------------------------------------------------------------------- 1 | struct t { 2 | int a[10]; 3 | int n; 4 | }; 5 | 6 | int main(void) 7 | { 8 | struct t t; 9 | struct t *tp = &t; 10 | int i; 11 | int sum = 0; 12 | tp->n = 10; 13 | for (i = 0; i < tp->n; i++) 14 | tp->a[i] = i; 15 | for (i = 0; i < t.n; i++) 16 | sum += t.a[i]; 17 | return sum != 45; 18 | } 19 | -------------------------------------------------------------------------------- /test/t0e.c: -------------------------------------------------------------------------------- 1 | struct t { 2 | int a; 3 | int b; 4 | }; 5 | 6 | int main(void) 7 | { 8 | struct t t[10]; 9 | int i; 10 | int sum = 0; 11 | for (i = 0; i < 10; i++) 12 | t[i].a = t[i].b = i; 13 | for (i = 0; i < 10; i++) 14 | if (t[i].a != i || t[i].b != i) 15 | return 1; 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /test/t0f.c: -------------------------------------------------------------------------------- 1 | struct t { 2 | int a[2]; 3 | int b; 4 | }; 5 | 6 | int main(void) 7 | { 8 | struct t t[2]; 9 | if (sizeof(t) != 6 * 4) 10 | return 1; 11 | if (sizeof(t[0]) != 3 * 4) 12 | return 1; 13 | if (sizeof(t[0].a) != 2 * 4) 14 | return 1; 15 | if (sizeof(t[0].b) != 4) 16 | return 1; 17 | if (sizeof(t[0].a[0]) != 4) 18 | return 1; 19 | if (sizeof(struct t) != 12) 20 | return 1; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /test/t10.c: -------------------------------------------------------------------------------- 1 | union t { 2 | int a[2]; 3 | int b; 4 | }; 5 | 6 | int main(void) 7 | { 8 | union t t; 9 | t.a[0] = 1; 10 | t.a[1] = 2; 11 | t.b = 3; 12 | if (sizeof(t) != 8) 13 | return 1; 14 | if (t.a[0] != 3) 15 | return 1; 16 | if (t.a[1] != 2) 17 | return 1; 18 | if (t.b != 3) 19 | return 1; 20 | if (&t.b != &t.a[0]) 21 | return 1; 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /test/t11.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | char a1[1 ? 10 : 20]; 4 | char a2[5 + 5]; 5 | char a3[(1 << 3) + 2]; 6 | char a4[2 < 1 ? 20 : 10]; 7 | if (sizeof(a1) != 10 || sizeof(a2) != 10) 8 | return 1; 9 | if (sizeof(a3) != 10 || sizeof(a4) != 10) 10 | return 1; 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /test/t12.c: -------------------------------------------------------------------------------- 1 | enum a { 2 | a0, 3 | a1, 4 | a2 = 5 + 5, 5 | a3, 6 | a4 = -2, 7 | a5, 8 | }; 9 | 10 | int main(void) 11 | { 12 | if (a0 != 0 || a1 != 1 || a2 != 10 || a3 != 11 || a4 != -2 || a5 != -1) 13 | return 1; 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /test/t13.c: -------------------------------------------------------------------------------- 1 | typedef int mint; 2 | 3 | int main(void) 4 | { 5 | mint a; 6 | if (sizeof(a) != 4 || sizeof(mint) != 4) 7 | return 1; 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/t14.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int i; 4 | for (i = 0; i < 10; i++) { 5 | if (i == 3) 6 | continue; 7 | if (i >= 3) 8 | break; 9 | } 10 | if (i != 4) 11 | return 1; 12 | i = 0; 13 | while (i < 10) { 14 | i++; 15 | if (i == 3) 16 | continue; 17 | if (i >= 3) 18 | break; 19 | } 20 | if (i != 4) 21 | return 1; 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /test/t15.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int i = 0; 4 | do { 5 | i++; 6 | } while (i < 10); 7 | if (i != 10) 8 | return 1; 9 | i = 0; 10 | do { 11 | i++; 12 | if (i == 3) 13 | continue; 14 | if (i == 4) 15 | break; 16 | } while (i < 10); 17 | if (i != 4) 18 | return 1; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /test/t16.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int i; 4 | for (i = 0; i < 10; i++) { 5 | switch (i) { 6 | case 0: 7 | if (i != 0) 8 | return 1; 9 | break; 10 | case 5: 11 | case 5 + 1: 12 | if (i != 5 && i != 6) 13 | return 2; 14 | break; 15 | default: 16 | if (i == 0 || i == 5 || i == 6) 17 | return 3; 18 | } 19 | } 20 | if (i != 10) 21 | return 4; 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /test/t17.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | unsigned char c1 = 244; 4 | char c2 = 244; 5 | long l = (char) -1; 6 | if (c2 != (char) c1) 7 | return 1; 8 | if (l != -1) 9 | return 2; 10 | if ((long) (char) -1 != -1) 11 | return 3; 12 | if ((long) (unsigned char) (char) -1 != 255) 13 | return 4; 14 | if ((int) ((long) -1 >> 31) != -1) 15 | return 5; 16 | #ifdef __x86_64__ 17 | if ((int) ((long) -1 >> 32) != -1) 18 | return 6; 19 | #endif 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /test/t18.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | long l = -1; 4 | char c = 254; 5 | if (l >> 28 != -1) 6 | return 1; 7 | if ((long) (unsigned char) c != 254) 8 | return 2; 9 | if ((unsigned long) (c + 1) != -1) 10 | return 3; 11 | if ((unsigned long) (c * 10) != -20) 12 | return 4; 13 | if (((unsigned long) (unsigned int) -1 >> 16) != 0xffff) 14 | return 5; 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /test/t19.c: -------------------------------------------------------------------------------- 1 | int g(void) 2 | { 3 | return 3; 4 | } 5 | 6 | int main(void) 7 | { 8 | int (*h1)(void) = g; 9 | int (*h2)(void) = &g; 10 | int (**h3)(void) = &h1; 11 | if (h1() != 3 || (*h1)() != 3) 12 | return 1; 13 | if (h2() != 3 || (*h2)() != 3) 14 | return 2; 15 | if ((*h3)() != 3 || (**h3)() != 3) 16 | return 3; 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /test/t1a.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a = 1; 4 | { 5 | int a = 2; 6 | if (a != 2) 7 | return 1; 8 | } 9 | if (a != 1) 10 | return 2; 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /test/t1b.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a[10][10]; 4 | int i, j; 5 | for (i = 0; i < 10; i++) 6 | for (j = 0; j < 10; j++) 7 | a[i][j] = i * 10 + j; 8 | for (i = 0; i < 10; i++) 9 | for (j = 0; j < 10; j++) 10 | if (a[i][j] != i * 10 + j) 11 | return j; 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/t1c.c: -------------------------------------------------------------------------------- 1 | static int g1(void) 2 | { 3 | static int i; 4 | return i++; 5 | } 6 | 7 | static int g2(void) 8 | { 9 | static int i; 10 | return i++; 11 | } 12 | 13 | int main(void) 14 | { 15 | if (g1() != 0 || g1() != 1) 16 | return 1; 17 | if (g2() != 0 || g2() != 1) 18 | return 2; 19 | if (g1() != 2 || g1() != 3) 20 | return 3; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /test/t1d.c: -------------------------------------------------------------------------------- 1 | signed char g(void) 2 | { 3 | return 254; 4 | } 5 | 6 | int main(void) 7 | { 8 | if (g() != -2) 9 | return 1; 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/t1e.c: -------------------------------------------------------------------------------- 1 | int g1(void); 2 | 3 | int main(void) 4 | { 5 | if (g1() != 11) 6 | return 1; 7 | if (g2() != 21) 8 | return 2; 9 | return 0; 10 | } 11 | 12 | int g1(void) 13 | { 14 | return 11; 15 | } 16 | 17 | int g2(void) 18 | { 19 | return 21; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /test/t1f.c: -------------------------------------------------------------------------------- 1 | struct t { 2 | int c[3]; 3 | long a; 4 | long b; 5 | }; 6 | 7 | int main(void) 8 | { 9 | struct t t1, t2; 10 | int b[3]; 11 | t1.a = 10; 12 | t1.b = 20; 13 | t1.c[0] = 30; 14 | t1.c[1] = 40; 15 | t1.c[2] = 50; 16 | t2 = t1; 17 | if (t2.a != 10 || t2.b != 20) 18 | return 1; 19 | if (t2.c[0] != 30 || t2.c[1] != 40 || t2.c[2] != 50) 20 | return 1; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /test/t20.c: -------------------------------------------------------------------------------- 1 | struct t { 2 | int a[3]; 3 | int b; 4 | int c; 5 | }; 6 | 7 | int main(void) 8 | { 9 | int a[3] = {1, 2}; 10 | struct t t = {{10, 20}, 30, 40}; 11 | if (a[0] != 1 || a[1] != 2 || a[2] != 0) 12 | return 1; 13 | if (t.a[0] != 10 || t.a[1] != 20 || t.a[2] != 0) 14 | return 2; 15 | if (t.b != 30 || t.c != 40) 16 | return 3; 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /test/t21.c: -------------------------------------------------------------------------------- 1 | int g(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9) 2 | { 3 | return p1 == 1 && p2 == 2 && p3 == 3 && p4 == 4 && p5 == 5 && 4 | p6 == 6 && p7 == 7 && p8 == 8 && p9 == 9; 5 | } 6 | 7 | int main(void) 8 | { 9 | return !g(1, 2, 3, 4, 5, 6, 7, 8, 9); 10 | } 11 | -------------------------------------------------------------------------------- /test/t22.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a[2][2] = {10, 20, 30}; 4 | int b[3] = {[1] = 40}; 5 | if (b[0] != 0 || b[1] != 40 || b[2] != 0) 6 | return 1; 7 | if (a[0][0] != 10 || a[0][1] != 20 || a[1][0] != 30 || a[1][1] != 0) 8 | return 2; 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /test/t23.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int ret = 2; 4 | goto l1; 5 | l1: 6 | ret = 0; 7 | goto end; 8 | ret = 5; 9 | end: 10 | return ret; 11 | } 12 | -------------------------------------------------------------------------------- /test/t24.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | char a[10] = "ab"; 4 | if (sizeof(a) != 10) 5 | return 1; 6 | if (a[0] == 'a' && a[1] == 'b' && a[2] == 0 && a[3] == 0) 7 | return 0; 8 | return 2; 9 | } 10 | -------------------------------------------------------------------------------- /test/t25.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | char a[3] = "ab"; 4 | if (sizeof(a) != 3) 5 | return 1; 6 | if (a[0] == 'a' && a[1] == 'b' && a[2] == 0) 7 | return 0; 8 | return 2; 9 | } 10 | -------------------------------------------------------------------------------- /test/t26.c: -------------------------------------------------------------------------------- 1 | struct { 2 | int a; 3 | int b; 4 | } t; 5 | 6 | int main(void) 7 | { 8 | if (sizeof(t) != 8) 9 | return 1; 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/t27.c: -------------------------------------------------------------------------------- 1 | struct t *g(struct t *t) 2 | { 3 | return t; 4 | } 5 | 6 | struct t { 7 | int a; 8 | int b; 9 | }; 10 | 11 | int main(void) 12 | { 13 | struct t t = {10, 20}; 14 | if (g(&t)->a != 10 || g(&t)->b != 20) 15 | return 1; 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /test/t28.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | char *s = "ab"; 4 | void *p = s; 5 | if (*(char *) p != 'a' || *(char *) ((char *) p + 1) != 'b') 6 | return 1; 7 | if (sizeof(*(char *) p) != 1) 8 | return 2; 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /test/t29.c: -------------------------------------------------------------------------------- 1 | int g1(void) 2 | { 3 | return 10; 4 | } 5 | 6 | int g2(int (*x)(void)) 7 | { 8 | return x(); 9 | } 10 | 11 | int main(void) 12 | { 13 | if (g2(g1) != 10) 14 | return 1; 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /test/t2a.c: -------------------------------------------------------------------------------- 1 | typedef struct t1 { 2 | int a[3]; 3 | } t1; 4 | 5 | typedef struct { 6 | int a[4]; 7 | } t2; 8 | 9 | int main(void) 10 | { 11 | t1 x1; 12 | t2 x2; 13 | if (sizeof(x1) != 12) 14 | return 1; 15 | if (sizeof(x2) != 16) 16 | return 2; 17 | x2.a[2] = 10; 18 | if (x2.a[2] != 10) 19 | return 3; 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /test/t2b.c: -------------------------------------------------------------------------------- 1 | void g(char *a[]) 2 | { 3 | a[1] = "d"; 4 | } 5 | 6 | int main(void) 7 | { 8 | char *a[3] = {"a", "b", "c"}; 9 | g(a); 10 | if (a[1][0] != 'd') 11 | return 1; 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/t2c.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | char a[] = "abc"; 4 | int b[] = {1, 2, 3, 4}; 5 | 6 | if (sizeof(a) != 4) 7 | return 1; 8 | if (a[0] != 'a' || a[1] != 'b' || a[2] != 'c' || a[3] != 0) 9 | return 2; 10 | if (sizeof(b) != 16) 11 | return 3; 12 | if (b[0] != 1 || b[1] != 2 || b[2] != 3 || b[3] != 4) 13 | return 4; 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /test/t2d.c: -------------------------------------------------------------------------------- 1 | struct t { 2 | int a[3]; 3 | int b; 4 | int c; 5 | }; 6 | 7 | static int a[3] = {1, 2}; 8 | 9 | int main(void) 10 | { 11 | static struct t t = {{10, 20}, 30, 40}; 12 | if (a[0] != 1 || a[1] != 2 || a[2] != 0) 13 | return 1; 14 | if (t.a[0] != 10 || t.a[1] != 20 || t.a[2] != 0) 15 | return 2; 16 | if (t.b != 30 || t.c != 40) 17 | return 3; 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /test/t2e.c: -------------------------------------------------------------------------------- 1 | int g(void) 2 | { 3 | return 10; 4 | } 5 | 6 | static int (*gp)(void) = &g; 7 | 8 | int main(void) 9 | { 10 | if (gp() != 10) 11 | return 1; 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/t2f.c: -------------------------------------------------------------------------------- 1 | struct t { 2 | int a; 3 | int b; 4 | }; 5 | 6 | static struct t t1[] = {{10, 20}}; 7 | 8 | int main(void) 9 | { 10 | struct t t2[] = {{30, 40}}; 11 | if (t1->a != 10 || t2->b != 40) 12 | return 1; 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /test/t30.c: -------------------------------------------------------------------------------- 1 | static char *a[] = { "a", "b", "c" }; 2 | 3 | int main(void) 4 | { 5 | if (a[0][0] != 'a' || a[1][0] != 'b' || a[2][0] != 'c') 6 | return 1; 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/t31.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | char *a = "a" "b" "c"; 4 | if (a[0] != 'a' || a[1] != 'b' || a[2] != 'c' || a[3] != 0) 5 | return 1; 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /test/t32.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | long a = 0x10 + 010 + 10; 4 | if (a != 16 + 8 + 10) 5 | return 1; 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /test/t33.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | char *s = "\33\xf\x11"; 4 | if ('\0' != 0) 5 | return 1; 6 | if (s[0] != 3 * 8 + 3) 7 | return 2; 8 | if (s[1] != 15 || s[2] != 1 * 16 + 1) 9 | return 3; 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/t34.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int i = 0; 4 | for (;;) { 5 | if (++i == 10) 6 | break; 7 | } 8 | if (i != 10) 9 | return 1; 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/t35.c: -------------------------------------------------------------------------------- 1 | #define N 10 2 | 3 | int main(void) 4 | { 5 | char a[N]; 6 | if (sizeof(a) != 10 || N != 10) 7 | return 1; 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/t36.c: -------------------------------------------------------------------------------- 1 | #define N 10 + \ 2 | 20 3 | 4 | int main(void) 5 | { 6 | if ((N) != 30) 7 | return 1; 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/t37.c: -------------------------------------------------------------------------------- 1 | #include "t55.h" 2 | 3 | int main(void) 4 | { 5 | if (g() != N) 6 | return 1; 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/t38.c: -------------------------------------------------------------------------------- 1 | #define M(a) ((a) + 1) /*((a) + 1)*/ 2 | 3 | int main(void) 4 | { 5 | if (M(2) != 3) 6 | return 1; 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/t39.c: -------------------------------------------------------------------------------- 1 | #define A 2 | 3 | int main(void) 4 | { 5 | int i = 0; 6 | #ifdef A 7 | i = 10; 8 | #else 9 | i = 20; 10 | #endif 11 | if (i != 10) 12 | return 1; 13 | #ifndef A 14 | i = 1; 15 | #else 16 | i = 2; 17 | #endif 18 | if (i != 2) 19 | return 2; 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /test/t3a.c: -------------------------------------------------------------------------------- 1 | #define A 1 2 | #define B 2 3 | 4 | int main(void) 5 | { 6 | int i = 0; 7 | #if A == B 8 | i = 10; 9 | #elif A == B / 2 10 | i = 20; 11 | #else 12 | i = 30; 13 | #endif 14 | if (i != 20) 15 | return 1; 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /test/t3b.c: -------------------------------------------------------------------------------- 1 | #define A 2 | 3 | #ifndef A 4 | #ifndef C 5 | #define B 10 6 | #else 7 | #define B 20 8 | #endif 9 | #else 10 | #if defined(A) && !defined(B) 11 | #define B 30 12 | #endif 13 | #endif 14 | 15 | #define D(a, b) ((a) + (b)) 16 | 17 | int main(void) 18 | { 19 | if (B != 30) 20 | return 1; 21 | if (D(B, 10) != 40) 22 | return 2; 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /test/t3c.c: -------------------------------------------------------------------------------- 1 | int g1(int a) 2 | { 3 | return a; 4 | } 5 | 6 | int g2(int a, int b) 7 | { 8 | return a + b; 9 | } 10 | 11 | int main(void) 12 | { 13 | if (g2(g1(1), g2(g1(2), g1(3))) != 6) 14 | return 1; 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /test/t3d.c: -------------------------------------------------------------------------------- 1 | #ifdef __x86_64__ 2 | int main(void) 3 | { 4 | char *s1[10]; 5 | char s3[10]; 6 | char (*s2)[10]; 7 | int (*x)(int a); 8 | if (sizeof(s1) != 80) 9 | return 1; 10 | if (sizeof(s2) != 8) 11 | return 2; 12 | if (sizeof(x) != 8) 13 | return 2; 14 | return 0; 15 | } 16 | #else 17 | int main(void) 18 | { 19 | char *s1[10]; 20 | char s3[10]; 21 | char (*s2)[10]; 22 | int (*x)(int a); 23 | if (sizeof(s1) != 40) 24 | return 1; 25 | if (sizeof(s2) != 4) 26 | return 2; 27 | if (sizeof(x) != 4) 28 | return 3; 29 | return 0; 30 | } 31 | #endif 32 | -------------------------------------------------------------------------------- /test/t3e.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int i = 2; 4 | if (!(i == 2)) 5 | return 1; 6 | if (!(i != 3)) 7 | return 2; 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/t3f.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int i = 0; 4 | int *p = &i; 5 | *p |= 4; 6 | if (i != 4) 7 | return 1; 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/t40.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | char a[] = "ab"; 4 | int cur = 0; 5 | if (a[cur++] != 'a') 6 | return 1; 7 | if (a[cur++] != 'b') 8 | return 2; 9 | if (a[cur++] != '\0') 10 | return 3; 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /test/t41.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | unsigned long l = 1; 4 | if (l != 1) 5 | return 1; 6 | if (!l != 0) 7 | return 2; 8 | if (!!l != 1) 9 | return 3; 10 | if (!l) 11 | return 4; 12 | if (!!!l) 13 | return 5; 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /test/t42.c: -------------------------------------------------------------------------------- 1 | int slen(char *s) 2 | { 3 | int n = 0; 4 | while (*s++) 5 | n++; 6 | return n; 7 | } 8 | 9 | int main(void) 10 | { 11 | char *s[] = {"ab", "c"}; 12 | int len[] = {slen(s[0]), slen(s[1])}; 13 | if (len[0] != 2 || len[1] != 1) 14 | return 1; 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /test/t43.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | long x = 1; 4 | if (x << 31 != 1ul << 31) 5 | return 1; 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /test/t44.c: -------------------------------------------------------------------------------- 1 | struct t { 2 | int a; 3 | }; 4 | 5 | int g(void) 6 | { 7 | return 1; 8 | } 9 | 10 | int main(void) 11 | { 12 | struct t t; 13 | struct t *p = &t; 14 | p->a = g(); 15 | if (t.a != 1) 16 | return 1; 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /test/t45.c: -------------------------------------------------------------------------------- 1 | int g(void) 2 | { 3 | return 30; 4 | } 5 | 6 | int main(void) 7 | { 8 | int a = 10; 9 | int b = a + a - a + (a == 20 ? g() : 10); 10 | if (a != 10 || g() != 30 || b != 20) 11 | return 1; 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/t46.c: -------------------------------------------------------------------------------- 1 | enum { 2 | TEN = 10, 3 | TWENTY = 20, 4 | THIRTY = 30 5 | }; 6 | int g(void) 7 | { 8 | return 30; 9 | } 10 | 11 | int main(void) 12 | { 13 | switch (g()) { 14 | case TEN: 15 | return 1; 16 | case TWENTY: 17 | return 2; 18 | case THIRTY: 19 | return 0; 20 | default: 21 | return 3; 22 | } 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /test/t47.c: -------------------------------------------------------------------------------- 1 | int g(int i) 2 | { 3 | return i; 4 | } 5 | 6 | int main(void) 7 | { 8 | int (*p)(int i) = g; 9 | if (p(10) != 10) 10 | return 1; 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /test/t48.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int off = -0x88; 4 | if (off == (char) off) 5 | return 1; 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /test/t49.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int i[3] = {2, 0, 3}; 4 | for (i[1] = 9; i[1] >= 0; --i[1]) 5 | ; 6 | if (i[0] != 2 || i[2] != 3) 7 | return 1; 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/t4a.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | long i = 0xffffffff; 4 | if (i != (unsigned) i) 5 | return 1; 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /test/t4b.c: -------------------------------------------------------------------------------- 1 | static int rr = 0; 2 | static int gr = 0; 3 | static int br = 0; 4 | static int rl = 16; 5 | static int gl = 8; 6 | static int bl = 0; 7 | 8 | unsigned int g(unsigned char r, unsigned char g, unsigned char b) 9 | { 10 | return ((r >> rr) << rl) | ((g >> gr) << gl) | ((b >> br) << bl); 11 | } 12 | 13 | int main(void) 14 | { 15 | unsigned char cr = 0x11; 16 | unsigned char cg = 0x22; 17 | unsigned char cb = 0x33; 18 | if (g(0, 0, 0) != 0) 19 | return 1; 20 | if (g(255, 255, 255) != 0x00ffffff) 21 | return 2; 22 | if (g(0x11, 0x22, 0x33) != 0x00112233) 23 | return 3; 24 | if (g(cr, cg, cb) != 0x00112233) 25 | return 4; 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /test/t4c.c: -------------------------------------------------------------------------------- 1 | static int i; 2 | static int a[2]; 3 | 4 | int main(void) 5 | { 6 | int j = 10; 7 | int b[2]; 8 | int *p = a; 9 | if (i++ != 0 || i != 1) 10 | return 1; 11 | if (--j != 9 || j != 9) 12 | return 2; 13 | p = a; 14 | *p++ = 10; 15 | *p++ = 20; 16 | if (a[0] != 10 || a[1] != 20) 17 | return 3; 18 | p = b + 1; 19 | *p-- = 30; 20 | *p-- = 40; 21 | if (b[0] != 40 || b[1] != 30) 22 | return 4; 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /test/t4d.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a[3] = {10, 20, 30}; 4 | int *p = a; 5 | p += 1; 6 | if (*p != 20) 7 | return 1; 8 | p++; 9 | if (*p != 30) 10 | return 2; 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /test/t4e.c: -------------------------------------------------------------------------------- 1 | int g1(void) 2 | { 3 | return 10; 4 | } 5 | 6 | int g2(void) 7 | { 8 | return 20; 9 | } 10 | 11 | int main(void) 12 | { 13 | int (*x1[])(void) = {g1, g2}; 14 | int (*x2[][1])(void) = {{g1}, {g2}}; 15 | if (x1[0]() != 10 || x1[1]() != 20) 16 | return 1; 17 | if (x2[0][0]() != 10 || x2[1][0]() != 20) 18 | return 2; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /test/t4f.c: -------------------------------------------------------------------------------- 1 | #define TWICE(a) ((a) * 2) 2 | 3 | int STH(int a) 4 | { 5 | return a * 3; 6 | } 7 | 8 | #define STH(a) (STH(a) * 2) 9 | 10 | int main(void) 11 | { 12 | int a = 5; 13 | if (TWICE(1) != 2 && TWICE(TWICE(1)) != 4) 14 | return 1; 15 | if (STH(2) != 12) 16 | return 2; 17 | if (TWICE(TWICE(a)) != 20) 18 | return 3; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /test/t50.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int i = 0, j, k; 4 | j = 1; 5 | k = 2; 6 | return i + j + k != 3; 7 | } 8 | -------------------------------------------------------------------------------- /test/t51.c: -------------------------------------------------------------------------------- 1 | struct t { 2 | int f1; 3 | int f2; 4 | int f3; 5 | int f4; 6 | int f5; 7 | int f6; 8 | }; 9 | 10 | int g(int p1, int p2, int p3, int p4) 11 | { 12 | return p1 + p2 + p3 + p4; 13 | } 14 | 15 | int main(void) 16 | { 17 | struct t t = {1, 1, 2, 2, 3, 3}; 18 | struct t *tp = &t; 19 | int (*fp)(int a1, ...) = g; 20 | return fp(tp->f6, tp->f5, tp->f4, tp->f3, tp->f2, tp->f1) != 10; 21 | } 22 | -------------------------------------------------------------------------------- /test/t52.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | char *s = "\2\12\123\x32"; 4 | if (s[0] != 02 || s[1] != 012 || s[2] != 0123) 5 | return 1; 6 | if (s[3] != 0x32) 7 | return 2; 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/t53.c: -------------------------------------------------------------------------------- 1 | /* testing optimized version of mul/div/mod for powers of two */ 2 | 3 | static unsigned a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 4 | 5 | int main(void) 6 | { 7 | unsigned i; 8 | i = 5; 9 | if (a[i] != 5) 10 | return 1; 11 | if (i * 16 != 80) 12 | return 2; 13 | i = 22; 14 | if (i / 4 != 5) 15 | return 3; 16 | if (i % 4 != 2) 17 | return 4; 18 | i = 0x12345678; 19 | if (i % 0x00010000 != 0x00005678) 20 | return 4; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /test/t54.c: -------------------------------------------------------------------------------- 1 | /* testing signed multiplication */ 2 | 3 | int main(void) 4 | { 5 | long i1 = 2; 6 | long i2 = 3; 7 | long i3 = -4; 8 | long i4 = -5; 9 | if (i1 * i2 != 6) 10 | return 1; 11 | if (i1 * i3 != -8) 12 | return 2; 13 | if (i3 * i4 != 20) 14 | return 3; 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /test/t55.c: -------------------------------------------------------------------------------- 1 | static int digits(unsigned long n, int base) 2 | { 3 | int i; 4 | for (i = 0; n; i++) 5 | n /= base; 6 | return i ? i : 1; 7 | } 8 | 9 | static char *digs = "0123456789abcdef"; 10 | 11 | static void putint(char *s, unsigned long n, int base) 12 | { 13 | int d; 14 | int i; 15 | d = digits(n, base); 16 | for (i = 0; i < d; i++) { 17 | s[d - i - 1] = digs[n % base]; 18 | n /= base; 19 | } 20 | s[d] = '\0'; 21 | } 22 | 23 | static int mstrcmp(char *s, char *r) 24 | { 25 | while (*s == *r) { 26 | if (!*s) 27 | return 0; 28 | s++; 29 | r++; 30 | } 31 | return *r - *s; 32 | } 33 | 34 | int main(void) 35 | { 36 | char dst[16]; 37 | if (digits(123, 10) != 3) 38 | return 1; 39 | putint(dst, 123, 10); 40 | if (mstrcmp("123", dst)) 41 | return 2; 42 | putint(dst, 130, 2); 43 | if (mstrcmp("10000010", dst)) 44 | return 3; 45 | putint(dst, 0x1234, 16); 46 | if (mstrcmp("1234", dst)) 47 | return 4; 48 | putint(dst, 0x8f8f8f8f, 16); 49 | if (mstrcmp("8f8f8f8f", dst)) 50 | return 5; 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /test/t55.h: -------------------------------------------------------------------------------- 1 | #define N 10 2 | 3 | int g(void) 4 | { 5 | return N; 6 | } 7 | -------------------------------------------------------------------------------- /test/t56.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | unsigned int s1 = 30; 4 | int s2 = -50; 5 | if (s1 * 4 != 120) 6 | return 1; 7 | if (s2 * 4 != -200) 8 | return 2; 9 | if (s1 / 2 != 15) 10 | return 3; 11 | if (s2 / 2 != -25) 12 | return 4; 13 | if (s2 % 2 != 0) 14 | return 5; 15 | if (s2 / 8 != -6) 16 | return 7; 17 | if (s2 % 8 != -2) 18 | return 8; 19 | if (s2 / -8 != 6) 20 | return 9; 21 | if (s2 % -8 != -2) 22 | return 10; 23 | if (s1 % 8 != 6) 24 | return 11; 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /test/t57.c: -------------------------------------------------------------------------------- 1 | #define SZ (1 << 10) 2 | 3 | int main(void) 4 | { 5 | int x[123]; 6 | int a[SZ]; 7 | int i; 8 | short j; 9 | i = 0x11223344; 10 | j = 0x5566; 11 | if (i != 0x11223344) 12 | return 1; 13 | if (j != 0x5566) 14 | return 2; 15 | for (i = 0; i < SZ; i++) 16 | a[i] = i; 17 | for (i = 0; i < SZ; i++) 18 | if (a[i] != i) 19 | return 3; 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /test/t58.c: -------------------------------------------------------------------------------- 1 | /* should not optimize the last return if it is nested */ 2 | int f(int i) 3 | { 4 | if (i) 5 | return i; 6 | } 7 | 8 | int main(void) 9 | { 10 | f(1); 11 | f(2); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/t59.c: -------------------------------------------------------------------------------- 1 | #define SZ (1 << 18) 2 | 3 | int main(void) 4 | { 5 | int a[20]; 6 | int i = 10; 7 | int j; 8 | a[i] = 5; 9 | j = (unsigned char) a[i]; 10 | if (j != 5) 11 | return 1; 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/t5a.c: -------------------------------------------------------------------------------- 1 | static int g(void) 2 | { 3 | return 0x1234; 4 | } 5 | 6 | static void *f(int (*x)(void)) 7 | { 8 | return x; 9 | } 10 | 11 | int main(void) 12 | { 13 | if (g != f(g)) 14 | return 1; 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /test/t5b.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int c0 = 0; 4 | int c1 = 1; 5 | if (c0 || c0 && c1 || c0) 6 | return 1; 7 | if (c0 && (c0 || c1)) 8 | return 2; 9 | if (c1 != 0 && (c0 || c1)) 10 | return 0; 11 | return 3; 12 | } 13 | -------------------------------------------------------------------------------- /test/t5c.c: -------------------------------------------------------------------------------- 1 | #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) 2 | 3 | int main(void) 4 | { 5 | int c7 = 7; 6 | int c4 = 4; 7 | if (ALIGN(c7, c4) != 8) 8 | return 1; 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /test/t5d.c: -------------------------------------------------------------------------------- 1 | struct type { 2 | unsigned bt; 3 | }; 4 | 5 | static void g(void) 6 | { 7 | } 8 | 9 | int f(struct type *t) 10 | { 11 | int sign = 1; 12 | int size = 4; 13 | int done = 0; 14 | int i = 0; 15 | g(); 16 | t->bt = size | (sign ? 0x100 : 0); 17 | return 0; 18 | } 19 | 20 | int main(void) 21 | { 22 | struct type t; 23 | f(&t); 24 | if (t.bt != 0x104) 25 | return 1; 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /test/t5e.c: -------------------------------------------------------------------------------- 1 | #define A() (10) 2 | #define B(a) (10) 3 | 4 | int main(void) 5 | { 6 | int c10 = 10; 7 | if (A() != c10) 8 | return 1; 9 | if (B(0) == c10) 10 | return 0; 11 | return 2; 12 | } 13 | -------------------------------------------------------------------------------- /test/t5f.c: -------------------------------------------------------------------------------- 1 | static int a; 2 | 3 | int main(void) 4 | { 5 | int f(void); 6 | if (f() != 0) 7 | return 1; 8 | a = 1; 9 | if (f() != 1) 10 | return 2; 11 | return 0; 12 | } 13 | 14 | int f(void) 15 | { 16 | return a; 17 | } 18 | -------------------------------------------------------------------------------- /test/t60.c: -------------------------------------------------------------------------------- 1 | int f(void) 2 | { 3 | extern int a; 4 | return a; 5 | } 6 | 7 | int a; 8 | 9 | int main(void) 10 | { 11 | if (f() != 0) 12 | return 1; 13 | a = 1; 14 | if (f() != 1) 15 | return 2; 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /test/t61.c: -------------------------------------------------------------------------------- 1 | struct dat { 2 | int a[16]; 3 | }; 4 | 5 | static int a = 0; 6 | 7 | static struct dat *f(void) 8 | { 9 | a++; 10 | return 0; 11 | } 12 | 13 | int main(void) 14 | { 15 | int sz = sizeof(f()->a); 16 | if (sizeof(f()->a) != 16 * sizeof(int)) 17 | return 1; 18 | if (sz != 16 * sizeof(int)) 19 | return 2; 20 | if (a) 21 | return 3; 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /test/t62.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | unsigned char a[10]; 4 | int i; 5 | for (i = 0; i < sizeof(a); i++) 6 | a[i] = i; 7 | a[5] += 2; 8 | for (i = 0; i < sizeof(a); i++) 9 | if (i != 5 && a[i] != i) 10 | return i; 11 | if (a[5] != 7) 12 | return 5; 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /test/t63.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a = 5; 4 | int r = 0; 5 | switch (a) { 6 | case 1: 7 | r |= 0x01; 8 | case 3: 9 | r |= 0x02; 10 | case 5: 11 | r |= 0x04; 12 | case 7: 13 | r |= 0x08; 14 | default: 15 | r |= 0x10; 16 | } 17 | if (r != 0x1c) 18 | return 1; 19 | r = 0; 20 | switch (a) { 21 | case 1: 22 | r |= 0x01; 23 | default: 24 | r |= 0x02; 25 | case 7: 26 | r |= 0x08; 27 | break; 28 | } 29 | if (r != 0x0a) 30 | return 2; 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /test/t64.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int i = 0; 4 | if (1) 5 | do { 6 | i = 1; 7 | } while (0); 8 | else 9 | i = 2; 10 | return i != 1; 11 | } 12 | -------------------------------------------------------------------------------- /test/t65.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int v = 1; 4 | if ((1 ? v : 2) != 1) 5 | return 1; 6 | if ((0 ? v : 2) != 2) 7 | return 1; 8 | if ((1 ? 2 : v) != 2) 9 | return 1; 10 | if ((0 ? 2 : v) != 1) 11 | return 1; 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/t66.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int t = 1; 4 | int f = 0; 5 | int v = 3; 6 | if ((t ? v : 2) != 3) 7 | return 1; 8 | if ((f ? v : 2) != 2) 9 | return 1; 10 | if ((t ? 2 : v) != 2) 11 | return 1; 12 | if ((f ? 2 : v) != 3) 13 | return 1; 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /test/t67.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a = 1; 4 | if ((sizeof a + 1) != sizeof(a) + 1) 5 | return 1; 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /test/t68.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int t = 1, f = 0; 4 | int a = 1; 5 | return (t ? f ? a * 2 : a * 3 : f ? 5 : 7) != 3; 6 | } 7 | -------------------------------------------------------------------------------- /test/t69.c: -------------------------------------------------------------------------------- 1 | #define TABITEMS 0x1000 2 | 3 | int hash(char *s) 4 | { 5 | unsigned h = 0x12345678; 6 | while (*s) { 7 | h ^= (h >> ((h & 0xf) + 1)); 8 | h += *s++; 9 | h ^= (h << ((h & 0xf) + 5)); 10 | } 11 | h &= (TABITEMS - 1); 12 | return h ? h : 1; 13 | } 14 | 15 | int main(void) 16 | { 17 | hash("__STDC__"); 18 | hash("__i386__"); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /test/t6a.c: -------------------------------------------------------------------------------- 1 | static char *buf = "((x))"; 2 | static int cur = 1; 3 | static int len = 5; 4 | 5 | void readarg(void) 6 | { 7 | int depth = 0; 8 | while (cur < len && (depth || buf[cur] != ')')) { 9 | switch (buf[cur++]) { 10 | case '(': 11 | case '[': 12 | case '{': 13 | depth++; 14 | break; 15 | case ')': 16 | case ']': 17 | case '}': 18 | depth--; 19 | break; 20 | } 21 | } 22 | } 23 | 24 | int main(void) 25 | { 26 | readarg(); 27 | if (cur != 4) 28 | return 1; 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /test/t6b.c: -------------------------------------------------------------------------------- 1 | #define B "//" 2 | 3 | int main(void) 4 | { 5 | char *s = "a" B; 6 | if (s[0] != 'a' || s[1] != '/' || s[2] != '/' || s[3] != '\0') 7 | return 1; 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/t6c.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | switch (2) { 4 | default: 5 | return 1; 6 | case 2: 7 | return 0; 8 | } 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /test/t6d.c: -------------------------------------------------------------------------------- 1 | int f1(void) 2 | { 3 | return 1; 4 | } 5 | 6 | int f2(void) 7 | { 8 | return 2; 9 | } 10 | 11 | int main(void) 12 | { 13 | int c = 0; 14 | if ((c ? f1 : f2)() != 2) 15 | return 1; 16 | c = 1; 17 | if ((c ? f1 : f2)() != 1) 18 | return 2; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /test/t6e.c: -------------------------------------------------------------------------------- 1 | #define ABC "ABC" 2 | 3 | char abc[80] = {ABC}; 4 | 5 | int main(void) 6 | { 7 | if (abc[0] != 'A' || abc[1] != 'B' || abc[2] != 'C' || abc[3] != '\0') 8 | return 1; 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /test/t6f.c: -------------------------------------------------------------------------------- 1 | #define ABC "ABC" 2 | 3 | char s[][4] = {"a0", "a1", "a2"}; 4 | 5 | int main(void) 6 | { 7 | if (s[0][0] != 'a' || s[0][1] != '0' || s[0][2] != '\0') 8 | return 1; 9 | if (s[1][0] != 'a' || s[1][1] != '1' || s[1][2] != '\0') 10 | return 1; 11 | if (s[2][0] != 'a' || s[2][1] != '2' || s[2][2] != '\0') 12 | return 1; 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /test/t70.c: -------------------------------------------------------------------------------- 1 | char f1(void) 2 | { 3 | return -1; 4 | } 5 | 6 | short f2(void) 7 | { 8 | return -1; 9 | } 10 | 11 | int f3(void) 12 | { 13 | return -1; 14 | } 15 | 16 | long f4(void) 17 | { 18 | return -1; 19 | } 20 | 21 | int main(void) 22 | { 23 | if (f1() >= 0) 24 | return 1; 25 | if (f2() >= 0) 26 | return 2; 27 | if (f3() >= 0) 28 | return 3; 29 | if (f4() >= 0) 30 | return 4; 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /test/t71.c: -------------------------------------------------------------------------------- 1 | static struct tmp { 2 | long addr; 3 | unsigned loc; 4 | unsigned bt; 5 | } tmp[2]; 6 | 7 | int main(void) 8 | { 9 | tmp[0].addr = 1; 10 | tmp[0].loc = 1; 11 | tmp[0].bt = 1; 12 | tmp[1].addr = 2; 13 | tmp[1].loc = 2; 14 | tmp[1].bt = 2; 15 | if (tmp[0].addr != 1 || tmp[0].loc != 1 || tmp[0].bt != 1) 16 | return 1; 17 | if (tmp[1].addr != 2 || tmp[1].loc != 2 || tmp[1].bt != 2) 18 | return 2; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /test/t72.c: -------------------------------------------------------------------------------- 1 | #define BUF_FILE 0 2 | 3 | int main(void) 4 | { 5 | int type = 2; 6 | if (type & BUF_FILE) 7 | return 1; 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/t73.c: -------------------------------------------------------------------------------- 1 | int f(i, j) 2 | { 3 | return i + j; 4 | } 5 | 6 | int main(void) 7 | { 8 | return f(1, 2) - 3; 9 | } 10 | -------------------------------------------------------------------------------- /test/t74.c: -------------------------------------------------------------------------------- 1 | int f(s, i) 2 | char *s; 3 | int i; 4 | { 5 | while (*s++) 6 | i++; 7 | return i; 8 | } 9 | 10 | int main(void) 11 | { 12 | if (f("aaa", 1) != 4) 13 | return 1; 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /test/t75.c: -------------------------------------------------------------------------------- 1 | #define HASH_BITS 13 2 | #define BITS 16 3 | 4 | #if HASH_BITS > BITS-1 5 | error: this should not be parsed! 6 | #endif 7 | 8 | int main(void) 9 | { 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/t76.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a = 1; 4 | int b = 2; 5 | a += (a += 2, b = 4); 6 | return a - 7; 7 | } 8 | -------------------------------------------------------------------------------- /test/t77.c: -------------------------------------------------------------------------------- 1 | int f(int a[][2]) 2 | { 3 | a[0][0] = 0; 4 | a[0][1] = 1; 5 | a[1][0] = 2; 6 | a[1][1] = 3; 7 | } 8 | 9 | int main(void) 10 | { 11 | int a[2][2]; 12 | f(a); 13 | if (a[0][0] != 0 || a[0][1] != 1 || a[1][0] != 2 || a[1][1] != 3) 14 | return 1; 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /test/t78.c: -------------------------------------------------------------------------------- 1 | f(a) 2 | { 3 | return a * 3; 4 | } 5 | 6 | int main(void) 7 | { 8 | return f(2) - 6; 9 | } 10 | -------------------------------------------------------------------------------- /test/t79.c: -------------------------------------------------------------------------------- 1 | #define NOFUNC (int (*)()) 0 2 | 3 | int main(void) 4 | { 5 | void *v = NOFUNC; 6 | return v != 0; 7 | } 8 | -------------------------------------------------------------------------------- /test/t7a.c: -------------------------------------------------------------------------------- 1 | int g(int x) 2 | { 3 | int a, b, c, d, e, f; 4 | int ret = 0; 5 | a = x; 6 | b = x; 7 | c = x; 8 | d = x; 9 | e = x; 10 | f = x; 11 | if (x > 0 && g(x - 1)) 12 | return 1; 13 | if (a != x || b != x || c != x || d != x || e != d || f != d) 14 | return 1; 15 | return ret; 16 | } 17 | 18 | int main(void) 19 | { 20 | return g(16); 21 | } 22 | -------------------------------------------------------------------------------- /test/t7b.c: -------------------------------------------------------------------------------- 1 | #define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) 2 | #define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) 3 | #define ELF_ST_INFO ELF64_ST_INFO 4 | 5 | int main(void) 6 | { 7 | if (ELF_ST_INFO(1, 2) != 0x12) 8 | return 1; 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /test/t7c.c: -------------------------------------------------------------------------------- 1 | static char *digs = "0123456789abcdef"; 2 | 3 | void putint(char *s, int n, int base) 4 | { 5 | int d = 10; 6 | int i; 7 | for (i = 0; i < d; i++) 8 | s[d - i] = digs[n % base]; 9 | s[d] = '\0'; 10 | } 11 | 12 | int main(void) 13 | { 14 | char dst[16]; 15 | putint(dst, 2, 10); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /test/t7d.c: -------------------------------------------------------------------------------- 1 | #define LONGSZ 4 2 | #define BT_SZMASK 0x00ff 3 | #define BT_SIGNED 0x0100 4 | #define BT_SZ(bt) ((bt) & BT_SZMASK) 5 | 6 | struct tmp { 7 | long addr; 8 | }; 9 | 10 | void num_cast(struct tmp *t, unsigned bt) 11 | { 12 | if (!(bt & BT_SIGNED) && BT_SZ(bt) != LONGSZ) 13 | t->addr &= ((1l << (long) (BT_SZ(bt) * 8)) - 1); 14 | if (bt & BT_SIGNED && BT_SZ(bt) != LONGSZ && 15 | t->addr > (1l << (BT_SZ(bt) * 8 - 1))) 16 | t->addr = -((1l << (BT_SZ(bt) * 8)) - t->addr); 17 | } 18 | 19 | int main(void) 20 | { 21 | struct tmp t[10]; 22 | struct tmp *t0 = &t[0]; 23 | struct tmp *t1 = &t[1]; 24 | struct tmp *t2 = &t[2]; 25 | struct tmp *t3 = &t[3]; 26 | num_cast(t0, 4); 27 | num_cast(t1, 4); 28 | num_cast(t2, 4); 29 | num_cast(t3, 4); 30 | if (t0 != &t[0]) 31 | return 1; 32 | if (t1 != &t[1]) 33 | return 1; 34 | if (t2 != &t[2]) 35 | return 1; 36 | if (t3 != &t[3]) 37 | return 1; 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /test/t7e.c: -------------------------------------------------------------------------------- 1 | static char scrs[0][32]; 2 | 3 | int main(void) 4 | { 5 | if (sizeof(scrs) != 0) 6 | return 1; 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/t7f.c: -------------------------------------------------------------------------------- 1 | static char saved[2]; 2 | 3 | int main(void) 4 | { 5 | if (sizeof(saved) != 2) 6 | return 1; 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/t80.c: -------------------------------------------------------------------------------- 1 | int a; 2 | 3 | void f(int v) 4 | { 5 | a = v; 6 | } 7 | 8 | int main(void) 9 | { 10 | a ? f(2) : f(1); 11 | return a != 1; 12 | } 13 | -------------------------------------------------------------------------------- /test/t81.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return sizeof("123456789") != 10; 4 | } 5 | -------------------------------------------------------------------------------- /test/t82.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return \ 4 | 0; 5 | } 6 | -------------------------------------------------------------------------------- /test/t83.c: -------------------------------------------------------------------------------- 1 | #define C1(x) (!((x) & ~0x7f)) 2 | #define C2(x) ((x) < 0x80) 3 | 4 | int main(void) 5 | { 6 | int i; 7 | for (i = 0; i < 0x1000; i++) 8 | if (C1(i) != C2(i)) 9 | return 1; 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/t84.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a = 10; 4 | if (!a) 5 | return 1; 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /test/t85.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | #ifdef __x86_64__ 4 | long a = 0x00001000000000ul; 5 | return a != (1l << 36); 6 | #endif 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/t86.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int a = + 3; 4 | int b = - 3; 5 | return a - - b; 6 | } 7 | -------------------------------------------------------------------------------- /test/t87.c: -------------------------------------------------------------------------------- 1 | static int files[16][1024]; 2 | static int nfiles; 3 | static int cfile; 4 | 5 | static int f(char *s) 6 | { 7 | return 0; 8 | } 9 | 10 | int main(void) 11 | { 12 | f(files[nfiles++]); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /test/t88.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int x = -200; 4 | x /= 6; 5 | return x != -33; 6 | } 7 | -------------------------------------------------------------------------------- /test/t89.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | char a[] = "\18"; 4 | return a[0] != 1 || a[1] != '8' || a[2] != 0; 5 | } 6 | -------------------------------------------------------------------------------- /test/t8a.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int i = 0; 4 | while (++i < 10) { 5 | if (i == 5) 6 | goto out; 7 | if (i == 3) 8 | continue; 9 | } 10 | out: 11 | return i != 5; 12 | } 13 | -------------------------------------------------------------------------------- /test/t8b.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The following requires operations to be performed using int values 3 | * and not using values with architecture word size. 4 | */ 5 | int main(void) 6 | { 7 | unsigned n = 0xffffff00; 8 | int shift = 24; 9 | return (n << shift) != 0; 10 | } 11 | -------------------------------------------------------------------------------- /test/t8c.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | unsigned n = 0x10000000; 4 | int m = 0x1000; 5 | unsigned a = 0x80000001; 6 | unsigned b = 0x80000002; 7 | if ((n * m / m) != 0) 8 | return 1; 9 | if (a + b != 0x00000003) 10 | return 2; 11 | if (sizeof(a + b) != 4) 12 | return 3; 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /test/t8d.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | unsigned short a = 0x8001; 4 | unsigned short b = 0x8002; 5 | int c = a + b; 6 | if (c != 0x00010003) 7 | return 1; 8 | if (sizeof(a - b) != 4) 9 | return 2; 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/t8e.c: -------------------------------------------------------------------------------- 1 | /* Reported by Alexey Frunze */ 2 | int main(void) 3 | { 4 | int n = 0X01; 5 | if (n++, n++, n++, n++, ++n != 6) 6 | return 1; 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/t8f.c: -------------------------------------------------------------------------------- 1 | struct rstate { 2 | int mark[64 * 2]; 3 | int pc; 4 | char *s; 5 | char *o; 6 | int flg; 7 | }; 8 | 9 | static int flg(struct rstate *rs) 10 | { 11 | struct rstate x = *rs; 12 | return x.flg; 13 | } 14 | 15 | int main(void) 16 | { 17 | struct rstate y; 18 | y.flg = 0x11223344; 19 | if (flg(&y) != 0x11223344) 20 | return 1; 21 | if (y.flg != 0x11223344) 22 | return 2; 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /test/t90.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | char (*p)[10]; 4 | char a[10] = "abcd"; 5 | p = a; 6 | if (sizeof(p) != sizeof(long)) 7 | return 1; 8 | if (sizeof(p[0]) != 10) 9 | return 1; 10 | if (p[0][2] != 'c') 11 | return 2; 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/t91.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | char (*p[3])[10]; 4 | char a[10] = "abcd"; 5 | p[1] = a; 6 | if (sizeof(p) != sizeof(long) * 3) 7 | return 1; 8 | if (sizeof(p[1][0]) != 10) 9 | return 1; 10 | if (p[1][0][2] != 'c') 11 | return 2; 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/t92.c: -------------------------------------------------------------------------------- 1 | #define n_itn (*nreg(map(".itn"))) /* .it lines left */ 2 | 3 | int x = 2; 4 | 5 | int map(char *x) 6 | { 7 | return 1; 8 | } 9 | 10 | int *nreg(int id) 11 | { 12 | return &x; 13 | } 14 | 15 | int main(void) 16 | { 17 | int i = --(n_itn); 18 | return x - 1; 19 | } 20 | -------------------------------------------------------------------------------- /test/t93.c: -------------------------------------------------------------------------------- 1 | static int f(void) 2 | { 3 | char s1[1] = ""; 4 | return 0; 5 | } 6 | 7 | int main(void) 8 | { 9 | return f(); 10 | } 11 | -------------------------------------------------------------------------------- /test/t94.c: -------------------------------------------------------------------------------- 1 | static int f(int a, int b, int c, int d) 2 | { 3 | int *p = &d; 4 | return p ? d : 0; 5 | } 6 | 7 | int main(void) 8 | { 9 | return f(1, 2, 3, 4) != 4; 10 | } 11 | -------------------------------------------------------------------------------- /test/t95.c: -------------------------------------------------------------------------------- 1 | int uc_slen(char *s) 2 | { 3 | return 5; 4 | } 5 | 6 | char **uc_chop(char *s, int *n) 7 | { 8 | char **chrs; 9 | *n = uc_slen(s); 10 | return 0; 11 | } 12 | 13 | int main(void) 14 | { 15 | int n; 16 | uc_chop(0, &n); 17 | if (n != 5) 18 | return 1; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /test/t96.c: -------------------------------------------------------------------------------- 1 | /* Reported by Morten Brøns-Pedersen */ 2 | int f(int a) 3 | { 4 | return 1 >= a; 5 | } 6 | int main() { 7 | return f(1) == 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/t97.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int x = 0; 4 | unsigned int y = 0; 5 | if (x < -1) 6 | return 1; 7 | if (y > -1) 8 | return 1; 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /test/t98.c: -------------------------------------------------------------------------------- 1 | #define S(x) #x 2 | #define S3(x, y, z) #x#y /* #x */ #z 3 | 4 | int main(void) 5 | { 6 | char *s = S(abc); 7 | char *r = S3(a, b, c); 8 | if (s[0] != 'a' || s[1] != 'b' || s[2] != 'c' || s[3]) 9 | return 1; 10 | if (r[0] != 'a' || r[1] != 'b' || r[2] != 'c' || r[3]) 11 | return 2; 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/t99.c: -------------------------------------------------------------------------------- 1 | #define T(x) a##x 2 | #define T3(x, y, z) a##x##y##z 3 | 4 | int main(void) 5 | { 6 | int aabc = 1; 7 | if (T(abc) != 1) 8 | return 2; 9 | if (T3(a, b, c) != 1) 10 | return 2; 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /test/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #LOADER=../ldelf/ldelf 3 | LOADER=../ldelf/load 4 | for i in `seq -w 0 30` 5 | do 6 | f="b$i.x" 7 | if test -f $f 8 | then 9 | n=`echo $i | sed 's/^0\+//'` 10 | $LOADER ./$f 11 | o="$?" 12 | if test $o != $n 13 | then 14 | echo "$f $o" 15 | fi 16 | fi 17 | done 18 | 19 | for x in t??.x 20 | do 21 | $LOADER ./$x 22 | o=$? 23 | if test "$o" != "0" 24 | then 25 | echo "$x $o" 26 | fi 27 | done 28 | -------------------------------------------------------------------------------- /test/x64.s: -------------------------------------------------------------------------------- 1 | ;default rel ; default generate rip-relative code 2 | 3 | extern main 4 | global _start 5 | _start: 6 | xor rbp, rbp 7 | pop rdi ; argc 8 | mov rsi, rsp ; argv 9 | push rdi 10 | lea rdx, [rsi + rdi * 8 + 8]; envp 11 | and rsp, -16 ; align rsp 12 | 13 | call main 14 | mov rdi, rax 15 | %ifdef Darwin 16 | mov rax,0x2000001 ; OSX _exit 17 | %else 18 | mov rax,60 ; Linux _exit 19 | %endif 20 | syscall 21 | -------------------------------------------------------------------------------- /test/x86.s: -------------------------------------------------------------------------------- 1 | format ELF 2 | 3 | extrn main 4 | public _start 5 | _start: 6 | xor ebp, ebp 7 | xor eax, eax 8 | push 6 9 | call main 10 | pop edx 11 | mov ebx, eax 12 | mov eax, 1 13 | int 0x80 14 | --------------------------------------------------------------------------------