From 3a3aea8eed5247c650befe2d5ca82e1b220b54c7 Mon Sep 17 00:00:00 2001 From: hpa Date: Fri, 17 Dec 2004 18:54:08 +0000 Subject: [PATCH] Actually parse argc/argv properly. --- dos/Makefile | 2 +- dos/argv.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ dos/crt0.S | 44 +++++++---------------------- dos/malloc.c | 5 ++-- 4 files changed, 104 insertions(+), 37 deletions(-) create mode 100644 dos/argv.c diff --git a/dos/Makefile b/dos/Makefile index 3e8b531..135fe31 100644 --- a/dos/Makefile +++ b/dos/Makefile @@ -6,7 +6,7 @@ INCLUDES = -include code16.h -I. -I.. -I../libfat CFLAGS = -W -Wall -ffreestanding $(OPTFLAGS) $(INCLUDES) LDFLAGS = -T com16.ld -SRCS = syslinux.c conio.c skipatou.c atou.c malloc.c free.c \ +SRCS = syslinux.c conio.c skipatou.c atou.c malloc.c free.c argv.c \ ../syslxmod.c ../bootsect_bin.c ../ldlinux_bin.c \ $(wildcard ../libfat/*.c) OBJS = crt0.o memcpy.o memset.o $(patsubst %.c,%.o,$(notdir $(SRCS))) diff --git a/dos/argv.c b/dos/argv.c new file mode 100644 index 0000000..62c3b04 --- /dev/null +++ b/dos/argv.c @@ -0,0 +1,90 @@ +#ident "$Id$" +/* ----------------------------------------------------------------------- * + * + * Copyright 2004 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * argv.c + * + * Parse a single C string into argc and argv (argc is return value.) + * memptr points to available memory. + */ + +#include +#include + +#define ALIGN_UP(p,t) ((t *)(((uintptr_t)(p) + (sizeof(t)-1)) & ~(sizeof(t)-1))) + +extern char _end[]; /* Symbol created by linker */ +void *__mem_end = &_end; /* Global variable for use by malloc() */ + +int __parse_argv(char ***argv, const char *str) +{ + char *mem = __mem_end; + const char *p = str; + char *q = mem; + char *r; + char **arg; + int wasspace = 0; + int argc = 1; + + /* First copy the string, turning whitespace runs into nulls */ + for ( p = str ; ; p++ ) { + if ( *p <= ' ' ) { + if ( !wasspace ) { + wasspace = 1; + *q++ = '\0'; + } + } else { + if ( wasspace ) { + argc++; + wasspace = 0; + } + *q++ = *p; + } + + /* This test is AFTER we have processed the null byte; + we treat it as a whitespace character */ + if ( ! *p ) + break; + } + q--; /* Point to final null */ + + /* Now create argv */ + *argv = arg = ALIGN_UP(q,char *); + *arg++ = mem; /* argv[0] */ + + for ( r = mem ; r < q ; r++ ) { + if ( *r == '\0' ) + *arg++ = r+1; + } + + *arg++ = NULL; /* Null pointer at the end */ + __mem_end = arg; /* End of memory we used */ + + return argc; +} + diff --git a/dos/crt0.S b/dos/crt0.S index 38f6725..f567177 100644 --- a/dos/crt0.S +++ b/dos/crt0.S @@ -17,45 +17,21 @@ _start: rep ; stosl # Compute argc and argv - movzbw 0x80,%cx - movl $0x81,%esi - movw $argv,%di - - xorl %eax,%eax # Dummy argv[0] - stosl - -1: - # Skip any space or control character - jcxz 2f - lodsb - decw %cx - cmp $0x20,%al - ja 3f -5: - movb $0,-1(%si) - jmp 1b - -3: - movl %esi,%eax - stosl -4: - # Skip this word - jcxz 2f - lodsb - decw %cx - cmp $0x20,%al - ja 4b - jmp 5b -2: - xorl %eax,%eax # Final null argv entry - stosl + xorl %edx,%edx + movzbw 80,%bx + movb %dl,81(%bx) # Zero-terminate string + movb $81,%dl + pushl %eax # Make space for argv + movl %esp,%eax + calll __parse_argv + pushl %eax # argc # Initialize malloc calll __init_memory_arena # Now call main... - movl $argv,%edx # argv - xorl %eax,%eax # dummy argc (we dont use it) + popl %eax # argc + popl %edx # argv calll main # Here %eax is the exit code, fall through into exit diff --git a/dos/malloc.c b/dos/malloc.c index 93a51bb..8d37b5d 100644 --- a/dos/malloc.c +++ b/dos/malloc.c @@ -29,13 +29,14 @@ static inline size_t sp(void) return sp; } +extern void *__mem_end; + void __init_memory_arena(void) { - extern char _end[]; /* Symbol created by the linker */ struct free_arena_header *fp; size_t start, total_space; - start = (size_t)ARENA_ALIGN_UP(_end); + start = (size_t)ARENA_ALIGN_UP(__mem_end); total_space = sp() - start; fp = (struct free_arena_header *)start; -- 2.7.4