diff --git a/kernel/main.c b/kernel/main.c index e5b8522fd3f527c46340104719273abc5c1d4b87..e0806dec903a57a731fc6d24b6c47349ad53ace3 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -81,7 +81,7 @@ static char * argv_rc[] = { "/bin/sh", NULL }; static char * envp_rc[] = { "HOME=/", NULL ,NULL }; //static char * argv[] = { "-/bin/sh",NULL }; -static char * argv[] = { "/usrs/", NULL }; +static char * argv[] = { "/usr/bin", NULL }; static char * envp[] = { "HOME=/usr/root", NULL, NULL }; void main() { @@ -170,7 +170,7 @@ static void run_sh() { int pid; if (!(pid=fork())) { printf("read to start shell\n"); - execve("/tmp/et",argv,envp); + execve("/usr/bin/ls", argv,envp); } } diff --git a/mm/memory.c b/mm/memory.c index 009cd63beaf9ccd9f2a4aad188f33e756900d1a2..e24361f26b2cec4a1ceca7bca1972de09bd09737 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -277,7 +277,7 @@ void do_no_page(unsigned long error_code,unsigned long address) { address &= 0xfffff000; tmp = address - current->start_code; - if (!current->executable || tmp >= current->end_code) { + if (!current->executable || tmp >= current->end_data) { get_empty_page(address); return; } @@ -289,7 +289,7 @@ void do_no_page(unsigned long error_code,unsigned long address) { oom(); block = 1 + tmp / BLOCK_SIZE; - + printk("blocks is %d, 0x%x\n", block, tmp); for (i = 0; i < 4; block++, i++) { nr[i] = bmap(current->executable, block); diff --git a/tools/Makefile b/tools/Makefile deleted file mode 100644 index 42a04ec12bdd658343a9d76c2cbfe4ed17bfdd91..0000000000000000000000000000000000000000 --- a/tools/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -rt.img: mfs et root.img - ./mfs -c et -t /tmp/et -o rt.img root.img - -mfs: mfs.cpp utils.cpp mfs.h - g++ -o mfs mfs.cpp utils.cpp - -et: myld test - ./myld test - -myld: myld.c - gcc -o myld myld.c - -test: test.o crt0.o - ld -Ttext 0x0 --oformat binary -m elf_i386 -o test crt0.o test.o ../lib/lib.a - -test.o: test.c - gcc -m32 -ffreestanding -c -o test.o test.c - -crt0.o: crt0.S - gcc -c -m32 -o crt0.o crt0.S - -clean: - -rm crt0.o - -rm test - -rm test.o - -rm myld - -rm et - -rm mfs - -rm rt.img diff --git a/tools/mkfs/Makefile b/tools/mkfs/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..e17a42e9206770acfa605b9e16f4b51dc5e49ba7 --- /dev/null +++ b/tools/mkfs/Makefile @@ -0,0 +1,6 @@ +mfs: mfs.cpp utils.cpp + g++ -o mfs mfs.cpp utils.cpp + +clean: + -rm mfs + -rm rt.img diff --git a/tools/mfs.cpp b/tools/mkfs/mfs.cpp similarity index 95% rename from tools/mfs.cpp rename to tools/mkfs/mfs.cpp index e23f2b4d0fd9222034c2888c39a3af9d27d0d615..4095f78de8d85cad2769513fd1c15eb9bcbce4e2 100644 --- a/tools/mfs.cpp +++ b/tools/mkfs/mfs.cpp @@ -339,12 +339,13 @@ m_inode* get_new_dir_inode(m_inode* parent) { return new m_inode(inode, nr); } -m_inode* get_new_file_inode() { +m_inode* get_new_file_inode(long length) { int nr = find_empty_inode(); d_inode* inode = iget(nr); - inode->i_zone[0] = get_new_block(); - inode->i_zone[1] = get_new_block(); - inode->i_size = BLOCK_SIZE * 2; + inode->i_size = (unsigned int)length; + for (int i = 0; i < UPPER(inode->i_size, BLOCK_SIZE); i++) { + create_block(inode, i); + } inode->i_mode = I_REGULAR | 0777; return new m_inode(inode, nr); @@ -360,13 +361,13 @@ void write_image() { fclose(tfile); } -m_inode* create_new_file() { +m_inode* create_new_file(long length) { char* parent_name = get_dir_name(dir_name); m_inode* parent = namei(parent_name); const char* dname = get_entry_name(dir_name); printf("new file: %s\n", dname); - m_inode* ndnode = get_new_file_inode(); + m_inode* ndnode = get_new_file_inode(length); char* pwd_block = get_block(bmap(parent->p, 0)); struct dir_entry* dir = (struct dir_entry*)pwd_block; @@ -400,13 +401,17 @@ m_inode* create_new_file() { int write_file(const char* src_file, const char* dst_file) { read_file(); FILE* srcf = fopen(src_file, "r"); - m_inode* finode = create_new_file(); + + m_inode* finode = create_new_file(file_length(srcf)); dir_name = get_dir_name(dir_name); list_dir(); - printf("i_zone[0] is %d\n", finode->p->i_zone[0]); - fread(get_block(finode->p->i_zone[0]), sizeof(char), BLOCK_SIZE, srcf); - fread(get_block(finode->p->i_zone[1]), sizeof(char), BLOCK_SIZE, srcf); + int total = 0; + for (int i = 0; i < UPPER(finode->p->i_size, BLOCK_SIZE); i++) { + total += fread(get_block(bmap(finode->p, i)), sizeof(char), BLOCK_SIZE, srcf); + printf("%d block write\n", bmap(finode->p, i)); + } + printf("%d bytes read\n", total); write_image(); fclose(img_file); diff --git a/tools/mfs.h b/tools/mkfs/mfs.h similarity index 98% rename from tools/mfs.h rename to tools/mkfs/mfs.h index 303926f068e6e7386fbd3741b53685266d375fa4..3e92ed1e475adc0ef75e9c01dde3759812263a1d 100644 --- a/tools/mfs.h +++ b/tools/mkfs/mfs.h @@ -2,6 +2,7 @@ #define _FS_H #include +#include #define I_DIRECTORY 0040000 #define I_REGULAR 0100000 @@ -148,5 +149,6 @@ char* get_dir_name(char* full_name); const char* get_entry_name(char* full_name); void free_strings(char** dirs); char** split(const char* name); +long file_length(FILE* f); #endif diff --git a/tools/root.img b/tools/mkfs/root.img similarity index 100% rename from tools/root.img rename to tools/mkfs/root.img diff --git a/tools/utils.cpp b/tools/mkfs/utils.cpp similarity index 93% rename from tools/utils.cpp rename to tools/mkfs/utils.cpp index b33d05092581de065b11989ac19dd455b72e2906..31728c1b0d26764a4adf994150cd5627c7792ec7 100644 --- a/tools/utils.cpp +++ b/tools/mkfs/utils.cpp @@ -2,6 +2,13 @@ #include +long file_length(FILE* f) { + fseek(f, 0, SEEK_END); + long file_size = ftell(f); + fseek(f, 0, 0); + return file_size; +} + void free_strings(char** dirs) { char** dir_list = dirs; while (*dir_list) { diff --git a/tools/myld.c b/tools/myld.c deleted file mode 100644 index 9dbe8e6bae142d4437ed7d79088471c62a98858a..0000000000000000000000000000000000000000 --- a/tools/myld.c +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include - -struct exec { - unsigned int a_magic; - unsigned int a_text; - unsigned int a_data; - unsigned int a_bss; - unsigned int a_syms; - unsigned int a_entry; - unsigned int a_trsize; - unsigned int a_drsize; -}; - -#define ZMAGIC 0413 - -#define BLOCK_SIZE 1024 - -char* content[BLOCK_SIZE * 2]; - -int main(int argc, char** argv) { - memset(content, 0, BLOCK_SIZE*2); - struct exec* header = (struct exec*) content; - header->a_magic = ZMAGIC; - - FILE* f = fopen("test", "r"); - unsigned int len = fread(content + BLOCK_SIZE, sizeof(char), BLOCK_SIZE, f); - printf("read %d bytes\n", len); - header->a_text = len; - fclose(f); - - f = fopen("et", "w+"); - fwrite(content, sizeof(char), BLOCK_SIZE, f); - fwrite(content + BLOCK_SIZE, sizeof(char), BLOCK_SIZE, f); - fclose(f); - - return 0; -} - diff --git a/tools/tcc/Makefile b/tools/tcc/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..2bd6065b16d9f7d1c5166e18d27889b3b3462d9a --- /dev/null +++ b/tools/tcc/Makefile @@ -0,0 +1,28 @@ +AR := ar +GCC := gcc +CCFLAG := -m32 -I./include -ffreestanding -fno-pic -Wall -fomit-frame-pointer -fno-stack-protector -c +OBJS := write.o errno.o printf.o vsprintf.o string.o + +libc.a: $(OBJS) + $(AR) rcs $@ $^ + sync + +write.o: runtime/write.c + $(GCC) $(CCFLAG) -o $@ $< + +errno.o: runtime/errno.c + $(GCC) $(CCFLAG) -o $@ $< + +printf.o: runtime/printf.c + $(GCC) $(CCFLAG) -o $@ $< + +vsprintf.o: runtime/vsprintf.c + $(GCC) $(CCFLAG) -o $@ $< + +string.o: runtime/string.c + $(GCC) $(CCFLAG) -o $@ $< + +clean: + -rm *.o + -rm libc.a + diff --git a/tools/crt0.S b/tools/tcc/crt0.S similarity index 100% rename from tools/crt0.S rename to tools/tcc/crt0.S diff --git a/tools/tcc/include/stdarg.h b/tools/tcc/include/stdarg.h new file mode 100644 index 0000000000000000000000000000000000000000..ebb37ccc2b12ba032eed3d9ffd8adb2573629ad9 --- /dev/null +++ b/tools/tcc/include/stdarg.h @@ -0,0 +1,29 @@ +#ifndef _STDARG_H +#define _STDARG_H + +typedef char *va_list; + +/* Amount of space required in an argument list for an arg of type TYPE. + * TYPE may alternatively be an expression whose type is used. */ + +#define __va_rounded_size(TYPE) \ + (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) + +#ifndef __sparc__ +#define va_start(AP, LASTARG) \ + (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) +#else +#define va_start(AP, LASTARG) \ + (__builtin_saveregs (), \ + AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) +#endif + +void va_end (va_list); /* Defined in gnulib */ +#define va_end(AP) + +#define va_arg(AP, TYPE) \ + (AP += __va_rounded_size (TYPE), \ + *((TYPE *) (AP - __va_rounded_size (TYPE)))) + +#endif /* _STDARG_H */ + diff --git a/tools/tcc/include/stddef.h b/tools/tcc/include/stddef.h new file mode 100644 index 0000000000000000000000000000000000000000..c340e05fb2b43243450038c8b8ca792552b59952 --- /dev/null +++ b/tools/tcc/include/stddef.h @@ -0,0 +1,19 @@ +#ifndef _STDDEF_H +#define _STDDEF_H + +#ifndef _PTRDIFF_T +#define _PTRDIFF_T +typedef long ptrdiff_t; +#endif + +#ifndef _SIZE_T +#define _SIZE_T +typedef unsigned long size_t; +#endif + +#undef NULL +#define NULL ((void *)0) + +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + diff --git a/tools/tcc/include/stdio.h b/tools/tcc/include/stdio.h new file mode 100644 index 0000000000000000000000000000000000000000..5fd1574e8266dea00602b4c6edce259538f7961d --- /dev/null +++ b/tools/tcc/include/stdio.h @@ -0,0 +1,4 @@ +#include + +int printf(const char* fmt, ...); +int vsprintf(char *buf, const char *fmt, va_list args); diff --git a/tools/tcc/include/string.h b/tools/tcc/include/string.h new file mode 100644 index 0000000000000000000000000000000000000000..e437c28a693d1707924877512f863869e2751371 --- /dev/null +++ b/tools/tcc/include/string.h @@ -0,0 +1,68 @@ +#ifndef _STRING_H_ +#define _STRING_H_ + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#ifndef _SIZE_T +#define _SIZE_T +typedef unsigned int size_t; +#endif + +extern char * strerror(int errno); + +/* + * This string-include defines all string functions as inline + * functions. Use gcc. It also assumes ds=es=data space, this should be + * normal. Most of the string-functions are rather heavily hand-optimized, + * see especially strtok,strstr,str[c]spn. They should work, but are not + * very easy to understand. Everything is done entirely within the register + * set, making the functions fast and clean. String instructions have been + * used through-out, making for "slightly" unclear code :-) + * + * (C) 1991 Linus Torvalds + */ + +extern inline char * strcpy(char * dest,const char *src); + +extern inline char * strncpy(char * dest,const char *src,int count); + +extern inline char * strcat(char * dest,const char * src); + +extern inline char * strncat(char * dest,const char * src,int count); + +extern inline int strcmp(const char * cs,const char * ct); + +extern inline int strncmp(const char * cs,const char * ct,int count); + +extern inline char * strchr(const char * s,char c); + +extern inline char * strrchr(const char * s,char c); + +extern inline int strspn(const char * cs, const char * ct); + +extern inline int strcspn(const char * cs, const char * ct); + +extern inline char * strpbrk(const char * cs,const char * ct); + +extern inline char * strstr(const char * cs,const char * ct); + +extern inline int strlen(const char * s); + +extern char * ___strtok; + +extern inline char * strtok(char * s,const char * ct); + +extern inline void * memcpy(void * dest,const void * src, int n); + +extern inline void * memmove(void * dest,const void * src, int n); + +extern inline int memcmp(const void * cs,const void * ct,int count); + +extern inline void * memchr(const void * cs,char c,int count); + +extern inline void * memset(void * s,char c,int count); + +#endif + diff --git a/tools/tcc/include/sys/types.h b/tools/tcc/include/sys/types.h new file mode 100644 index 0000000000000000000000000000000000000000..b75fb69c89ccd35e68b1340dbe04c246218a9a20 --- /dev/null +++ b/tools/tcc/include/sys/types.h @@ -0,0 +1,37 @@ +#ifndef _SYS_TYPES_H +#define _SYS_TYPES_H + +#ifndef _SIZE_T +#define _SIZE_T +typedef unsigned int size_t; +#endif + +#ifndef _TIME_T +#define _TIME_T +typedef long time_t; +#endif + +#ifndef _PTRDIFF_T +#define _PTRDIFF_T +typedef long ptrdiff_t; +#endif + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +typedef long off_t; + +typedef int pid_t; +typedef unsigned short uid_t; +typedef unsigned short mode_t; +typedef unsigned short ino_t; +typedef unsigned short gid_t; +typedef unsigned short dev_t; +typedef unsigned short umode_t; +typedef unsigned char nlink_t; +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned long tcflag_t; + +#endif diff --git a/tools/tcc/include/unistd.h b/tools/tcc/include/unistd.h new file mode 100644 index 0000000000000000000000000000000000000000..67ddf62e064ebb914eb96ce51438a1a4b61ab03c --- /dev/null +++ b/tools/tcc/include/unistd.h @@ -0,0 +1,154 @@ +#ifndef _UNISTD_H +#define _UNISTD_H + +#include + +#ifndef NULL +#define NULL ((void*)0) +#endif + +#ifdef __LIBRARY__ + +#define __NR_setup 0 /* used only by init, to get system going */ +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 +#define __NR_break 17 +#define __NR_stat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_fstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_phys 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_uname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_lstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 + +#define _syscall0(type, name) \ +type name() { \ + long __res; \ +__asm__ volatile("int $0x80\n\r"\ + : "=a"(__res) \ + : "a"(__NR_##name)); \ + if (__res >= 0) \ + return (type)__res; \ + errno = -__res; \ + return -1; \ +} + +#define _syscall1(type, name, atype, a) \ +type name(atype a) { \ + long __res; \ +__asm__ volatile("int $0x80\n\r"\ + : "=a"(__res) \ + : "a"(__NR_##name), "b"((long)(a))); \ + if (__res >= 0) \ + return (type)__res; \ + errno = -__res; \ + return -1; \ +} + +#define _syscall2(type, name, atype, a, btype, b) \ +type name(atype a, btype b) { \ + long __res; \ +__asm__ volatile("int $0x80\n\r"\ + : "=a"(__res) \ + : "a"(__NR_##name), "b"((long)(a)), "c"((long)(b))); \ + if (__res >= 0) \ + return (type)__res; \ + errno = -__res; \ + return -1; \ +} + +#define _syscall3(type,name,atype,a,btype,b,ctype,c) \ +type name(atype a, btype b, ctype c) { \ + long __res; \ +__asm__ volatile("int $0x80\n\r"\ + : "=a"(__res) \ + : "a"(__NR_##name), "b"((long)(a)), "c"((long)(b)), "d"((long)(c))); \ + if (__res >= 0) \ + return (type)__res; \ + errno = -__res; \ + return -1; \ +} + +#endif /* __LIBRARY__ */ + +extern int errno; + +int write(int fildes, const char * buf, off_t count); + +#endif diff --git a/tools/linkerscript/a.out.header b/tools/tcc/linkerscript/a.out.header similarity index 100% rename from tools/linkerscript/a.out.header rename to tools/tcc/linkerscript/a.out.header diff --git a/tools/linkerscript/a.out.header.c b/tools/tcc/linkerscript/a.out.header.c similarity index 100% rename from tools/linkerscript/a.out.header.c rename to tools/tcc/linkerscript/a.out.header.c diff --git a/tools/linkerscript/a.out.header.s b/tools/tcc/linkerscript/a.out.header.s similarity index 100% rename from tools/linkerscript/a.out.header.s rename to tools/tcc/linkerscript/a.out.header.s diff --git a/tools/linkerscript/a.out.lds b/tools/tcc/linkerscript/a.out.lds similarity index 100% rename from tools/linkerscript/a.out.lds rename to tools/tcc/linkerscript/a.out.lds diff --git a/tools/linkerscript/sample/build.sh b/tools/tcc/linkerscript/sample/build.sh similarity index 100% rename from tools/linkerscript/sample/build.sh rename to tools/tcc/linkerscript/sample/build.sh diff --git a/tools/linkerscript/sample/foo.c b/tools/tcc/linkerscript/sample/foo.c similarity index 100% rename from tools/linkerscript/sample/foo.c rename to tools/tcc/linkerscript/sample/foo.c diff --git a/tools/tcc/runtime/errno.c b/tools/tcc/runtime/errno.c new file mode 100644 index 0000000000000000000000000000000000000000..74de031f42380499e701fd6a12b1aea46c1d0b03 --- /dev/null +++ b/tools/tcc/runtime/errno.c @@ -0,0 +1,2 @@ +int errno; + diff --git a/tools/tcc/runtime/printf.c b/tools/tcc/runtime/printf.c new file mode 100644 index 0000000000000000000000000000000000000000..2a78add56a115cdbc390bee84fdb7307580de278 --- /dev/null +++ b/tools/tcc/runtime/printf.c @@ -0,0 +1,15 @@ +#include + +char printbuf[256]; + +int printf(const char* fmt, ...) { + va_list args; + int i; + + va_start(args, fmt); + write(1, printbuf, i = vsprintf(printbuf, fmt, args)); + va_end(args); + + return i; +} + diff --git a/tools/tcc/runtime/string.c b/tools/tcc/runtime/string.c new file mode 100644 index 0000000000000000000000000000000000000000..391d351ebf1f8a4c3e1eea82c65de0649322cd89 --- /dev/null +++ b/tools/tcc/runtime/string.c @@ -0,0 +1,369 @@ +#include + +inline char * strcpy(char * dest,const char *src) { +__asm__("cld\n" + "1:\tlodsb\n\t" + "stosb\n\t" + "testb %%al,%%al\n\t" + "jne 1b" + ::"S" (src),"D" (dest):"ax"); +return dest; +} + +inline char * strncpy(char * dest,const char *src,int count) { +__asm__("cld\n" + "1:\tdecl %2\n\t" + "js 2f\n\t" + "lodsb\n\t" + "stosb\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n\t" + "rep\n\t" + "stosb\n" + "2:" + ::"S" (src),"D" (dest),"c" (count):"ax"); +return dest; +} + +inline char * strcat(char * dest,const char * src) { +__asm__("cld\n\t" + "repne\n\t" + "scasb\n\t" + "decl %1\n" + "1:\tlodsb\n\t" + "stosb\n\t" + "testb %%al,%%al\n\t" + "jne 1b" + ::"S" (src),"D" (dest),"a" (0),"c" (0xffffffff):); +return dest; +} + +inline char * strncat(char * dest,const char * src,int count) { +__asm__("cld\n\t" + "repne\n\t" + "scasb\n\t" + "decl %1\n\t" + "movl %4,%3\n" + "1:\tdecl %3\n\t" + "js 2f\n\t" + "lodsb\n\t" + "stosb\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n" + "2:\txorl %2,%2\n\t" + "stosb" + ::"S" (src),"D" (dest),"a" (0),"c" (0xffffffff),"g" (count) + :); +return dest; +} + +inline int strcmp(const char * cs,const char * ct) { +register int __res __asm__("ax"); +__asm__("cld\n" + "1:\tlodsb\n\t" + "scasb\n\t" + "jne 2f\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n\t" + "xorl %%eax,%%eax\n\t" + "jmp 3f\n" + "2:\tmovl $1,%%eax\n\t" + "jl 3f\n\t" + "negl %%eax\n" + "3:" + :"=a" (__res):"D" (cs),"S" (ct):); +return __res; +} + +inline int strncmp(const char * cs,const char * ct,int count) +{ +register int __res __asm__("ax"); +__asm__("cld\n" + "1:\tdecl %3\n\t" + "js 2f\n\t" + "lodsb\n\t" + "scasb\n\t" + "jne 3f\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n" + "2:\txorl %%eax,%%eax\n\t" + "jmp 4f\n" + "3:\tmovl $1,%%eax\n\t" + "jl 4f\n\t" + "negl %%eax\n" + "4:" + :"=a" (__res):"D" (cs),"S" (ct),"c" (count):); +return __res; +} + +inline char * strchr(const char * s,char c) +{ +register char * __res __asm__("ax"); +__asm__("cld\n\t" + "movb %%al,%%ah\n" + "1:\tlodsb\n\t" + "cmpb %%ah,%%al\n\t" + "je 2f\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n\t" + "movl $1,%1\n" + "2:\tmovl %1,%0\n\t" + "decl %0" + :"=a" (__res):"S" (s),"0" (c):); +return __res; +} + +inline char * strrchr(const char * s,char c) +{ +register char * __res __asm__("dx"); +__asm__("cld\n\t" + "movb %%al,%%ah\n" + "1:\tlodsb\n\t" + "cmpb %%ah,%%al\n\t" + "jne 2f\n\t" + "movl %%esi,%0\n\t" + "decl %0\n" + "2:\ttestb %%al,%%al\n\t" + "jne 1b" + :"=d" (__res):"0" (0),"S" (s),"a" (c):); +return __res; +} + +inline int strspn(const char * cs, const char * ct) +{ +register char * __res __asm__("si"); +__asm__("cld\n\t" + "movl %4,%%edi\n\t" + "repne\n\t" + "scasb\n\t" + "notl %%ecx\n\t" + "decl %%ecx\n\t" + "movl %%ecx,%%edx\n" + "1:\tlodsb\n\t" + "testb %%al,%%al\n\t" + "je 2f\n\t" + "movl %4,%%edi\n\t" + "movl %%edx,%%ecx\n\t" + "repne\n\t" + "scasb\n\t" + "je 1b\n" + "2:\tdecl %0" + :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) + :"dx","di"); +return __res-cs; +} + +inline int strcspn(const char * cs, const char * ct) +{ +register char * __res __asm__("si"); +__asm__("cld\n\t" + "movl %4,%%edi\n\t" + "repne\n\t" + "scasb\n\t" + "notl %%ecx\n\t" + "decl %%ecx\n\t" + "movl %%ecx,%%edx\n" + "1:\tlodsb\n\t" + "testb %%al,%%al\n\t" + "je 2f\n\t" + "movl %4,%%edi\n\t" + "movl %%edx,%%ecx\n\t" + "repne\n\t" + "scasb\n\t" + "jne 1b\n" + "2:\tdecl %0" + :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) + :"dx","di"); +return __res-cs; +} + +inline char * strpbrk(const char * cs,const char * ct) +{ +register char * __res __asm__("si"); +__asm__("cld\n\t" + "movl %4,%%edi\n\t" + "repne\n\t" + "scasb\n\t" + "notl %%ecx\n\t" + "decl %%ecx\n\t" + "movl %%ecx,%%edx\n" + "1:\tlodsb\n\t" + "testb %%al,%%al\n\t" + "je 2f\n\t" + "movl %4,%%edi\n\t" + "movl %%edx,%%ecx\n\t" + "repne\n\t" + "scasb\n\t" + "jne 1b\n\t" + "decl %0\n\t" + "jmp 3f\n" + "2:\txorl %0,%0\n" + "3:" + :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) + :"dx","di"); +return __res; +} + +inline char * strstr(const char * cs,const char * ct) +{ +register char * __res __asm__("ax"); +__asm__("cld\n\t" + "movl %4,%%edi\n\t" + "repne\n\t" + "scasb\n\t" + "notl %%ecx\n\t" + "decl %%ecx\n\t" + "movl %%ecx,%%edx\n" + "1:\tmovl %4,%%edi\n\t" + "movl %%esi,%%eax\n\t" + "movl %%edx,%%ecx\n\t" + "repe\n\t" + "cmpsb\n\t" + "je 2f\n\t" + "xchgl %%eax,%%esi\n\t" + "incl %%esi\n\t" + "cmpb $0,-1(%%eax)\n\t" + "jne 1b\n\t" + "xorl %%eax,%%eax\n\t" + "2:" + :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct) + :"dx","di"); +return __res; +} + +inline int strlen(const char * s) +{ + const char* p = s; + while (*p) p++; + return p - s; +} + + +inline void * memcpy(void * dest,const void * src, int n) +{ +__asm__("cld\n\t" + "rep\n\t" + "movsb" + ::"c" (n),"S" (src),"D" (dest) + :); +return dest; +} + +inline void * memmove(void * dest,const void * src, int n) +{ +if (dest +#include + +#define is_digit(c) ((c) >= '0' && (c) <= '9') + +static int skip_atoi(const char **s) { + int i=0; + + while (is_digit(**s)) { + i = i*10 + *((*s)++) - '0'; + } + + return i; +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SPECIAL 32 /* 0x */ +#define SMALL 64 /* use 'abcdef' instead of 'ABCDEF' */ + +#define do_div(n,base) ({ \ + int __res; \ + __asm__("divl %4":"=a" (n),"=d" (__res):"0" (n),"1" (0),"r" (base)); \ + __res; }) + +static char * number(char * str, int num, int base, int size, int precision + ,int type) { + char c,sign,tmp[36]; + const char *digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + int i = 0; + + if (type&SMALL) digits="0123456789abcdefghijklmnopqrstuvwxyz"; + if (type&LEFT) type &= ~ZEROPAD; + if (base<2 || base>36) + return 0; + + c = (type & ZEROPAD) ? '0' : ' ' ; + if (type&SIGN && num<0) { + sign = '-'; + num = -num; + } + else { + sign=(type&PLUS) ? '+' : ((type&SPACE) ? ' ' : 0); + } + + if (sign) size--; + if (type&SPECIAL) { + if (base==16) size -= 2; + else if (base==8) size--; + } + + if (num==0) + tmp[i++]='0'; + else { + while (num!=0) { + tmp[i++]=digits[do_div(num,base)]; + } + } + + if (i>precision) precision=i; + size -= precision; + + if (!(type&(ZEROPAD+LEFT))) { + while(size-->0) + *str++ = ' '; + } + + if (sign) + *str++ = sign; + + if (type&SPECIAL) { + if (base==8) + *str++ = '0'; + else if (base==16) { + *str++ = '0'; + *str++ = digits[33]; + } + } + + if (!(type&LEFT)) { + while(size-->0) + *str++ = c; + } + + while(i0) + *str++ = tmp[i]; + + while(size-->0) + *str++ = ' '; + + return str; +} + +int vsprintf(char *buf, const char *fmt, va_list args) { + int len; + int i; + char * str; + char *s; + int *ip; + + int flags; /* flags to number() */ + int field_width; /* width of output field */ + int precision; /* min. # of digits for integers; max + number of chars for from string */ + int qualifier; /* 'h', 'l', or 'L' for integer fields */ + + for (str = buf; *fmt; fmt++) { + if (*fmt != '%') { + *str++ = *fmt; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': flags |= LEFT; goto repeat; + case '+': flags |= PLUS; goto repeat; + case ' ': flags |= SPACE; goto repeat; + case '#': flags |= SPECIAL; goto repeat; + case '0': flags |= ZEROPAD; goto repeat; + } + + /* get field width */ + field_width = -1; + if (is_digit(*fmt)) { + field_width = skip_atoi(&fmt); + } + else if (*fmt == '*') { + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if (is_digit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + /* it's the next argument */ + precision = va_arg(args, int); + } + + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { + qualifier = *fmt; + ++fmt; + } + + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = ' '; + *str++ = (unsigned char) va_arg(args, int); + while (--field_width > 0) + *str++ = ' '; + break; + case 's': + s = va_arg(args, char *); + len = strlen(s); + + if (precision < 0) + precision = len; + else if (len > precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + break; + + case 'o': + str = number(str, va_arg(args, unsigned long), 8, + field_width, precision, flags); + break; + + case 'p': + if (field_width == -1) { + field_width = 8; + flags |= ZEROPAD; + } + str = number(str, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + break; + + case 'x': + flags |= SMALL; + case 'X': + str = number(str, va_arg(args, unsigned long), 16, + field_width, precision, flags); + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + str = number(str, va_arg(args, unsigned long), 10, + field_width, precision, flags); + break; + + case 'n': + ip = va_arg(args, int *); + *ip = (str - buf); + break; + + default: + if (*fmt != '%') + *str++ = '%'; + + if (*fmt) + *str++ = *fmt; + else + --fmt; + break; + } + } + + *str = '\0'; + return str-buf; +} + diff --git a/tools/tcc/runtime/write.c b/tools/tcc/runtime/write.c new file mode 100644 index 0000000000000000000000000000000000000000..2613f17e37e2a26064bd13520d05c3dc0d147081 --- /dev/null +++ b/tools/tcc/runtime/write.c @@ -0,0 +1,4 @@ +#define __LIBRARY__ +#include + +_syscall3(int,write,int,fd,const char *,buf,off_t,count) diff --git a/tools/tcc/tcc b/tools/tcc/tcc new file mode 100755 index 0000000000000000000000000000000000000000..1b7844af4daa6ba607ef5868d18614f0d18d2e7a --- /dev/null +++ b/tools/tcc/tcc @@ -0,0 +1,7 @@ +#!/bin/bash +export LDEMULATION=elf_i386 +filename=$1 +objfile=${filename/".c"/".o"} +echo ${filename/".c"/".o"} +gcc -c -fno-pic -m32 -ffreestanding -I./include -o $objfile $filename +ld -M -T linkerscript/a.out.lds linkerscript/a.out.header crt0.o $objfile libc.a -o $2 > test.map diff --git a/tools/test.c b/tools/tcc/test/test.c similarity index 81% rename from tools/test.c rename to tools/tcc/test/test.c index 3a60a2150caaaf168d1d5c28d669559caec5a482..6248279c8c1327afdf48467297e23925a4ec06af 100644 --- a/tools/test.c +++ b/tools/tcc/test/test.c @@ -1,7 +1,7 @@ -int errno; +#include int main(int argc, char** argv, char** envp) { - write(1, "argv\n", 5); + printf("argc is %d\n", argc); while (*argv) { write(1, *argv, 3); argv++; diff --git a/tools/test.S b/tools/test.S deleted file mode 100644 index a1649b167c56d7f4150baf3d8680baad3ce81959..0000000000000000000000000000000000000000 --- a/tools/test.S +++ /dev/null @@ -1,14 +0,0 @@ -.code32 - -movl $4, %eax -movl $1, %ebx -movl $msg, %ecx -movl $9, %edx - -int $0x80 - -loop: - jmp loop - -msg: - .ascii "hello sh\n"