# HG changeset patch # User Tatsuki IHA # Date 1508664339 -32400 # Node ID c450faca55f4de7eeff5f64e78da86f7bd50d7f4 Init diff -r 000000000000 -r c450faca55f4 Dockerfile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Dockerfile Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,9 @@ +FROM phitek/qemu-arm +RUN apt-get update -y +RUN apt-get remove gdb -y +RUN apt-get install gcc-arm-none-eabi gdb-arm-none-eabi qemu-system-arm mercurial -y +WORKDIR /code +RUN hg clone http://www.cr.ie.u-ryukyu.ac.jp/hg/Members/innparusu/xv6_rpi_port/ +WORKDIR /code/xv6_rpi_port/src +RUN make +CMD /bin/bash diff -r 000000000000 -r c450faca55f4 LICENSE --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LICENSE Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,30 @@ +The xv6 RPI port software is: + +Copyright (c) 2013-2014 +Zhiyi Huang, University of Otago +Alex Bradbury, University of Cambridge +Alex Chadwick, University of Cambridge +Theo Markettos, University of Cambridge +Robert Mullins, University of Cambridge +Robert N. M. Watson, University of Cambridge + + +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. + diff -r 000000000000 -r c450faca55f4 Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,77 @@ +############################################################################### +# makefile +# by Alex Chadwick +# +# A makefile script for generation of raspberry pi kernel images. +############################################################################### + +# The toolchain to use. arm-none-eabi works, but there does exist +# arm-bcm2708-linux-gnueabi. +#ARMGNU ?= arm-none-eabi + +# The intermediate directory for compiled object files. +BUILD = build/ + +# The directory in which source files are stored. +SOURCE = source/ + +# The name of the output file to generate. +TARGET = kernel.img + +# The name of the assembler listing file to generate. +LIST = kernel.list + +# The name of the map file to generate. +MAP = kernel.map + +# The name of the linker script to use. +LINKER = kernel.ld + +# The names of libraries to use. +LIBRARIES := csud + +#CFLAGS := -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -MD -ggdb -Werror -fno-omit-frame-pointer -nostdinc -nostdlib -fno-stack-protector +CFLAGS := -fno-pic -static -Wno-packed-bitfield-compat -fno-builtin -fno-strict-aliasing -fshort-wchar -O2 -Wall -MD -ggdb -Werror -fno-omit-frame-pointer -fno-stack-protector -Wa,-march=armv6 -Wa,-mcpu=arm1176jzf-s -I include + +CC := gcc + +# The names of all object files that must be generated. Deduced from the +# assembly code files in source. +OBJECTS := $(patsubst $(SOURCE)%.s,$(BUILD)%.o,$(wildcard $(SOURCE)*.s)) + +C_OBJS := $(patsubst $(SOURCE)%.c,$(BUILD)%.o,$(wildcard $(SOURCE)*.c)) + +# Rule to make everything. +all: $(TARGET) $(LIST) + +# Rule to remake everything. Does not include clean. +#rebuild: all + +# Rule to make the listing file. +$(LIST) : $(BUILD)output.elf + $(ARMGNU)-objdump -d $(BUILD)output.elf > $(LIST) + +# Rule to make the image file. +$(TARGET) : $(BUILD)output.elf + $(ARMGNU)-objcopy $(BUILD)output.elf -O binary $(TARGET) + +# Rule to make the elf file. +$(BUILD)output.elf : $(OBJECTS) $(C_OBJS) $(LINKER) + $(ARMGNU)-ld --no-undefined $(OBJECTS) $(C_OBJS) -L. $(patsubst %,-l %,$(LIBRARIES)) -Map $(MAP) -o $(BUILD)output.elf -T $(LINKER) + +# Rule to make the object files. +$(BUILD)%.o: $(SOURCE)%.s $(BUILD) + $(ARMGNU)-as -I $(SOURCE) $< -o $@ + +$(BUILD)%.o: $(SOURCE)%.c $(BUILD) + $(CC) -c $(CFLAGS) $< -o $@ + +$(BUILD): + mkdir $@ + +# Rule to clean files. +clean : + -rm -rf $(BUILD) + -rm -f $(TARGET) + -rm -f $(LIST) + -rm -f $(MAP) diff -r 000000000000 -r c450faca55f4 README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,50 @@ +xv6_rpi_port is based on MIT xv6 (http://pdos.csail.mit.edu/6.828/2012/v6.html). +It is ported from x86 to armv6 in Raspberry Pi (RPI). The rpi port follows +the coding style of xv6 as much as possible to hide the architectural +differences between x86 and armv6. The port is not for multiprocessor yet +as RPI has only a single processor. + +ACKNOWLEDGEMENTS + +xv6_rpi_port is inspired by MIT xv6 and Alex Chadwick's Baking Pi +Tutorials (http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/). +Most architecture-independent code is directly from MIT xv6 though sometimes +minor adjustments were done to explicitly initialize data structures. +Some C code such as the GPU driver is based on the understanding of +Alex Chadwick's assembly code. + +Some code for mmu and trap handling is based on the understanding of the +Plan 9 bcm port (http://plan9.bell-labs.com/sources/plan9/sys/src/9/bcm/), +though the assembly code was completely rewritten. +David Welch's RPI code (https://github.com/dwelch67/raspberrypi) is also +inspiring for trap handling and uart driver. + +If you spot errors or suggest improvements, please send email to +Zhiyi Huang (hzy@cs.otago.ac.nz). + +Building xv6_rpi_port: + +Suppose you have checked out the source with: + +$ git clone https://github.com/zhiyihuang/xv6_rpi_port.git + +On an RPI installed with Raspbian, type 'make' to make 'kernel.img'. + +Copy 'kernel.img' to /boot with a different name: +# cp kernel.img /boot/kernel-xv6.img + +Comment out the entry 'kernel=kernel_36y.img' and add a new entry +'kernel=kernel-xv6.img' to /boot/config.txt. + +Reboot the machine. + +Building xv6 user programs and FS (You don't need this step if you +don't change the user programs): + +cd uprogs +make initcode +make fs.img + +copy 'initcode' and 'fs.img' to the directory 'source' + + diff -r 000000000000 -r c450faca55f4 docker-setup.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docker-setup.md Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,9 @@ +# xv6-rpi on Docker +## build +- ``$ docker build . --tag xv6-rpi`` + +## run debug mode +- ``$ docker run --privileged -it --name xv6 xv6-rpi ./run-debug.sh`` + +## run gdb(up another process) +- ``$ docker exec -it xv6 ./debug.sh`` diff -r 000000000000 -r c450faca55f4 include/arm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/arm.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,72 @@ +/***************************************************************** +* arm.h +* by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + + + +#define PSR_MODE_USR 0x00000010 +#define PSR_MODE_FIQ 0x00000011 +#define PSR_MODE_IRQ 0x00000012 +#define PSR_MODE_SVC 0x00000013 +#define PSR_MODE_MON 0x00000016 +#define PSR_MODE_ABT 0x00000017 +#define PSR_MODE_UND 0x0000001B +#define PSR_MODE_SYS 0x0000001F +#define PSR_MASK 0x0000001F +#define USER_MODE 0x0 + +#define PSR_DISABLE_IRQ 0x00000080 +#define PSR_DISABLE_FIQ 0x00000040 + +#define PSR_V 0x10000000 +#define PSR_C 0x20000000 +#define PSR_Z 0x40000000 +#define PSR_N 0x80000000 + + +static inline uint +inw(uint addr) +{ + uint data; + + asm volatile("ldr %0,[%1]" : "=r"(data) : "r"(addr)); + return data; +} + +static inline void +outw(uint addr, uint data) +{ + asm volatile("str %1,[%0]" : : "r"(addr), "r"(data)); +} + + +// Layout of the trap frame built on the stack +// by exception.s, and passed to trap(). +struct trapframe { + uint sp; // user mode sp + uint r0; + uint r1; + uint r2; + uint r3; + uint r4; + uint r5; + uint r6; + uint r7; + uint r8; + uint r9; + uint r10; + uint r11; + uint r12; + uint r13; + uint r14; + uint trapno; + uint ifar; // Instruction Fault Address Register (IFAR) + uint cpsr; + uint spsr; // saved cpsr from the trapped/interrupted mode + uint pc; // return address of the interrupted code +}; + diff -r 000000000000 -r c450faca55f4 include/buf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/buf.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,13 @@ +struct buf { + int flags; + uint dev; + uint sector; + struct buf *prev; // LRU cache list + struct buf *next; + struct buf *qnext; // disk queue + uchar data[512]; +}; +#define B_BUSY 0x1 // buffer is locked by some process +#define B_VALID 0x2 // buffer has been read from disk +#define B_DIRTY 0x4 // buffer needs to be written to disk + diff -r 000000000000 -r c450faca55f4 include/defs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/defs.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,231 @@ +struct buf; +struct context; +struct file; +struct inode; +struct pipe; +struct proc; +struct spinlock; +struct stat; +struct superblock; + +void OkLoop(void); +void NotOkLoop(void); + +// mmu.c +void mmuinit1(void); +void barriers(void); +void dsb_barrier(void); +void flush_tlb(void); +void flush_dcache_all(void); +void flush_dcache(uint va1, uint va2); +void flush_idcache(void); +void set_pgtbase(uint base); + +// bio.c +void binit(void); +struct buf* bread(uint, uint); +void brelse(struct buf*); +void bwrite(struct buf*); + +// console.c +void consoleinit(void); +void cprintf(char*, ...); +void consoleintr(int(*)(void)); +void panic(char*) __attribute__((noreturn)); +void drawcharacter(u8, uint, uint); +void gpuputc(uint); + + +// fs.c +void readsb(int dev, struct superblock *sb); +int dirlink(struct inode*, char*, uint); +struct inode* dirlookup(struct inode*, char*, uint*); +struct inode* ialloc(uint, short); +struct inode* idup(struct inode*); +void iinit(void); +void ilock(struct inode*); +void iput(struct inode*); +void iunlock(struct inode*); +void iunlockput(struct inode*); +void iupdate(struct inode*); +int namecmp(const char*, const char*); +struct inode* namei(char*); +struct inode* nameiparent(char*, char*); +int readi(struct inode*, char*, uint, uint); +void stati(struct inode*, struct stat*); +int writei(struct inode*, char*, uint, uint); + + +// ide.c +void ideinit(void); +void ideintr(void); +void iderw(struct buf*); + +// exec.c +int exec(char*, char**); + +// file.c +struct file* filealloc(void); +void fileclose(struct file*); +struct file* filedup(struct file*); +void fileinit(void); +int fileread(struct file*, char*, int n); +int filestat(struct file*, struct stat*); +int filewrite(struct file*, char*, int n); + + +// fs.c +void readsb(int dev, struct superblock *sb); +int dirlink(struct inode*, char*, uint); +struct inode* dirlookup(struct inode*, char*, uint*); +struct inode* ialloc(uint, short); +struct inode* idup(struct inode*); +void iinit(void); +void ilock(struct inode*); +void iput(struct inode*); +void iunlock(struct inode*); +void iunlockput(struct inode*); +void iupdate(struct inode*); +int namecmp(const char*, const char*); +struct inode* namei(char*); +struct inode* nameiparent(char*, char*); +int readi(struct inode*, char*, uint, uint); +void stati(struct inode*, struct stat*); +int writei(struct inode*, char*, uint, uint); + +// kalloc.c +char* kalloc(void); +void kfree(char*); +void kinit1(void*, void*); +void kinit2(void*, void*); + + +// log.c +void initlog(void); +void log_write(struct buf*); +void begin_trans(); +void commit_trans(); + +// pipe.c +int pipealloc(struct file**, struct file**); +void pipeclose(struct pipe*, int); +int piperead(struct pipe*, char*, int); +int pipewrite(struct pipe*, char*, int); + +//PAGEBREAK: 16 +// proc.c +struct proc* copyproc(struct proc*); +void exit(void); +int fork(void); +int growproc(int); +int kill(int); +void pinit(void); +void procdump(void); +void scheduler(void) __attribute__((noreturn)); +void sched(void); +void sleep(void*, struct spinlock*); +void userinit(void); +int wait(void); +void wakeup(void*); +void yield(void); + + +// swtch.S +void swtch(struct context**, struct context*); + +// syscall.c +int argint(int, int*); +int argptr(int, char**, int); +int argstr(int, char**); +int fetchint(uint, int*); +int fetchstr(uint, char**); +void syscall(void); + +void kvmalloc(void); + + +int UsbInitialise(void); +void KeyboardUpdate(void); +char KeyboardGetChar(void); +uint KeyboardCount(void); +uint KeyboardGetAddress(uint); +struct KeyboardLeds KeyboardGetLedSupport(uint); + +// spinlock.c +void acquire(struct spinlock*); +void getcallerpcs(void*, uint*); +int holding(struct spinlock*); +void initlock(struct spinlock*, char*); +void release(struct spinlock*); +void pushcli(void); +void popcli(void); + +// string.c +int memcmp(const void*, const void*, uint); +void* memmove(void*, const void*, uint); +void* memset(void*, int, uint); +char* safestrcpy(char*, const char*, int); +int strlen(const char*); +int strncmp(const char*, const char*, uint); +char* strncpy(char*, const char*, int); +uint div(uint n, uint d); + +// syscall.c +int argint(int, int*); +int argptr(int, char**, int); +int argstr(int, char**); +int fetchint(uint, int*); +int fetchstr(uint, char**); +void syscall(void); + +// timer.c +void timer3init(void); +void timer3intr(void); +unsigned long long getsystemtime(void); +void delay(uint); + +// trap.c +void tvinit(void); +void sti(void); +void cli(void); +void disable_intrs(void); +void enable_intrs(void); +extern uint ticks; +extern struct spinlock tickslock; +uint readcpsr(void); + +// uart.c +void uartinit(void); +void miniuartintr(void); +void uartputc(uint); +void setgpiofunc(uint, uint); +void setgpioval(uint, uint); + +// vm.c +void seginit(void); +void kvmalloc(void); +void vmenable(void); +pde_t* setupkvm(void); +char* uva2ka(pde_t*, char*); +int allocuvm(pde_t*, uint, uint); +int deallocuvm(pde_t*, uint, uint); +void freevm(pde_t*); +void inituvm(pde_t*, char*, uint); +int loaduvm(pde_t*, char*, struct inode*, uint, uint); +pde_t* copyuvm(pde_t*, uint); +void switchuvm(struct proc*); +void switchkvm(void); +int copyout(pde_t*, uint, void*, uint); +void clearpteu(pde_t *pgdir, char *uva); + +// mailbox.c +uint readmailbox(u8); +void writemailbox(uint *, u8); +void create_request(volatile uint *mbuf, uint tag, uint buflen, uint len, uint *data); +void mailboxinit(void); + + + +// number of elements in fixed-size array +#define NELEM(x) (sizeof(x)/sizeof((x)[0])) + diff -r 000000000000 -r c450faca55f4 include/elf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/elf.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,42 @@ +// Format of an ELF executable file + +#define ELF_MAGIC 0x464C457FU // "\x7FELF" in little endian + +// File header +struct elfhdr { + uint magic; // must equal ELF_MAGIC + uchar elf[12]; + ushort type; + ushort machine; + uint version; + uint entry; + uint phoff; + uint shoff; + uint flags; + ushort ehsize; + ushort phentsize; + ushort phnum; + ushort shentsize; + ushort shnum; + ushort shstrndx; +}; + +// Program section header +struct proghdr { + uint type; + uint off; + uint vaddr; + uint paddr; + uint filesz; + uint memsz; + uint flags; + uint align; +}; + +// Values for Proghdr type +#define ELF_PROG_LOAD 1 + +// Flag bits for Proghdr flags +#define ELF_PROG_FLAG_EXEC 1 +#define ELF_PROG_FLAG_WRITE 2 +#define ELF_PROG_FLAG_READ 4 diff -r 000000000000 -r c450faca55f4 include/fcntl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/fcntl.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,4 @@ +#define O_RDONLY 0x000 +#define O_WRONLY 0x001 +#define O_RDWR 0x002 +#define O_CREATE 0x200 diff -r 000000000000 -r c450faca55f4 include/file.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/file.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,38 @@ +struct file { + enum { FD_NONE, FD_PIPE, FD_INODE } type; + int ref; // reference count + char readable; + char writable; + struct pipe *pipe; + struct inode *ip; + uint off; +}; + + +// in-memory copy of an inode +struct inode { + uint dev; // Device number + uint inum; // Inode number + int ref; // Reference count + int flags; // I_BUSY, I_VALID + + short type; // copy of disk inode + short major; + short minor; + short nlink; + uint size; + uint addrs[NDIRECT+1]; +}; +#define I_BUSY 0x1 +#define I_VALID 0x2 + +// table mapping major device number to +// device functions +struct devsw { + int (*read)(struct inode*, char*, int); + int (*write)(struct inode*, char*, int); +}; + +extern struct devsw devsw[]; + +#define CONSOLE 1 diff -r 000000000000 -r c450faca55f4 include/fs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/fs.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,55 @@ +// On-disk file system format. +// Both the kernel and user programs use this header file. + +// Block 0 is unused. +// Block 1 is super block. +// Blocks 2 through sb.ninodes/IPB hold inodes. +// Then free bitmap blocks holding sb.size bits. +// Then sb.nblocks data blocks. +// Then sb.nlog log blocks. + +#define ROOTINO 1 // root i-number +#define BSIZE 512 // block size + +// File system super block +struct superblock { + uint size; // Size of file system image (blocks) + uint nblocks; // Number of data blocks + uint ninodes; // Number of inodes. + uint nlog; // Number of log blocks +}; + +#define NDIRECT 12 +#define NINDIRECT (BSIZE / sizeof(uint)) +#define MAXFILE (NDIRECT + NINDIRECT) + +// On-disk inode structure +struct dinode { + short type; // File type + short major; // Major device number (T_DEV only) + short minor; // Minor device number (T_DEV only) + short nlink; // Number of links to inode in file system + uint size; // Size of file (bytes) + uint addrs[NDIRECT+1]; // Data block addresses +}; + +// Inodes per block. +#define IPB (BSIZE / sizeof(struct dinode)) + +// Block containing inode i +#define IBLOCK(i) ((i) / IPB + 2) + +// Bitmap bits per block +#define BPB (BSIZE*8) + +// Block containing bit for block b +#define BBLOCK(b, ninodes) (b/BPB + (ninodes)/IPB + 3) + +// Directory is a file containing a sequence of dirent structures. +#define DIRSIZ 14 + +struct dirent { + ushort inum; + char name[DIRSIZ]; +}; + diff -r 000000000000 -r c450faca55f4 include/mailbox.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/mailbox.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,38 @@ +#define MAILBOX_BASE 0xFE00B880 + +#define MPI_REQUEST 0x00000000 +#define MPI_RESPONSE_OK 0x80000000 +#define MPI_RESPONSE_ERR 0x80000001 + +#define POS_OVERALL_LENGTH 0 +#define POS_RV 1 +#define POS_TAG 2 + +#define POS_TAG_ID 0 +#define POS_TAG_BUFLEN 1 +#define POS_TAG_DATALEN 2 +#define POS_TAG_DATA 3 + + +#define MB_HEADER_LENGTH 2 +#define TAG_HEADER_LENGTH 3 + +/* to be extended */ +#define MPI_TAG_GET_FIRMWARE 0x00000001 +#define MPI_TAG_GET_BOARD_MODEL 0x00010001 +#define MPI_TAG_GET_BOARD_REVISION 0x00010002 +#define MPI_TAG_GET_MAC_ADDRESS 0x00010003 +#define MPI_TAG_GET_BOARD_SERIAL 0x00010004 +#define MPI_TAG_GET_ARM_MEMORY 0x00010005 +#define MPI_TAG_GET_VC_MEMORY 0x00010006 +#define MPI_TAG_GET_CLOCKS 0x00010007 +#define MPI_TAG_GET_COMMANDLINE 0x00050001 +#define MPI_TAG_GET_DMA_CHANNELS 0x00060001 +#define MPI_TAG_GET_POWER_STATE 0x00020001 +#define MPI_TAG_SET_POWER_STATE 0x00028001 +#define MPI_TAG_GET_TIMING 0x00020002 +#define MPI_TAG_GET_FIRMWARE 0x00000001 +#define MPI_TAG_GET_CLOCK_STATE 0x00030001 +#define MPI_TAG_SET_CLOCK_STATE 0x00038001 + + diff -r 000000000000 -r c450faca55f4 include/memlayout.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/memlayout.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,37 @@ +/***************************************************************** +* memlayout.h +* by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + + +// Memory layout + +#define EXTMEM 0x8000 /* start of kernel code */ +#define PHYSTOP 0xC000000 /* assuming 128M RAM; need a fix to find the true RAM size */ +#define DEVSPACE 0xFE000000 /* i/o registers */ + +// Key addresses for address space layout (see kmap in vm.c for layout) +#define KERNBASE 0x80000000 // First kernel virtual address +#define KERNLINK (KERNBASE+EXTMEM) // Address where kernel is linked +#define USERBOUND 0x40000000 // maximum user space due to one page pgd +#define GPUMEMBASE 0x40000000 +#define GPUMEMSIZE (1024*MBYTE) + +#define PA_START 0x0 +#define PHYSIO 0x20000000 +#define RAMSIZE 0xC000000 +#define IOSIZE (16*MBYTE) +#define TVSIZE 0x1000 + +static inline uint v2p(void *a) { return ((uint) (a)) - KERNBASE; } +static inline void *p2v(uint a) { return (void *) ((a) + KERNBASE); } + +#define V2P(a) (((uint) (a)) - KERNBASE) +#define P2V(a) (((void *) (a)) + KERNBASE) + +#define V2P_WO(x) ((x) - KERNBASE) // same as V2P, but without casts +#define P2V_WO(x) ((x) + KERNBASE) // same as V2P, but without casts + diff -r 000000000000 -r c450faca55f4 include/mmu.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/mmu.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,82 @@ +/***************************************************************** +* mmu.h +* by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + +#define MBYTE 0x100000 +#define K_PDX_BASE 0x4000 +#define K_PTX_BASE 0x3000 + +#define CACHELINESIZE 32 + +/* + * page table entries. +*/ + +#define UNMAPPED 0x00000000 + +#define COARSE (0<<4|1) +#define SECTION (0<<4|2) + +#define LARGE 0x00000001 +#define SMALL 0x00000002 +#define BUFFERED 0x00000004 +#define CACHED 0x00000008 +#define DOMAIN0 0 + +#define NOACCESS 0 +#define K_RW 1 +#define U_AP 2 +#define U_RW 3 + +#define ACCESS_PERM(n, v) (((v) & 3) << (((n) * 2) + 4)) +#define PDX_AP(ap) (ACCESS_PERM(3, (ap))) +#define PTX_AP(ap) (ACCESS_PERM(3, (ap)) | ACCESS_PERM(2, (ap)) \ + | ACCESS_PERM(1, (ap)) | ACCESS_PERM(0, (ap))) + +#define HVECTORS 0xffff0000 + +// A virtual address 'la' has a three-part structure as follows: +// +// +--------12------+-------8--------+---------12----------+ +// | Page Directory | Page Table | Offset within Page | +// | Index | Index | | +// +----------------+----------------+---------------------+ +// \--- PDX(va) --/ \--- PTX(va) --/ + +// page directory index +#define PDX(va) (((uint)(va) >> PDXSHIFT) & 0xFFF) + +// page table index +#define PTX(va) (((uint)(va) >> PTXSHIFT) & 0xFF) + +// construct virtual address from indexes and offset +#define PGADDR(d, t, o) ((uint)((d) << PDXSHIFT | (t) << PTXSHIFT | (o))) + +// Address in page table or page directory entry +#define PTE_ADDR(pte) ((uint)(pte) & ~0xFFF) +#define PTE_FLAGS(pte) ((uint)(pte) & 0xFFF) + +// Page directory and page table constants. +#define NPDENTRIES 1024 // # directory entries per page directory +#define NPTENTRIES 1024 // # PTEs per page table +#define PGSIZE 4096 // bytes mapped by a page + +#define PGSHIFT 12 // log2(PGSIZE) +#define PTXSHIFT 12 // offset of PTX in a linear address +#define PDXSHIFT 20 // offset of PDX in a linear address + + +#define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1)) +#define PGROUNDDOWN(a) (((a)) & ~(PGSIZE-1)) + +#define PGDIR_BASE P2V(K_PDX_BASE) + +#define KVMPDXATTR DOMAIN0|PDX_AP(U_RW)|SECTION|CACHED|BUFFERED + +#define UVMPDXATTR DOMAIN0|COARSE +#define UVMPTXATTR PTX_AP(U_RW)|CACHED|BUFFERED|SMALL + diff -r 000000000000 -r c450faca55f4 include/param.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/param.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,12 @@ +#define NPROC 64 // maximum number of processes +#define KSTACKSIZE 4096 // size of per-process kernel stack +#define NCPU 8 // maximum number of CPUs +#define NOFILE 16 // open files per process +#define NFILE 100 // open files per system +#define NBUF 10 // size of disk block cache +#define NINODE 50 // maximum number of active i-nodes +#define NDEV 10 // maximum major device number +#define ROOTDEV 1 // device number of file system root disk +#define MAXARG 32 // max exec arguments +#define LOGSIZE 10 // max data sectors in on-disk log + diff -r 000000000000 -r c450faca55f4 include/proc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/proc.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,91 @@ +/***************************************************************** +* proc.h +* adapted from MIT xv6 by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + + +// Segments in proc->gdt. +#define NSEGS 7 + +// Per-CPU state +struct cpu { + uchar id; // Local APIC ID; index into cpus[] below + struct context *scheduler; // swtch() here to enter scheduler + volatile uint started; // Has the CPU started? + int ncli; // Depth of pushcli nesting. + int intena; // Were interrupts enabled before pushcli? + + // Cpu-local storage variables; see below + struct cpu *cpu; + struct proc *proc; // The currently-running process. +}; + +struct cpu cpus[NCPU]; +//extern int ncpu; + +// Per-CPU variables, holding pointers to the +// current cpu and to the current process. +// The asm suffix tells gcc to use "%gs:0" to refer to cpu +// and "%gs:4" to refer to proc. seginit sets up the +// %gs segment register so that %gs refers to the memory +// holding those two variables in the local cpu's struct cpu. +// This is similar to how thread-local variables are implemented +// in thread libraries such as Linux pthreads. +//extern struct cpu *cpu asm("%gs:0"); // &cpus[cpunum()] +//extern struct proc *proc asm("%gs:4"); // cpus[cpunum()].proc + +#define curr_cpu (&cpus[0]) +#define curr_proc (cpus[0].proc) + +//PAGEBREAK: 17 +// Saved registers for kernel context switches. +// Don't need to save all the segment registers (%cs, etc), +// because they are constant across kernel contexts. +// Don't need to save %eax, %ecx, %edx, because the +// x86 convention is that the caller has saved them. +// Contexts are stored at the bottom of the stack they +// describe; the stack pointer is the address of the context. +// The layout of the context matches the layout of the stack in swtch.S +// at the "Switch stacks" comment. Switch doesn't save eip explicitly, +// but it is on the stack and allocproc() manipulates it. +struct context { + uint r4; + uint r5; + uint r6; + uint r7; + uint r8; + uint r9; + uint r10; + uint r11; + uint r12; + uint lr; + uint pc; +}; + +enum procstate { UNUSED=0, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE }; + +// Per-process state +struct proc { + uint sz; // Size of process memory (bytes) + pde_t* pgdir; // Page table + char *kstack; // Bottom of kernel stack for this process + enum procstate state; // Process state + volatile int pid; // Process ID + struct proc *parent; // Parent process + struct trapframe *tf; // Trap frame for current syscall + struct context *context; // swtch() here to run process + void *chan; // If non-zero, sleeping on chan + int killed; // If non-zero, have been killed + struct file *ofile[NOFILE]; // Open files + struct inode *cwd; // Current directory + char name[16]; // Process name (debugging) +}; + +// Process memory is laid out contiguously, low addresses first: +// text +// original data and bss +// fixed-size stack +// expandable heap diff -r 000000000000 -r c450faca55f4 include/spinlock.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/spinlock.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,11 @@ +// Mutual exclusion lock. +struct spinlock { + uint locked; // Is the lock held? + + // For debugging: + char *name; // Name of lock. + struct cpu *cpu; // The cpu holding the lock. + uint pcs[10]; // The call stack (an array of program counters) + // that locked the lock. +}; + diff -r 000000000000 -r c450faca55f4 include/stat.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/stat.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,11 @@ +#define T_DIR 1 // Directory +#define T_FILE 2 // File +#define T_DEV 3 // Device + +struct stat { + short type; // Type of file + int dev; // File system's disk device + uint ino; // Inode number + short nlink; // Number of links to file + uint size; // Size of file in bytes +}; diff -r 000000000000 -r c450faca55f4 include/syscall.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/syscall.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,22 @@ +// System call numbers +#define SYS_fork 1 +#define SYS_exit 2 +#define SYS_wait 3 +#define SYS_pipe 4 +#define SYS_read 5 +#define SYS_kill 6 +#define SYS_exec 7 +#define SYS_fstat 8 +#define SYS_chdir 9 +#define SYS_dup 10 +#define SYS_getpid 11 +#define SYS_sbrk 12 +#define SYS_sleep 13 +#define SYS_uptime 14 +#define SYS_open 15 +#define SYS_write 16 +#define SYS_mknod 17 +#define SYS_unlink 18 +#define SYS_link 19 +#define SYS_mkdir 20 +#define SYS_close 21 diff -r 000000000000 -r c450faca55f4 include/traps.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/traps.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,21 @@ +/***************************************************************** +* traps.h +* by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + + +// These are arbitrarily chosen, but with care not to overlap +// processor defined exceptions or interrupt vectors. +#define T_SYSCALL 0x40 // system call +#define T_IRQ 0x80 // interrupt +#define T_UND 0x01 // undefined instruction +#define T_PABT 0x02 // prefetch abort +#define T_DABT 0x04 // data abort + +#define IRQ_TIMER3 3 +#define IRQ_MINIUART 29 + +#define INT_REGS_BASE (DEVSPACE+0xB200) diff -r 000000000000 -r c450faca55f4 include/types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/types.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,53 @@ +/***************************************************************** +* types.h +* by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + +typedef unsigned int u32; +typedef unsigned short u16; +typedef unsigned char u8; +typedef unsigned long long u64; + +typedef unsigned int uint; +typedef unsigned short ushort; +typedef unsigned char uchar; +typedef uint pde_t; +typedef uint pte_t; + + +/* trap vectors layout at virtual +address HVECTORS (and KZERO(0x80000000), doubled mapped).*/ +typedef struct Vpage0 { + void (*vectors[8])(void); + uint vtable[8]; +} Vpage0; + + +/* ARM interrupt control registers */ +typedef struct intctrlregs { + uint armpending; + uint gpupending[2]; + uint fiqctrl; + uint gpuenable[2]; + uint armenable; + uint gpudisable[2]; + uint armdisable; +} intctrlregs; + +struct framebufdescription { + uint width; //width + uint height; // height + uint v_width; // virtual width + uint v_height; // virtual height + uint pitch; // GPU pitch + uint depth; // bit depth + uint x; + uint y; + uint fbp; //GPU framebuffer pointer + uint fbs; // GPU framebuffer size +}; + +typedef struct framebufdescription FBI; diff -r 000000000000 -r c450faca55f4 include/user.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/user.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,38 @@ +struct stat; + +// system calls +int fork(void); +int exit(void) __attribute__((noreturn)); +int wait(void); +int pipe(int*); +int write(int, void*, int); +int read(int, void*, int); +int close(int); +int kill(int); +int exec(char*, char**); +int open(char*, int); +int mknod(char*, short, short); +int unlink(char*); +int fstat(int fd, struct stat*); +int link(char*, char*); +int mkdir(char*); +int chdir(char*); +int dup(int); +int getpid(void); +char* sbrk(int); +int sleep(int); +int uptime(void); + +// ulib.c +int stat(char*, struct stat*); +char* strcpy(char*, char*); +void *memmove(void*, void*, int); +char* strchr(const char*, char c); +int strcmp(const char*, const char*); +void printf(int, char*, ...); +char* gets(char*, int max); +uint strlen(char*); +void* memset(void*, int, uint); +void* malloc(uint); +void free(void*); +int atoi(const char*); diff -r 000000000000 -r c450faca55f4 kernel.ld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel.ld Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,62 @@ +/****************************************************************************** +* kernel.ld +* by Alex Chadwick +* +* A linker script for generation of raspberry pi kernel images. +******************************************************************************/ + +SECTIONS { + /* Link the kernel at this address: "." means the current address */ + /* Must be equal to KERNLINK */ + . = 0x80008000; + + + /* + * First and formost we need the .init section, containing the code to + * be run first. We allow room for the ATAGs and stack and conform to + * the bootloader's expectation by putting this code at 0x8000. + */ + .init 0x80008000 : AT(0x8000) { + *(.init) + } + + /* + * Next we put the rest of the code. + */ + .text : { + *.c.o(.text) + *(.text .stub .text.*) + } + + /* + * read-only data + */ + .rodata : { + *(.rodata .rodata.*) + } + + /* Adjust the address for the data segment to the next page */ + . = ALIGN(0x1000); + + /* + * Next we put the data. + */ + .data : { + *(.data) + *.c.o(*) + } + + .bss : { + *(.bss) + } + + PROVIDE(end = .); + + /* + * Finally comes everything else. A fun trick here is to put all other + * sections into this section, which will be discarded by default. + */ + /DISCARD/ : { + *(.eh_frame .note.GNU-stack) + } +} diff -r 000000000000 -r c450faca55f4 libcsud.a Binary file libcsud.a has changed diff -r 000000000000 -r c450faca55f4 source/LICENSE --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/LICENSE Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,24 @@ +The xv6 software is: + +Copyright (c) 2006-2009 Frans Kaashoek, Robert Morris, Russ Cox, + Massachusetts Institute of Technology + +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. + diff -r 000000000000 -r c450faca55f4 source/bio.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/bio.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,141 @@ +// Buffer cache. +// +// The buffer cache is a linked list of buf structures holding +// cached copies of disk block contents. Caching disk blocks +// in memory reduces the number of disk reads and also provides +// a synchronization point for disk blocks used by multiple processes. +// +// Interface: +// * To get a buffer for a particular disk block, call bread. +// * After changing buffer data, call bwrite to write it to disk. +// * When done with the buffer, call brelse. +// * Do not use the buffer after calling brelse. +// * Only one process at a time can use a buffer, +// so do not keep them longer than necessary. +// +// The implementation uses three state flags internally: +// * B_BUSY: the block has been returned from bread +// and has not been passed back to brelse. +// * B_VALID: the buffer data has been read from the disk. +// * B_DIRTY: the buffer data has been modified +// and needs to be written to disk. + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "spinlock.h" +#include "buf.h" + +struct { + struct spinlock lock; + struct buf buf[NBUF]; + + // Linked list of all buffers, through prev/next. + // head.next is most recently used. + struct buf head; +} bcache; + +void +binit(void) +{ + struct buf *b; + + memset(&bcache, 0, sizeof(bcache)); + initlock(&bcache.lock, "bcache"); + +//PAGEBREAK! + // Create linked list of buffers + bcache.head.prev = &bcache.head; + bcache.head.next = &bcache.head; + for(b = bcache.buf; b < bcache.buf+NBUF; b++){ + b->next = bcache.head.next; + b->prev = &bcache.head; + b->dev = -1; + bcache.head.next->prev = b; + bcache.head.next = b; + } +} + +// Look through buffer cache for sector on device dev. +// If not found, allocate fresh block. +// In either case, return B_BUSY buffer. +static struct buf* +bget(uint dev, uint sector) +{ + struct buf *b; + + acquire(&bcache.lock); + + loop: + // Is the sector already cached? + for(b = bcache.head.next; b != &bcache.head; b = b->next){ + if(b->dev == dev && b->sector == sector){ + if(!(b->flags & B_BUSY)){ + b->flags |= B_BUSY; + release(&bcache.lock); + return b; + } + sleep(b, &bcache.lock); + goto loop; + } + } + + // Not cached; recycle some non-busy and clean buffer. + for(b = bcache.head.prev; b != &bcache.head; b = b->prev){ + if((b->flags & B_BUSY) == 0 && (b->flags & B_DIRTY) == 0){ + b->dev = dev; + b->sector = sector; + b->flags = B_BUSY; + release(&bcache.lock); + return b; + } + } + panic("bget: no buffers"); + return 0; +} + +// Return a B_BUSY buf with the contents of the indicated disk sector. +struct buf* +bread(uint dev, uint sector) +{ + struct buf *b; + + b = bget(dev, sector); + if(!(b->flags & B_VALID)) + iderw(b); + return b; +} + +// Write b's contents to disk. Must be B_BUSY. +void +bwrite(struct buf *b) +{ + if((b->flags & B_BUSY) == 0) + panic("bwrite"); + b->flags |= B_DIRTY; + iderw(b); +} + +// Release a B_BUSY buffer. +// Move to the head of the MRU list. +void +brelse(struct buf *b) +{ + if((b->flags & B_BUSY) == 0) + panic("brelse"); + + acquire(&bcache.lock); + + b->next->prev = b->prev; + b->prev->next = b->next; + b->next = bcache.head.next; + b->prev = &bcache.head; + bcache.head.next->prev = b; + bcache.head.next = b; + + b->flags &= ~B_BUSY; + wakeup(b); + + release(&bcache.lock); +} + diff -r 000000000000 -r c450faca55f4 source/console.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/console.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,411 @@ +/***************************************************************** +* console.c +* adapted from MIT xv6 by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "traps.h" +#include "spinlock.h" +#include "fs.h" +#include "file.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" +#include "arm.h" + +#define BACKSPACE 0x100 + +static int panicked = 0; + +static struct { + struct spinlock lock; + int locking; +} cons; + + +uint cursor_x=0, cursor_y=0; +uint frameheight=768, framewidth=1024, framecolors=16; +uint fontheight=16, fontwidth=8; +FBI fbinfo __attribute__ ((aligned (16), nocommon)); + + +extern u8 font[]; +static uint gpucolour=0xffff; + +void setgpucolour(u16 c) +{ + gpucolour = c; +} + +uint initframebuf(uint width, uint height, uint depth) +{ + fbinfo.width = width; + fbinfo.height = height; + fbinfo.v_width = width; + fbinfo.v_height = height; + fbinfo.pitch = 0; + fbinfo.depth = depth; + fbinfo.x = 0; + fbinfo.y = 0; + fbinfo.fbp = 0; + fbinfo.fbs = 0; + writemailbox((uint *)&fbinfo, 1); + return readmailbox(1); +} + +#define INPUT_BUF 128 +struct { + struct spinlock lock; + char buf[INPUT_BUF]; + uint r; // Read index + uint w; // Write index + uint e; // Edit index +} input; + +int +consolewrite(struct inode *ip, char *buf, int n) +{ + int i; + +// cprintf("consolewrite is called: ip=%x buf=%x, n=%x", ip, buf, n); + iunlock(ip); + acquire(&cons.lock); + for(i = 0; i < n; i++){ + gpuputc(buf[i] & 0xff); + uartputc(buf[i] & 0xff); + } + release(&cons.lock); + ilock(ip); + + return n; +} + + +void drawpixel(uint x, uint y) +{ + u16 *addr; + + if(x >= framewidth || y >= frameheight) return; + addr = (u16 *) fbinfo.fbp; +// addr = (u16 *) ((FBI *)FrameBufferInfo)->fbp; + addr += y*1024 + x; + *addr = gpucolour; + return; +} + + +void drawcursor(uint x, uint y) +{ +u8 row, bit; + + for(row=0; row<15; row++) + for(bit=0; bit<8; bit++) + drawpixel(x+bit, y+row); +} + +void drawcharacter(u8 c, uint x, uint y) +{ +u8 *faddr; +u8 row, bit, bits; +uint tv; + + if(c > 127) return; + tv = ((uint)c) << 4; + faddr = font + tv; + for(row=0; row<15; row++){ + bits = *(faddr+row); + for(bit=0; bit<8; bit++){ + if((bits>>bit) & 1) drawpixel(x+bit, y+row); + } + } + +} + +//static void +void +gpuputc(uint c) +{ + if(c=='\n'){ + cursor_x = 0; + cursor_y += fontheight; + if(cursor_y >= frameheight) { + memmove((u8 *)fbinfo.fbp, (u8 *)fbinfo.fbp+framewidth*fontheight*2, (frameheight - fontheight)*framewidth*2); + cursor_y = frameheight - fontheight; + setgpucolour(0); + while(cursor_x < framewidth) { + drawcursor(cursor_x, cursor_y); + cursor_x = cursor_x + fontwidth; + } + setgpucolour(0xffff); + cursor_x = 0; + } + } else if(c == BACKSPACE) { + if (cursor_x > 0) { + cursor_x -= fontwidth; + setgpucolour(0); + drawcursor(cursor_x, cursor_y); + setgpucolour(0xffff); + } + } else { + setgpucolour(0); + drawcursor(cursor_x, cursor_y); + setgpucolour(0xffff); + if(c!=' ') drawcharacter(c, cursor_x, cursor_y); + cursor_x = cursor_x + fontwidth; + if(cursor_x >= framewidth) { + cursor_x = 0; + cursor_y += fontheight; + if(cursor_y >= frameheight) { + memmove((u8 *)fbinfo.fbp, (u8 *)fbinfo.fbp+framewidth*fontheight*2, (frameheight - fontheight)*framewidth*2); + cursor_y = frameheight - fontheight; + setgpucolour(0); + while(cursor_x < framewidth) { + drawcursor(cursor_x, cursor_y); + cursor_x = cursor_x + fontwidth; + } + setgpucolour(0xffff); + cursor_x = 0; + } + } + } + +} + + +static void +printint(int xx, int base, int sign) +{ + static u8 digits[] = "0123456789abcdef"; + u8 buf[16]; + int i; + uint x, y, b; + + if(sign && (sign = xx < 0)) + x = -xx; + else + x = xx; + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + + if(sign) + buf[i++] = '-'; + + while(--i >= 0){ + gpuputc(buf[i]); + uartputc(buf[i]); + } +} + + +// Print to the console. only understands %d, %x, %p, %s. +void +cprintf(char *fmt, ...) +{ + int i, c; + int locking; + uint *argp; + char *s; + + locking = cons.locking; + if(locking) + acquire(&cons.lock); + + if (fmt == 0) + panic("null fmt"); + + argp = (uint *)(void*)(&fmt + 1); + for(i = 0; (c = fmt[i] & 0xff) != 0; i++){ + if(c != '%'){ + gpuputc(c); + uartputc(c); + continue; + } + c = fmt[++i] & 0xff; + if(c == 0) + break; + switch(c){ + case 'd': + printint(*argp++, 10, 1); + break; + case 'x': + case 'p': + printint(*argp++, 16, 0); + break; + case 's': + if((s = (char*)*argp++) == 0) + s = "(null)"; + for(; *s; s++){ + gpuputc(*s); + uartputc(*s); + } + break; + case '%': + gpuputc('%'); + uartputc('%'); + break; + default: + // Print unknown % sequence to draw attention. + gpuputc('%'); + uartputc('%'); + gpuputc(c); + uartputc(c); + break; + } + } + if(locking) + release(&cons.lock); +} + +void +panic(char *s) +{ + int i; + uint pcs[10]; + + cprintf("cpu%d: panic: ", 0); + cprintf(s); + cprintf("\n"); + getcallerpcs(&s, pcs); + for(i=0; i<10; i++) + cprintf(" %p", pcs[i]); + panicked = 1; // freeze other CPU + + for(;;) + ; +} + +#define C(x) ((x)-'@') // Control-x + +void +consputc(int c) +{ + if(panicked){ + cli(); + for(;;) + ; + } + + if(c == BACKSPACE){ + gpuputc('\b'); gpuputc(' '); gpuputc('\b'); + uartputc('\b'); uartputc(' '); uartputc('\b'); + } else if(c == C('D')) { + gpuputc('^'); gpuputc('D'); + uartputc('^'); uartputc('D'); + } else { + gpuputc(c); + uartputc(c); + } +} + + +void +consoleintr(int (*getc)(void)) +{ + int c; + + acquire(&input.lock); + while((c = getc()) >= 0){ + switch(c){ + case C('P'): // Process listing. + procdump(); + break; + case C('U'): // Kill line. + while(input.e != input.w && + input.buf[(input.e-1) % INPUT_BUF] != '\n'){ + input.e--; + consputc(BACKSPACE); + } + break; + case C('H'): case '\x7f': // Backspace + if(input.e != input.w){ + input.e--; + consputc(BACKSPACE); + } + break; + default: + if(c != 0 && input.e-input.r < INPUT_BUF){ + if(c == 0xa) break; + c = (c == 0xd) ? '\n' : c; + input.buf[input.e++ % INPUT_BUF] = c; + consputc(c); + if(c == '\n' || c == C('D') || input.e == input.r+INPUT_BUF){ + input.w = input.e; + wakeup(&input.r); + } + } + break; + } + } + release(&input.lock); +} + +int +consoleread(struct inode *ip, char *dst, int n) +{ + uint target; + int c; + +//cprintf("inside consoleread\n"); + iunlock(ip); + target = n; + acquire(&input.lock); + while(n > 0){ + while(input.r == input.w){ + if(curr_proc->killed){ + release(&input.lock); + ilock(ip); + return -1; + } + sleep(&input.r, &input.lock); + } + c = input.buf[input.r++ % INPUT_BUF]; + if(c == C('D')){ // EOF + if(n < target){ + // Save ^D for next time, to make sure + // caller gets a 0-byte result. + input.r--; + } + break; + } + *dst++ = c; + --n; + if(c == '\n') + break; + } + release(&input.lock); + ilock(ip); + + return target - n; +} + +void consoleinit(void) +{ +uint fbinfoaddr; + + fbinfoaddr = initframebuf(framewidth, frameheight, framecolors); + if(fbinfoaddr != 0) NotOkLoop(); + + initlock(&cons.lock, "console"); + memset(&input, 0, sizeof(input)); + initlock(&input.lock, "input"); + + memset(devsw, 0, sizeof(struct devsw)*NDEV); + devsw[CONSOLE].write = consolewrite; + devsw[CONSOLE].read = consoleread; + cons.locking = 1; + panicked = 0; // must initialize in code since the compiler does not + + cursor_x=cursor_y=0; +} + diff -r 000000000000 -r c450faca55f4 source/entry.s --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/entry.s Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,104 @@ +/***************************************************************** +* entry.s +* by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + +.section .init +.globl _start +_start: + +b entry /* branch to the actual entry code */ + +.section .data + +.align 4 +.globl font +font: + .incbin "font1.bin" + +.align 4 +.global _binary_initcode_start +_binary_initcode_start: + .incbin "initcode" +.global _binary_initcode_end +_binary_initcode_end: + +.align 4 +.global _binary_fs_img_start +_binary_fs_img_start: + .incbin "fs.img" +.global _binary_fs_img_end +_binary_fs_img_end: + + +.section .text + +entry: + +/* interrupts disabled, SVC mode by setting PSR_DISABLE_IRQ|PSR_DISABLE_FIQ|PSR_MODE_SVC */ +mov r1, #0x00000080 /* PSR_DISABLE_IRQ */ +orr r1, #0x00000040 /* PSR_DISABLE_FIQ */ +orr r1, #0x00000013 /* PSR_MODE_SVC */ +msr cpsr, r1 + +mov sp, #0x3000 +bl mmuinit0 + +/* switch SP and PC into KZERO space */ +mov r1, sp +add r1, #0x80000000 +mov sp, r1 + +ldr r1, =_pagingstart +bx r1 + +.global _pagingstart +_pagingstart: +bl cmain /* call C functions now */ +bl NotOkLoop + +.global dsb_barrier +dsb_barrier: + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 + bx lr +.global flush_dcache_all +flush_dcache_all: + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 /* dsb */ + mov r0, #0 + mcr p15, 0, r0, c7, c14, 0 /* invalidate d-cache */ + bx lr +.global flush_idcache +flush_idcache: + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 /* dsb */ + mov r0, #0 + mcr p15, 0, r0, c7, c14, 0 /* invalidate d-cache */ + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 /* invalidate i-cache */ + bx lr +.global flush_tlb +flush_tlb: + mov r0, #0 + mcr p15, 0, r0, c8, c7, 0 + mcr p15, 0, r0, c7, c10, 4 + bx lr +.global flush_dcache /* flush a range of data cache flush_dcache(va1, va2) */ +flush_dcache: + mcrr p15, 0, r0, r1, c14 + bx lr +.global set_pgtbase /* set the page table base set_pgtbase(base) */ +set_pgtbase: + mcr p15, 0, r0, c2, c0 + bx lr + +.global getsystemtime +getsystemtime: + ldr r0, =0xFE003004 /* addr of the time-stamp lower 32 bits */ + ldrd r0, r1, [r0] + bx lr + + diff -r 000000000000 -r c450faca55f4 source/exception.s --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/exception.s Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,226 @@ +/***************************************************************** +* exception.s +* by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + +.align 4 +.section .text + +.global vectors +vectors: + ldr pc, reset_handler + ldr pc, undefintr_handler + ldr pc, swi_handler + ldr pc, prefetch_handler + ldr pc, data_handler + ldr pc, unused_handler + ldr pc, irq_handler + ldr pc, fiq_handler +reset_handler: + .word hang /* reset, in svc mode already */ +undefintr_handler: + .word do_und /* undefined instruction */ +swi_handler: + .word do_svc /* SWI & SVC */ +prefetch_handler: + .word do_pabt /* prefetch abort */ +data_handler: + .word do_dabt /* data abort */ +unused_handler: + .word hang /* reserved */ +irq_handler: + .word do_irq /* IRQ */ +fiq_handler: + .word hang /* FIQ */ + +hang: + bl NotOkLoop; + b hang +do_svc: + push {lr} + mrs lr, spsr + push {lr} + mrs lr, cpsr + push {lr} + mrc p15, 0, lr, c6, c0, 2 /* read Instruction Fault Address Register (IFAR) */ + push {lr} + mov lr, #0x40 + push {lr} + STMFD sp, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14} + sub sp, sp, #60 + mov r0, sp /* save sp */ + STMFD r0, {r13}^ /* save user mode sp */ + mov r1, r1 /* three nops after STM with user mode banked registers */ + mov r1, r1 + mov r1, r1 + mov sp, r0 /* restore sp */ + sub sp, sp, #4 + mov r0, sp + bl trap + +.global trapret +trapret: + mov r0, sp /* save sp in case it is changed to sp_usr after the following LDMFD instruction */ + LDMFD r0, {r13}^ /* restore user mode sp */ + mov r1, r1 /* three nops after LDMFD */ + mov r1, r1 + mov r1, r1 + mov sp, r0 /* restore sp */ + add sp, sp, #4 + LDMFD sp, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12} + add sp, sp, #72 + pop {lr} + msr spsr, lr + pop {lr} + movs pc, lr /* subs pc,lr,#0 */ + +do_und: + STMFD sp, {r0-r4} + mov r0, #0x01 + b _switchtosvc + +do_pabt: + STMFD sp, {r0-r4} + mov r0, #0x02 + b _switchtosvc + +do_dabt: + STMFD sp, {r0-r4} + mov r0, #0x04 + b _switchtosvc + +do_irq: + STMFD sp, {r0-r4} + mov r0, #0x80 + b _switchtosvc +_switchtosvc: + mrs r1, spsr + sub r2, lr, #4 + mov r3, sp + mrs lr, cpsr + bic lr, #0x0000001F /* PSR_MASK */ + orr lr, #0x00000080 /* PSR_DISABLE_IRQ */ + orr lr, #0x00000013 /* PSR_MODE_SVC */ + msr cpsr, lr /* switch to svc */ + push {r2} + push {r1} + mrs r1, cpsr + push {r1} + mrc p15, 0, r1, c6, c0, 2 /* read Instruction Fault Address Register (I +FAR) */ + push {r1} + push {r0} + sub r1, r3, #20 + LDMFD r1, {r0-r4} + STMFD sp, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14} + sub sp, sp, #60 + mov r0, sp /* save sp */ + STMFD r0, {r13}^ /* save user mode sp */ + mov r1, r1 /* three nops after STM with user mode banked registers */ + mov r1, r1 + mov r1, r1 + mov sp, r0 /* restore sp */ + sub sp, sp, #4 + mov r0, sp + + bl trap + + mov r0, sp + add r0, #76 + LDMIA r0, {r1} + mov r2, r1 + and r2, #0xf + cmp r2, #0 + beq _backtouser + msr cpsr, r1 + add sp, #4 + LDMFD sp, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12} + add sp, sp, #56 + pop {r14} + add sp, sp, #16 + pop {pc} + +_backtouser: + mov r0, sp /* save sp in case it is changed to sp_usr after the following LDMFD instruction */ + LDMFD r0, {r13}^ /* restore user mode sp */ + mov r1, r1 /* three nops after LDMFD */ + mov r1, r1 + mov r1, r1 + mov sp, r0 /* restore sp */ + add sp, sp, #4 + LDMIA sp, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12} + add sp, sp, #72 + pop {lr} + msr spsr, lr + pop {lr} + movs pc, lr /* subs pc,lr,#0 */ + + +.global set_mode_sp +set_mode_sp: + mrs r2, cpsr + msr cpsr_c,r1 + mov sp, r0 + mrs r0, cpsr + orr r0, #0x00000080 /* PSR_DISABLE_IRQ */ + orr r0, #0x00000040 /* PSR_DISABLE_FIQ */ + msr cpsr, r0 + msr cpsr_c, r2 + bx lr + +.global readcpsr +readcpsr: + mrs r0, cpsr + bx lr + +.global cli +cli: + mrs r0, cpsr + orr r0, #0x00000080 /* PSR_DISABLE_IRQ */ + msr cpsr, r0 + bx lr + +.global sti +sti: + mrs r0, cpsr + bic r0, r0, #0x00000080 /* PSR_DISABLE_IRQ */ + msr cpsr, r0 + bx lr + +.global swtch +swtch: + push {lr} /* save the return address */ + push {lr} + /* save old callee-save registers */ + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + + /* switch stacks */ + str sp, [r0] + mov sp, r1 + + /* load new callee-save registers */ + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + + /* return to previously saved pc */ + pop {lr} + pop {pc} + diff -r 000000000000 -r c450faca55f4 source/exec.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/exec.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,104 @@ +#include "types.h" +#include "param.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" +#include "defs.h" +#include "arm.h" +#include "elf.h" + +int +exec(char *path, char **argv) +{ + char *last; + int i, off; + uint argc, sz, sp, ustack[3+MAXARG+1]; + struct elfhdr elf; + struct inode *ip; + struct proghdr ph; + pde_t *pgdir, *oldpgdir; + + if((ip = namei(path)) == 0) + return -1; + ilock(ip); + pgdir = 0; + + // Check ELF header + if(readi(ip, (char*)&elf, 0, sizeof(elf)) < sizeof(elf)) + goto bad; + if(elf.magic != ELF_MAGIC) + goto bad; + + if((pgdir = setupkvm()) == 0) + goto bad; + // Load program into memory. + sz = 0; + for(i=0, off=elf.phoff; i= MAXARG) + goto bad; + sp = (sp - (strlen(argv[argc]) + 1)) & ~3; + if(copyout(pgdir, sp, argv[argc], strlen(argv[argc]) + 1) < 0) + goto bad; + ustack[3+argc] = sp; + } + ustack[3+argc] = 0; + +//cprintf("Exec is called argc=%d sz=%x\n", argc, sz); + + ustack[0] = 0xffffffff; // fake return PC + ustack[1] = argc; + ustack[2] = sp - (argc+1)*4; // argv pointer + + sp -= (3+argc+1) * 4; + if(copyout(pgdir, sp, ustack, (3+argc+1)*4) < 0) + goto bad; + + // Save program name for debugging. +/* for(last=s=path; *s; s++) + if(*s == '/') + last = s+1;*/ + last = argv[0]; + safestrcpy(curr_proc->name, last, sizeof(curr_proc->name)); + + // Commit to the user image. + oldpgdir = curr_proc->pgdir; + curr_proc->pgdir = pgdir; + curr_proc->sz = sz; + curr_proc->tf->pc = elf.entry; // main + curr_proc->tf->sp = sp; + curr_proc->tf->r0 = ustack[1]; + curr_proc->tf->r1 = ustack[2]; + switchuvm(curr_proc); + freevm(oldpgdir); + return 0; + + bad: + if(pgdir) + freevm(pgdir); + if(ip) + iunlockput(ip); + return -1; +} diff -r 000000000000 -r c450faca55f4 source/file.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/file.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,162 @@ +// +// File descriptors +// + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "fs.h" +#include "file.h" +#include "spinlock.h" + +struct devsw devsw[NDEV]; +struct { + struct spinlock lock; + struct file file[NFILE]; +} ftable; + +void +fileinit(void) +{ + memset(&ftable, 0, sizeof(ftable)); + initlock(&ftable.lock, "ftable"); +} + +// Allocate a file structure. +struct file* +filealloc(void) +{ + struct file *f; + + acquire(&ftable.lock); + for(f = ftable.file; f < ftable.file + NFILE; f++){ + if(f->ref == 0){ + f->ref = 1; + release(&ftable.lock); + return f; + } + } + release(&ftable.lock); + return 0; +} + +// Increment ref count for file f. +struct file* +filedup(struct file *f) +{ + acquire(&ftable.lock); + if(f->ref < 1) + panic("filedup"); + f->ref++; + release(&ftable.lock); + return f; +} + +// Close file f. (Decrement ref count, close when reaches 0.) +void +fileclose(struct file *f) +{ + struct file ff; + + acquire(&ftable.lock); + if(f->ref < 1) + panic("fileclose"); + if(--f->ref > 0){ + release(&ftable.lock); + return; + } + ff = *f; + f->ref = 0; + f->type = FD_NONE; + release(&ftable.lock); + + if(ff.type == FD_PIPE) + pipeclose(ff.pipe, ff.writable); + else if(ff.type == FD_INODE){ + begin_trans(); + iput(ff.ip); + commit_trans(); + } +} + +// Get metadata about file f. +int +filestat(struct file *f, struct stat *st) +{ + if(f->type == FD_INODE){ + ilock(f->ip); + stati(f->ip, st); + iunlock(f->ip); + return 0; + } + return -1; +} + +// Read from file f. +int +fileread(struct file *f, char *addr, int n) +{ + int r; + + if(f->readable == 0) + return -1; + if(f->type == FD_PIPE) + return piperead(f->pipe, addr, n); + if(f->type == FD_INODE){ + ilock(f->ip); +//cprintf("inside fileread\n"); + if((r = readi(f->ip, addr, f->off, n)) > 0) + f->off += r; +//cprintf("inside fileread: after readi rv=%x\n", r); + iunlock(f->ip); + return r; + } + panic("fileread"); + return -1; +} + +//PAGEBREAK! +// Write to file f. +int +filewrite(struct file *f, char *addr, int n) +{ + int r; + + if(f->writable == 0) + return -1; +//cprintf("inside filewrite\n"); + if(f->type == FD_PIPE) + return pipewrite(f->pipe, addr, n); + if(f->type == FD_INODE){ + // write a few blocks at a time to avoid exceeding + // the maximum log transaction size, including + // i-node, indirect block, allocation blocks, + // and 2 blocks of slop for non-aligned writes. + // this really belongs lower down, since writei() + // might be writing a device like the console. + int max = ((LOGSIZE-1-1-2) / 2) * 512; + int i = 0; + while(i < n){ + int n1 = n - i; + if(n1 > max) + n1 = max; + + begin_trans(); + ilock(f->ip); + if ((r = writei(f->ip, addr + i, f->off, n1)) > 0) + f->off += r; + iunlock(f->ip); + commit_trans(); + + if(r < 0) + break; + if(r != n1) + panic("short filewrite"); + i += r; + } + return i == n ? n : -1; + } + panic("filewrite"); + return -1; +} + diff -r 000000000000 -r c450faca55f4 source/font.bin Binary file source/font.bin has changed diff -r 000000000000 -r c450faca55f4 source/font1.bin Binary file source/font1.bin has changed diff -r 000000000000 -r c450faca55f4 source/fs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/fs.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,656 @@ +// File system implementation. Five layers: +// + Blocks: allocator for raw disk blocks. +// + Log: crash recovery for multi-step updates. +// + Files: inode allocator, reading, writing, metadata. +// + Directories: inode with special contents (list of other inodes!) +// + Names: paths like /usr/rtm/xv6/fs.c for convenient naming. +// +// This file contains the low-level file system manipulation +// routines. The (higher-level) system call implementations +// are in sysfile.c. + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "stat.h" +#include "mmu.h" +#include "proc.h" +#include "spinlock.h" +#include "buf.h" +#include "fs.h" +#include "file.h" + +#define min(a, b) ((a) < (b) ? (a) : (b)) +static void itrunc(struct inode*); + +// Read the super block. +void +readsb(int dev, struct superblock *sb) +{ + struct buf *bp; + + bp = bread(dev, 1); + memmove(sb, bp->data, sizeof(*sb)); + brelse(bp); +} + +// Zero a block. +static void +bzero(int dev, int bno) +{ + struct buf *bp; + + bp = bread(dev, bno); + memset(bp->data, 0, BSIZE); + log_write(bp); + brelse(bp); +} + +// Blocks. + +// Allocate a zeroed disk block. +static uint +balloc(uint dev) +{ + int b, bi, m; + struct buf *bp; + struct superblock sb; + + bp = 0; + readsb(dev, &sb); + for(b = 0; b < sb.size; b += BPB){ + bp = bread(dev, BBLOCK(b, sb.ninodes)); + for(bi = 0; bi < BPB && b + bi < sb.size; bi++){ + m = 1 << (bi % 8); + if((bp->data[bi/8] & m) == 0){ // Is block free? + bp->data[bi/8] |= m; // Mark block in use. + log_write(bp); + brelse(bp); + bzero(dev, b + bi); + return b + bi; + } + } + brelse(bp); + } + panic("balloc: out of blocks"); + return -1; +} + +// Free a disk block. +static void +bfree(int dev, uint b) +{ + struct buf *bp; + struct superblock sb; + int bi, m; + + readsb(dev, &sb); + bp = bread(dev, BBLOCK(b, sb.ninodes)); + bi = b % BPB; + m = 1 << (bi % 8); + if((bp->data[bi/8] & m) == 0) + panic("freeing free block"); + bp->data[bi/8] &= ~m; + log_write(bp); + brelse(bp); +} + +// Inodes. +// +// An inode describes a single unnamed file. +// The inode disk structure holds metadata: the file's type, +// its size, the number of links referring to it, and the +// list of blocks holding the file's content. +// +// The inodes are laid out sequentially on disk immediately after +// the superblock. Each inode has a number, indicating its +// position on the disk. +// +// The kernel keeps a cache of in-use inodes in memory +// to provide a place for synchronizing access +// to inodes used by multiple processes. The cached +// inodes include book-keeping information that is +// not stored on disk: ip->ref and ip->flags. +// +// An inode and its in-memory represtative go through a +// sequence of states before they can be used by the +// rest of the file system code. +// +// * Allocation: an inode is allocated if its type (on disk) +// is non-zero. ialloc() allocates, iput() frees if +// the link count has fallen to zero. +// +// * Referencing in cache: an entry in the inode cache +// is free if ip->ref is zero. Otherwise ip->ref tracks +// the number of in-memory pointers to the entry (open +// files and current directories). iget() to find or +// create a cache entry and increment its ref, iput() +// to decrement ref. +// +// * Valid: the information (type, size, &c) in an inode +// cache entry is only correct when the I_VALID bit +// is set in ip->flags. ilock() reads the inode from +// the disk and sets I_VALID, while iput() clears +// I_VALID if ip->ref has fallen to zero. +// +// * Locked: file system code may only examine and modify +// the information in an inode and its content if it +// has first locked the inode. The I_BUSY flag indicates +// that the inode is locked. ilock() sets I_BUSY, +// while iunlock clears it. +// +// Thus a typical sequence is: +// ip = iget(dev, inum) +// ilock(ip) +// ... examine and modify ip->xxx ... +// iunlock(ip) +// iput(ip) +// +// ilock() is separate from iget() so that system calls can +// get a long-term reference to an inode (as for an open file) +// and only lock it for short periods (e.g., in read()). +// The separation also helps avoid deadlock and races during +// pathname lookup. iget() increments ip->ref so that the inode +// stays cached and pointers to it remain valid. +// +// Many internal file system functions expect the caller to +// have locked the inodes involved; this lets callers create +// multi-step atomic operations. + +struct { + struct spinlock lock; + struct inode inode[NINODE]; +} icache; + +void +iinit(void) +{ + memset(&icache, 0, sizeof(icache)); + initlock(&icache.lock, "icache"); +} + +static struct inode* iget(uint dev, uint inum); + +//PAGEBREAK! +// Allocate a new inode with the given type on device dev. +// A free inode has a type of zero. +struct inode* +ialloc(uint dev, short type) +{ + int inum; + struct buf *bp; + struct dinode *dip; + struct superblock sb; + + readsb(dev, &sb); + + for(inum = 1; inum < sb.ninodes; inum++){ + bp = bread(dev, IBLOCK(inum)); + dip = (struct dinode*)bp->data + inum%IPB; + if(dip->type == 0){ // a free inode + memset(dip, 0, sizeof(*dip)); + dip->type = type; + log_write(bp); // mark it allocated on the disk + brelse(bp); + return iget(dev, inum); + } + brelse(bp); + } + panic("ialloc: no inodes"); + return 0; +} + +// Copy a modified in-memory inode to disk. +void +iupdate(struct inode *ip) +{ + struct buf *bp; + struct dinode *dip; + + bp = bread(ip->dev, IBLOCK(ip->inum)); + dip = (struct dinode*)bp->data + ip->inum%IPB; + dip->type = ip->type; + dip->major = ip->major; + dip->minor = ip->minor; + dip->nlink = ip->nlink; + dip->size = ip->size; + memmove(dip->addrs, ip->addrs, sizeof(ip->addrs)); + log_write(bp); + brelse(bp); +} + +// Find the inode with number inum on device dev +// and return the in-memory copy. Does not lock +// the inode and does not read it from disk. +static struct inode* +iget(uint dev, uint inum) +{ + struct inode *ip, *empty; + + acquire(&icache.lock); + + // Is the inode already cached? + empty = 0; + for(ip = &icache.inode[0]; ip < &icache.inode[NINODE]; ip++){ + if(ip->ref > 0 && ip->dev == dev && ip->inum == inum){ + ip->ref++; + release(&icache.lock); + return ip; + } + if(empty == 0 && ip->ref == 0) // Remember empty slot. + empty = ip; + } + + // Recycle an inode cache entry. + if(empty == 0) + panic("iget: no inodes"); + + ip = empty; + ip->dev = dev; + ip->inum = inum; + ip->ref = 1; + ip->flags = 0; + release(&icache.lock); + + return ip; +} + +// Increment reference count for ip. +// Returns ip to enable ip = idup(ip1) idiom. +struct inode* +idup(struct inode *ip) +{ + acquire(&icache.lock); + ip->ref++; + release(&icache.lock); + return ip; +} + +// Lock the given inode. +// Reads the inode from disk if necessary. +void +ilock(struct inode *ip) +{ + struct buf *bp; + struct dinode *dip; + + if(ip == 0 || ip->ref < 1) + panic("ilock"); + + acquire(&icache.lock); + while(ip->flags & I_BUSY) + sleep(ip, &icache.lock); + ip->flags |= I_BUSY; + release(&icache.lock); + + if(!(ip->flags & I_VALID)){ + bp = bread(ip->dev, IBLOCK(ip->inum)); + dip = (struct dinode*)bp->data + ip->inum%IPB; + ip->type = dip->type; + ip->major = dip->major; + ip->minor = dip->minor; + ip->nlink = dip->nlink; + ip->size = dip->size; + memmove(ip->addrs, dip->addrs, sizeof(ip->addrs)); + brelse(bp); + ip->flags |= I_VALID; + if(ip->type == 0) + panic("ilock: no type"); + } +} + +// Unlock the given inode. +void +iunlock(struct inode *ip) +{ + if(ip == 0 || !(ip->flags & I_BUSY) || ip->ref < 1) + panic("iunlock"); + + acquire(&icache.lock); + ip->flags &= ~I_BUSY; + wakeup(ip); + release(&icache.lock); +} + +// Drop a reference to an in-memory inode. +// If that was the last reference, the inode cache entry can +// be recycled. +// If that was the last reference and the inode has no links +// to it, free the inode (and its content) on disk. +void +iput(struct inode *ip) +{ + acquire(&icache.lock); + if(ip->ref == 1 && (ip->flags & I_VALID) && ip->nlink == 0){ + // inode has no links: truncate and free inode. + if(ip->flags & I_BUSY) + panic("iput busy"); + ip->flags |= I_BUSY; + release(&icache.lock); + itrunc(ip); + ip->type = 0; + iupdate(ip); + acquire(&icache.lock); + ip->flags = 0; + wakeup(ip); + } + ip->ref--; + release(&icache.lock); +} + +// Common idiom: unlock, then put. +void +iunlockput(struct inode *ip) +{ + iunlock(ip); + iput(ip); +} + +//PAGEBREAK! +// Inode content +// +// The content (data) associated with each inode is stored +// in blocks on the disk. The first NDIRECT block numbers +// are listed in ip->addrs[]. The next NINDIRECT blocks are +// listed in block ip->addrs[NDIRECT]. + +// Return the disk block address of the nth block in inode ip. +// If there is no such block, bmap allocates one. +static uint +bmap(struct inode *ip, uint bn) +{ + uint addr, *a; + struct buf *bp; + + if(bn < NDIRECT){ + if((addr = ip->addrs[bn]) == 0) + ip->addrs[bn] = addr = balloc(ip->dev); + return addr; + } + bn -= NDIRECT; + + if(bn < NINDIRECT){ + // Load indirect block, allocating if necessary. + if((addr = ip->addrs[NDIRECT]) == 0) + ip->addrs[NDIRECT] = addr = balloc(ip->dev); + bp = bread(ip->dev, addr); + a = (uint*)bp->data; + if((addr = a[bn]) == 0){ + a[bn] = addr = balloc(ip->dev); + log_write(bp); + } + brelse(bp); + return addr; + } + + panic("bmap: out of range"); + return -1; +} + +// Truncate inode (discard contents). +// Only called when the inode has no links +// to it (no directory entries referring to it) +// and has no in-memory reference to it (is +// not an open file or current directory). +static void +itrunc(struct inode *ip) +{ + int i, j; + struct buf *bp; + uint *a; + + for(i = 0; i < NDIRECT; i++){ + if(ip->addrs[i]){ + bfree(ip->dev, ip->addrs[i]); + ip->addrs[i] = 0; + } + } + + if(ip->addrs[NDIRECT]){ + bp = bread(ip->dev, ip->addrs[NDIRECT]); + a = (uint*)bp->data; + for(j = 0; j < NINDIRECT; j++){ + if(a[j]) + bfree(ip->dev, a[j]); + } + brelse(bp); + bfree(ip->dev, ip->addrs[NDIRECT]); + ip->addrs[NDIRECT] = 0; + } + + ip->size = 0; + iupdate(ip); +} + +// Copy stat information from inode. +void +stati(struct inode *ip, struct stat *st) +{ + st->dev = ip->dev; + st->ino = ip->inum; + st->type = ip->type; + st->nlink = ip->nlink; + st->size = ip->size; +} + +//PAGEBREAK! +// Read data from inode. +int +readi(struct inode *ip, char *dst, uint off, uint n) +{ + uint tot, m; + struct buf *bp; + + if(ip->type == T_DEV){ + if(ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].read) + return -1; +//cprintf("inside readi\n"); + return devsw[ip->major].read(ip, dst, n); + } + + if(off > ip->size || off + n < off) + return -1; + if(off + n > ip->size) + n = ip->size - off; + + for(tot=0; totdev, bmap(ip, off/BSIZE)); + m = min(n - tot, BSIZE - off%BSIZE); + memmove(dst, bp->data + off%BSIZE, m); + brelse(bp); + } + return n; +} + +// PAGEBREAK! +// Write data to inode. +int +writei(struct inode *ip, char *src, uint off, uint n) +{ + uint tot, m; + struct buf *bp; +//cprintf("inside writei: type=%x major=%x, func addr: %x\n", ip->type, ip->major, devsw[ip->major].write); + if(ip->type == T_DEV){ + if(ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].write) + return -1; +//cprintf("before calling consolewrite: major=%x, func addr: %x\n", ip->major, devsw[ip->major].write); + return devsw[ip->major].write(ip, src, n); + } + + if(off > ip->size || off + n < off) + return -1; + if(off + n > MAXFILE*BSIZE) + return -1; + + for(tot=0; totdev, bmap(ip, off/BSIZE)); + m = min(n - tot, BSIZE - off%BSIZE); + memmove(bp->data + off%BSIZE, src, m); + log_write(bp); + brelse(bp); + } + + if(n > 0 && off > ip->size){ + ip->size = off; + iupdate(ip); + } + return n; +} + +//PAGEBREAK! +// Directories + +int +namecmp(const char *s, const char *t) +{ + return strncmp(s, t, DIRSIZ); +} + +// Look for a directory entry in a directory. +// If found, set *poff to byte offset of entry. +struct inode* +dirlookup(struct inode *dp, char *name, uint *poff) +{ + uint off, inum; + struct dirent de; + + if(dp->type != T_DIR) + panic("dirlookup not DIR"); + + for(off = 0; off < dp->size; off += sizeof(de)){ + if(readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) + panic("dirlink read"); + if(de.inum == 0) + continue; + if(namecmp(name, de.name) == 0){ + // entry matches path element + if(poff) + *poff = off; + inum = de.inum; + return iget(dp->dev, inum); + } + } + + return 0; +} + +// Write a new directory entry (name, inum) into the directory dp. +int +dirlink(struct inode *dp, char *name, uint inum) +{ + int off; + struct dirent de; + struct inode *ip; + + // Check that name is not present. + if((ip = dirlookup(dp, name, 0)) != 0){ + iput(ip); + return -1; + } + + // Look for an empty dirent. + for(off = 0; off < dp->size; off += sizeof(de)){ + if(readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) + panic("dirlink read"); + if(de.inum == 0) + break; + } + + strncpy(de.name, name, DIRSIZ); + de.inum = inum; + if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) + panic("dirlink"); + + return 0; +} + +//PAGEBREAK! +// Paths + +// Copy the next path element from path into name. +// Return a pointer to the element following the copied one. +// The returned path has no leading slashes, +// so the caller can check *path=='\0' to see if the name is the last one. +// If no name to remove, return 0. +// +// Examples: +// skipelem("a/bb/c", name) = "bb/c", setting name = "a" +// skipelem("///a//bb", name) = "bb", setting name = "a" +// skipelem("a", name) = "", setting name = "a" +// skipelem("", name) = skipelem("////", name) = 0 +// +static char* +skipelem(char *path, char *name) +{ + char *s; + int len; + + while(*path == '/') + path++; + if(*path == 0) + return 0; + s = path; + while(*path != '/' && *path != 0) + path++; + len = path - s; + if(len >= DIRSIZ) + memmove(name, s, DIRSIZ); + else { + memmove(name, s, len); + name[len] = 0; + } + while(*path == '/') + path++; + return path; +} + +// Look up and return the inode for a path name. +// If parent != 0, return the inode for the parent and copy the final +// path element into name, which must have room for DIRSIZ bytes. +static struct inode* +namex(char *path, int nameiparent, char *name) +{ + struct inode *ip, *next; + + if(*path == '/') + ip = iget(ROOTDEV, ROOTINO); + else + ip = idup(curr_proc->cwd); + + while((path = skipelem(path, name)) != 0){ + ilock(ip); + if(ip->type != T_DIR){ + iunlockput(ip); + return 0; + } + if(nameiparent && *path == '\0'){ + // Stop one level early. + iunlock(ip); + return ip; + } + if((next = dirlookup(ip, name, 0)) == 0){ + iunlockput(ip); + return 0; + } + iunlockput(ip); + ip = next; + } + if(nameiparent){ + iput(ip); + return 0; + } + return ip; +} + +struct inode* +namei(char *path) +{ + char name[DIRSIZ]; + return namex(path, 0, name); +} + +struct inode* +nameiparent(char *path, char *name) +{ + return namex(path, 1, name); +} diff -r 000000000000 -r c450faca55f4 source/fs.img Binary file source/fs.img has changed diff -r 000000000000 -r c450faca55f4 source/initcode Binary file source/initcode has changed diff -r 000000000000 -r c450faca55f4 source/kalloc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/kalloc.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,94 @@ +#include "types.h" +#include "defs.h" +#include "param.h" +#include "memlayout.h" +#include "mmu.h" +#include "spinlock.h" + +void freerange(void *vstart, void *vend); +extern char end[]; // first address after kernel loaded from ELF file + +struct run { + struct run *next; +}; + +struct { + struct spinlock lock; + int use_lock; + struct run *freelist; +} kmem; + +// Initialization happens in two phases. +// 1. main() calls kinit1() while still using entrypgdir to place just +// the pages mapped by entrypgdir on free list. +// 2. main() calls kinit2() with the rest of the physical pages +// after installing a full page table that maps them on all cores. +void +kinit1(void *vstart, void *vend) +{ + initlock(&kmem.lock, "kmem"); + kmem.use_lock = 0; + kmem.freelist = 0; + freerange(vstart, vend); +} + +void +kinit2(void *vstart, void *vend) +{ + freerange(vstart, vend); + kmem.use_lock = 1; +} + +void +freerange(void *vstart, void *vend) +{ + char *p; + p = (char*)PGROUNDUP((uint)vstart); + for(; p + PGSIZE <= (char*)vend; p += PGSIZE) + kfree(p); +} + +//PAGEBREAK: 21 +// Free the page of physical memory pointed at by v, +// which normally should have been returned by a +// call to kalloc(). (The exception is when +// initializing the allocator; see kinit above.) +void +kfree(char *v) +{ + struct run *r; + + if((uint)v % PGSIZE || v < end || v2p(v) >= PHYSTOP) + panic("kfree"); + + // Fill with junk to catch dangling refs. + memset(v, 1, PGSIZE); + + if(kmem.use_lock) + acquire(&kmem.lock); + r = (struct run*)v; + r->next = kmem.freelist; + kmem.freelist = r; + if(kmem.use_lock) + release(&kmem.lock); +} + +// Allocate one 4096-byte page of physical memory. +// Returns a pointer that the kernel can use. +// Returns 0 if the memory cannot be allocated. +char* +kalloc(void) +{ + struct run *r; + + if(kmem.use_lock) + acquire(&kmem.lock); + r = kmem.freelist; + if(r) + kmem.freelist = r->next; + if(kmem.use_lock) + release(&kmem.lock); + return (char*)r; +} + + diff -r 000000000000 -r c450faca55f4 source/keyboard.s --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/keyboard.s Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,210 @@ +/****************************************************************************** +* keyboard.s +* by Alex Chadwick +* +* A sample assembly code implementation of the input01 operating system. +* See main.s for details. +* +* keyboard.s contains code to do with the keyboard. +******************************************************************************/ + +.section .data +/* NEW +* The address of the keyboard we're reading from. +* C++ Signautre: u32 KeyboardAddress; +*/ +.align 2 +KeyboardAddress: + .int 0 + +/* NEW +* The scan codes that were down before the current set on the keyboard. +* C++ Signautre: u16* KeyboardOldDown; +*/ +KeyboardOldDown: + .rept 6 + .hword 0 + .endr + +/* NEW +* KeysNoShift contains the ascii representations of the first 104 scan codes +* when the shift key is up. Special keys are ignored. +* C++ Signature: char* KeysNoShift; +*/ +.align 3 +KeysNormal: + .byte 0x0, 0x0, 0x0, 0x0, 'a', 'b', 'c', 'd' + .byte 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l' + .byte 'm', 'n', 'o', 'p', 'q', 'r', 's', 't' + .byte 'u', 'v', 'w', 'x', 'y', 'z', '1', '2' + .byte '3', '4', '5', '6', '7', '8', '9', '0' + .byte '\n', 0x0, '\b', '\t', ' ', '-', '=', '[' + .byte ']', '\\', '#', ';', '\'', '`', ',', '.' + .byte '/', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 + .byte 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 + .byte 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 + .byte 0x0, 0x0, 0x0, 0x0, '/', '*', '-', '+' + .byte '\n', '1', '2', '3', '4', '5', '6', '7' + .byte '8', '9', '0', '.', '\\', 0x0, 0x0, '=' + +/* NEW +* KeysShift contains the ascii representations of the first 104 scan codes +* when the shift key is held. Special keys are ignored. +* C++ Signature: char* KeysShift; +*/ +.align 3 +KeysShift: + .byte 0x0, 0x0, 0x0, 0x0, 'A', 'B', 'C', 'D' + .byte 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L' + .byte 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T' + .byte 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '"' + .byte '£', '$', '%', '^', '&', '*', '(', ')' + .byte '\n', 0x0, '\b', '\t', ' ', '_', '+', '{' + .byte '}', '|', '~', ':', '@', '¬', '<', '>' + .byte '?', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 + .byte 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 + .byte 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 + .byte 0x0, 0x0, 0x0, 0x0, '/', '*', '-', '+' + .byte '\n', '1', '2', '3', '4', '5', '6', '7' + .byte '8', '9', '0', '.', '|', 0x0, 0x0, '=' + +.section .text +/* NEW +* Updates the keyboard pressed and released data. +* C++ Signature: void KeyboardUpdate(); +*/ +.globl KeyboardUpdate +KeyboardUpdate: + push {r4,r5,lr} + + kbd .req r4 + ldr r0,=KeyboardAddress + ldr kbd,[r0] + + teq kbd,#0 + bne haveKeyboard$ + +getKeyboard$: + bl UsbCheckForChange + bl KeyboardCount + teq r0,#0 + ldreq r1,=KeyboardAddress + streq r0,[r1] + beq return$ + + mov r0,#0 + bl KeyboardGetAddress + ldr r1,=KeyboardAddress + str r0,[r1] + teq r0,#0 + beq return$ + mov kbd,r0 + +haveKeyboard$: + mov r5,#0 + + saveKeys$: + mov r0,kbd + mov r1,r5 + bl KeyboardGetKeyDown + + ldr r1,=KeyboardOldDown + add r1,r5,lsl #1 + strh r0,[r1] + add r5,#1 + cmp r5,#6 + blt saveKeys$ + + mov r0,kbd + bl KeyboardPoll + teq r0,#0 + bne getKeyboard$ + +return$: + pop {r4,r5,pc} + .unreq kbd + +/* NEW +* Returns r0=0 if a in r1 key was not pressed before the current scan, and r0 +* not 0 otherwise. +* C++ Signature bool KeyWasDown(u16 scanCode) +*/ +.globl KeyWasDown +KeyWasDown: + ldr r1,=KeyboardOldDown + mov r2,#0 + + keySearch$: + ldrh r3,[r1] + teq r3,r0 + moveq r0,#1 + moveq pc,lr + + add r1,#2 + add r2,#1 + cmp r2,#6 + blt keySearch$ + + mov r0,#0 + mov pc,lr + +/* NEW +* Returns the ascii character last typed on the keyboard, with r0=0 if no +* character was typed. +* C++ Signature char KeyboardGetChar() +*/ +.globl KeyboardGetChar +KeyboardGetChar: + ldr r0,=KeyboardAddress + ldr r1,[r0] + teq r1,#0 + moveq r0,#0 + moveq pc,lr + + push {r4,r5,r6,lr} + + kbd .req r4 + key .req r6 + + mov r4,r1 + mov r5,#0 + + keyLoop$: + mov r0,kbd + mov r1,r5 + bl KeyboardGetKeyDown + + teq r0,#0 + beq keyLoopBreak$ + + mov key,r0 + bl KeyWasDown + teq r0,#0 + bne keyLoopContinue$ + + cmp key,#104 + bge keyLoopContinue$ + + mov r0,kbd + bl KeyboardGetModifiers + + tst r0,#0b00100010 + ldreq r0,=KeysNormal + ldrne r0,=KeysShift + + ldrb r0,[r0,key] + teq r0,#0 + bne keyboardGetCharReturn$ + + keyLoopContinue$: + add r5,#1 + cmp r5,#6 + blt keyLoop$ + + keyLoopBreak$: + mov r0,#0 +keyboardGetCharReturn$: + pop {r4,r5,r6,pc} + .unreq kbd + .unreq key + \ No newline at end of file diff -r 000000000000 -r c450faca55f4 source/log.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/log.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,186 @@ +#include "types.h" +#include "defs.h" +#include "param.h" +#include "spinlock.h" +#include "fs.h" +#include "buf.h" + +// Simple logging. Each system call that might write the file system +// should be surrounded with begin_trans() and commit_trans() calls. +// +// The log holds at most one transaction at a time. Commit forces +// the log (with commit record) to disk, then installs the affected +// blocks to disk, then erases the log. begin_trans() ensures that +// only one system call can be in a transaction; others must wait. +// +// Allowing only one transaction at a time means that the file +// system code doesn't have to worry about the possibility of +// one transaction reading a block that another one has modified, +// for example an i-node block. +// +// Read-only system calls don't need to use transactions, though +// this means that they may observe uncommitted data. I-node and +// buffer locks prevent read-only calls from seeing inconsistent data. +// +// The log is a physical re-do log containing disk blocks. +// The on-disk log format: +// header block, containing sector #s for block A, B, C, ... +// block A +// block B +// block C +// ... +// Log appends are synchronous. + +// Contents of the header block, used for both the on-disk header block +// and to keep track in memory of logged sector #s before commit. +struct logheader { + int n; + int sector[LOGSIZE]; +}; + +struct log { + struct spinlock lock; + int start; + int size; + int busy; // a transaction is active + int dev; + struct logheader lh; +}; +struct log log; + +static void recover_from_log(void); + +void +initlog(void) +{ + if (sizeof(struct logheader) >= BSIZE) + panic("initlog: too big logheader"); + + struct superblock sb; + memset(&log, 0, sizeof(log)); + initlock(&log.lock, "log"); + readsb(ROOTDEV, &sb); + log.start = sb.size - sb.nlog; + log.size = sb.nlog; + log.dev = ROOTDEV; + recover_from_log(); +} + +// Copy committed blocks from log to their home location +static void +install_trans(void) +{ + int tail; + + for (tail = 0; tail < log.lh.n; tail++) { + struct buf *lbuf = bread(log.dev, log.start+tail+1); // read log block + struct buf *dbuf = bread(log.dev, log.lh.sector[tail]); // read dst + memmove(dbuf->data, lbuf->data, BSIZE); // copy block to dst + bwrite(dbuf); // write dst to disk + brelse(lbuf); + brelse(dbuf); + } +} + +// Read the log header from disk into the in-memory log header +static void +read_head(void) +{ + struct buf *buf = bread(log.dev, log.start); + struct logheader *lh = (struct logheader *) (buf->data); + int i; + log.lh.n = lh->n; + for (i = 0; i < log.lh.n; i++) { + log.lh.sector[i] = lh->sector[i]; + } + brelse(buf); +} + +// Write in-memory log header to disk. +// This is the true point at which the +// current transaction commits. +static void +write_head(void) +{ + struct buf *buf = bread(log.dev, log.start); + struct logheader *hb = (struct logheader *) (buf->data); + int i; + hb->n = log.lh.n; + for (i = 0; i < log.lh.n; i++) { + hb->sector[i] = log.lh.sector[i]; + } + bwrite(buf); + brelse(buf); +} + +static void +recover_from_log(void) +{ + read_head(); + install_trans(); // if committed, copy from log to disk + log.lh.n = 0; + write_head(); // clear the log +} + +void +begin_trans(void) +{ + acquire(&log.lock); + while (log.busy) { + sleep(&log, &log.lock); + } + log.busy = 1; + release(&log.lock); +} + +void +commit_trans(void) +{ + if (log.lh.n > 0) { + write_head(); // Write header to disk -- the real commit + install_trans(); // Now install writes to home locations + log.lh.n = 0; + write_head(); // Erase the transaction from the log + } + + acquire(&log.lock); + log.busy = 0; + wakeup(&log); + release(&log.lock); +} + +// Caller has modified b->data and is done with the buffer. +// Append the block to the log and record the block number, +// but don't write the log header (which would commit the write). +// log_write() replaces bwrite(); a typical use is: +// bp = bread(...) +// modify bp->data[] +// log_write(bp) +// brelse(bp) +void +log_write(struct buf *b) +{ + int i; + + if (log.lh.n >= LOGSIZE || log.lh.n >= log.size - 1) + panic("too big a transaction"); + if (!log.busy) + panic("write outside of trans"); + + for (i = 0; i < log.lh.n; i++) { + if (log.lh.sector[i] == b->sector) // log absorbtion? + break; + } + log.lh.sector[i] = b->sector; + struct buf *lbuf = bread(b->dev, log.start+i+1); + memmove(lbuf->data, b->data, BSIZE); + bwrite(lbuf); + brelse(lbuf); + if (i == log.lh.n) + log.lh.n++; + b->flags |= B_DIRTY; // XXX prevent eviction +} + +//PAGEBREAK! +// Blank page. + diff -r 000000000000 -r c450faca55f4 source/mailbox.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/mailbox.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,94 @@ +/***************************************************************** +* mailbox.c +* by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "traps.h" +#include "spinlock.h" +#include "fs.h" +#include "file.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" +#include "arm.h" +#include "mailbox.h" + +/* Note: for more tags refer to +https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface */ +/* Note for Matthew: support more than one tag in buffer */ + + +void +create_request(volatile uint *mbuf, uint tag, uint buflen, uint len, uint *data) +{ + int i; + volatile uint *tag_info; + uint nw, tag_len, total_len; + + tag_info = mbuf + POS_TAG; + + tag_info[POS_TAG_ID] = tag; + tag_info[POS_TAG_BUFLEN] = buflen; + tag_info[POS_TAG_DATALEN] = len & 0x7FFFFFFF; + + nw = buflen >> 2; + + if (!data) + for (i = 0; i < nw; ++i) tag_info[POS_TAG_DATA + i] = 0; + else + for (i = 0; i < nw; ++i) tag_info[POS_TAG_DATA + i] = data[i]; + + tag_info[POS_TAG_DATA+nw] = 0; // indicate end of tag + + tag_len = mbuf[MB_HEADER_LENGTH + POS_TAG_BUFLEN]; + total_len = (MB_HEADER_LENGTH*4) + (TAG_HEADER_LENGTH*4) + tag_len + 4; + + mbuf[POS_OVERALL_LENGTH] = total_len; + mbuf[POS_RV] = MPI_REQUEST; + +} + +volatile uint *mailbuffer; + +void mailboxinit() +{ +mailbuffer = (uint *)kalloc(); +} + +uint +readmailbox(u8 channel) +{ + uint x, y, z; + +again: + while ((inw(MAILBOX_BASE+24) & 0x40000000) != 0); + x = inw(MAILBOX_BASE); + z = x & 0xf; y = (uint)(channel & 0xf); + if(z != y) goto again; + + return x&0xfffffff0; +} + +void +writemailbox(uint *addr, u8 channel) +{ + uint x, y, a; + + a = (uint)addr; + a -= KERNBASE; /* convert to ARM physical address */ + a += 0x40000000; /* convert to VC address space */ + x = a & 0xfffffff0; + y = x | (uint)(channel & 0xf); + + flush_dcache_all(); + + while ((inw(MAILBOX_BASE+24) & 0x80000000) != 0); + outw(MAILBOX_BASE+32, y); +} diff -r 000000000000 -r c450faca55f4 source/main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/main.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,95 @@ +/***************************************************************** +* main.c +* by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" +#include "arm.h" +#include "mailbox.h" + +extern char end[]; // first address after kernel loaded from ELF file +extern pde_t *kpgdir; +extern FBI fbinfo; +extern volatile uint *mailbuffer; + +void OkLoop() +{ + setgpiofunc(16, 1); // gpio 16, set as an output + while(1){ + setgpioval(16, 0); + delay(1000000); + setgpioval(16, 1); + delay(1000000); + } +} + +void NotOkLoop() +{ + setgpiofunc(16, 1); // gpio 16, set as an output + while(1){ + setgpioval(16, 0); + delay(100000); + setgpioval(16, 1); + delay(100000); + } +} + +void machinit(void) +{ + memset(cpus, 0, sizeof(struct cpu)*NCPU); +} + + +void enableirqminiuart(void); + +int cmain() +{ + + mmuinit1(); + machinit(); + uartinit(); + dsb_barrier(); + consoleinit(); + cprintf("\nHello World from xv6\n"); + kinit1(end, P2V(8*1024*1024)); // reserve 8 pages for PGDIR + kpgdir=p2v(K_PDX_BASE); + + mailboxinit(); + create_request(mailbuffer, MPI_TAG_GET_ARM_MEMORY, 8, 0, 0); + writemailbox((uint *)mailbuffer, 8); + readmailbox(8); + if(mailbuffer[1] != 0x80000000) cprintf("new error readmailbox\n"); + else +cprintf("ARM memory is %x %x\n", mailbuffer[MB_HEADER_LENGTH + TAG_HEADER_LENGTH], mailbuffer[MB_HEADER_LENGTH + TAG_HEADER_LENGTH+1]); + + pinit(); + tvinit(); + cprintf("it is ok after tvinit\n"); + binit(); +cprintf("it is ok after binit\n"); + fileinit(); +cprintf("it is ok after fileinit\n"); + iinit(); +cprintf("it is ok after iinit\n"); + ideinit(); +cprintf("it is ok after ideinit\n"); + timer3init(); + kinit2(P2V(8*1024*1024), P2V(PHYSTOP)); +cprintf("it is ok after kinit2\n"); + userinit(); +cprintf("it is ok after userinit\n"); + scheduler(); + + + NotOkLoop(); + + return 0; +} diff -r 000000000000 -r c450faca55f4 source/memide.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/memide.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,58 @@ +// Fake IDE disk; stores blocks in memory. +// Useful for running kernel without scratch disk. + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "mmu.h" +#include "proc.h" +#include "arm.h" +#include "traps.h" +#include "spinlock.h" +#include "buf.h" + +extern uchar _binary_fs_img_start[], _binary_fs_img_end[]; + +static int disksize; +static uchar *memdisk; + +void +ideinit(void) +{ + memdisk = _binary_fs_img_start; + disksize = div(((uint)_binary_fs_img_end - (uint)_binary_fs_img_start), 512); +} + +// Interrupt handler. +void +ideintr(void) +{ + // no-op +} + +// Sync buf with disk. +// If B_DIRTY is set, write buf to disk, clear B_DIRTY, set B_VALID. +// Else if B_VALID is not set, read buf from disk, set B_VALID. +void +iderw(struct buf *b) +{ + uchar *p; + + if(!(b->flags & B_BUSY)) + panic("iderw: buf not busy"); + if((b->flags & (B_VALID|B_DIRTY)) == B_VALID) + panic("iderw: nothing to do"); + if(b->dev != 1) + panic("iderw: request not for disk 1"); + if(b->sector >= disksize) + panic("iderw: sector out of range"); + + p = memdisk + b->sector*512; + + if(b->flags & B_DIRTY){ + b->flags &= ~B_DIRTY; + memmove(p, b->data, 512); + } else + memmove(b->data, p, 512); + b->flags |= B_VALID; +} diff -r 000000000000 -r c450faca55f4 source/mmu.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/mmu.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,109 @@ +/***************************************************************** +* mmu.c +* by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + +#include "types.h" +#include "defs.h" +#include "memlayout.h" +#include "mmu.h" + +void mmuinit0(void) +{ + pde_t *l1; + pte_t *l2; + uint pa, va, *p; + + // diable mmu + // use inline assembly here as there is a limit on + // branch distance after mmu is disabled + asm volatile("mrc p15, 0, r1, c1, c0, 0\n\t" + "bic r1,r1,#0x00000004\n\t" + "bic r1,r1,#0x00001000\n\t" + "bic r1,r1,#0x00000800\n\t" + "bic r1,r1,#0x00000001\n\t" + "mcr p15, 0, r1, c1, c0, 0\n\t" + "mov r0, #0\n\t" + "mcr p15, 0, r0, c7, c7, 0\n\t" + "mcr p15, 0, r0, c8, c7, 0\n\t" + ::: "r0", "r1", "cc", "memory"); + + + for(p=(uint *)0x2000; p<(uint *)0x8000; p++) *p = 0; + + l1 = (pde_t *) K_PDX_BASE; + l2 = (pte_t *) K_PTX_BASE; + + // map all of ram at KERNBASE + va = KERNBASE; + for(pa = PA_START; pa < PA_START+RAMSIZE; pa += MBYTE){ + l1[PDX(va)] = pa|DOMAIN0|PDX_AP(K_RW)|SECTION|CACHED|BUFFERED; + va += MBYTE; + } + + // identity map first MB of ram so mmu can be enabled + l1[PDX(PA_START)] = PA_START|DOMAIN0|PDX_AP(K_RW)|SECTION|CACHED|BUFFERED; + + // map IO region + va = DEVSPACE; + for(pa = PHYSIO; pa < PHYSIO+IOSIZE; pa += MBYTE){ + l1[PDX(va)] = pa|DOMAIN0|PDX_AP(K_RW)|SECTION; + va += MBYTE; + } + + // map GPU memory + va = GPUMEMBASE; + for(pa = GPUMEMBASE; pa < (uint)GPUMEMBASE+(uint)GPUMEMSIZE; pa += MBYTE){ + l1[PDX(va)] = pa|DOMAIN0|PDX_AP(K_RW)|SECTION; + va += MBYTE; + } + + // double map exception vectors at top of virtual memory + va = HVECTORS; + l1[PDX(va)] = (uint)l2|DOMAIN0|COARSE; + l2[PTX(va)] = PA_START|PTX_AP(K_RW)|SMALL; + + + asm volatile("mov r1, #1\n\t" + "mcr p15, 0, r1, c3, c0\n\t" + "mov r1, #0x4000\n\t" + "mcr p15, 0, r1, c2, c0\n\t" + "mrc p15, 0, r0, c1, c0, 0\n\t" + "mov r1, #0x00002000\n\t" + "orr r1, #0x00000004\n\t" + "orr r1, #0x00001000\n\t" + "orr r1, #0x00000001\n\t" + "orr r0, r1\n\t" + "mcr p15, 0, r0, c1, c0, 0\n\t" + "mov r1, #1\n\t" + "mcr p15, 0, r1, c15, c12, 0\n\t" + ::: "r0", "r1", "cc", "memory"); + +} + +void +mmuinit1(void) +{ + pde_t *l1; + uint va1, va2; + + l1 = (pde_t*)(K_PDX_BASE); + + // undo identity map of first MB of ram + l1[PDX(PA_START)] = 0; + + // drain write buffer; writeback data cache range [va, va+n] + va1 = (uint)&l1[PDX(PA_START)]; + va2 = va1 + sizeof(pde_t); + va1 = va1 & ~((uint)CACHELINESIZE-1); + va2 = va2 & ~((uint)CACHELINESIZE-1); + flush_dcache(va1, va2); + + // invalidate TLB; DSB barrier used + flush_tlb(); + +} + diff -r 000000000000 -r c450faca55f4 source/pipe.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/pipe.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,121 @@ +#include "types.h" +#include "defs.h" +#include "param.h" +#include "mmu.h" +#include "proc.h" +#include "fs.h" +#include "file.h" +#include "spinlock.h" + +#define PIPESIZE 512 + +struct pipe { + struct spinlock lock; + char data[PIPESIZE]; + uint nread; // number of bytes read + uint nwrite; // number of bytes written + int readopen; // read fd is still open + int writeopen; // write fd is still open +}; + +int +pipealloc(struct file **f0, struct file **f1) +{ + struct pipe *p; + + p = 0; + *f0 = *f1 = 0; + if((*f0 = filealloc()) == 0 || (*f1 = filealloc()) == 0) + goto bad; + if((p = (struct pipe*)kalloc()) == 0) + goto bad; + memset(p, 0, PGSIZE); + p->readopen = 1; + p->writeopen = 1; + p->nwrite = 0; + p->nread = 0; + initlock(&p->lock, "pipe"); + (*f0)->type = FD_PIPE; + (*f0)->readable = 1; + (*f0)->writable = 0; + (*f0)->pipe = p; + (*f1)->type = FD_PIPE; + (*f1)->readable = 0; + (*f1)->writable = 1; + (*f1)->pipe = p; + return 0; + +//PAGEBREAK: 20 + bad: + if(p) + kfree((char*)p); + if(*f0) + fileclose(*f0); + if(*f1) + fileclose(*f1); + return -1; +} + +void +pipeclose(struct pipe *p, int writable) +{ + acquire(&p->lock); + if(writable){ + p->writeopen = 0; + wakeup(&p->nread); + } else { + p->readopen = 0; + wakeup(&p->nwrite); + } + if(p->readopen == 0 && p->writeopen == 0){ + release(&p->lock); + kfree((char*)p); + } else + release(&p->lock); +} + +//PAGEBREAK: 40 +int +pipewrite(struct pipe *p, char *addr, int n) +{ + int i; + + acquire(&p->lock); + for(i = 0; i < n; i++){ + while(p->nwrite == p->nread + PIPESIZE){ //DOC: pipewrite-full + if(p->readopen == 0 || curr_proc->killed){ + release(&p->lock); + return -1; + } + wakeup(&p->nread); + sleep(&p->nwrite, &p->lock); //DOC: pipewrite-sleep + } + p->data[p->nwrite++ % PIPESIZE] = addr[i]; + } + wakeup(&p->nread); //DOC: pipewrite-wakeup1 + release(&p->lock); + return n; +} + +int +piperead(struct pipe *p, char *addr, int n) +{ + int i; + + acquire(&p->lock); + while(p->nread == p->nwrite && p->writeopen){ //DOC: pipe-empty + if(curr_proc->killed){ + release(&p->lock); + return -1; + } + sleep(&p->nread, &p->lock); //DOC: piperead-sleep + } + for(i = 0; i < n; i++){ //DOC: piperead-copy + if(p->nread == p->nwrite) + break; + addr[i] = p->data[p->nread++ % PIPESIZE]; + } + wakeup(&p->nwrite); //DOC: piperead-wakeup + release(&p->lock); + return i; +} diff -r 000000000000 -r c450faca55f4 source/proc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/proc.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,453 @@ +/***************************************************************** +* proc.c +* adapted from MIT xv6 by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "memlayout.h" +#include "mmu.h" +#include "arm.h" +#include "proc.h" +#include "spinlock.h" + +struct { + struct spinlock lock; + struct proc proc[NPROC]; +} ptable; + +static struct proc *initproc; + +int first_sched = 1; +int nextpid = 1; +extern void forkret(void); +extern void trapret(void); + +static void wakeup1(void *chan); + +void +pinit(void) +{ + memset(&ptable, 0, sizeof(ptable)); + initlock(&ptable.lock, "ptable"); + +} + +//PAGEBREAK: 32 +// Look in the process table for an UNUSED proc. +// If found, change state to EMBRYO and initialize +// state required to run in the kernel. +// Otherwise return 0. +static struct proc* +allocproc(void) +{ + struct proc *p; + char *sp; + + acquire(&ptable.lock); + for(p = ptable.proc; p < &ptable.proc[NPROC]; p++) + if(p->state == UNUSED) + goto found; + release(&ptable.lock); + return 0; + +found: + p->state = EMBRYO; + p->pid = nextpid++; + release(&ptable.lock); + + // Allocate kernel stack. + if((p->kstack = kalloc()) == 0){ + p->state = UNUSED; + return 0; + } + memset(p->kstack, 0, PGSIZE); + sp = p->kstack + KSTACKSIZE; + + // Leave room for trap frame. + sp -= sizeof *p->tf; + p->tf = (struct trapframe*)sp; + + // Set up new context to start executing at forkret, + // which returns to trapret. + + sp -= sizeof *p->context; + p->context = (struct context*)sp; + memset(p->context, 0, sizeof *p->context); + p->context->pc = (uint)forkret; + p->context->lr = (uint)trapret; + + return p; +} + +//PAGEBREAK: 32 +// Set up first user process. +void +userinit(void) +{ + struct proc *p; + extern char _binary_initcode_start[], _binary_initcode_end[]; + uint _binary_initcode_size; + + _binary_initcode_size = (uint)_binary_initcode_end - (uint)_binary_initcode_start; + p = allocproc(); +//cprintf("after allocproc: initcode start: %x end %x\n", _binary_initcode_start, _binary_initcode_end); + initproc = p; +//cprintf("initproc is %x\n", initproc); + if((p->pgdir = setupkvm()) == 0) + panic("userinit: out of memory?"); +//cprintf("after setupkvm\n"); + inituvm(p->pgdir, _binary_initcode_start, _binary_initcode_size); +//cprintf("after initkvm\n"); + p->sz = PGSIZE; + memset(p->tf, 0, sizeof(*p->tf)); + p->tf->spsr = 0x10; + p->tf->sp = PGSIZE; + p->tf->pc = 0; // beginning of initcode.S + + safestrcpy(p->name, "initcode", sizeof(p->name)); + p->cwd = namei("/"); + + p->state = RUNNABLE; +} + +// Grow current process's memory by n bytes. +// Return 0 on success, -1 on failure. +int +growproc(int n) +{ + uint sz; + + sz = curr_proc->sz; + if(n > 0){ + if((sz = allocuvm(curr_proc->pgdir, sz, sz + n)) == 0) + return -1; + } else if(n < 0){ + if((sz = deallocuvm(curr_proc->pgdir, sz, sz + n)) == 0) + return -1; + } + curr_proc->sz = sz; + switchuvm(curr_proc); + return 0; +} + +// Create a new process copying p as the parent. +// Sets up stack to return as if from system call. +// Caller must set state of returned proc to RUNNABLE. +int +fork(void) +{ + int i, pid; + struct proc *np; + + // Allocate process. + if((np = allocproc()) == 0) + return -1; + + // Copy process state from p. + if((np->pgdir = copyuvm(curr_proc->pgdir, curr_proc->sz)) == 0){ + kfree(np->kstack); + np->kstack = 0; + np->state = UNUSED; + return -1; + } + np->sz = curr_proc->sz; + np->parent = curr_proc; + *np->tf = *curr_proc->tf; + + // Clear r0 so that fork returns 0 in the child. + np->tf->r0 = 0; + + for(i = 0; i < NOFILE; i++) + if(curr_proc->ofile[i]) + np->ofile[i] = filedup(curr_proc->ofile[i]); + np->cwd = idup(curr_proc->cwd); + + pid = np->pid; + np->state = RUNNABLE; + safestrcpy(np->name, curr_proc->name, sizeof(curr_proc->name)); + return pid; +} + +// Exit the current process. Does not return. +// An exited process remains in the zombie state +// until its parent calls wait() to find out it exited. +void +exit(void) +{ + struct proc *p; + int fd; + + if(curr_proc == initproc) + panic("init exiting"); + + // Close all open files. + for(fd = 0; fd < NOFILE; fd++){ + if(curr_proc->ofile[fd]){ + fileclose(curr_proc->ofile[fd]); + curr_proc->ofile[fd] = 0; + } + } + + iput(curr_proc->cwd); + curr_proc->cwd = 0; + + acquire(&ptable.lock); + + // Parent might be sleeping in wait(). + wakeup1(curr_proc->parent); + + // Pass abandoned children to init. + for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ + if(p->parent == curr_proc){ + p->parent = initproc; + if(p->state == ZOMBIE) + wakeup1(initproc); + } + } + + // Jump into the scheduler, never to return. + curr_proc->state = ZOMBIE; + sched(); + panic("zombie exit"); +} + +// Wait for a child process to exit and return its pid. +// Return -1 if this process has no children. +int +wait(void) +{ + struct proc *p; + int havekids, pid; + + acquire(&ptable.lock); + for(;;){ + // Scan through table looking for zombie children. + havekids = 0; + for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ + if(p->parent != curr_proc) + continue; + havekids = 1; + if(p->state == ZOMBIE){ + // Found one. + pid = p->pid; + kfree(p->kstack); + p->kstack = 0; + freevm(p->pgdir); + p->state = UNUSED; + p->pid = 0; + p->parent = 0; + p->name[0] = 0; + p->killed = 0; + release(&ptable.lock); + return pid; + } + } + + // No point waiting if we don't have any children. + if(!havekids || curr_proc->killed){ + release(&ptable.lock); + return -1; + } +//cprintf("inside wait before calling sleep\n"); + // Wait for children to exit. (See wakeup1 call in proc_exit.) + sleep(curr_proc, &ptable.lock); //DOC: wait-sleep + } +} + +//PAGEBREAK: 42 +// Per-CPU process scheduler. +// Each CPU calls scheduler() after setting itself up. +// Scheduler never returns. It loops, doing: +// - choose a process to run +// - swtch to start running that process +// - eventually that process transfers control +// via swtch back to the scheduler. +void +scheduler(void) +{ + struct proc *p; + + for(;;){ + // Enable interrupts on this processor. + //cprintf("before enabling interrupts\n"); + if(first_sched) first_sched = 0; + else sti(); + + // Loop over process table looking for process to run. + acquire(&ptable.lock); + for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ + if(p->state != RUNNABLE) + continue; + + // Switch to chosen process. It is the process's job + // to release ptable.lock and then reacquire it + // before jumping back to us. + curr_proc = p; +//cprintf("before switching page table\n"); + switchuvm(p); + p->state = RUNNING; +//cprintf("after switching page table\n"); + + swtch(&curr_cpu->scheduler, curr_proc->context); + + switchkvm(); + + // Process is done running for now. + // It should have changed its p->state before coming back. + curr_proc = 0; + } + release(&ptable.lock); + + } +} + +// Enter scheduler. Must hold only ptable.lock +// and have changed proc->state. +void +sched(void) +{ + int intena; + + if(!holding(&ptable.lock)) + panic("sched ptable.lock"); + if(curr_cpu->ncli != 1) + panic("sched locks"); + if(curr_proc->state == RUNNING) + panic("sched running"); + if(!(readcpsr()&PSR_DISABLE_IRQ)) + panic("sched interruptible"); + intena = curr_cpu->intena; + swtch(&curr_proc->context, curr_cpu->scheduler); + curr_cpu->intena = intena; +} + +// Give up the CPU for one scheduling round. +void +yield(void) +{ + acquire(&ptable.lock); //DOC: yieldlock + curr_proc->state = RUNNABLE; + sched(); + release(&ptable.lock); +} + +// A fork child's very first scheduling by scheduler() +// will swtch here. "Return" to user space. +void +forkret(void) +{ + static int first = 1; + // Still holding ptable.lock from scheduler. + release(&ptable.lock); + + if (first) { + // Some initialization functions must be run in the context + // of a regular process (e.g., they call sleep), and thus cannot + // be run from main(). + first = 0; + initlog(); + } +//cprintf("inside forkret\n"); + + // Return to "caller", actually trapret (see allocproc). +} + +// Atomically release lock and sleep on chan. +// Reacquires lock when awakened. +void +sleep(void *chan, struct spinlock *lk) +{ + if(curr_proc == 0) + panic("sleep"); + + if(lk == 0) + panic("sleep without lk"); + + // Must acquire ptable.lock in order to + // change p->state and then call sched. + // Once we hold ptable.lock, we can be + // guaranteed that we won't miss any wakeup + // (wakeup runs with ptable.lock locked), + // so it's okay to release lk. + if(lk != &ptable.lock){ //DOC: sleeplock0 + acquire(&ptable.lock); //DOC: sleeplock1 + release(lk); + } + + // Go to sleep. + curr_proc->chan = chan; + curr_proc->state = SLEEPING; +//cprintf("inside sleep before calling sched\n"); + sched(); + + // Tidy up. + curr_proc->chan = 0; + + // Reacquire original lock. + if(lk != &ptable.lock){ //DOC: sleeplock2 + release(&ptable.lock); + acquire(lk); + } +} + +//PAGEBREAK! +// Wake up all processes sleeping on chan. +// The ptable lock must be held. +static void +wakeup1(void *chan) +{ + struct proc *p; + + for(p = ptable.proc; p < &ptable.proc[NPROC]; p++) + if(p->state == SLEEPING && p->chan == chan) + p->state = RUNNABLE; +} + +// Wake up all processes sleeping on chan. +void +wakeup(void *chan) +{ + acquire(&ptable.lock); + wakeup1(chan); + release(&ptable.lock); +} + +// Kill the process with the given pid. +// Process won't exit until it returns +// to user space (see trap in trap.c). +int +kill(int pid) +{ + struct proc *p; + + acquire(&ptable.lock); + for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ + if(p->pid == pid){ + p->killed = 1; + // Wake process from sleep if necessary. + if(p->state == SLEEPING) + p->state = RUNNABLE; + release(&ptable.lock); + return 0; + } + } + release(&ptable.lock); + return -1; +} + +//PAGEBREAK: 36 +// Print a process listing to console. For debugging. +// Runs when user types ^P on console. +// No lock to avoid wedging a stuck machine further. +void +procdump(void) +{ +} + + diff -r 000000000000 -r c450faca55f4 source/spinlock.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/spinlock.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,105 @@ +/***************************************************************** +* spinlock.c +* adapted from MIT xv6 by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "arm.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" +#include "spinlock.h" + +void +initlock(struct spinlock *lk, char *name) +{ + lk->name = name; + lk->locked = 0; + lk->cpu = 0; +} + +// Acquire the lock. +// Loops (spins) until the lock is acquired. +// Holding a lock for a long time may cause +// other CPUs to waste time spinning to acquire it. +void +acquire(struct spinlock *lk) +{ + pushcli(); // disable interrupts to avoid deadlock. + if(holding(lk)){ + cprintf("lock name: %s, locked: %d, cpu: %x CPSR: %x\n", lk->name, lk->locked, lk->cpu, readcpsr()); + panic("acquire"); + } + + lk->locked = 1; + + // Record info about lock acquisition for debugging. + lk->cpu = curr_cpu; +} + +// Release the lock. +void +release(struct spinlock *lk) +{ + + if(!holding(lk)) + panic("release"); + + lk->pcs[0] = 0; + lk->cpu = 0; + + lk->locked = 0; + popcli(); +} + +// Record the current call stack in pcs[] by following the %ebp chain. +void +getcallerpcs(void *v, uint pcs[]) +{ +} + + +// Check whether this cpu is holding the lock. +int +holding(struct spinlock *lock) +{ +int rv; + rv = lock->locked && lock->cpu == curr_cpu; +/* if(rv){ + cprintf("The held lock: %s, locked: %d, cpu: %x\n", lock->name, lock->locked, lock->cpu); + }*/ + return rv; +} + + +// Pushcli/popcli are like cli/sti except that they are matched: +// it takes two popcli to undo two pushcli. Also, if interrupts +// are off, then pushcli, popcli leaves them off. + +void +pushcli(void) +{ + uint cpsr; + cpsr = readcpsr(); + cli(); + if(curr_cpu->ncli++ == 0) + curr_cpu->intena = (cpsr & PSR_DISABLE_IRQ) ? 0: 1; +} + +void +popcli(void) +{ + if(!(readcpsr()&PSR_DISABLE_IRQ)) + panic("popcli - interruptible"); + if(--curr_cpu->ncli < 0) + panic("popcli"); + if(curr_cpu->ncli == 0 && curr_cpu->intena) + sti(); +} + diff -r 000000000000 -r c450faca55f4 source/string.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/string.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,148 @@ +/***************************************************************** +* string.c +* adapted from MIT xv6 by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + +#include "types.h" + +void* +memsetw(int *dst, int c, uint n) +{ + int *p=dst; + uint rc=n; + + while (rc-- > 0) *p++ = c; + return (void *)p; +} + +void* +memsetb(char *dst, int c, uint n) +{ + char *p=dst; + uint rc=n; + + while (rc-- > 0) *p++ = c; + return (void *)p; +} + + +void* +memset(void *dst, int c, uint n) +{ + if ((int)dst%4 == 0 && n%4 == 0){ + c &= 0xFF; + return memsetw((int *)dst, (c<<24)|(c<<16)|(c<<8)|c, n/4); + } else + return memsetb((char *)dst, c, n); +} + +int +memcmp(const void *v1, const void *v2, uint n) +{ + const u8 *s1, *s2; + + s1 = v1; + s2 = v2; + while(n-- > 0){ + if(*s1 != *s2) + return *s1 - *s2; + s1++, s2++; + } + + return 0; +} + +void* +memmove(void *dst, const void *src, uint n) +{ + const char *s; + char *d; + + s = src; + d = dst; + if(s < d && s + n > d){ + s += n; + d += n; + while(n-- > 0) + *--d = *--s; + } else + while(n-- > 0) + *d++ = *s++; + + return dst; +} + +// memcpy exists to placate GCC. Use memmove. +void* +memcpy(void *dst, const void *src, uint n) +{ + return memmove(dst, src, n); +} + +int +strncmp(const char *p, const char *q, uint n) +{ + while(n > 0 && *p && *p == *q) + n--, p++, q++; + if(n == 0) + return 0; + return (u8)*p - (u8)*q; +} + +char* +strncpy(char *s, const char *t, int n) +{ + char *os; + + os = s; + while(n-- > 0 && (*s++ = *t++) != 0) + ; + while(n-- > 0) + *s++ = 0; + return os; +} + +// Like strncpy but guaranteed to NUL-terminate. +char* +safestrcpy(char *s, const char *t, int n) +{ + char *os; + + os = s; + if(n <= 0) + return os; + while(--n > 0 && (*s++ = *t++) != 0) + ; + *s = 0; + return os; +} + +int +strlen(const char *s) +{ + int n; + + for(n = 0; s[n]; n++) + ; + return n; +} + +uint div(uint n, uint d) // long division +{ + uint q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + } + } + return q; +} + diff -r 000000000000 -r c450faca55f4 source/syscall.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/syscall.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,152 @@ +/***************************************************************** +* syscall.c +* adapted from MIT xv6 by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" +#include "arm.h" +#include "syscall.h" + +// User code makes a system call with INT T_SYSCALL. +// System call number in %eax. +// Arguments on the stack, from the user call to the C +// library system call function. The saved user %esp points +// to a saved program counter, and then the first argument. + +// Fetch the int at addr from the current process. +int +fetchint(uint addr, int *ip) +{ + if(addr >= curr_proc->sz || addr+4 > curr_proc->sz) + return -1; + *ip = *(int*)(addr); + return 0; +} + +// Fetch the nul-terminated string at addr from the current process. +// Doesn't actually copy the string - just sets *pp to point at it. +// Returns length of string, not including nul. +int +fetchstr(uint addr, char **pp) +{ + char *s, *ep; + + if(addr >= curr_proc->sz) + return -1; + *pp = (char*)addr; + ep = (char*)curr_proc->sz; + for(s = *pp; s < ep; s++) + if(*s == 0) + return s - *pp; + return -1; +} + +// Fetch the nth 32-bit system call argument. +int +argint(int n, int *ip) +{ + return fetchint(curr_proc->tf->sp + 4*n, ip); +} + +// Fetch the nth word-sized system call argument as a pointer +// to a block of memory of size n bytes. Check that the pointer +// lies within the process address space. +int +argptr(int n, char **pp, int size) +{ + int i; + + if(argint(n, &i) < 0) + return -1; + if((uint)i >= curr_proc->sz || (uint)i+size > curr_proc->sz) + return -1; + *pp = (char*)i; + return 0; +} + +// Fetch the nth word-sized system call argument as a string pointer. +// Check that the pointer is valid and the string is nul-terminated. +// (There is no shared writable memory, so the string can't change +// between this check and being used by the kernel.) +int +argstr(int n, char **pp) +{ + int addr; + if(argint(n, &addr) < 0) + return -1; + return fetchstr(addr, pp); +} + +extern int sys_chdir(void); +extern int sys_close(void); +extern int sys_dup(void); +extern int sys_exec(void); +extern int sys_exit(void); +extern int sys_fork(void); +extern int sys_fstat(void); +extern int sys_getpid(void); +extern int sys_kill(void); +extern int sys_link(void); +extern int sys_mkdir(void); +extern int sys_mknod(void); +extern int sys_open(void); +extern int sys_pipe(void); +extern int sys_read(void); +extern int sys_sbrk(void); +extern int sys_sleep(void); +extern int sys_unlink(void); +extern int sys_wait(void); +extern int sys_write(void); +extern int sys_uptime(void); + +static int (*syscalls[])(void) = { +[SYS_fork] sys_fork, +[SYS_exit] sys_exit, +[SYS_wait] sys_wait, +[SYS_pipe] sys_pipe, +[SYS_read] sys_read, +[SYS_kill] sys_kill, +[SYS_exec] sys_exec, +[SYS_fstat] sys_fstat, +[SYS_chdir] sys_chdir, +[SYS_dup] sys_dup, +[SYS_getpid] sys_getpid, +[SYS_sbrk] sys_sbrk, +[SYS_sleep] sys_sleep, +[SYS_uptime] sys_uptime, +[SYS_open] sys_open, +[SYS_write] sys_write, +[SYS_mknod] sys_mknod, +[SYS_unlink] sys_unlink, +[SYS_link] sys_link, +[SYS_mkdir] sys_mkdir, +[SYS_close] sys_close, +}; + +void +syscall(void) +{ + int num; + + num = curr_proc->tf->r0; + if(num > 0 && num < NELEM(syscalls) && syscalls[num]) { +// cprintf("\n%d %s: sys call %d syscall address %x\n", +// curr_proc->pid, curr_proc->name, num, syscalls[num]); + + if(num == SYS_exec) { + if(syscalls[num]() == -1) curr_proc->tf->r0 = -1; + } else curr_proc->tf->r0 = syscalls[num](); + } else { + cprintf("%d %s: unknown sys call %d\n", + curr_proc->pid, curr_proc->name, num); + curr_proc->tf->r0 = -1; + } +} diff -r 000000000000 -r c450faca55f4 source/sysfile.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/sysfile.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,426 @@ +// +// File-system system calls. +// Mostly argument checking, since we don't trust +// user code, and calls into file.c and fs.c. +// + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "stat.h" +#include "mmu.h" +#include "proc.h" +#include "fs.h" +#include "file.h" +#include "fcntl.h" + +// Fetch the nth word-sized system call argument as a file descriptor +// and return both the descriptor and the corresponding struct file. +static int +argfd(int n, int *pfd, struct file **pf) +{ + int fd; + struct file *f; + + if(argint(n, &fd) < 0) + return -1; + if(fd < 0 || fd >= NOFILE || (f=curr_proc->ofile[fd]) == 0) + return -1; + if(pfd) + *pfd = fd; + if(pf) + *pf = f; + return 0; +} + +// Allocate a file descriptor for the given file. +// Takes over file reference from caller on success. +static int +fdalloc(struct file *f) +{ + int fd; + + for(fd = 0; fd < NOFILE; fd++){ + if(curr_proc->ofile[fd] == 0){ + curr_proc->ofile[fd] = f; + return fd; + } + } + return -1; +} + +int +sys_dup(void) +{ + struct file *f; + int fd; + + if(argfd(0, 0, &f) < 0) + return -1; + if((fd=fdalloc(f)) < 0) + return -1; + filedup(f); + return fd; +} + +int +sys_read(void) +{ + struct file *f; + int n; + char *p; + + if(argfd(0, 0, &f) < 0 || argint(2, &n) < 0 || argptr(1, &p, n) < 0) + return -1; + return fileread(f, p, n); +} + +int +sys_write(void) +{ + struct file *f; + int n; + char *p; + + if(argfd(0, 0, &f) < 0 || argint(2, &n) < 0 || argptr(1, &p, n) < 0) + return -1; +//cprintf("inside sys_write\n"); + return filewrite(f, p, n); +} + +int +sys_close(void) +{ + int fd; + struct file *f; + + if(argfd(0, &fd, &f) < 0) + return -1; + curr_proc->ofile[fd] = 0; + fileclose(f); + return 0; +} + +int +sys_fstat(void) +{ + struct file *f; + struct stat *st; + + if(argfd(0, 0, &f) < 0 || argptr(1, (void*)&st, sizeof(*st)) < 0) + return -1; + return filestat(f, st); +} + +// Create the path new as a link to the same inode as old. +int +sys_link(void) +{ + char name[DIRSIZ], *new, *old; + struct inode *dp, *ip; + + if(argstr(0, &old) < 0 || argstr(1, &new) < 0) + return -1; + if((ip = namei(old)) == 0) + return -1; + + begin_trans(); + + ilock(ip); + if(ip->type == T_DIR){ + iunlockput(ip); + commit_trans(); + return -1; + } + + ip->nlink++; + iupdate(ip); + iunlock(ip); + + if((dp = nameiparent(new, name)) == 0) + goto bad; + ilock(dp); + if(dp->dev != ip->dev || dirlink(dp, name, ip->inum) < 0){ + iunlockput(dp); + goto bad; + } + iunlockput(dp); + iput(ip); + + commit_trans(); + + return 0; + +bad: + ilock(ip); + ip->nlink--; + iupdate(ip); + iunlockput(ip); + commit_trans(); + return -1; +} + +// Is the directory dp empty except for "." and ".." ? +static int +isdirempty(struct inode *dp) +{ + int off; + struct dirent de; + + for(off=2*sizeof(de); offsize; off+=sizeof(de)){ + if(readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) + panic("isdirempty: readi"); + if(de.inum != 0) + return 0; + } + return 1; +} + +//PAGEBREAK! +int +sys_unlink(void) +{ + struct inode *ip, *dp; + struct dirent de; + char name[DIRSIZ], *path; + uint off; + + if(argstr(0, &path) < 0) + return -1; + if((dp = nameiparent(path, name)) == 0) + return -1; + + begin_trans(); + + ilock(dp); + + // Cannot unlink "." or "..". + if(namecmp(name, ".") == 0 || namecmp(name, "..") == 0) + goto bad; + + if((ip = dirlookup(dp, name, &off)) == 0) + goto bad; + ilock(ip); + + if(ip->nlink < 1) + panic("unlink: nlink < 1"); + if(ip->type == T_DIR && !isdirempty(ip)){ + iunlockput(ip); + goto bad; + } + + memset(&de, 0, sizeof(de)); + if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) + panic("unlink: writei"); + if(ip->type == T_DIR){ + dp->nlink--; + iupdate(dp); + } + iunlockput(dp); + + ip->nlink--; + iupdate(ip); + iunlockput(ip); + + commit_trans(); + + return 0; + +bad: + iunlockput(dp); + commit_trans(); + return -1; +} + +static struct inode* +create(char *path, short type, short major, short minor) +{ + uint off; + struct inode *ip, *dp; + char name[DIRSIZ]; + + if((dp = nameiparent(path, name)) == 0) + return 0; + ilock(dp); + + if((ip = dirlookup(dp, name, &off)) != 0){ + iunlockput(dp); + ilock(ip); + if(type == T_FILE && ip->type == T_FILE) + return ip; + iunlockput(ip); + return 0; + } + + if((ip = ialloc(dp->dev, type)) == 0) + panic("create: ialloc"); + + ilock(ip); + ip->major = major; + ip->minor = minor; + ip->nlink = 1; + iupdate(ip); + + if(type == T_DIR){ // Create . and .. entries. + dp->nlink++; // for ".." + iupdate(dp); + // No ip->nlink++ for ".": avoid cyclic ref count. + if(dirlink(ip, ".", ip->inum) < 0 || dirlink(ip, "..", dp->inum) < 0) + panic("create dots"); + } + + if(dirlink(dp, name, ip->inum) < 0) + panic("create: dirlink"); + + iunlockput(dp); + + return ip; +} + +int +sys_open(void) +{ + char *path; + int fd, omode; + struct file *f; + struct inode *ip; + + if(argstr(0, &path) < 0 || argint(1, &omode) < 0) + return -1; + if(omode & O_CREATE){ + begin_trans(); + ip = create(path, T_FILE, 0, 0); + commit_trans(); + if(ip == 0) + return -1; + } else { + if((ip = namei(path)) == 0) + return -1; + ilock(ip); + if(ip->type == T_DIR && omode != O_RDONLY){ + iunlockput(ip); + return -1; + } + } + + if((f = filealloc()) == 0 || (fd = fdalloc(f)) < 0){ + if(f) + fileclose(f); + iunlockput(ip); + return -1; + } + iunlock(ip); + + f->type = FD_INODE; + f->ip = ip; + f->off = 0; + f->readable = !(omode & O_WRONLY); + f->writable = (omode & O_WRONLY) || (omode & O_RDWR); + return fd; +} + +int +sys_mkdir(void) +{ + char *path; + struct inode *ip; + + begin_trans(); + if(argstr(0, &path) < 0 || (ip = create(path, T_DIR, 0, 0)) == 0){ + commit_trans(); + return -1; + } + iunlockput(ip); + commit_trans(); + return 0; +} + +int +sys_mknod(void) +{ + struct inode *ip; + char *path; + int len; + int major, minor; + + begin_trans(); + if((len=argstr(0, &path)) < 0 || + argint(1, &major) < 0 || + argint(2, &minor) < 0 || + (ip = create(path, T_DEV, major, minor)) == 0){ + commit_trans(); + return -1; + } + iunlockput(ip); + commit_trans(); + return 0; +} + +int +sys_chdir(void) +{ + char *path; + struct inode *ip; + + if(argstr(0, &path) < 0 || (ip = namei(path)) == 0) + return -1; + ilock(ip); + if(ip->type != T_DIR){ + iunlockput(ip); + return -1; + } + iunlock(ip); + iput(curr_proc->cwd); + curr_proc->cwd = ip; + return 0; +} + +int +sys_exec(void) +{ + char *path, *argv[MAXARG]; + int i; + uint uargv, uarg; + + if(argstr(0, &path) < 0 || argint(1, (int*)&uargv) < 0){ + return -1; + } + memset(argv, 0, sizeof(char *)*MAXARG); + for(i=0;; i++){ + if(i >= NELEM(argv)) + return -1; + if(fetchint(uargv+4*i, (int*)&uarg) < 0) + return -1; + if(uarg == 0){ + argv[i] = 0; + break; + } + if(fetchstr(uarg, &argv[i]) < 0) + return -1; + } + return exec(path, argv); +} + +int +sys_pipe(void) +{ + int *fd; + struct file *rf, *wf; + int fd0, fd1; + + if(argptr(0, (void*)&fd, 2*sizeof(fd[0])) < 0) + return -1; + if(pipealloc(&rf, &wf) < 0) + return -1; + fd0 = -1; + if((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0){ + if(fd0 >= 0) + curr_proc->ofile[fd0] = 0; + fileclose(rf); + fileclose(wf); + return -1; + } + fd[0] = fd0; + fd[1] = fd1; + return 0; +} diff -r 000000000000 -r c450faca55f4 source/sysproc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/sysproc.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,90 @@ +#include "types.h" +#include "arm.h" +#include "defs.h" +#include "param.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" + +int +sys_fork(void) +{ + return fork(); +} + +int +sys_exit(void) +{ + exit(); + return 0; // not reached +} + +int +sys_wait(void) +{ + return wait(); +} + +int +sys_kill(void) +{ + int pid; + + if(argint(0, &pid) < 0) + return -1; + return kill(pid); +} + +int +sys_getpid(void) +{ + return curr_proc->pid; +} + +int +sys_sbrk(void) +{ + int addr; + int n; + + if(argint(0, &n) < 0) + return -1; + addr = curr_proc->sz; + if(growproc(n) < 0) + return -1; + return addr; +} + +int +sys_sleep(void) +{ + int n; + uint ticks0; + + if(argint(0, &n) < 0) + return -1; + acquire(&tickslock); + ticks0 = ticks; + while(ticks - ticks0 < n){ + if(curr_proc->killed){ + release(&tickslock); + return -1; + } + sleep(&ticks, &tickslock); + } + release(&tickslock); + return 0; +} + +// return how many clock tick interrupts have occurred +// since start. +int +sys_uptime(void) +{ + uint xticks; + + acquire(&tickslock); + xticks = ticks; + release(&tickslock); + return xticks; +} diff -r 000000000000 -r c450faca55f4 source/timer.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/timer.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,81 @@ +/***************************************************************** +* timer.c +* by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + +// The System Timer peripheral + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "memlayout.h" +#include "proc.h" +#include "traps.h" +#include "arm.h" +#include "spinlock.h" + +#define TIMER_REGS_BASE 0xFE003000 +#define CONTROL_STATUS 0x0 // control/status +#define COUNTER_LO 0x4 // the time-stamp lower 32 bits +#define COUNTER_HI 0x8 // the time-stamp higher 32 bits +#define COMPARE0 0xc // compare 0 +#define COMPARE1 0x10 // compare 1 +#define COMPARE2 0x14 // compare 2 +#define COMPARE3 0x18 // compare 3 + +#define TIMER_FREQ 10000 // interrupt 100 times/sec. + +void +enabletimer3irq(void) +{ + intctrlregs *ip; + + ip = (intctrlregs *)INT_REGS_BASE; + ip->gpuenable[0] |= 1 << IRQ_TIMER3; // enable the system timer3 irq +} + + +void +timer3init(void) +{ +uint v; + + enabletimer3irq(); + + v = inw(TIMER_REGS_BASE+COUNTER_LO); + v += TIMER_FREQ; + + outw(TIMER_REGS_BASE+COMPARE3, v); + ticks = 0; +} + +void +timer3intr(void) +{ +uint v; +//cprintf("timer3 interrupt: %x\n", inw(TIMER_REGS_BASE+CONTROL_STATUS)); + outw(TIMER_REGS_BASE+CONTROL_STATUS, (1 << IRQ_TIMER3)); // clear timer3 irq + + ticks++; + wakeup(&ticks); + + // reset the value of compare3 + v=inw(TIMER_REGS_BASE+COUNTER_LO); + v += TIMER_FREQ; + outw(TIMER_REGS_BASE+COMPARE3, v); +} + +void +delay(uint m) +{ + unsigned long long t; + + if(m == 0) return; + + t = getsystemtime() + m; + while(t != getsystemtime()); + + return; +} diff -r 000000000000 -r c450faca55f4 source/trap.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/trap.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,197 @@ +/***************************************************************** +* trap.c +* by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + +#include "types.h" +#include "defs.h" +#include "param.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" +#include "arm.h" +#include "traps.h" +#include "spinlock.h" + +extern u8 *vectors; + +void cprintf(char*, ...); +void dsb_barrier(void); +void flush_idcache(void); +void *memmove(void *dst, const void *src, uint n); +void set_mode_sp(char *, uint); + +struct spinlock tickslock; +uint ticks; + +void enable_intrs(void) +{ + intctrlregs *ip; + + ip = (intctrlregs *)INT_REGS_BASE; + ip->gpuenable[0] |= 1 << 29; // enable the miniuart through Aux + //ip->gpuenable[1] |= 1 << 25; // enable uart + ip->armenable |= 1 << 0; // enable the system timer +} + + +void disable_intrs(void) +{ + intctrlregs *ip; + int disable; + + ip = (intctrlregs *)INT_REGS_BASE; + disable = ~0; + ip->gpudisable[0] = disable; + ip->gpudisable[1] = disable; + ip->armdisable = disable; + ip->fiqctrl = 0; +} + + +void tvinit(void) +{ + uint *d, *s; + char *ptr; + + /* initialize the exception vectors */ + d = (uint *)HVECTORS; + s = (uint *)&vectors; + memmove(d, s, sizeof(Vpage0)); + + /* cacheuwbinv(); drain write buffer and prefetch buffer + * writeback and invalidate data cache + * invalidate instruction cache + */ + dsb_barrier(); + flush_idcache(); + ptr = kalloc(); + memset(ptr, 0, PGSIZE); + set_mode_sp(ptr+4096, 0xD1);/* fiq mode, fiq and irq are disabled */ + + ptr = kalloc(); + memset(ptr, 0, PGSIZE); + set_mode_sp(ptr+4096, 0xD2);/* irq mode, fiq and irq are disabled */ + ptr = kalloc(); + memset(ptr, 0, PGSIZE); + set_mode_sp(ptr+4096, 0xDB);/* undefined mode, fiq and irq are disabled */ + ptr = kalloc(); + memset(ptr, 0, PGSIZE); + set_mode_sp(ptr+4096, 0xD7);/* abort mode, fiq and irq are disabled */ + ptr = kalloc(); + memset(ptr, 0, PGSIZE); + set_mode_sp(ptr+4096, 0xD6);/* secure monitor mode, fiq and irq are disabled */ + ptr = kalloc(); + memset(ptr, 0, PGSIZE); + set_mode_sp(ptr+4096, 0xDF);/* system mode, fiq and irq are disabled */ + + dsb_barrier(); +} + +void trap_oops(struct trapframe *tf) +{ + +cprintf("trapno: %x, spsr: %x, sp: %x, pc: %x cpsr: %x ifar: %x\n", tf->trapno, tf->spsr, tf->sp, tf->pc, tf->cpsr, tf->ifar); +cprintf("Saved registers: r0: %x, r1: %x, r2: %x, r3: %x, r4: %x, r5: %x\n", tf->r0, tf->r1, tf->r2, tf->r3, tf->r4, tf->r5); +cprintf("More registers: r6: %x, r7: %x, r8: %x, r9: %x, r10: %x, r11: %x, r12: %x\n", tf->r6, tf->r7, tf->r8, tf->r9, tf->r10, tf->r11, tf->r12); + +//NotOkLoop(); +} + +void handle_irq(struct trapframe *tf) +{ + intctrlregs *ip; + +/*cprintf("trapno: %x, spsr: %x, sp: %x, lr: %x cpsr: %x ifar: %x\n", tf->trapno, tf->spsr, tf->sp, tf->pc, tf->cpsr, tf->ifar); +cprintf("Saved registers: r0: %x, r1: %x, r2: %x, r3: %x, r4: %x, r5: %x, r6: %x\n", tf->r0, tf->r1, tf->r2, tf->r3, tf->r4, tf->r5, tf->r6); +cprintf("More registers: r6: %x, r7: %x, r8: %x, r9: %x, r10: %x, r11: %x, r12: %x, r13: %x, r14: %x\n", tf->r7, tf->r8, tf->r9, tf->r10, tf->r11, tf->r12, tf->r13, tf->r14); +*/ + ip = (intctrlregs *)INT_REGS_BASE; + while(ip->gpupending[0] || ip->gpupending[1] || ip->armpending){ + if(ip->gpupending[0] & (1 << 3)) { + timer3intr(); + } + if(ip->gpupending[0] & (1 << 29)) { + miniuartintr(); + } + } + +} + + +//PAGEBREAK: 41 +void +trap(struct trapframe *tf) +{ + intctrlregs *ip; + uint istimer; + +//cprintf("Trap %d from cpu %d eip %x (cr2=0x%x)\n", +// tf->trapno, curr_cpu->id, tf->eip, 0); + //trap_oops(tf); + if(tf->trapno == T_SYSCALL){ + if(curr_proc->killed) + exit(); + curr_proc->tf = tf; + syscall(); + if(curr_proc->killed) + exit(); + return; + } + + istimer = 0; + switch(tf->trapno){ + case T_IRQ: + ip = (intctrlregs *)INT_REGS_BASE; + while(ip->gpupending[0] || ip->gpupending[1] || ip->armpending){ + if(ip->gpupending[0] & (1 << IRQ_TIMER3)) { + istimer = 1; + timer3intr(); + } + if(ip->gpupending[0] & (1 << IRQ_MINIUART)) { + miniuartintr(); + } + } + + break; + default: + if(curr_proc == 0 || (tf->spsr & 0xF) != USER_MODE){ + // In kernel, it must be our mistake. + cprintf("unexpected trap %d from cpu %d addr %x spsr %x cpsr %x ifar %x\n", + tf->trapno, curr_cpu->id, tf->pc, tf->spsr, tf->cpsr, tf->ifar); + panic("trap"); + } + // In user space, assume process misbehaved. + cprintf("pid %d %s: trap %d on cpu %d " + "addr 0x%x spsr 0x%x cpsr 0x%x ifar 0x%x--kill proc\n", + curr_proc->pid, curr_proc->name, tf->trapno, curr_cpu->id, tf->pc, + tf->spsr, tf->cpsr, tf->ifar); + curr_proc->killed = 1; + } + + // Force process exit if it has been killed and is in user space. + // (If it is still executing in the kernel, let it keep running + // until it gets to the regular system call return.) + +//cprintf("Proc pointer: %d\n", curr_proc); + if(curr_proc){ + if(curr_proc->killed && (tf->spsr&0xF) == USER_MODE) + exit(); + + // Force process to give up CPU on clock tick. + // If interrupts were on while locks held, would need to check nlock. + if(curr_proc->state == RUNNING && istimer) + yield(); + + // Check if the process has been killed since we yielded + if(curr_proc->killed && (tf->spsr&0xF) == USER_MODE) + exit(); + } + +//cprintf("Proc pointer: %d after\n", curr_proc); + +} + diff -r 000000000000 -r c450faca55f4 source/uart.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/uart.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,135 @@ +/***************************************************************** +* uart.c +* by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + + +#include "types.h" +#include "defs.h" +#include "memlayout.h" +#include "traps.h" +#include "arm.h" + +#define GPFSEL0 0xFE200000 +#define GPFSEL1 0xFE200004 +#define GPFSEL2 0xFE200008 +#define GPFSEL3 0xFE20000C +#define GPFSEL4 0xFE200010 +#define GPFSEL5 0xFE200014 +#define GPSET0 0xFE20001C +#define GPSET1 0xFE200020 +#define GPCLR0 0xFE200028 +#define GPCLR1 0xFE20002C +#define GPPUD 0xFE200094 +#define GPPUDCLK0 0xFE200098 +#define GPPUDCLK1 0xFE20009C + +#define AUX_IRQ 0xFE215000 +#define AUX_ENABLES 0xFE215004 +#define AUX_MU_IO_REG 0xFE215040 +#define AUX_MU_IER_REG 0xFE215044 +#define AUX_MU_IIR_REG 0xFE215048 +#define AUX_MU_LCR_REG 0xFE21504C +#define AUX_MU_MCR_REG 0xFE215050 +#define AUX_MU_LSR_REG 0xFE215054 +#define AUX_MU_MSR_REG 0xFE215058 +#define AUX_MU_SCRATCH 0xFE21505C +#define AUX_MU_CNTL_REG 0xFE215060 +#define AUX_MU_STAT_REG 0xFE215064 +#define AUX_MU_BAUD_REG 0xFE215068 + +void +setgpioval(uint func, uint val) +{ + uint sel, ssel, rsel; + + if(func > 53) return; + sel = func >> 5; + ssel = GPSET0 + (sel << 2); + rsel = GPCLR0 + (sel << 2); + sel = func & 0x1f; + if(val == 0) outw(rsel, 1< 53) return; + sel = 0; + while (func > 10) { + func = func - 10; + sel++; + } + sel = (sel << 2) + GPFSEL0; + data = inw(sel); + shift = func + (func << 1); + data &= ~(7 << shift); + data |= alt << shift; + outw(sel, data); +} + + +void +uartputc(uint c) +{ + if(c=='\n') { + while(1) if(inw(AUX_MU_LSR_REG) & 0x20) break; + outw(AUX_MU_IO_REG, 0x0d); // add CR before LF + } + while(1) if(inw(AUX_MU_LSR_REG) & 0x20) break; + outw(AUX_MU_IO_REG, c); +} + +static int +uartgetc(void) +{ + if(inw(AUX_MU_LSR_REG)&0x1) return inw(AUX_MU_IO_REG); + else return -1; +} + +void +enableirqminiuart(void) +{ + intctrlregs *ip; + + ip = (intctrlregs *)INT_REGS_BASE; + ip->gpuenable[0] |= (1 << 29); // enable the miniuart through Aux +} + + +void +miniuartintr(void) +{ + consoleintr(uartgetc); +} + +void +uartinit(void) +{ + outw(AUX_ENABLES, 1); + outw(AUX_MU_CNTL_REG, 0); + outw(AUX_MU_LCR_REG, 0x3); + outw(AUX_MU_MCR_REG, 0); + outw(AUX_MU_IER_REG, 0x1); + outw(AUX_MU_IIR_REG, 0xC7); + outw(AUX_MU_BAUD_REG, 270); // (250,000,000/(115200*8))-1 = 270 + + setgpiofunc(14, 2); // gpio 14, alt 5 + setgpiofunc(15, 2); // gpio 15, alt 5 + + outw(GPPUD, 0); + delay(10); + outw(GPPUDCLK0, (1 << 14) | (1 << 15) ); + delay(10); + outw(GPPUDCLK0, 0); + + outw(AUX_MU_CNTL_REG, 3); + enableirqminiuart(); +} diff -r 000000000000 -r c450faca55f4 source/vm.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/vm.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,414 @@ +/***************************************************************** +* vm.c +* adapted from MIT xv6 by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + + +#include "param.h" +#include "types.h" +#include "defs.h" +#include "arm.h" +#include "memlayout.h" +#include "mmu.h" +#include "proc.h" +#include "elf.h" + +extern char data[]; // defined by kernel.ld +extern char end[]; // defined by kernel.ld + +pde_t *kpgdir; // for use in scheduler() + +// Return the address of the PTE in page table pgdir +// that corresponds to virtual address va. If alloc!=0, +// create any required page table pages. +static pte_t * +walkpgdir(pde_t *pgdir, const void *va, uint l1attr, int alloc) +{ + pde_t *pde; + pte_t *pgtab; + + pde = &pgdir[PDX(va)]; + if((uint)*pde != 0){ + pgtab = (pte_t*)p2v(PTE_ADDR(*pde)); + } else { + if(!alloc || (pgtab = (pte_t*)kalloc()) == 0) + return 0; + // Make sure all those PTE_P bits are zero. + memset(pgtab, 0, PGSIZE); + // The permissions here are overly generous, but they can + // be further restricted by the permissions in the page table + // entries, if necessary. + *pde = v2p(pgtab) | l1attr; +//cprintf("the pde value is %x\n", (uint)*pde); + } + return &pgtab[PTX(va)]; +} + +// Create PTEs for virtual addresses starting at va that refer to +// physical addresses starting at pa. va and size might not +// be page-aligned. +static int +mappages(pde_t *pgdir, void *va, uint size, uint pa, uint l1attr, uint l2attr) +{ + char *a, *last; + pte_t *pte; + + a = (char*)PGROUNDDOWN((uint)va); + last = (char*)PGROUNDDOWN(((uint)va) + size - 1); + +//cprintf("size= %x a=%x last= %x pa=%x\n", size, a, last, pa); + + if((SECTION & l1attr) != 0){// for 1 MB pages + for(;;){ + if(a > last) break; + if((uint)pgdir[PDX(a)] != 0) panic("remap"); + pgdir[PDX(a)] = pa | l1attr; +//cprintf("The pgdir entry: %x value: %x a=%x last= %x\n", PDX(a), pgdir[PDX(a)], a, last); + a += MBYTE; + pa += MBYTE; + } + } else if((COARSE & l1attr) != 0){// for 4kB pages + for(;;){ + //cprintf("The pgdir is %x value: %x a=%x last= %x\n", pgdir+PDX(a), pgdir[PDX(a)], a, last); + if((pte = walkpgdir(pgdir, a, l1attr, 1)) == 0) + return -1; + if((uint)*pte != 0) panic("remap"); + *pte = pa | l2attr; +//cprintf("The pte value is %x, the pde values is %x\n", (uint)*pte, pgdir[PDX(a)]); + if(a == last) break; + a += PGSIZE; + pa += PGSIZE; + } + } else panic("Unknown page attribute"); + return 0; +} + +// There is one page table per process, plus one that's used when +// a CPU is not running any process (kpgdir). The kernel uses the +// current process's page table during system calls and interrupts; +// page protection bits prevent user code from using the kernel's +// mappings. +// +// setupkvm() and exec() set up every page table like this: +// +// 0..KERNBASE: user memory (text+data+stack+heap), mapped to +// phys memory allocated by the kernel +// KERNBASE..KERNBASE+EXTMEM: mapped to 0..EXTMEM (for I/O space) +// KERNBASE+EXTMEM..data: mapped to EXTMEM..V2P(data) +// for the kernel's instructions and r/o data +// data..KERNBASE+PHYSTOP: mapped to V2P(data)..PHYSTOP, +// rw data + free physical memory +// 0xfe000000..0: mapped direct (devices such as ioapic) +// +// The kernel allocates physical memory for its heap and for user memory +// between V2P(end) and the end of physical memory (PHYSTOP) +// (directly addressable from end..P2V(PHYSTOP)). + +// This table defines the kernel's mappings, which are present in +// every process's page table. +static struct kmap { + void *virt; + uint phys_start; + uint phys_end; + uint l1attr; + uint l2attr; +} kmap[] = { + { (void*)KERNBASE, PA_START, PHYSTOP, DOMAIN0|PDX_AP(U_RW)|SECTION|CACHED|BUFFERED, 0}, + { (void*)DEVSPACE, PHYSIO, PHYSIO+IOSIZE, DOMAIN0|PDX_AP(U_RW)|SECTION, 0}, + { (void*)HVECTORS, PA_START, PA_START+TVSIZE, DOMAIN0|COARSE, PTX_AP(K_RW)|SMALL}, +}; + +// Set up kernel part of a page table. +// However, since the kernel part is shared, only the user part +// of the pgd is allocated (one page only for simplicity, so user space +// is now limited to 1GB +pde_t* +setupkvm(void) +{ + pde_t *pgdir; + + if((pgdir = (pde_t*)kalloc()) == 0) + return 0; +//cprintf("inside setupkvm: pgdir=%x\n", pgdir); + memset(pgdir, 0, PGSIZE); +//cprintf("after memset\n", pgdir); + return pgdir; +} + + +// Set up kernel part of a page table. +pde_t* +setupkvm_new(void) +{ + pde_t *pgdir; + struct kmap *k; + +/* if((pgdir = (pde_t*)kalloc()) == 0) + return 0;*/ + + pgdir = kpgdir; + memset(pgdir, 0, 4*PGSIZE); + if (p2v(PHYSTOP) > (void*)DEVSPACE) + panic("PHYSTOP too high"); + for(k = kmap; k < &kmap[NELEM(kmap)]; k++) + if(mappages(pgdir, k->virt, k->phys_end - k->phys_start, + (uint)k->phys_start, k->l1attr, k->l2attr) < 0) + return 0; + return pgdir; +} + +// Allocate one page table for the machine for the kernel address +// space for scheduler processes. +void +kvmalloc(void) +{ + kpgdir = setupkvm_new(); + switchkvm(); +} + +// Switch h/w page table register to the kernel-only page table, +// for when no process is running. +void +switchkvm(void) +{ +// do nothing here as the same pgdir is shared between kernel and user; +// will see if the user portion of the pgdir should be removed. +} + +void +switchkvm_new(void) +{ + dsb_barrier(); + flush_idcache(); + //cprintf("The phy pgtbase address is %x\n", (uint)v2p(kpgdir)); + set_pgtbase((uint)v2p(kpgdir)); // switch to the kernel page table + //cprintf("after set_pgtbase\n"); + dsb_barrier(); + flush_tlb(); + //cprintf("after flush_tlb\n"); +} + +// Switch TSS and h/w page table to correspond to process p. +void +switchuvm(struct proc *p) +{ + pushcli(); + //cpu->ts.esp0 = (uint)proc->kstack + KSTACKSIZE; + if(p->pgdir == 0) + panic("switchuvm: no pgdir"); +//cprintf("before copying uvm to kvm kpgdir=%x the first entry: %x\n", kpgdir, kpgdir[0]); + memmove((void *)kpgdir, (void *)p->pgdir, PGSIZE); // switch to new user address space + flush_idcache(); + flush_tlb(); + popcli(); +} + + +// Load the initcode into address 0 of pgdir. +// sz must be less than a page. +void +inituvm(pde_t *pgdir, char *init, uint sz) +{ + char *mem; + + if(sz >= PGSIZE) + panic("inituvm: more than a page"); + mem = kalloc(); + memset(mem, 0, PGSIZE); +//cprintf("inituvm: page is allocated at %x\n", mem); + mappages(pgdir, 0, PGSIZE, v2p(mem), UVMPDXATTR, UVMPTXATTR); + memmove(mem, init, sz); +} + +// Load a program segment into pgdir. addr must be page-aligned +// and the pages from addr to addr+sz must already be mapped. +int +loaduvm(pde_t *pgdir, char *addr, struct inode *ip, uint offset, uint sz) +{ + uint i, pa, n; + pte_t *pte; + + if((uint) addr % PGSIZE != 0) + panic("loaduvm: addr must be page aligned"); + if((uint)addr + sz > USERBOUND) + panic("loaduvm: user address space exceeds the allowed space (> 0x80000000)"); + for(i = 0; i < sz; i += PGSIZE){ + if((pte = walkpgdir(pgdir, addr+i, UVMPDXATTR, 0)) == 0) + panic("loaduvm: address should exist"); + pa = PTE_ADDR(*pte); + if(sz - i < PGSIZE) + n = sz - i; + else + n = PGSIZE; + if(readi(ip, p2v(pa), offset+i, n) != n) + return -1; + } + return 0; +} + +// Allocate page tables and physical memory to grow process from oldsz to +// newsz, which need not be page aligned. Returns new size or 0 on error. +int +allocuvm(pde_t *pgdir, uint oldsz, uint newsz) +{ + char *mem; + uint a; + + if(newsz >= USERBOUND) + return 0; + if(newsz < oldsz) + return oldsz; + + a = PGROUNDUP(oldsz); + for(; a < newsz; a += PGSIZE){ + mem = kalloc(); + if(mem == 0){ + cprintf("allocuvm out of memory\n"); + deallocuvm(pgdir, newsz, oldsz); + return 0; + } + memset(mem, 0, PGSIZE); + mappages(pgdir, (char*)a, PGSIZE, v2p(mem), UVMPDXATTR, UVMPTXATTR); + } + return newsz; +} + +// Deallocate user pages to bring the process size from oldsz to +// newsz. oldsz and newsz need not be page-aligned, nor does newsz +// need to be less than oldsz. oldsz can be larger than the actual +// process size. Returns the new process size. +int +deallocuvm(pde_t *pgdir, uint oldsz, uint newsz) +{ + pte_t *pte; + uint a, pa; + + if(newsz >= oldsz) + return oldsz; + + a = PGROUNDUP(newsz); + for(; a < oldsz; a += PGSIZE){ + pte = walkpgdir(pgdir, (char*)a, UVMPDXATTR, 0); + if(!pte) + a += (NPTENTRIES - 1) * PGSIZE; + else if(*pte != 0){ + pa = PTE_ADDR(*pte); + if(pa == 0) + panic("kfree"); + char *v = p2v(pa); + kfree(v); + *pte = 0; + } + } + return newsz; +} + +// Free a page table and all the physical memory pages +// in the user part. +void +freevm(pde_t *pgdir) +{ + uint i; + + if(pgdir == 0) + panic("freevm: no pgdir"); + deallocuvm(pgdir, USERBOUND, 0); + for(i = 0; i < NPDENTRIES; i++){ + if((uint)pgdir[i] != 0){ + char * v = p2v(PTE_ADDR(pgdir[i])); + kfree(v); + } + } + kfree((char*)pgdir); +} + +// Clear PTE_U on a page. Used to create an inaccessible +// page beneath the user stack. +void +clearpteu(pde_t *pgdir, char *uva) +{ + pte_t *pte; + + pte = walkpgdir(pgdir, uva, UVMPDXATTR, 0); + if(pte == 0) + panic("clearpteu"); + *pte &= ~PTX_AP(U_AP); +} + +// Given a parent process's page table, create a copy +// of it for a child. +pde_t* +copyuvm(pde_t *pgdir, uint sz) +{ + pde_t *d; + pte_t *pte; + uint pa, i, flags; + char *mem; + + if((d = setupkvm()) == 0) + return 0; + for(i = 0; i < sz; i += PGSIZE){ + if((pte = walkpgdir(pgdir, (void *) i, UVMPDXATTR, 0)) == 0) + panic("copyuvm: pte should exist"); + if((uint)*pte == 0) + panic("copyuvm: page not present"); + pa = PTE_ADDR(*pte); + flags = PTE_FLAGS(*pte); + if((mem = kalloc()) == 0) + goto bad; + memmove(mem, (char*)p2v(pa), PGSIZE); + if(mappages(d, (void*)i, PGSIZE, v2p(mem), UVMPDXATTR, flags) < 0) + goto bad; + } + return d; + +bad: + freevm(d); + return 0; +} + +//PAGEBREAK! +// Map user virtual address to kernel address. +char* +uva2ka(pde_t *pgdir, char *uva) +{ + pte_t *pte; + + pte = walkpgdir(pgdir, uva, UVMPDXATTR, 0); + if((uint)*pte == 0) + return 0; + if(((uint)*pte & PTX_AP(U_AP)) == 0) + return 0; + return (char*)p2v(PTE_ADDR(*pte)); +} + +// Copy len bytes from p to user address va in page table pgdir. +// Most useful when pgdir is not the current page table. +// uva2ka ensures this only works for PTE_U pages. +int +copyout(pde_t *pgdir, uint va, void *p, uint len) +{ + char *buf, *pa0; + uint n, va0; + + buf = (char*)p; + while(len > 0){ + va0 = (uint)PGROUNDDOWN(va); + pa0 = uva2ka(pgdir, (char*)va0); + if(pa0 == 0) + return -1; + n = PGSIZE - (va - va0); + if(n > len) + n = len; + memmove(pa0 + (va - va0), buf, n); + len -= n; + buf += n; + va = va0 + PGSIZE; + } + return 0; +} + + diff -r 000000000000 -r c450faca55f4 uprogs/LICENSE --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/LICENSE Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,24 @@ +The xv6 software is: + +Copyright (c) 2006-2009 Frans Kaashoek, Robert Morris, Russ Cox, + Massachusetts Institute of Technology + +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. + diff -r 000000000000 -r c450faca55f4 uprogs/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/Makefile Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,67 @@ +# Cross-compiling (e.g., on Mac OS X) +#TOOLPREFIX = i386-jos-elf- +# Using native tools (e.g., on X86 Linux) +TOOLPREFIX = + + +# The intermediate directory for compiled object files. +BUILD = build/ + +CC = $(TOOLPREFIX)gcc +AS = $(TOOLPREFIX)as +LD = $(TOOLPREFIX)ld +OBJCOPY = $(TOOLPREFIX)objcopy +OBJDUMP = $(TOOLPREFIX)objdump +CFLAGS := -fno-pic -static -fno-builtin -fno-strict-aliasing -fshort-wchar -O2 -Wall -MD -ggdb -Werror -fno-omit-frame-pointer -fno-stack-protector -Wa,-march=armv6 -Wa,-mcpu=arm1176jzf-s + +initcode: initcode.S + $(CC) $(CFLAGS) -nostdinc -I. -c initcode.S + $(LD) $(LDFLAGS) -N -e start -Ttext 0 -o initcode.out initcode.o + $(OBJCOPY) -S -O binary initcode.out initcode + $(OBJDUMP) -S initcode.o > initcode.asm + + +ULIB = ulib.o usys.o printf.o umalloc.o + +_%: %.o $(ULIB) + $(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $@ $^ + $(OBJDUMP) -S $@ > $*.asm + $(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $*.sym + +_forktest: forktest.o $(ULIB) + # forktest has less library code linked in - needs to be small + # in order to be able to max out the proc table. + $(LD) $(LDFLAGS) -N -e main -Ttext 0 -o _forktest forktest.o ulib.o usys.o + $(OBJDUMP) -S _forktest > forktest.asm + +mkfs: mkfs.c ../include/fs.h + gcc -Werror -Wall -o mkfs mkfs.c + +# Prevent deletion of intermediate files, e.g. cat.o, after first build, so +# that disk image changes after first build are persistent until clean. More +# details: +# http://www.gnu.org/software/make/manual/html_node/Chained-Rules.html +.PRECIOUS: %.o + +UPROGS=\ + _cat\ + _echo\ + _forktest\ + _grep\ + _init\ + _kill\ + _ln\ + _ls\ + _mkdir\ + _rm\ + _sh\ + _stressfs\ + _usertests\ + _wc\ + _zombie\ + +fs.img: mkfs README $(UPROGS) + ./mkfs fs.img README $(UPROGS) + +clean: + rm -f *.o *.d fs.img mkfs $(UPROGS) diff -r 000000000000 -r c450faca55f4 uprogs/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/README Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,50 @@ +xv6 is a re-implementation of Dennis Ritchie's and Ken Thompson's Unix +Version 6 (v6). xv6 loosely follows the structure and style of v6, +but is implemented for a modern x86-based multiprocessor using ANSI C. + +ACKNOWLEDGMENTS + +xv6 is inspired by John Lions's Commentary on UNIX 6th Edition (Peer +to Peer Communications; ISBN: 1-57398-013-7; 1st edition (June 14, +2000)). See also http://pdos.csail.mit.edu/6.828/2012/v6.html, which +provides pointers to on-line resources for v6. + +xv6 borrows code from the following sources: + JOS (asm.h, elf.h, mmu.h, bootasm.S, ide.c, console.c, and others) + Plan 9 (entryother.S, mp.h, mp.c, lapic.c) + FreeBSD (ioapic.c) + NetBSD (console.c) + +The following people have made contributions: + Russ Cox (context switching, locking) + Cliff Frey (MP) + Xiao Yu (MP) + Nickolai Zeldovich + Austin Clements + +In addition, we are grateful for the patches contributed by Greg +Price, Yandong Mao, and Hitoshi Mitake. + +The code in the files that constitute xv6 is +Copyright 2006-2012 Frans Kaashoek, Robert Morris, and Russ Cox. + +ERROR REPORTS + +If you spot errors or have suggestions for improvement, please send +email to Frans Kaashoek and Robert Morris (kaashoek,rtm@csail.mit.edu). + +BUILDING AND RUNNING XV6 + +To build xv6 on an x86 ELF machine (like Linux or FreeBSD), run "make". +On non-x86 or non-ELF machines (like OS X, even on x86), you will +need to install a cross-compiler gcc suite capable of producing x86 ELF +binaries. See http://pdos.csail.mit.edu/6.828/2012/tools.html. +Then run "make TOOLPREFIX=i386-jos-elf-". + +To run xv6, you can use the Bochs or QEMU PC simulators. Bochs makes +debugging easier, but QEMU is much faster. To run in Bochs, run "make +bochs" and then type "c" at the bochs prompt. To run in QEMU, run +"make qemu". + +To create a typeset version of the code, run "make xv6.pdf". This +requires the "mpage" utility. See http://www.mesa.nl/pub/mpage/. diff -r 000000000000 -r c450faca55f4 uprogs/a.out Binary file uprogs/a.out has changed diff -r 000000000000 -r c450faca55f4 uprogs/arm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/arm.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,25 @@ +//PAGEBREAK: 36 +// Layout of the trap frame built on the stack by the +// hardware and by trapasm.S, and passed to trap(). +struct trapframe { + uint trapno; + uint spsr; // saved cpsr from the trapped/interrupted mode + uint ifar; // Instruction Fault Address Register (IFAR) + uint cpsr; + uint sp; // user mode sp + uint lr; // return address of the interrupted code + uint r12; + uint r11; + uint r10; + uint r9; + uint r8; + uint r7; + uint r6; + uint r5; + uint r4; + uint r3; + uint r2; + uint r1; + uint r0; +}; + diff -r 000000000000 -r c450faca55f4 uprogs/buf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/buf.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,13 @@ +struct buf { + int flags; + uint dev; + uint sector; + struct buf *prev; // LRU cache list + struct buf *next; + struct buf *qnext; // disk queue + uchar data[512]; +}; +#define B_BUSY 0x1 // buffer is locked by some process +#define B_VALID 0x2 // buffer has been read from disk +#define B_DIRTY 0x4 // buffer needs to be written to disk + diff -r 000000000000 -r c450faca55f4 uprogs/cat.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/cat.asm Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,1762 @@ + +_cat: file format elf32-littlearm + + +Disassembly of section .text: + +00000000
: +int +main(int argc, char *argv[]) +{ + int fd, i; + + if(argc <= 1){ + 0: e3500001 cmp r0, #1 + } +} + +int +main(int argc, char *argv[]) +{ + 4: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + 8: e1a07000 mov r7, r0 + c: e28db01c add fp, sp, #28 + exit(); + } +} + +int +main(int argc, char *argv[]) + 10: c2814004 addgt r4, r1, #4 + 14: c3a05001 movgt r5, #1 +{ + int fd, i; + + if(argc <= 1){ + 18: da000012 ble 68 + cat(0); + exit(); + } + + for(i = 1; i < argc; i++){ + if((fd = open(argv[i], 0)) < 0){ + 1c: e5940000 ldr r0, [r4] + 20: e3a01000 mov r1, #0 + 24: eb000137 bl 508 + 28: e1a06004 mov r6, r4 + 2c: e2844004 add r4, r4, #4 + 30: e2508000 subs r8, r0, #0 + 34: ba000006 blt 54 + printf(1, "cat: cannot open %s\n", argv[i]); + exit(); + } + cat(fd); + 38: eb00000e bl 78 + if(argc <= 1){ + cat(0); + exit(); + } + + for(i = 1; i < argc; i++){ + 3c: e2855001 add r5, r5, #1 + if((fd = open(argv[i], 0)) < 0){ + printf(1, "cat: cannot open %s\n", argv[i]); + exit(); + } + cat(fd); + close(fd); + 40: e1a00008 mov r0, r8 + 44: eb000108 bl 46c + if(argc <= 1){ + cat(0); + exit(); + } + + for(i = 1; i < argc; i++){ + 48: e1550007 cmp r5, r7 + 4c: 1afffff2 bne 1c + exit(); + } + cat(fd); + close(fd); + } + exit(); + 50: eb0000c4 bl 368 + exit(); + } + + for(i = 1; i < argc; i++){ + if((fd = open(argv[i], 0)) < 0){ + printf(1, "cat: cannot open %s\n", argv[i]); + 54: e3a00001 mov r0, #1 + 58: e59f1014 ldr r1, [pc, #20] ; 74 + 5c: e5962000 ldr r2, [r6] + 60: eb000213 bl 8b4 + exit(); + 64: eb0000bf bl 368 +main(int argc, char *argv[]) +{ + int fd, i; + + if(argc <= 1){ + cat(0); + 68: e3a00000 mov r0, #0 + 6c: eb000001 bl 78 + exit(); + 70: eb0000bc bl 368 + 74: 00000bb0 .word 0x00000bb0 + +00000078 : + +char buf[512]; + +void +cat(int fd) +{ + 78: e92d4818 push {r3, r4, fp, lr} + 7c: e1a04000 mov r4, r0 + 80: e28db00c add fp, sp, #12 + int n; + while((n = read(fd, buf, sizeof(buf))) > 0) + 84: ea000002 b 94 + write(1, buf, n); + 88: e3a00001 mov r0, #1 + 8c: e59f102c ldr r1, [pc, #44] ; c0 + 90: eb0000e8 bl 438 + +void +cat(int fd) +{ + int n; + while((n = read(fd, buf, sizeof(buf))) > 0) + 94: e3a02c02 mov r2, #512 ; 0x200 + 98: e1a00004 mov r0, r4 + 9c: e59f101c ldr r1, [pc, #28] ; c0 + a0: eb0000d7 bl 404 + a4: e2502000 subs r2, r0, #0 + a8: cafffff6 bgt 88 + write(1, buf, n); + if(n < 0){ + ac: 08bd8818 popeq {r3, r4, fp, pc} + printf(1, "cat: read error\n"); + b0: e3a00001 mov r0, #1 + b4: e59f1008 ldr r1, [pc, #8] ; c4 + b8: eb0001fd bl 8b4 + exit(); + bc: eb0000a9 bl 368 + c0: 00000bf0 .word 0x00000bf0 + c4: 00000b9c .word 0x00000b9c + +000000c8 : +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + c8: e52db004 push {fp} ; (str fp, [sp, #-4]!) + char *os; + + os = s; + while((*s++ = *t++) != 0) + cc: e1a02000 mov r2, r0 +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + d0: e28db000 add fp, sp, #0 + char *os; + + os = s; + while((*s++ = *t++) != 0) + d4: e4d13001 ldrb r3, [r1], #1 + d8: e3530000 cmp r3, #0 + dc: e4c23001 strb r3, [r2], #1 + e0: 1afffffb bne d4 + ; + return os; +} + e4: e28bd000 add sp, fp, #0 + e8: e8bd0800 pop {fp} + ec: e12fff1e bx lr + +000000f0 : + +int +strcmp(const char *p, const char *q) +{ + f0: e52db004 push {fp} ; (str fp, [sp, #-4]!) + f4: e28db000 add fp, sp, #0 + while(*p && *p == *q) + f8: e5d03000 ldrb r3, [r0] + fc: e5d12000 ldrb r2, [r1] + 100: e3530000 cmp r3, #0 + 104: 1a000004 bne 11c + 108: ea000005 b 124 + 10c: e5f03001 ldrb r3, [r0, #1]! + 110: e3530000 cmp r3, #0 + 114: 0a000006 beq 134 + 118: e5f12001 ldrb r2, [r1, #1]! + 11c: e1530002 cmp r3, r2 + 120: 0afffff9 beq 10c + p++, q++; + return (uchar)*p - (uchar)*q; +} + 124: e0620003 rsb r0, r2, r3 + 128: e28bd000 add sp, fp, #0 + 12c: e8bd0800 pop {fp} + 130: e12fff1e bx lr +} + +int +strcmp(const char *p, const char *q) +{ + while(*p && *p == *q) + 134: e5d12001 ldrb r2, [r1, #1] + 138: eafffff9 b 124 + +0000013c : + return (uchar)*p - (uchar)*q; +} + +uint +strlen(char *s) +{ + 13c: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 140: e28db000 add fp, sp, #0 + int n; + + for(n = 0; s[n]; n++) + 144: e5d03000 ldrb r3, [r0] + 148: e3530000 cmp r3, #0 + 14c: 01a00003 moveq r0, r3 + 150: 0a000006 beq 170 + 154: e1a02000 mov r2, r0 + 158: e3a03000 mov r3, #0 + 15c: e5f21001 ldrb r1, [r2, #1]! + 160: e2833001 add r3, r3, #1 + 164: e1a00003 mov r0, r3 + 168: e3510000 cmp r1, #0 + 16c: 1afffffa bne 15c + ; + return n; +} + 170: e28bd000 add sp, fp, #0 + 174: e8bd0800 pop {fp} + 178: e12fff1e bx lr + +0000017c : +memset(void *dst, int c, uint n) +{ + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 17c: e3520000 cmp r2, #0 + return n; +} + +void* +memset(void *dst, int c, uint n) +{ + 180: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 184: e28db000 add fp, sp, #0 + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 188: 0a000006 beq 1a8 + 18c: e6ef1071 uxtb r1, r1 + 190: e1a03002 mov r3, r2 +} + +void* +memset(void *dst, int c, uint n) +{ + char *p=dst; + 194: e1a0c000 mov ip, r0 + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 198: e2533001 subs r3, r3, #1 + 19c: e4cc1001 strb r1, [ip], #1 + 1a0: 1afffffc bne 198 + 1a4: e0800002 add r0, r0, r2 + return (void *)p; +} + 1a8: e28bd000 add sp, fp, #0 + 1ac: e8bd0800 pop {fp} + 1b0: e12fff1e bx lr + +000001b4 : + +char* +strchr(const char *s, char c) +{ + 1b4: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 1b8: e28db000 add fp, sp, #0 + for(; *s; s++) + 1bc: e5d03000 ldrb r3, [r0] + 1c0: e3530000 cmp r3, #0 + 1c4: 1a000004 bne 1dc + 1c8: ea000008 b 1f0 + 1cc: e5d03001 ldrb r3, [r0, #1] + 1d0: e2800001 add r0, r0, #1 + 1d4: e3530000 cmp r3, #0 + 1d8: 0a000004 beq 1f0 + if(*s == c) + 1dc: e1530001 cmp r3, r1 + 1e0: 1afffff9 bne 1cc + return (char*)s; + return 0; +} + 1e4: e28bd000 add sp, fp, #0 + 1e8: e8bd0800 pop {fp} + 1ec: e12fff1e bx lr +strchr(const char *s, char c) +{ + for(; *s; s++) + if(*s == c) + return (char*)s; + return 0; + 1f0: e1a00003 mov r0, r3 + 1f4: eafffffa b 1e4 + +000001f8 : +} + +char* +gets(char *buf, int max) +{ + 1f8: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + 1fc: e28db018 add fp, sp, #24 + 200: e24dd00c sub sp, sp, #12 + 204: e1a08000 mov r8, r0 + 208: e1a07001 mov r7, r1 + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 20c: e1a06000 mov r6, r0 + 210: e3a05000 mov r5, #0 + 214: ea000008 b 23c + cc = read(0, &c, 1); + 218: eb000079 bl 404 + if(cc < 1) + 21c: e3500000 cmp r0, #0 + 220: da00000b ble 254 + break; + buf[i++] = c; + 224: e55b301d ldrb r3, [fp, #-29] + if(c == '\n' || c == '\r') + 228: e1a05004 mov r5, r4 + 22c: e353000a cmp r3, #10 + 230: 1353000d cmpne r3, #13 + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + if(cc < 1) + break; + buf[i++] = c; + 234: e4c63001 strb r3, [r6], #1 + if(c == '\n' || c == '\r') + 238: 0a00000a beq 268 +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + 23c: e3a02001 mov r2, #1 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 240: e0854002 add r4, r5, r2 + 244: e1540007 cmp r4, r7 + cc = read(0, &c, 1); + 248: e3a00000 mov r0, #0 + 24c: e24b101d sub r1, fp, #29 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 250: bafffff0 blt 218 + break; + buf[i++] = c; + if(c == '\n' || c == '\r') + break; + } + buf[i] = '\0'; + 254: e3a03000 mov r3, #0 + 258: e7c83005 strb r3, [r8, r5] + return buf; +} + 25c: e1a00008 mov r0, r8 + 260: e24bd018 sub sp, fp, #24 + 264: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 268: e1a05004 mov r5, r4 + 26c: eafffff8 b 254 + +00000270 : + return buf; +} + +int +stat(char *n, struct stat *st) +{ + 270: e92d4830 push {r4, r5, fp, lr} + 274: e1a05001 mov r5, r1 + 278: e28db00c add fp, sp, #12 + int fd; + int r; + + fd = open(n, O_RDONLY); + 27c: e3a01000 mov r1, #0 + 280: eb0000a0 bl 508 + if(fd < 0) + 284: e2504000 subs r4, r0, #0 + return -1; + 288: b3e05000 mvnlt r5, #0 +{ + int fd; + int r; + + fd = open(n, O_RDONLY); + if(fd < 0) + 28c: ba000004 blt 2a4 + return -1; + r = fstat(fd, st); + 290: e1a01005 mov r1, r5 + 294: eb0000c2 bl 5a4 + 298: e1a05000 mov r5, r0 + close(fd); + 29c: e1a00004 mov r0, r4 + 2a0: eb000071 bl 46c + return r; +} + 2a4: e1a00005 mov r0, r5 + 2a8: e8bd8830 pop {r4, r5, fp, pc} + +000002ac : + +int +atoi(const char *s) +{ + 2ac: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 2b0: e28db000 add fp, sp, #0 + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 2b4: e5d03000 ldrb r3, [r0] + 2b8: e2432030 sub r2, r3, #48 ; 0x30 + 2bc: e6ef2072 uxtb r2, r2 + 2c0: e3520009 cmp r2, #9 +int +atoi(const char *s) +{ + int n; + + n = 0; + 2c4: 83a00000 movhi r0, #0 + while('0' <= *s && *s <= '9') + 2c8: 8a000009 bhi 2f4 + 2cc: e1a02000 mov r2, r0 +int +atoi(const char *s) +{ + int n; + + n = 0; + 2d0: e3a00000 mov r0, #0 + while('0' <= *s && *s <= '9') + n = n*10 + *s++ - '0'; + 2d4: e0800100 add r0, r0, r0, lsl #2 + 2d8: e0830080 add r0, r3, r0, lsl #1 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 2dc: e5f23001 ldrb r3, [r2, #1]! + n = n*10 + *s++ - '0'; + 2e0: e2400030 sub r0, r0, #48 ; 0x30 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 2e4: e2431030 sub r1, r3, #48 ; 0x30 + 2e8: e6ef1071 uxtb r1, r1 + 2ec: e3510009 cmp r1, #9 + 2f0: 9afffff7 bls 2d4 + n = n*10 + *s++ - '0'; + return n; +} + 2f4: e28bd000 add sp, fp, #0 + 2f8: e8bd0800 pop {fp} + 2fc: e12fff1e bx lr + +00000300 : +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 300: e3520000 cmp r2, #0 + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) +{ + 304: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 308: e28db000 add fp, sp, #0 + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 30c: da000005 ble 328 + n = n*10 + *s++ - '0'; + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) + 310: e0802002 add r2, r0, r2 +{ + char *dst, *src; + + dst = vdst; + 314: e1a03000 mov r3, r0 + src = vsrc; + while(n-- > 0) + *dst++ = *src++; + 318: e4d1c001 ldrb ip, [r1], #1 + 31c: e4c3c001 strb ip, [r3], #1 +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 320: e1530002 cmp r3, r2 + 324: 1afffffb bne 318 + *dst++ = *src++; + return vdst; +} + 328: e28bd000 add sp, fp, #0 + 32c: e8bd0800 pop {fp} + 330: e12fff1e bx lr + +00000334 : + 334: e92d4000 push {lr} + 338: e92d0008 push {r3} + 33c: e92d0004 push {r2} + 340: e92d0002 push {r1} + 344: e92d0001 push {r0} + 348: e3a00001 mov r0, #1 + 34c: ef000040 svc 0x00000040 + 350: e8bd0002 pop {r1} + 354: e8bd0002 pop {r1} + 358: e8bd0004 pop {r2} + 35c: e8bd0008 pop {r3} + 360: e8bd4000 pop {lr} + 364: e12fff1e bx lr + +00000368 : + 368: e92d4000 push {lr} + 36c: e92d0008 push {r3} + 370: e92d0004 push {r2} + 374: e92d0002 push {r1} + 378: e92d0001 push {r0} + 37c: e3a00002 mov r0, #2 + 380: ef000040 svc 0x00000040 + 384: e8bd0002 pop {r1} + 388: e8bd0002 pop {r1} + 38c: e8bd0004 pop {r2} + 390: e8bd0008 pop {r3} + 394: e8bd4000 pop {lr} + 398: e12fff1e bx lr + +0000039c : + 39c: e92d4000 push {lr} + 3a0: e92d0008 push {r3} + 3a4: e92d0004 push {r2} + 3a8: e92d0002 push {r1} + 3ac: e92d0001 push {r0} + 3b0: e3a00003 mov r0, #3 + 3b4: ef000040 svc 0x00000040 + 3b8: e8bd0002 pop {r1} + 3bc: e8bd0002 pop {r1} + 3c0: e8bd0004 pop {r2} + 3c4: e8bd0008 pop {r3} + 3c8: e8bd4000 pop {lr} + 3cc: e12fff1e bx lr + +000003d0 : + 3d0: e92d4000 push {lr} + 3d4: e92d0008 push {r3} + 3d8: e92d0004 push {r2} + 3dc: e92d0002 push {r1} + 3e0: e92d0001 push {r0} + 3e4: e3a00004 mov r0, #4 + 3e8: ef000040 svc 0x00000040 + 3ec: e8bd0002 pop {r1} + 3f0: e8bd0002 pop {r1} + 3f4: e8bd0004 pop {r2} + 3f8: e8bd0008 pop {r3} + 3fc: e8bd4000 pop {lr} + 400: e12fff1e bx lr + +00000404 : + 404: e92d4000 push {lr} + 408: e92d0008 push {r3} + 40c: e92d0004 push {r2} + 410: e92d0002 push {r1} + 414: e92d0001 push {r0} + 418: e3a00005 mov r0, #5 + 41c: ef000040 svc 0x00000040 + 420: e8bd0002 pop {r1} + 424: e8bd0002 pop {r1} + 428: e8bd0004 pop {r2} + 42c: e8bd0008 pop {r3} + 430: e8bd4000 pop {lr} + 434: e12fff1e bx lr + +00000438 : + 438: e92d4000 push {lr} + 43c: e92d0008 push {r3} + 440: e92d0004 push {r2} + 444: e92d0002 push {r1} + 448: e92d0001 push {r0} + 44c: e3a00010 mov r0, #16 + 450: ef000040 svc 0x00000040 + 454: e8bd0002 pop {r1} + 458: e8bd0002 pop {r1} + 45c: e8bd0004 pop {r2} + 460: e8bd0008 pop {r3} + 464: e8bd4000 pop {lr} + 468: e12fff1e bx lr + +0000046c : + 46c: e92d4000 push {lr} + 470: e92d0008 push {r3} + 474: e92d0004 push {r2} + 478: e92d0002 push {r1} + 47c: e92d0001 push {r0} + 480: e3a00015 mov r0, #21 + 484: ef000040 svc 0x00000040 + 488: e8bd0002 pop {r1} + 48c: e8bd0002 pop {r1} + 490: e8bd0004 pop {r2} + 494: e8bd0008 pop {r3} + 498: e8bd4000 pop {lr} + 49c: e12fff1e bx lr + +000004a0 : + 4a0: e92d4000 push {lr} + 4a4: e92d0008 push {r3} + 4a8: e92d0004 push {r2} + 4ac: e92d0002 push {r1} + 4b0: e92d0001 push {r0} + 4b4: e3a00006 mov r0, #6 + 4b8: ef000040 svc 0x00000040 + 4bc: e8bd0002 pop {r1} + 4c0: e8bd0002 pop {r1} + 4c4: e8bd0004 pop {r2} + 4c8: e8bd0008 pop {r3} + 4cc: e8bd4000 pop {lr} + 4d0: e12fff1e bx lr + +000004d4 : + 4d4: e92d4000 push {lr} + 4d8: e92d0008 push {r3} + 4dc: e92d0004 push {r2} + 4e0: e92d0002 push {r1} + 4e4: e92d0001 push {r0} + 4e8: e3a00007 mov r0, #7 + 4ec: ef000040 svc 0x00000040 + 4f0: e8bd0002 pop {r1} + 4f4: e8bd0002 pop {r1} + 4f8: e8bd0004 pop {r2} + 4fc: e8bd0008 pop {r3} + 500: e8bd4000 pop {lr} + 504: e12fff1e bx lr + +00000508 : + 508: e92d4000 push {lr} + 50c: e92d0008 push {r3} + 510: e92d0004 push {r2} + 514: e92d0002 push {r1} + 518: e92d0001 push {r0} + 51c: e3a0000f mov r0, #15 + 520: ef000040 svc 0x00000040 + 524: e8bd0002 pop {r1} + 528: e8bd0002 pop {r1} + 52c: e8bd0004 pop {r2} + 530: e8bd0008 pop {r3} + 534: e8bd4000 pop {lr} + 538: e12fff1e bx lr + +0000053c : + 53c: e92d4000 push {lr} + 540: e92d0008 push {r3} + 544: e92d0004 push {r2} + 548: e92d0002 push {r1} + 54c: e92d0001 push {r0} + 550: e3a00011 mov r0, #17 + 554: ef000040 svc 0x00000040 + 558: e8bd0002 pop {r1} + 55c: e8bd0002 pop {r1} + 560: e8bd0004 pop {r2} + 564: e8bd0008 pop {r3} + 568: e8bd4000 pop {lr} + 56c: e12fff1e bx lr + +00000570 : + 570: e92d4000 push {lr} + 574: e92d0008 push {r3} + 578: e92d0004 push {r2} + 57c: e92d0002 push {r1} + 580: e92d0001 push {r0} + 584: e3a00012 mov r0, #18 + 588: ef000040 svc 0x00000040 + 58c: e8bd0002 pop {r1} + 590: e8bd0002 pop {r1} + 594: e8bd0004 pop {r2} + 598: e8bd0008 pop {r3} + 59c: e8bd4000 pop {lr} + 5a0: e12fff1e bx lr + +000005a4 : + 5a4: e92d4000 push {lr} + 5a8: e92d0008 push {r3} + 5ac: e92d0004 push {r2} + 5b0: e92d0002 push {r1} + 5b4: e92d0001 push {r0} + 5b8: e3a00008 mov r0, #8 + 5bc: ef000040 svc 0x00000040 + 5c0: e8bd0002 pop {r1} + 5c4: e8bd0002 pop {r1} + 5c8: e8bd0004 pop {r2} + 5cc: e8bd0008 pop {r3} + 5d0: e8bd4000 pop {lr} + 5d4: e12fff1e bx lr + +000005d8 : + 5d8: e92d4000 push {lr} + 5dc: e92d0008 push {r3} + 5e0: e92d0004 push {r2} + 5e4: e92d0002 push {r1} + 5e8: e92d0001 push {r0} + 5ec: e3a00013 mov r0, #19 + 5f0: ef000040 svc 0x00000040 + 5f4: e8bd0002 pop {r1} + 5f8: e8bd0002 pop {r1} + 5fc: e8bd0004 pop {r2} + 600: e8bd0008 pop {r3} + 604: e8bd4000 pop {lr} + 608: e12fff1e bx lr + +0000060c : + 60c: e92d4000 push {lr} + 610: e92d0008 push {r3} + 614: e92d0004 push {r2} + 618: e92d0002 push {r1} + 61c: e92d0001 push {r0} + 620: e3a00014 mov r0, #20 + 624: ef000040 svc 0x00000040 + 628: e8bd0002 pop {r1} + 62c: e8bd0002 pop {r1} + 630: e8bd0004 pop {r2} + 634: e8bd0008 pop {r3} + 638: e8bd4000 pop {lr} + 63c: e12fff1e bx lr + +00000640 : + 640: e92d4000 push {lr} + 644: e92d0008 push {r3} + 648: e92d0004 push {r2} + 64c: e92d0002 push {r1} + 650: e92d0001 push {r0} + 654: e3a00009 mov r0, #9 + 658: ef000040 svc 0x00000040 + 65c: e8bd0002 pop {r1} + 660: e8bd0002 pop {r1} + 664: e8bd0004 pop {r2} + 668: e8bd0008 pop {r3} + 66c: e8bd4000 pop {lr} + 670: e12fff1e bx lr + +00000674 : + 674: e92d4000 push {lr} + 678: e92d0008 push {r3} + 67c: e92d0004 push {r2} + 680: e92d0002 push {r1} + 684: e92d0001 push {r0} + 688: e3a0000a mov r0, #10 + 68c: ef000040 svc 0x00000040 + 690: e8bd0002 pop {r1} + 694: e8bd0002 pop {r1} + 698: e8bd0004 pop {r2} + 69c: e8bd0008 pop {r3} + 6a0: e8bd4000 pop {lr} + 6a4: e12fff1e bx lr + +000006a8 : + 6a8: e92d4000 push {lr} + 6ac: e92d0008 push {r3} + 6b0: e92d0004 push {r2} + 6b4: e92d0002 push {r1} + 6b8: e92d0001 push {r0} + 6bc: e3a0000b mov r0, #11 + 6c0: ef000040 svc 0x00000040 + 6c4: e8bd0002 pop {r1} + 6c8: e8bd0002 pop {r1} + 6cc: e8bd0004 pop {r2} + 6d0: e8bd0008 pop {r3} + 6d4: e8bd4000 pop {lr} + 6d8: e12fff1e bx lr + +000006dc : + 6dc: e92d4000 push {lr} + 6e0: e92d0008 push {r3} + 6e4: e92d0004 push {r2} + 6e8: e92d0002 push {r1} + 6ec: e92d0001 push {r0} + 6f0: e3a0000c mov r0, #12 + 6f4: ef000040 svc 0x00000040 + 6f8: e8bd0002 pop {r1} + 6fc: e8bd0002 pop {r1} + 700: e8bd0004 pop {r2} + 704: e8bd0008 pop {r3} + 708: e8bd4000 pop {lr} + 70c: e12fff1e bx lr + +00000710 : + 710: e92d4000 push {lr} + 714: e92d0008 push {r3} + 718: e92d0004 push {r2} + 71c: e92d0002 push {r1} + 720: e92d0001 push {r0} + 724: e3a0000d mov r0, #13 + 728: ef000040 svc 0x00000040 + 72c: e8bd0002 pop {r1} + 730: e8bd0002 pop {r1} + 734: e8bd0004 pop {r2} + 738: e8bd0008 pop {r3} + 73c: e8bd4000 pop {lr} + 740: e12fff1e bx lr + +00000744 : + 744: e92d4000 push {lr} + 748: e92d0008 push {r3} + 74c: e92d0004 push {r2} + 750: e92d0002 push {r1} + 754: e92d0001 push {r0} + 758: e3a0000e mov r0, #14 + 75c: ef000040 svc 0x00000040 + 760: e8bd0002 pop {r1} + 764: e8bd0002 pop {r1} + 768: e8bd0004 pop {r2} + 76c: e8bd0008 pop {r3} + 770: e8bd4000 pop {lr} + 774: e12fff1e bx lr + +00000778 : +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 778: e92d4800 push {fp, lr} + 77c: e28db004 add fp, sp, #4 + 780: e24b3004 sub r3, fp, #4 + 784: e24dd008 sub sp, sp, #8 + write(fd, &c, 1); + 788: e3a02001 mov r2, #1 +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 78c: e5631001 strb r1, [r3, #-1]! + write(fd, &c, 1); + 790: e1a01003 mov r1, r3 + 794: ebffff27 bl 438 +} + 798: e24bd004 sub sp, fp, #4 + 79c: e8bd8800 pop {fp, pc} + +000007a0 : + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 7a0: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 7a4: e1a04000 mov r4, r0 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 7a8: e1a00fa1 lsr r0, r1, #31 + 7ac: e3530000 cmp r3, #0 + 7b0: 03a03000 moveq r3, #0 + 7b4: 12003001 andne r3, r0, #1 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 7b8: e28db020 add fp, sp, #32 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 7bc: e3530000 cmp r3, #0 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 7c0: e24dd014 sub sp, sp, #20 + 7c4: e59f909c ldr r9, [pc, #156] ; 868 + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + x = -xx; + 7c8: 12611000 rsbne r1, r1, #0 + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + 7cc: 13a03001 movne r3, #1 + } else { + x = xx; + } + + b = base; + i = 0; + 7d0: e3a0a000 mov sl, #0 + 7d4: e24b6034 sub r6, fp, #52 ; 0x34 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 7d8: e3a08001 mov r8, #1 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 7dc: e3a07000 mov r7, #0 + int i; + + for(i=31;i>=0;i--){ + 7e0: e3a0001f mov r0, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 7e4: e1a0c007 mov ip, r7 + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 7e8: e1a0e031 lsr lr, r1, r0 + 7ec: e20ee001 and lr, lr, #1 + 7f0: e18ec08c orr ip, lr, ip, lsl #1 + if(r >= d) { + 7f4: e152000c cmp r2, ip + r = r - d; + q = q | (1 << i); + 7f8: 91877018 orrls r7, r7, r8, lsl r0 + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 7fc: 9062c00c rsbls ip, r2, ip +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 800: e2500001 subs r0, r0, #1 + 804: 2afffff7 bcs 7e8 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 808: e0000792 mul r0, r2, r7 + }while((x = y) != 0); + 80c: e3570000 cmp r7, #0 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 810: e0601001 rsb r1, r0, r1 + 814: e28a5001 add r5, sl, #1 + 818: e7d91001 ldrb r1, [r9, r1] + 81c: e7c6100a strb r1, [r6, sl] + }while((x = y) != 0); + 820: 11a01007 movne r1, r7 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 824: 11a0a005 movne sl, r5 + 828: 1affffeb bne 7dc + }while((x = y) != 0); + if(neg) + 82c: e3530000 cmp r3, #0 + buf[i++] = '-'; + 830: 124b2024 subne r2, fp, #36 ; 0x24 + 834: 10823005 addne r3, r2, r5 + 838: 128a5002 addne r5, sl, #2 + + while(--i >= 0) + 83c: e2455001 sub r5, r5, #1 + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + 840: 13a0202d movne r2, #45 ; 0x2d + 844: 15432010 strbne r2, [r3, #-16] + + while(--i >= 0) + putc(fd, buf[i]); + 848: e7d61005 ldrb r1, [r6, r5] + 84c: e1a00004 mov r0, r4 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 850: e2455001 sub r5, r5, #1 + putc(fd, buf[i]); + 854: ebffffc7 bl 778 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 858: e3750001 cmn r5, #1 + 85c: 1afffff9 bne 848 + putc(fd, buf[i]); +} + 860: e24bd020 sub sp, fp, #32 + 864: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} + 868: 00000bc8 .word 0x00000bc8 + +0000086c
: + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 86c: e3a03000 mov r3, #0 +{ + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + 870: e92d0830 push {r4, r5, fp} + 874: e1a02000 mov r2, r0 + 878: e28db008 add fp, sp, #8 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 87c: e3a0c01f mov ip, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 880: e1a00003 mov r0, r3 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 884: e3a05001 mov r5, #1 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 888: e1a04c32 lsr r4, r2, ip + 88c: e2044001 and r4, r4, #1 + 890: e1843083 orr r3, r4, r3, lsl #1 + if(r >= d) { + 894: e1530001 cmp r3, r1 + r = r - d; + q = q | (1 << i); + 898: 21800c15 orrcs r0, r0, r5, lsl ip + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 89c: 20613003 rsbcs r3, r1, r3 +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 8a0: e25cc001 subs ip, ip, #1 + 8a4: 2afffff7 bcs 888 + r = r - d; + q = q | (1 << i); + } + } + return q; +} + 8a8: e24bd008 sub sp, fp, #8 + 8ac: e8bd0830 pop {r4, r5, fp} + 8b0: e12fff1e bx lr + +000008b4 : +} + +// Print to the given fd. Only understands %d, %x, %p, %s. +void +printf(int fd, char *fmt, ...) +{ + 8b4: e92d000e push {r1, r2, r3} + 8b8: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 8bc: e28db020 add fp, sp, #32 + 8c0: e1a05000 mov r5, r0 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 8c4: e59b4004 ldr r4, [fp, #4] + 8c8: e5d48000 ldrb r8, [r4] + 8cc: e3580000 cmp r8, #0 + 8d0: 0a000027 beq 974 + ap++; + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + 8d4: e59f712c ldr r7, [pc, #300] ; a08 + char *s; + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + 8d8: e28b6008 add r6, fp, #8 +{ + char *s; + int c, i, state; + uint *ap; + + state = 0; + 8dc: e3a0a000 mov sl, #0 + 8e0: ea000008 b 908 + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 8e4: e3580025 cmp r8, #37 ; 0x25 + state = '%'; + 8e8: 01a0a008 moveq sl, r8 + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 8ec: 0a000002 beq 8fc + state = '%'; + } else { + putc(fd, c); + 8f0: e1a00005 mov r0, r5 + 8f4: e1a01008 mov r1, r8 + 8f8: ebffff9e bl 778 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 8fc: e5f48001 ldrb r8, [r4, #1]! + 900: e3580000 cmp r8, #0 + 904: 0a00001a beq 974 + c = fmt[i] & 0xff; + if(state == 0){ + 908: e35a0000 cmp sl, #0 + 90c: 0afffff4 beq 8e4 + if(c == '%'){ + state = '%'; + } else { + putc(fd, c); + } + } else if(state == '%'){ + 910: e35a0025 cmp sl, #37 ; 0x25 + 914: 1afffff8 bne 8fc + if(c == 'd'){ + 918: e3580064 cmp r8, #100 ; 0x64 + 91c: 0a00002c beq 9d4 + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + 920: e3580078 cmp r8, #120 ; 0x78 + 924: 13580070 cmpne r8, #112 ; 0x70 + 928: 13a09000 movne r9, #0 + 92c: 03a09001 moveq r9, #1 + 930: 0a000013 beq 984 + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + 934: e3580073 cmp r8, #115 ; 0x73 + 938: 0a000018 beq 9a0 + s = "(null)"; + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + 93c: e3580063 cmp r8, #99 ; 0x63 + 940: 0a00002a beq 9f0 + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 944: e3580025 cmp r8, #37 ; 0x25 + putc(fd, c); + 948: e1a0100a mov r1, sl + 94c: e1a00005 mov r0, r5 + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 950: 0a000002 beq 960 + putc(fd, c); + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + 954: ebffff87 bl 778 + putc(fd, c); + 958: e1a00005 mov r0, r5 + 95c: e1a01008 mov r1, r8 + 960: ebffff84 bl 778 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 964: e5f48001 ldrb r8, [r4, #1]! + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 968: e1a0a009 mov sl, r9 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 96c: e3580000 cmp r8, #0 + 970: 1affffe4 bne 908 + putc(fd, c); + } + state = 0; + } + } +} + 974: e24bd020 sub sp, fp, #32 + 978: e8bd4ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 97c: e28dd00c add sp, sp, #12 + 980: e12fff1e bx lr + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + 984: e1a00005 mov r0, r5 + 988: e4961004 ldr r1, [r6], #4 + 98c: e3a02010 mov r2, #16 + 990: e3a03000 mov r3, #0 + 994: ebffff81 bl 7a0 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 998: e3a0a000 mov sl, #0 + 99c: eaffffd6 b 8fc + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + s = (char*)*ap; + 9a0: e4968004 ldr r8, [r6], #4 + ap++; + if(s == 0) + s = "(null)"; + 9a4: e3580000 cmp r8, #0 + 9a8: 01a08007 moveq r8, r7 + while(*s != 0){ + 9ac: e5d81000 ldrb r1, [r8] + 9b0: e3510000 cmp r1, #0 + 9b4: 0a000004 beq 9cc + putc(fd, *s); + 9b8: e1a00005 mov r0, r5 + 9bc: ebffff6d bl 778 + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + while(*s != 0){ + 9c0: e5f81001 ldrb r1, [r8, #1]! + 9c4: e3510000 cmp r1, #0 + 9c8: 1afffffa bne 9b8 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 9cc: e1a0a001 mov sl, r1 + 9d0: eaffffc9 b 8fc + } else { + putc(fd, c); + } + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + 9d4: e1a00005 mov r0, r5 + 9d8: e4961004 ldr r1, [r6], #4 + 9dc: e3a0200a mov r2, #10 + 9e0: e3a03001 mov r3, #1 + 9e4: ebffff6d bl 7a0 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 9e8: e3a0a000 mov sl, #0 + 9ec: eaffffc2 b 8fc + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 9f0: e4961004 ldr r1, [r6], #4 + 9f4: e1a00005 mov r0, r5 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 9f8: e1a0a009 mov sl, r9 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 9fc: e6ef1071 uxtb r1, r1 + a00: ebffff5c bl 778 + a04: eaffffbc b 8fc + a08: 00000bdc .word 0x00000bdc + +00000a0c : +free(void *ap) +{ + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + a0c: e59f3098 ldr r3, [pc, #152] ; aac +static Header base; +static Header *freep; + +void +free(void *ap) +{ + a10: e92d0830 push {r4, r5, fp} + Header *bp, *p; + + bp = (Header*)ap - 1; + a14: e240c008 sub ip, r0, #8 + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + a18: e5932000 ldr r2, [r3] +static Header base; +static Header *freep; + +void +free(void *ap) +{ + a1c: e28db008 add fp, sp, #8 + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + a20: e152000c cmp r2, ip + a24: e5921000 ldr r1, [r2] + a28: 2a000001 bcs a34 + a2c: e15c0001 cmp ip, r1 + a30: 3a000007 bcc a54 + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + a34: e1520001 cmp r2, r1 + a38: 3a000003 bcc a4c + a3c: e152000c cmp r2, ip + a40: 3a000003 bcc a54 + a44: e15c0001 cmp ip, r1 + a48: 3a000001 bcc a54 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + a4c: e1a02001 mov r2, r1 + a50: eafffff2 b a20 + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + a54: e5104004 ldr r4, [r0, #-4] + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + freep = p; + a58: e5832000 str r2, [r3] + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + a5c: e08c5184 add r5, ip, r4, lsl #3 + a60: e1550001 cmp r5, r1 + bp->s.size += p->s.ptr->s.size; + a64: 05911004 ldreq r1, [r1, #4] + a68: 00814004 addeq r4, r1, r4 + a6c: 05004004 streq r4, [r0, #-4] + bp->s.ptr = p->s.ptr->s.ptr; + a70: 05921000 ldreq r1, [r2] + a74: 05911000 ldreq r1, [r1] + } else + bp->s.ptr = p->s.ptr; + a78: e5001008 str r1, [r0, #-8] + if(p + p->s.size == bp){ + a7c: e5921004 ldr r1, [r2, #4] + a80: e0824181 add r4, r2, r1, lsl #3 + a84: e15c0004 cmp ip, r4 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + a88: 1582c000 strne ip, [r2] + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + } else + bp->s.ptr = p->s.ptr; + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + a8c: 0510c004 ldreq ip, [r0, #-4] + a90: 008c1001 addeq r1, ip, r1 + a94: 05821004 streq r1, [r2, #4] + p->s.ptr = bp->s.ptr; + a98: 05101008 ldreq r1, [r0, #-8] + a9c: 05821000 streq r1, [r2] + } else + p->s.ptr = bp; + freep = p; +} + aa0: e24bd008 sub sp, fp, #8 + aa4: e8bd0830 pop {r4, r5, fp} + aa8: e12fff1e bx lr + aac: 00000be4 .word 0x00000be4 + +00000ab0 : + return freep; +} + +void* +malloc(uint nbytes) +{ + ab0: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + ab4: e2804007 add r4, r0, #7 + if((prevp = freep) == 0){ + ab8: e59f50d4 ldr r5, [pc, #212] ; b94 +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + abc: e1a041a4 lsr r4, r4, #3 + return freep; +} + +void* +malloc(uint nbytes) +{ + ac0: e28db01c add fp, sp, #28 + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + ac4: e5953000 ldr r3, [r5] +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + ac8: e2844001 add r4, r4, #1 + if((prevp = freep) == 0){ + acc: e3530000 cmp r3, #0 + ad0: 0a00002b beq b84 + ad4: e5930000 ldr r0, [r3] + ad8: e5902004 ldr r2, [r0, #4] + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + adc: e1520004 cmp r2, r4 + ae0: 2a00001b bcs b54 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + ae4: e59f80ac ldr r8, [pc, #172] ; b98 + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + ae8: e1a07184 lsl r7, r4, #3 + aec: ea000003 b b00 + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + af0: e5930000 ldr r0, [r3] + if(p->s.size >= nunits){ + af4: e5902004 ldr r2, [r0, #4] + af8: e1540002 cmp r4, r2 + afc: 9a000014 bls b54 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + b00: e5952000 ldr r2, [r5] + b04: e1a03000 mov r3, r0 + b08: e1500002 cmp r0, r2 + b0c: 1afffff7 bne af0 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + b10: e1540008 cmp r4, r8 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + b14: 81a00007 movhi r0, r7 + b18: 93a00902 movls r0, #32768 ; 0x8000 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + b1c: 81a06004 movhi r6, r4 + b20: 93a06a01 movls r6, #4096 ; 0x1000 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + b24: ebfffeec bl 6dc + b28: e1a03000 mov r3, r0 + if(p == (char*)-1) + b2c: e3730001 cmn r3, #1 + return 0; + hp = (Header*)p; + hp->s.size = nu; + free((void*)(hp + 1)); + b30: e2800008 add r0, r0, #8 + Header *hp; + + if(nu < 4096) + nu = 4096; + p = sbrk(nu * sizeof(Header)); + if(p == (char*)-1) + b34: 0a000010 beq b7c + return 0; + hp = (Header*)p; + hp->s.size = nu; + b38: e5836004 str r6, [r3, #4] + free((void*)(hp + 1)); + b3c: ebffffb2 bl a0c + return freep; + b40: e5953000 ldr r3, [r5] + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + if((p = morecore(nunits)) == 0) + b44: e3530000 cmp r3, #0 + b48: 1affffe8 bne af0 + return 0; + b4c: e1a00003 mov r0, r3 + } +} + b50: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + b54: e1540002 cmp r4, r2 + prevp->s.ptr = p->s.ptr; + else { + p->s.size -= nunits; + b58: 10642002 rsbne r2, r4, r2 + b5c: 15802004 strne r2, [r0, #4] + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + b60: 05902000 ldreq r2, [r0] + else { + p->s.size -= nunits; + p += p->s.size; + b64: 10800182 addne r0, r0, r2, lsl #3 + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + b68: 05832000 streq r2, [r3] + else { + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + b6c: 15804004 strne r4, [r0, #4] + } + freep = prevp; + b70: e5853000 str r3, [r5] + return (void*)(p + 1); + b74: e2800008 add r0, r0, #8 + b78: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + } + if(p == freep) + if((p = morecore(nunits)) == 0) + return 0; + b7c: e3a00000 mov r0, #0 + b80: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + b84: e2850004 add r0, r5, #4 + b88: e5850000 str r0, [r5] + base.s.size = 0; + b8c: e9850009 stmib r5, {r0, r3} + b90: eaffffd3 b ae4 + b94: 00000be4 .word 0x00000be4 + b98: 00000fff .word 0x00000fff diff -r 000000000000 -r c450faca55f4 uprogs/cat.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/cat.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,38 @@ +#include "types.h" +#include "stat.h" +#include "user.h" + +char buf[512]; + +void +cat(int fd) +{ + int n; + while((n = read(fd, buf, sizeof(buf))) > 0) + write(1, buf, n); + if(n < 0){ + printf(1, "cat: read error\n"); + exit(); + } +} + +int +main(int argc, char *argv[]) +{ + int fd, i; + + if(argc <= 1){ + cat(0); + exit(); + } + + for(i = 1; i < argc; i++){ + if((fd = open(argv[i], 0)) < 0){ + printf(1, "cat: cannot open %s\n", argv[i]); + exit(); + } + cat(fd); + close(fd); + } + exit(); +} diff -r 000000000000 -r c450faca55f4 uprogs/cat.sym --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/cat.sym Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,66 @@ +00000000 .text +00000b9c .rodata +00000be4 .bss +00000000 .comment +00000000 .ARM.attributes +00000000 .debug_aranges +00000000 .debug_info +00000000 .debug_abbrev +00000000 .debug_line +00000000 .debug_frame +00000000 .debug_str +00000000 .debug_loc +00000000 .debug_ranges +00000000 cat.c +00000000 ulib.c +00000000 printf.c +00000778 putc +000007a0 printint +00000bc8 digits.993 +00000000 umalloc.c +00000be4 freep +00000be8 base +000000c8 strcpy +000008b4 printf +00000300 memmove +0000053c mknod +00000df0 _bss_end__ +000001f8 gets +000006a8 getpid +00000078 cat +00000ab0 malloc +00000710 sleep +00000be4 __bss_start__ +000003d0 pipe +00000438 write +000005a4 fstat +000004a0 kill +00000640 chdir +000004d4 exec +00000df0 __bss_end__ +0000039c wait +00000404 read +00000570 unlink +00000334 fork +000006dc sbrk +00000744 uptime +00000be4 __bss_start +0000017c memset +00000000 main +00000df0 __end__ +000000f0 strcmp +00000674 dup +00000bf0 buf +00000270 stat +00000be4 _edata +00000df0 _end +000005d8 link +00000368 exit +000002ac atoi +0000013c strlen +00000508 open +0000086c div +000001b4 strchr +0000060c mkdir +0000046c close +00000a0c free diff -r 000000000000 -r c450faca55f4 uprogs/defs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/defs.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,208 @@ +struct buf; +struct context; +struct file; +struct inode; +struct pipe; +struct proc; +struct spinlock; +struct stat; +struct superblock; + +void OkLoop(void); +void NotOkLoop(void); + +void uart_putc(u32); +void cprintf(char*, ...); +void SetGpio(u32, u32); +void SetGpioFunction(u32, u32); +void Wait(u32); +void consoleinit(void); +void uart_init(void); +void mmuinit1(void); +void barriers(void); +void dsb_barrier(void); +void flush_tlb(void); +void flush_dcache(u32 va1, u32 va2); +void flush_idcache(void); +void set_pgtbase(u32 base); + +// bio.c +void binit(void); +struct buf* bread(uint, uint); +void brelse(struct buf*); +void bwrite(struct buf*); + +// fs.c +void readsb(int dev, struct superblock *sb); +int dirlink(struct inode*, char*, uint); +struct inode* dirlookup(struct inode*, char*, uint*); +struct inode* ialloc(uint, short); +struct inode* idup(struct inode*); +void iinit(void); +void ilock(struct inode*); +void iput(struct inode*); +void iunlock(struct inode*); +void iunlockput(struct inode*); +void iupdate(struct inode*); +int namecmp(const char*, const char*); +struct inode* namei(char*); +struct inode* nameiparent(char*, char*); +int readi(struct inode*, char*, uint, uint); +void stati(struct inode*, struct stat*); +int writei(struct inode*, char*, uint, uint); + + +// ide.c +void ideinit(void); +void ideintr(void); +void iderw(struct buf*); + +// exec.c +int exec(char*, char**); + +// file.c +struct file* filealloc(void); +void fileclose(struct file*); +struct file* filedup(struct file*); +void fileinit(void); +int fileread(struct file*, char*, int n); +int filestat(struct file*, struct stat*); +int filewrite(struct file*, char*, int n); + + +// fs.c +void readsb(int dev, struct superblock *sb); +int dirlink(struct inode*, char*, uint); +struct inode* dirlookup(struct inode*, char*, uint*); +struct inode* ialloc(uint, short); +struct inode* idup(struct inode*); +void iinit(void); +void ilock(struct inode*); +void iput(struct inode*); +void iunlock(struct inode*); +void iunlockput(struct inode*); +void iupdate(struct inode*); +int namecmp(const char*, const char*); +struct inode* namei(char*); +struct inode* nameiparent(char*, char*); +int readi(struct inode*, char*, uint, uint); +void stati(struct inode*, struct stat*); +int writei(struct inode*, char*, uint, uint); + +// kalloc.c +char* kalloc(void); +void kfree(char*); +void kinit1(void*, void*); +void kinit2(void*, void*); + + +// log.c +void initlog(void); +void log_write(struct buf*); +void begin_trans(); +void commit_trans(); + +// pipe.c +int pipealloc(struct file**, struct file**); +void pipeclose(struct pipe*, int); +int piperead(struct pipe*, char*, int); +int pipewrite(struct pipe*, char*, int); + +//PAGEBREAK: 16 +// proc.c +struct proc* copyproc(struct proc*); +void exit(void); +int fork(void); +int growproc(int); +int kill(int); +void pinit(void); +void procdump(void); +void scheduler(void) __attribute__((noreturn)); +void sched(void); +void sleep(void*, struct spinlock*); +void userinit(void); +int wait(void); +void wakeup(void*); +void yield(void); + + +// swtch.S +void swtch(struct context**, struct context*); + +// syscall.c +int argint(int, int*); +int argptr(int, char**, int); +int argstr(int, char**); +int fetchint(uint, int*); +int fetchstr(uint, char**); +void syscall(void); + +void kvmalloc(void); + + +void drawCharacter(u8, u32, u32); +int UsbInitialise(void); +void KeyboardUpdate(void); +char KeyboardGetChar(void); +void gpuputc(u32); +u32 KeyboardCount(void); +u32 KeyboardGetAddress(u32); +struct KeyboardLeds KeyboardGetLedSupport(u32); + +void panic(char *s); + +// spinlock.c +void acquire(struct spinlock*); +void getcallerpcs(void*, uint*); +int holding(struct spinlock*); +void initlock(struct spinlock*, char*); +void release(struct spinlock*); +void pushcli(void); +void popcli(void); + +// string.c +int memcmp(const void*, const void*, uint); +void* memmove(void*, const void*, uint); +void* memset(void*, int, uint); +char* safestrcpy(char*, const char*, int); +int strlen(const char*); +int strncmp(const char*, const char*, uint); +char* strncpy(char*, const char*, int); +u32 div(u32 n, u32 d); + +// syscall.c +int argint(int, int*); +int argptr(int, char**, int); +int argstr(int, char**); +int fetchint(uint, int*); +int fetchstr(uint, char**); +void syscall(void); + +// trap.c +void trap_init(void); +extern uint ticks; +extern struct spinlock tickslock; + + +// vm.c +void seginit(void); +void kvmalloc(void); +void vmenable(void); +pde_t* setupkvm(void); +char* uva2ka(pde_t*, char*); +int allocuvm(pde_t*, uint, uint); +int deallocuvm(pde_t*, uint, uint); +void freevm(pde_t*); +void inituvm(pde_t*, char*, uint); +int loaduvm(pde_t*, char*, struct inode*, uint, uint); +pde_t* copyuvm(pde_t*, uint); +void switchuvm(struct proc*); +void switchkvm(void); +int copyout(pde_t*, uint, void*, uint); +void clearpteu(pde_t *pgdir, char *uva); + + + +// number of elements in fixed-size array +#define NELEM(x) (sizeof(x)/sizeof((x)[0])) + diff -r 000000000000 -r c450faca55f4 uprogs/echo.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/echo.asm Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,1665 @@ + +_echo: file format elf32-littlearm + + +Disassembly of section .text: + +00000000
: +int +main(int argc, char *argv[]) +{ + int i; + + for(i = 1; i < argc; i++) + 0: e3500001 cmp r0, #1 +#include "stat.h" +#include "user.h" + +int +main(int argc, char *argv[]) +{ + 4: e92d4878 push {r3, r4, r5, r6, fp, lr} + 8: e1a06000 mov r6, r0 + c: e28db014 add fp, sp, #20 + int i; + + for(i = 1; i < argc; i++) + 10: da000011 ble 5c + 14: e3a04001 mov r4, #1 + 18: e1a05001 mov r5, r1 + printf(1, "%s%s", argv[i], i+1 < argc ? " " : "\n"); + 1c: e2844001 add r4, r4, #1 + 20: e1540006 cmp r4, r6 + 24: e5b52004 ldr r2, [r5, #4]! + 28: e3a00001 mov r0, #1 + 2c: e59f102c ldr r1, [pc, #44] ; 60 + 30: 0a000007 beq 54 + 34: e59f3028 ldr r3, [pc, #40] ; 64 + 38: e2844001 add r4, r4, #1 + 3c: eb000205 bl 858 + 40: e1540006 cmp r4, r6 + 44: e5b52004 ldr r2, [r5, #4]! + 48: e3a00001 mov r0, #1 + 4c: e59f100c ldr r1, [pc, #12] ; 60 + 50: 1afffff7 bne 34 + 54: e59f300c ldr r3, [pc, #12] ; 68 + 58: eb0001fe bl 858 + exit(); + 5c: eb0000aa bl 30c + 60: 00000b40 .word 0x00000b40 + 64: 00000b48 .word 0x00000b48 + 68: 00000b4c .word 0x00000b4c + +0000006c : +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 6c: e52db004 push {fp} ; (str fp, [sp, #-4]!) + char *os; + + os = s; + while((*s++ = *t++) != 0) + 70: e1a02000 mov r2, r0 +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 74: e28db000 add fp, sp, #0 + char *os; + + os = s; + while((*s++ = *t++) != 0) + 78: e4d13001 ldrb r3, [r1], #1 + 7c: e3530000 cmp r3, #0 + 80: e4c23001 strb r3, [r2], #1 + 84: 1afffffb bne 78 + ; + return os; +} + 88: e28bd000 add sp, fp, #0 + 8c: e8bd0800 pop {fp} + 90: e12fff1e bx lr + +00000094 : + +int +strcmp(const char *p, const char *q) +{ + 94: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 98: e28db000 add fp, sp, #0 + while(*p && *p == *q) + 9c: e5d03000 ldrb r3, [r0] + a0: e5d12000 ldrb r2, [r1] + a4: e3530000 cmp r3, #0 + a8: 1a000004 bne c0 + ac: ea000005 b c8 + b0: e5f03001 ldrb r3, [r0, #1]! + b4: e3530000 cmp r3, #0 + b8: 0a000006 beq d8 + bc: e5f12001 ldrb r2, [r1, #1]! + c0: e1530002 cmp r3, r2 + c4: 0afffff9 beq b0 + p++, q++; + return (uchar)*p - (uchar)*q; +} + c8: e0620003 rsb r0, r2, r3 + cc: e28bd000 add sp, fp, #0 + d0: e8bd0800 pop {fp} + d4: e12fff1e bx lr +} + +int +strcmp(const char *p, const char *q) +{ + while(*p && *p == *q) + d8: e5d12001 ldrb r2, [r1, #1] + dc: eafffff9 b c8 + +000000e0 : + return (uchar)*p - (uchar)*q; +} + +uint +strlen(char *s) +{ + e0: e52db004 push {fp} ; (str fp, [sp, #-4]!) + e4: e28db000 add fp, sp, #0 + int n; + + for(n = 0; s[n]; n++) + e8: e5d03000 ldrb r3, [r0] + ec: e3530000 cmp r3, #0 + f0: 01a00003 moveq r0, r3 + f4: 0a000006 beq 114 + f8: e1a02000 mov r2, r0 + fc: e3a03000 mov r3, #0 + 100: e5f21001 ldrb r1, [r2, #1]! + 104: e2833001 add r3, r3, #1 + 108: e1a00003 mov r0, r3 + 10c: e3510000 cmp r1, #0 + 110: 1afffffa bne 100 + ; + return n; +} + 114: e28bd000 add sp, fp, #0 + 118: e8bd0800 pop {fp} + 11c: e12fff1e bx lr + +00000120 : +memset(void *dst, int c, uint n) +{ + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 120: e3520000 cmp r2, #0 + return n; +} + +void* +memset(void *dst, int c, uint n) +{ + 124: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 128: e28db000 add fp, sp, #0 + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 12c: 0a000006 beq 14c + 130: e6ef1071 uxtb r1, r1 + 134: e1a03002 mov r3, r2 +} + +void* +memset(void *dst, int c, uint n) +{ + char *p=dst; + 138: e1a0c000 mov ip, r0 + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 13c: e2533001 subs r3, r3, #1 + 140: e4cc1001 strb r1, [ip], #1 + 144: 1afffffc bne 13c + 148: e0800002 add r0, r0, r2 + return (void *)p; +} + 14c: e28bd000 add sp, fp, #0 + 150: e8bd0800 pop {fp} + 154: e12fff1e bx lr + +00000158 : + +char* +strchr(const char *s, char c) +{ + 158: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 15c: e28db000 add fp, sp, #0 + for(; *s; s++) + 160: e5d03000 ldrb r3, [r0] + 164: e3530000 cmp r3, #0 + 168: 1a000004 bne 180 + 16c: ea000008 b 194 + 170: e5d03001 ldrb r3, [r0, #1] + 174: e2800001 add r0, r0, #1 + 178: e3530000 cmp r3, #0 + 17c: 0a000004 beq 194 + if(*s == c) + 180: e1530001 cmp r3, r1 + 184: 1afffff9 bne 170 + return (char*)s; + return 0; +} + 188: e28bd000 add sp, fp, #0 + 18c: e8bd0800 pop {fp} + 190: e12fff1e bx lr +strchr(const char *s, char c) +{ + for(; *s; s++) + if(*s == c) + return (char*)s; + return 0; + 194: e1a00003 mov r0, r3 + 198: eafffffa b 188 + +0000019c : +} + +char* +gets(char *buf, int max) +{ + 19c: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + 1a0: e28db018 add fp, sp, #24 + 1a4: e24dd00c sub sp, sp, #12 + 1a8: e1a08000 mov r8, r0 + 1ac: e1a07001 mov r7, r1 + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 1b0: e1a06000 mov r6, r0 + 1b4: e3a05000 mov r5, #0 + 1b8: ea000008 b 1e0 + cc = read(0, &c, 1); + 1bc: eb000079 bl 3a8 + if(cc < 1) + 1c0: e3500000 cmp r0, #0 + 1c4: da00000b ble 1f8 + break; + buf[i++] = c; + 1c8: e55b301d ldrb r3, [fp, #-29] + if(c == '\n' || c == '\r') + 1cc: e1a05004 mov r5, r4 + 1d0: e353000a cmp r3, #10 + 1d4: 1353000d cmpne r3, #13 + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + if(cc < 1) + break; + buf[i++] = c; + 1d8: e4c63001 strb r3, [r6], #1 + if(c == '\n' || c == '\r') + 1dc: 0a00000a beq 20c +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + 1e0: e3a02001 mov r2, #1 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 1e4: e0854002 add r4, r5, r2 + 1e8: e1540007 cmp r4, r7 + cc = read(0, &c, 1); + 1ec: e3a00000 mov r0, #0 + 1f0: e24b101d sub r1, fp, #29 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 1f4: bafffff0 blt 1bc + break; + buf[i++] = c; + if(c == '\n' || c == '\r') + break; + } + buf[i] = '\0'; + 1f8: e3a03000 mov r3, #0 + 1fc: e7c83005 strb r3, [r8, r5] + return buf; +} + 200: e1a00008 mov r0, r8 + 204: e24bd018 sub sp, fp, #24 + 208: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 20c: e1a05004 mov r5, r4 + 210: eafffff8 b 1f8 + +00000214 : + return buf; +} + +int +stat(char *n, struct stat *st) +{ + 214: e92d4830 push {r4, r5, fp, lr} + 218: e1a05001 mov r5, r1 + 21c: e28db00c add fp, sp, #12 + int fd; + int r; + + fd = open(n, O_RDONLY); + 220: e3a01000 mov r1, #0 + 224: eb0000a0 bl 4ac + if(fd < 0) + 228: e2504000 subs r4, r0, #0 + return -1; + 22c: b3e05000 mvnlt r5, #0 +{ + int fd; + int r; + + fd = open(n, O_RDONLY); + if(fd < 0) + 230: ba000004 blt 248 + return -1; + r = fstat(fd, st); + 234: e1a01005 mov r1, r5 + 238: eb0000c2 bl 548 + 23c: e1a05000 mov r5, r0 + close(fd); + 240: e1a00004 mov r0, r4 + 244: eb000071 bl 410 + return r; +} + 248: e1a00005 mov r0, r5 + 24c: e8bd8830 pop {r4, r5, fp, pc} + +00000250 : + +int +atoi(const char *s) +{ + 250: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 254: e28db000 add fp, sp, #0 + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 258: e5d03000 ldrb r3, [r0] + 25c: e2432030 sub r2, r3, #48 ; 0x30 + 260: e6ef2072 uxtb r2, r2 + 264: e3520009 cmp r2, #9 +int +atoi(const char *s) +{ + int n; + + n = 0; + 268: 83a00000 movhi r0, #0 + while('0' <= *s && *s <= '9') + 26c: 8a000009 bhi 298 + 270: e1a02000 mov r2, r0 +int +atoi(const char *s) +{ + int n; + + n = 0; + 274: e3a00000 mov r0, #0 + while('0' <= *s && *s <= '9') + n = n*10 + *s++ - '0'; + 278: e0800100 add r0, r0, r0, lsl #2 + 27c: e0830080 add r0, r3, r0, lsl #1 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 280: e5f23001 ldrb r3, [r2, #1]! + n = n*10 + *s++ - '0'; + 284: e2400030 sub r0, r0, #48 ; 0x30 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 288: e2431030 sub r1, r3, #48 ; 0x30 + 28c: e6ef1071 uxtb r1, r1 + 290: e3510009 cmp r1, #9 + 294: 9afffff7 bls 278 + n = n*10 + *s++ - '0'; + return n; +} + 298: e28bd000 add sp, fp, #0 + 29c: e8bd0800 pop {fp} + 2a0: e12fff1e bx lr + +000002a4 : +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 2a4: e3520000 cmp r2, #0 + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) +{ + 2a8: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 2ac: e28db000 add fp, sp, #0 + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 2b0: da000005 ble 2cc + n = n*10 + *s++ - '0'; + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) + 2b4: e0802002 add r2, r0, r2 +{ + char *dst, *src; + + dst = vdst; + 2b8: e1a03000 mov r3, r0 + src = vsrc; + while(n-- > 0) + *dst++ = *src++; + 2bc: e4d1c001 ldrb ip, [r1], #1 + 2c0: e4c3c001 strb ip, [r3], #1 +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 2c4: e1530002 cmp r3, r2 + 2c8: 1afffffb bne 2bc + *dst++ = *src++; + return vdst; +} + 2cc: e28bd000 add sp, fp, #0 + 2d0: e8bd0800 pop {fp} + 2d4: e12fff1e bx lr + +000002d8 : + 2d8: e92d4000 push {lr} + 2dc: e92d0008 push {r3} + 2e0: e92d0004 push {r2} + 2e4: e92d0002 push {r1} + 2e8: e92d0001 push {r0} + 2ec: e3a00001 mov r0, #1 + 2f0: ef000040 svc 0x00000040 + 2f4: e8bd0002 pop {r1} + 2f8: e8bd0002 pop {r1} + 2fc: e8bd0004 pop {r2} + 300: e8bd0008 pop {r3} + 304: e8bd4000 pop {lr} + 308: e12fff1e bx lr + +0000030c : + 30c: e92d4000 push {lr} + 310: e92d0008 push {r3} + 314: e92d0004 push {r2} + 318: e92d0002 push {r1} + 31c: e92d0001 push {r0} + 320: e3a00002 mov r0, #2 + 324: ef000040 svc 0x00000040 + 328: e8bd0002 pop {r1} + 32c: e8bd0002 pop {r1} + 330: e8bd0004 pop {r2} + 334: e8bd0008 pop {r3} + 338: e8bd4000 pop {lr} + 33c: e12fff1e bx lr + +00000340 : + 340: e92d4000 push {lr} + 344: e92d0008 push {r3} + 348: e92d0004 push {r2} + 34c: e92d0002 push {r1} + 350: e92d0001 push {r0} + 354: e3a00003 mov r0, #3 + 358: ef000040 svc 0x00000040 + 35c: e8bd0002 pop {r1} + 360: e8bd0002 pop {r1} + 364: e8bd0004 pop {r2} + 368: e8bd0008 pop {r3} + 36c: e8bd4000 pop {lr} + 370: e12fff1e bx lr + +00000374 : + 374: e92d4000 push {lr} + 378: e92d0008 push {r3} + 37c: e92d0004 push {r2} + 380: e92d0002 push {r1} + 384: e92d0001 push {r0} + 388: e3a00004 mov r0, #4 + 38c: ef000040 svc 0x00000040 + 390: e8bd0002 pop {r1} + 394: e8bd0002 pop {r1} + 398: e8bd0004 pop {r2} + 39c: e8bd0008 pop {r3} + 3a0: e8bd4000 pop {lr} + 3a4: e12fff1e bx lr + +000003a8 : + 3a8: e92d4000 push {lr} + 3ac: e92d0008 push {r3} + 3b0: e92d0004 push {r2} + 3b4: e92d0002 push {r1} + 3b8: e92d0001 push {r0} + 3bc: e3a00005 mov r0, #5 + 3c0: ef000040 svc 0x00000040 + 3c4: e8bd0002 pop {r1} + 3c8: e8bd0002 pop {r1} + 3cc: e8bd0004 pop {r2} + 3d0: e8bd0008 pop {r3} + 3d4: e8bd4000 pop {lr} + 3d8: e12fff1e bx lr + +000003dc : + 3dc: e92d4000 push {lr} + 3e0: e92d0008 push {r3} + 3e4: e92d0004 push {r2} + 3e8: e92d0002 push {r1} + 3ec: e92d0001 push {r0} + 3f0: e3a00010 mov r0, #16 + 3f4: ef000040 svc 0x00000040 + 3f8: e8bd0002 pop {r1} + 3fc: e8bd0002 pop {r1} + 400: e8bd0004 pop {r2} + 404: e8bd0008 pop {r3} + 408: e8bd4000 pop {lr} + 40c: e12fff1e bx lr + +00000410 : + 410: e92d4000 push {lr} + 414: e92d0008 push {r3} + 418: e92d0004 push {r2} + 41c: e92d0002 push {r1} + 420: e92d0001 push {r0} + 424: e3a00015 mov r0, #21 + 428: ef000040 svc 0x00000040 + 42c: e8bd0002 pop {r1} + 430: e8bd0002 pop {r1} + 434: e8bd0004 pop {r2} + 438: e8bd0008 pop {r3} + 43c: e8bd4000 pop {lr} + 440: e12fff1e bx lr + +00000444 : + 444: e92d4000 push {lr} + 448: e92d0008 push {r3} + 44c: e92d0004 push {r2} + 450: e92d0002 push {r1} + 454: e92d0001 push {r0} + 458: e3a00006 mov r0, #6 + 45c: ef000040 svc 0x00000040 + 460: e8bd0002 pop {r1} + 464: e8bd0002 pop {r1} + 468: e8bd0004 pop {r2} + 46c: e8bd0008 pop {r3} + 470: e8bd4000 pop {lr} + 474: e12fff1e bx lr + +00000478 : + 478: e92d4000 push {lr} + 47c: e92d0008 push {r3} + 480: e92d0004 push {r2} + 484: e92d0002 push {r1} + 488: e92d0001 push {r0} + 48c: e3a00007 mov r0, #7 + 490: ef000040 svc 0x00000040 + 494: e8bd0002 pop {r1} + 498: e8bd0002 pop {r1} + 49c: e8bd0004 pop {r2} + 4a0: e8bd0008 pop {r3} + 4a4: e8bd4000 pop {lr} + 4a8: e12fff1e bx lr + +000004ac : + 4ac: e92d4000 push {lr} + 4b0: e92d0008 push {r3} + 4b4: e92d0004 push {r2} + 4b8: e92d0002 push {r1} + 4bc: e92d0001 push {r0} + 4c0: e3a0000f mov r0, #15 + 4c4: ef000040 svc 0x00000040 + 4c8: e8bd0002 pop {r1} + 4cc: e8bd0002 pop {r1} + 4d0: e8bd0004 pop {r2} + 4d4: e8bd0008 pop {r3} + 4d8: e8bd4000 pop {lr} + 4dc: e12fff1e bx lr + +000004e0 : + 4e0: e92d4000 push {lr} + 4e4: e92d0008 push {r3} + 4e8: e92d0004 push {r2} + 4ec: e92d0002 push {r1} + 4f0: e92d0001 push {r0} + 4f4: e3a00011 mov r0, #17 + 4f8: ef000040 svc 0x00000040 + 4fc: e8bd0002 pop {r1} + 500: e8bd0002 pop {r1} + 504: e8bd0004 pop {r2} + 508: e8bd0008 pop {r3} + 50c: e8bd4000 pop {lr} + 510: e12fff1e bx lr + +00000514 : + 514: e92d4000 push {lr} + 518: e92d0008 push {r3} + 51c: e92d0004 push {r2} + 520: e92d0002 push {r1} + 524: e92d0001 push {r0} + 528: e3a00012 mov r0, #18 + 52c: ef000040 svc 0x00000040 + 530: e8bd0002 pop {r1} + 534: e8bd0002 pop {r1} + 538: e8bd0004 pop {r2} + 53c: e8bd0008 pop {r3} + 540: e8bd4000 pop {lr} + 544: e12fff1e bx lr + +00000548 : + 548: e92d4000 push {lr} + 54c: e92d0008 push {r3} + 550: e92d0004 push {r2} + 554: e92d0002 push {r1} + 558: e92d0001 push {r0} + 55c: e3a00008 mov r0, #8 + 560: ef000040 svc 0x00000040 + 564: e8bd0002 pop {r1} + 568: e8bd0002 pop {r1} + 56c: e8bd0004 pop {r2} + 570: e8bd0008 pop {r3} + 574: e8bd4000 pop {lr} + 578: e12fff1e bx lr + +0000057c : + 57c: e92d4000 push {lr} + 580: e92d0008 push {r3} + 584: e92d0004 push {r2} + 588: e92d0002 push {r1} + 58c: e92d0001 push {r0} + 590: e3a00013 mov r0, #19 + 594: ef000040 svc 0x00000040 + 598: e8bd0002 pop {r1} + 59c: e8bd0002 pop {r1} + 5a0: e8bd0004 pop {r2} + 5a4: e8bd0008 pop {r3} + 5a8: e8bd4000 pop {lr} + 5ac: e12fff1e bx lr + +000005b0 : + 5b0: e92d4000 push {lr} + 5b4: e92d0008 push {r3} + 5b8: e92d0004 push {r2} + 5bc: e92d0002 push {r1} + 5c0: e92d0001 push {r0} + 5c4: e3a00014 mov r0, #20 + 5c8: ef000040 svc 0x00000040 + 5cc: e8bd0002 pop {r1} + 5d0: e8bd0002 pop {r1} + 5d4: e8bd0004 pop {r2} + 5d8: e8bd0008 pop {r3} + 5dc: e8bd4000 pop {lr} + 5e0: e12fff1e bx lr + +000005e4 : + 5e4: e92d4000 push {lr} + 5e8: e92d0008 push {r3} + 5ec: e92d0004 push {r2} + 5f0: e92d0002 push {r1} + 5f4: e92d0001 push {r0} + 5f8: e3a00009 mov r0, #9 + 5fc: ef000040 svc 0x00000040 + 600: e8bd0002 pop {r1} + 604: e8bd0002 pop {r1} + 608: e8bd0004 pop {r2} + 60c: e8bd0008 pop {r3} + 610: e8bd4000 pop {lr} + 614: e12fff1e bx lr + +00000618 : + 618: e92d4000 push {lr} + 61c: e92d0008 push {r3} + 620: e92d0004 push {r2} + 624: e92d0002 push {r1} + 628: e92d0001 push {r0} + 62c: e3a0000a mov r0, #10 + 630: ef000040 svc 0x00000040 + 634: e8bd0002 pop {r1} + 638: e8bd0002 pop {r1} + 63c: e8bd0004 pop {r2} + 640: e8bd0008 pop {r3} + 644: e8bd4000 pop {lr} + 648: e12fff1e bx lr + +0000064c : + 64c: e92d4000 push {lr} + 650: e92d0008 push {r3} + 654: e92d0004 push {r2} + 658: e92d0002 push {r1} + 65c: e92d0001 push {r0} + 660: e3a0000b mov r0, #11 + 664: ef000040 svc 0x00000040 + 668: e8bd0002 pop {r1} + 66c: e8bd0002 pop {r1} + 670: e8bd0004 pop {r2} + 674: e8bd0008 pop {r3} + 678: e8bd4000 pop {lr} + 67c: e12fff1e bx lr + +00000680 : + 680: e92d4000 push {lr} + 684: e92d0008 push {r3} + 688: e92d0004 push {r2} + 68c: e92d0002 push {r1} + 690: e92d0001 push {r0} + 694: e3a0000c mov r0, #12 + 698: ef000040 svc 0x00000040 + 69c: e8bd0002 pop {r1} + 6a0: e8bd0002 pop {r1} + 6a4: e8bd0004 pop {r2} + 6a8: e8bd0008 pop {r3} + 6ac: e8bd4000 pop {lr} + 6b0: e12fff1e bx lr + +000006b4 : + 6b4: e92d4000 push {lr} + 6b8: e92d0008 push {r3} + 6bc: e92d0004 push {r2} + 6c0: e92d0002 push {r1} + 6c4: e92d0001 push {r0} + 6c8: e3a0000d mov r0, #13 + 6cc: ef000040 svc 0x00000040 + 6d0: e8bd0002 pop {r1} + 6d4: e8bd0002 pop {r1} + 6d8: e8bd0004 pop {r2} + 6dc: e8bd0008 pop {r3} + 6e0: e8bd4000 pop {lr} + 6e4: e12fff1e bx lr + +000006e8 : + 6e8: e92d4000 push {lr} + 6ec: e92d0008 push {r3} + 6f0: e92d0004 push {r2} + 6f4: e92d0002 push {r1} + 6f8: e92d0001 push {r0} + 6fc: e3a0000e mov r0, #14 + 700: ef000040 svc 0x00000040 + 704: e8bd0002 pop {r1} + 708: e8bd0002 pop {r1} + 70c: e8bd0004 pop {r2} + 710: e8bd0008 pop {r3} + 714: e8bd4000 pop {lr} + 718: e12fff1e bx lr + +0000071c : +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 71c: e92d4800 push {fp, lr} + 720: e28db004 add fp, sp, #4 + 724: e24b3004 sub r3, fp, #4 + 728: e24dd008 sub sp, sp, #8 + write(fd, &c, 1); + 72c: e3a02001 mov r2, #1 +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 730: e5631001 strb r1, [r3, #-1]! + write(fd, &c, 1); + 734: e1a01003 mov r1, r3 + 738: ebffff27 bl 3dc +} + 73c: e24bd004 sub sp, fp, #4 + 740: e8bd8800 pop {fp, pc} + +00000744 : + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 744: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 748: e1a04000 mov r4, r0 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 74c: e1a00fa1 lsr r0, r1, #31 + 750: e3530000 cmp r3, #0 + 754: 03a03000 moveq r3, #0 + 758: 12003001 andne r3, r0, #1 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 75c: e28db020 add fp, sp, #32 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 760: e3530000 cmp r3, #0 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 764: e24dd014 sub sp, sp, #20 + 768: e59f909c ldr r9, [pc, #156] ; 80c + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + x = -xx; + 76c: 12611000 rsbne r1, r1, #0 + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + 770: 13a03001 movne r3, #1 + } else { + x = xx; + } + + b = base; + i = 0; + 774: e3a0a000 mov sl, #0 + 778: e24b6034 sub r6, fp, #52 ; 0x34 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 77c: e3a08001 mov r8, #1 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 780: e3a07000 mov r7, #0 + int i; + + for(i=31;i>=0;i--){ + 784: e3a0001f mov r0, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 788: e1a0c007 mov ip, r7 + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 78c: e1a0e031 lsr lr, r1, r0 + 790: e20ee001 and lr, lr, #1 + 794: e18ec08c orr ip, lr, ip, lsl #1 + if(r >= d) { + 798: e152000c cmp r2, ip + r = r - d; + q = q | (1 << i); + 79c: 91877018 orrls r7, r7, r8, lsl r0 + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 7a0: 9062c00c rsbls ip, r2, ip +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 7a4: e2500001 subs r0, r0, #1 + 7a8: 2afffff7 bcs 78c + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 7ac: e0000792 mul r0, r2, r7 + }while((x = y) != 0); + 7b0: e3570000 cmp r7, #0 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 7b4: e0601001 rsb r1, r0, r1 + 7b8: e28a5001 add r5, sl, #1 + 7bc: e7d91001 ldrb r1, [r9, r1] + 7c0: e7c6100a strb r1, [r6, sl] + }while((x = y) != 0); + 7c4: 11a01007 movne r1, r7 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 7c8: 11a0a005 movne sl, r5 + 7cc: 1affffeb bne 780 + }while((x = y) != 0); + if(neg) + 7d0: e3530000 cmp r3, #0 + buf[i++] = '-'; + 7d4: 124b2024 subne r2, fp, #36 ; 0x24 + 7d8: 10823005 addne r3, r2, r5 + 7dc: 128a5002 addne r5, sl, #2 + + while(--i >= 0) + 7e0: e2455001 sub r5, r5, #1 + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + 7e4: 13a0202d movne r2, #45 ; 0x2d + 7e8: 15432010 strbne r2, [r3, #-16] + + while(--i >= 0) + putc(fd, buf[i]); + 7ec: e7d61005 ldrb r1, [r6, r5] + 7f0: e1a00004 mov r0, r4 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 7f4: e2455001 sub r5, r5, #1 + putc(fd, buf[i]); + 7f8: ebffffc7 bl 71c + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 7fc: e3750001 cmn r5, #1 + 800: 1afffff9 bne 7ec + putc(fd, buf[i]); +} + 804: e24bd020 sub sp, fp, #32 + 808: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} + 80c: 00000b50 .word 0x00000b50 + +00000810
: + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 810: e3a03000 mov r3, #0 +{ + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + 814: e92d0830 push {r4, r5, fp} + 818: e1a02000 mov r2, r0 + 81c: e28db008 add fp, sp, #8 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 820: e3a0c01f mov ip, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 824: e1a00003 mov r0, r3 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 828: e3a05001 mov r5, #1 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 82c: e1a04c32 lsr r4, r2, ip + 830: e2044001 and r4, r4, #1 + 834: e1843083 orr r3, r4, r3, lsl #1 + if(r >= d) { + 838: e1530001 cmp r3, r1 + r = r - d; + q = q | (1 << i); + 83c: 21800c15 orrcs r0, r0, r5, lsl ip + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 840: 20613003 rsbcs r3, r1, r3 +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 844: e25cc001 subs ip, ip, #1 + 848: 2afffff7 bcs 82c + r = r - d; + q = q | (1 << i); + } + } + return q; +} + 84c: e24bd008 sub sp, fp, #8 + 850: e8bd0830 pop {r4, r5, fp} + 854: e12fff1e bx lr + +00000858 : +} + +// Print to the given fd. Only understands %d, %x, %p, %s. +void +printf(int fd, char *fmt, ...) +{ + 858: e92d000e push {r1, r2, r3} + 85c: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 860: e28db020 add fp, sp, #32 + 864: e1a05000 mov r5, r0 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 868: e59b4004 ldr r4, [fp, #4] + 86c: e5d48000 ldrb r8, [r4] + 870: e3580000 cmp r8, #0 + 874: 0a000027 beq 918 + ap++; + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + 878: e59f712c ldr r7, [pc, #300] ; 9ac + char *s; + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + 87c: e28b6008 add r6, fp, #8 +{ + char *s; + int c, i, state; + uint *ap; + + state = 0; + 880: e3a0a000 mov sl, #0 + 884: ea000008 b 8ac + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 888: e3580025 cmp r8, #37 ; 0x25 + state = '%'; + 88c: 01a0a008 moveq sl, r8 + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 890: 0a000002 beq 8a0 + state = '%'; + } else { + putc(fd, c); + 894: e1a00005 mov r0, r5 + 898: e1a01008 mov r1, r8 + 89c: ebffff9e bl 71c + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 8a0: e5f48001 ldrb r8, [r4, #1]! + 8a4: e3580000 cmp r8, #0 + 8a8: 0a00001a beq 918 + c = fmt[i] & 0xff; + if(state == 0){ + 8ac: e35a0000 cmp sl, #0 + 8b0: 0afffff4 beq 888 + if(c == '%'){ + state = '%'; + } else { + putc(fd, c); + } + } else if(state == '%'){ + 8b4: e35a0025 cmp sl, #37 ; 0x25 + 8b8: 1afffff8 bne 8a0 + if(c == 'd'){ + 8bc: e3580064 cmp r8, #100 ; 0x64 + 8c0: 0a00002c beq 978 + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + 8c4: e3580078 cmp r8, #120 ; 0x78 + 8c8: 13580070 cmpne r8, #112 ; 0x70 + 8cc: 13a09000 movne r9, #0 + 8d0: 03a09001 moveq r9, #1 + 8d4: 0a000013 beq 928 + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + 8d8: e3580073 cmp r8, #115 ; 0x73 + 8dc: 0a000018 beq 944 + s = "(null)"; + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + 8e0: e3580063 cmp r8, #99 ; 0x63 + 8e4: 0a00002a beq 994 + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 8e8: e3580025 cmp r8, #37 ; 0x25 + putc(fd, c); + 8ec: e1a0100a mov r1, sl + 8f0: e1a00005 mov r0, r5 + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 8f4: 0a000002 beq 904 + putc(fd, c); + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + 8f8: ebffff87 bl 71c + putc(fd, c); + 8fc: e1a00005 mov r0, r5 + 900: e1a01008 mov r1, r8 + 904: ebffff84 bl 71c + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 908: e5f48001 ldrb r8, [r4, #1]! + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 90c: e1a0a009 mov sl, r9 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 910: e3580000 cmp r8, #0 + 914: 1affffe4 bne 8ac + putc(fd, c); + } + state = 0; + } + } +} + 918: e24bd020 sub sp, fp, #32 + 91c: e8bd4ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 920: e28dd00c add sp, sp, #12 + 924: e12fff1e bx lr + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + 928: e1a00005 mov r0, r5 + 92c: e4961004 ldr r1, [r6], #4 + 930: e3a02010 mov r2, #16 + 934: e3a03000 mov r3, #0 + 938: ebffff81 bl 744 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 93c: e3a0a000 mov sl, #0 + 940: eaffffd6 b 8a0 + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + s = (char*)*ap; + 944: e4968004 ldr r8, [r6], #4 + ap++; + if(s == 0) + s = "(null)"; + 948: e3580000 cmp r8, #0 + 94c: 01a08007 moveq r8, r7 + while(*s != 0){ + 950: e5d81000 ldrb r1, [r8] + 954: e3510000 cmp r1, #0 + 958: 0a000004 beq 970 + putc(fd, *s); + 95c: e1a00005 mov r0, r5 + 960: ebffff6d bl 71c + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + while(*s != 0){ + 964: e5f81001 ldrb r1, [r8, #1]! + 968: e3510000 cmp r1, #0 + 96c: 1afffffa bne 95c + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 970: e1a0a001 mov sl, r1 + 974: eaffffc9 b 8a0 + } else { + putc(fd, c); + } + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + 978: e1a00005 mov r0, r5 + 97c: e4961004 ldr r1, [r6], #4 + 980: e3a0200a mov r2, #10 + 984: e3a03001 mov r3, #1 + 988: ebffff6d bl 744 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 98c: e3a0a000 mov sl, #0 + 990: eaffffc2 b 8a0 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 994: e4961004 ldr r1, [r6], #4 + 998: e1a00005 mov r0, r5 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 99c: e1a0a009 mov sl, r9 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 9a0: e6ef1071 uxtb r1, r1 + 9a4: ebffff5c bl 71c + 9a8: eaffffbc b 8a0 + 9ac: 00000b64 .word 0x00000b64 + +000009b0 : +free(void *ap) +{ + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 9b0: e59f3098 ldr r3, [pc, #152] ; a50 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 9b4: e92d0830 push {r4, r5, fp} + Header *bp, *p; + + bp = (Header*)ap - 1; + 9b8: e240c008 sub ip, r0, #8 + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 9bc: e5932000 ldr r2, [r3] +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 9c0: e28db008 add fp, sp, #8 + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 9c4: e152000c cmp r2, ip + 9c8: e5921000 ldr r1, [r2] + 9cc: 2a000001 bcs 9d8 + 9d0: e15c0001 cmp ip, r1 + 9d4: 3a000007 bcc 9f8 + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + 9d8: e1520001 cmp r2, r1 + 9dc: 3a000003 bcc 9f0 + 9e0: e152000c cmp r2, ip + 9e4: 3a000003 bcc 9f8 + 9e8: e15c0001 cmp ip, r1 + 9ec: 3a000001 bcc 9f8 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 9f0: e1a02001 mov r2, r1 + 9f4: eafffff2 b 9c4 + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + 9f8: e5104004 ldr r4, [r0, #-4] + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + freep = p; + 9fc: e5832000 str r2, [r3] + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + a00: e08c5184 add r5, ip, r4, lsl #3 + a04: e1550001 cmp r5, r1 + bp->s.size += p->s.ptr->s.size; + a08: 05911004 ldreq r1, [r1, #4] + a0c: 00814004 addeq r4, r1, r4 + a10: 05004004 streq r4, [r0, #-4] + bp->s.ptr = p->s.ptr->s.ptr; + a14: 05921000 ldreq r1, [r2] + a18: 05911000 ldreq r1, [r1] + } else + bp->s.ptr = p->s.ptr; + a1c: e5001008 str r1, [r0, #-8] + if(p + p->s.size == bp){ + a20: e5921004 ldr r1, [r2, #4] + a24: e0824181 add r4, r2, r1, lsl #3 + a28: e15c0004 cmp ip, r4 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + a2c: 1582c000 strne ip, [r2] + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + } else + bp->s.ptr = p->s.ptr; + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + a30: 0510c004 ldreq ip, [r0, #-4] + a34: 008c1001 addeq r1, ip, r1 + a38: 05821004 streq r1, [r2, #4] + p->s.ptr = bp->s.ptr; + a3c: 05101008 ldreq r1, [r0, #-8] + a40: 05821000 streq r1, [r2] + } else + p->s.ptr = bp; + freep = p; +} + a44: e24bd008 sub sp, fp, #8 + a48: e8bd0830 pop {r4, r5, fp} + a4c: e12fff1e bx lr + a50: 00000b6c .word 0x00000b6c + +00000a54 : + return freep; +} + +void* +malloc(uint nbytes) +{ + a54: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + a58: e2804007 add r4, r0, #7 + if((prevp = freep) == 0){ + a5c: e59f50d4 ldr r5, [pc, #212] ; b38 +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + a60: e1a041a4 lsr r4, r4, #3 + return freep; +} + +void* +malloc(uint nbytes) +{ + a64: e28db01c add fp, sp, #28 + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + a68: e5953000 ldr r3, [r5] +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + a6c: e2844001 add r4, r4, #1 + if((prevp = freep) == 0){ + a70: e3530000 cmp r3, #0 + a74: 0a00002b beq b28 + a78: e5930000 ldr r0, [r3] + a7c: e5902004 ldr r2, [r0, #4] + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + a80: e1520004 cmp r2, r4 + a84: 2a00001b bcs af8 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + a88: e59f80ac ldr r8, [pc, #172] ; b3c + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + a8c: e1a07184 lsl r7, r4, #3 + a90: ea000003 b aa4 + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + a94: e5930000 ldr r0, [r3] + if(p->s.size >= nunits){ + a98: e5902004 ldr r2, [r0, #4] + a9c: e1540002 cmp r4, r2 + aa0: 9a000014 bls af8 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + aa4: e5952000 ldr r2, [r5] + aa8: e1a03000 mov r3, r0 + aac: e1500002 cmp r0, r2 + ab0: 1afffff7 bne a94 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + ab4: e1540008 cmp r4, r8 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + ab8: 81a00007 movhi r0, r7 + abc: 93a00902 movls r0, #32768 ; 0x8000 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + ac0: 81a06004 movhi r6, r4 + ac4: 93a06a01 movls r6, #4096 ; 0x1000 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + ac8: ebfffeec bl 680 + acc: e1a03000 mov r3, r0 + if(p == (char*)-1) + ad0: e3730001 cmn r3, #1 + return 0; + hp = (Header*)p; + hp->s.size = nu; + free((void*)(hp + 1)); + ad4: e2800008 add r0, r0, #8 + Header *hp; + + if(nu < 4096) + nu = 4096; + p = sbrk(nu * sizeof(Header)); + if(p == (char*)-1) + ad8: 0a000010 beq b20 + return 0; + hp = (Header*)p; + hp->s.size = nu; + adc: e5836004 str r6, [r3, #4] + free((void*)(hp + 1)); + ae0: ebffffb2 bl 9b0 + return freep; + ae4: e5953000 ldr r3, [r5] + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + if((p = morecore(nunits)) == 0) + ae8: e3530000 cmp r3, #0 + aec: 1affffe8 bne a94 + return 0; + af0: e1a00003 mov r0, r3 + } +} + af4: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + af8: e1540002 cmp r4, r2 + prevp->s.ptr = p->s.ptr; + else { + p->s.size -= nunits; + afc: 10642002 rsbne r2, r4, r2 + b00: 15802004 strne r2, [r0, #4] + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + b04: 05902000 ldreq r2, [r0] + else { + p->s.size -= nunits; + p += p->s.size; + b08: 10800182 addne r0, r0, r2, lsl #3 + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + b0c: 05832000 streq r2, [r3] + else { + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + b10: 15804004 strne r4, [r0, #4] + } + freep = prevp; + b14: e5853000 str r3, [r5] + return (void*)(p + 1); + b18: e2800008 add r0, r0, #8 + b1c: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + } + if(p == freep) + if((p = morecore(nunits)) == 0) + return 0; + b20: e3a00000 mov r0, #0 + b24: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + b28: e2850004 add r0, r5, #4 + b2c: e5850000 str r0, [r5] + base.s.size = 0; + b30: e9850009 stmib r5, {r0, r3} + b34: eaffffd3 b a88 + b38: 00000b6c .word 0x00000b6c + b3c: 00000fff .word 0x00000fff diff -r 000000000000 -r c450faca55f4 uprogs/echo.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/echo.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,13 @@ +#include "types.h" +#include "stat.h" +#include "user.h" + +int +main(int argc, char *argv[]) +{ + int i; + + for(i = 1; i < argc; i++) + printf(1, "%s%s", argv[i], i+1 < argc ? " " : "\n"); + exit(); +} diff -r 000000000000 -r c450faca55f4 uprogs/echo.sym --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/echo.sym Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,64 @@ +00000000 .text +00000b40 .rodata +00000b6c .bss +00000000 .comment +00000000 .ARM.attributes +00000000 .debug_aranges +00000000 .debug_info +00000000 .debug_abbrev +00000000 .debug_line +00000000 .debug_frame +00000000 .debug_str +00000000 .debug_loc +00000000 .debug_ranges +00000000 echo.c +00000000 ulib.c +00000000 printf.c +0000071c putc +00000744 printint +00000b50 digits.993 +00000000 umalloc.c +00000b6c freep +00000b70 base +0000006c strcpy +00000858 printf +000002a4 memmove +000004e0 mknod +00000b78 _bss_end__ +0000019c gets +0000064c getpid +00000a54 malloc +000006b4 sleep +00000b6c __bss_start__ +00000374 pipe +000003dc write +00000548 fstat +00000444 kill +000005e4 chdir +00000478 exec +00000b78 __bss_end__ +00000340 wait +000003a8 read +00000514 unlink +000002d8 fork +00000680 sbrk +000006e8 uptime +00000b6c __bss_start +00000120 memset +00000000 main +00000b78 __end__ +00000094 strcmp +00000618 dup +00000214 stat +00000b6c _edata +00000b78 _end +0000057c link +0000030c exit +00000250 atoi +000000e0 strlen +000004ac open +00000810 div +00000158 strchr +000005b0 mkdir +00000410 close +000009b0 free diff -r 000000000000 -r c450faca55f4 uprogs/elf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/elf.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,42 @@ +// Format of an ELF executable file + +#define ELF_MAGIC 0x464C457FU // "\x7FELF" in little endian + +// File header +struct elfhdr { + uint magic; // must equal ELF_MAGIC + uchar elf[12]; + ushort type; + ushort machine; + uint version; + uint entry; + uint phoff; + uint shoff; + uint flags; + ushort ehsize; + ushort phentsize; + ushort phnum; + ushort shentsize; + ushort shnum; + ushort shstrndx; +}; + +// Program section header +struct proghdr { + uint type; + uint off; + uint vaddr; + uint paddr; + uint filesz; + uint memsz; + uint flags; + uint align; +}; + +// Values for Proghdr type +#define ELF_PROG_LOAD 1 + +// Flag bits for Proghdr flags +#define ELF_PROG_FLAG_EXEC 1 +#define ELF_PROG_FLAG_WRITE 2 +#define ELF_PROG_FLAG_READ 4 diff -r 000000000000 -r c450faca55f4 uprogs/fcntl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/fcntl.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,4 @@ +#define O_RDONLY 0x000 +#define O_WRONLY 0x001 +#define O_RDWR 0x002 +#define O_CREATE 0x200 diff -r 000000000000 -r c450faca55f4 uprogs/file.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/file.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,38 @@ +struct file { + enum { FD_NONE, FD_PIPE, FD_INODE } type; + int ref; // reference count + char readable; + char writable; + struct pipe *pipe; + struct inode *ip; + uint off; +}; + + +// in-memory copy of an inode +struct inode { + uint dev; // Device number + uint inum; // Inode number + int ref; // Reference count + int flags; // I_BUSY, I_VALID + + short type; // copy of disk inode + short major; + short minor; + short nlink; + uint size; + uint addrs[NDIRECT+1]; +}; +#define I_BUSY 0x1 +#define I_VALID 0x2 + +// table mapping major device number to +// device functions +struct devsw { + int (*read)(struct inode*, char*, int); + int (*write)(struct inode*, char*, int); +}; + +extern struct devsw devsw[]; + +#define CONSOLE 1 diff -r 000000000000 -r c450faca55f4 uprogs/forktest.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/forktest.asm Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,912 @@ + +_forktest: file format elf32-littlearm + + +Disassembly of section .text: + +00000000
: + printf(1, "fork test OK\n"); +} + +int +main(void) +{ + 0: e92d4800 push {fp, lr} + 4: e28db004 add fp, sp, #4 + forktest(); + 8: eb00000f bl 4c + exit(); + c: eb0000e3 bl 3a0 + +00000010 : + +#define N 1000 + +void +printf(int fd, char *s, ...) +{ + 10: e92d000e push {r1, r2, r3} + 14: e92d4838 push {r3, r4, r5, fp, lr} + 18: e28db010 add fp, sp, #16 + 1c: e1a05000 mov r5, r0 + 20: e59b4004 ldr r4, [fp, #4] + write(fd, s, strlen(s)); + 24: e1a00004 mov r0, r4 + 28: eb000051 bl 174 + 2c: e1a01004 mov r1, r4 + 30: e1a02000 mov r2, r0 + 34: e1a00005 mov r0, r5 + 38: eb00010c bl 470 +} + 3c: e24bd010 sub sp, fp, #16 + 40: e8bd4838 pop {r3, r4, r5, fp, lr} + 44: e28dd00c add sp, sp, #12 + 48: e12fff1e bx lr + +0000004c : + +void +forktest(void) +{ + 4c: e92d4818 push {r3, r4, fp, lr} + int n, pid; + + printf(1, "fork test\n"); + 50: e3a00001 mov r0, #1 + write(fd, s, strlen(s)); +} + +void +forktest(void) +{ + 54: e28db00c add fp, sp, #12 + int n, pid; + + printf(1, "fork test\n"); + 58: e59f108c ldr r1, [pc, #140] ; ec + 5c: ebffffeb bl 10 + + for(n=0; n + pid = fork(); + if(pid < 0) + break; + if(pid == 0) + 68: 0a00001b beq dc +{ + int n, pid; + + printf(1, "fork test\n"); + + for(n=0; n + pid = fork(); + 78: eb0000bb bl 36c + if(pid < 0) + 7c: e3500000 cmp r0, #0 + 80: aafffff8 bge 68 + if(n == N){ + printf(1, "fork claimed to work N times!\n", N); + exit(); + } + + for(; n > 0; n--){ + 84: e3540000 cmp r4, #0 + 88: 0a000004 beq a0 + if(wait() < 0){ + 8c: eb0000d0 bl 3d4 + 90: e3500000 cmp r0, #0 + 94: ba00000d blt d0 + if(n == N){ + printf(1, "fork claimed to work N times!\n", N); + exit(); + } + + for(; n > 0; n--){ + 98: e2544001 subs r4, r4, #1 + 9c: 1afffffa bne 8c + printf(1, "wait stopped early\n"); + exit(); + } + } + + if(wait() != -1){ + a0: eb0000cb bl 3d4 + a4: e3700001 cmn r0, #1 + printf(1, "wait got too many\n"); + a8: e3a00001 mov r0, #1 + printf(1, "wait stopped early\n"); + exit(); + } + } + + if(wait() != -1){ + ac: 1a00000b bne e0 + printf(1, "wait got too many\n"); + exit(); + } + + printf(1, "fork test OK\n"); + b0: e59f1038 ldr r1, [pc, #56] ; f0 +} + b4: e8bd4818 pop {r3, r4, fp, lr} + if(wait() != -1){ + printf(1, "wait got too many\n"); + exit(); + } + + printf(1, "fork test OK\n"); + b8: eaffffd4 b 10 + if(pid == 0) + exit(); + } + + if(n == N){ + printf(1, "fork claimed to work N times!\n", N); + bc: e3a00001 mov r0, #1 + c0: e59f102c ldr r1, [pc, #44] ; f4 + c4: e1a02004 mov r2, r4 + c8: ebffffd0 bl 10 + exit(); + cc: eb0000b3 bl 3a0 + } + + for(; n > 0; n--){ + if(wait() < 0){ + printf(1, "wait stopped early\n"); + d0: e3a00001 mov r0, #1 + d4: e59f101c ldr r1, [pc, #28] ; f8 + d8: ebffffcc bl 10 + exit(); + dc: eb0000af bl 3a0 + } + } + + if(wait() != -1){ + printf(1, "wait got too many\n"); + e0: e59f1014 ldr r1, [pc, #20] ; fc + e4: ebffffc9 bl 10 + exit(); + e8: eb0000ac bl 3a0 + ec: 000007b0 .word 0x000007b0 + f0: 000007e4 .word 0x000007e4 + f4: 000007f4 .word 0x000007f4 + f8: 000007bc .word 0x000007bc + fc: 000007d0 .word 0x000007d0 + +00000100 : +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 100: e52db004 push {fp} ; (str fp, [sp, #-4]!) + char *os; + + os = s; + while((*s++ = *t++) != 0) + 104: e1a02000 mov r2, r0 +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 108: e28db000 add fp, sp, #0 + char *os; + + os = s; + while((*s++ = *t++) != 0) + 10c: e4d13001 ldrb r3, [r1], #1 + 110: e3530000 cmp r3, #0 + 114: e4c23001 strb r3, [r2], #1 + 118: 1afffffb bne 10c + ; + return os; +} + 11c: e28bd000 add sp, fp, #0 + 120: e8bd0800 pop {fp} + 124: e12fff1e bx lr + +00000128 : + +int +strcmp(const char *p, const char *q) +{ + 128: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 12c: e28db000 add fp, sp, #0 + while(*p && *p == *q) + 130: e5d03000 ldrb r3, [r0] + 134: e5d12000 ldrb r2, [r1] + 138: e3530000 cmp r3, #0 + 13c: 1a000004 bne 154 + 140: ea000005 b 15c + 144: e5f03001 ldrb r3, [r0, #1]! + 148: e3530000 cmp r3, #0 + 14c: 0a000006 beq 16c + 150: e5f12001 ldrb r2, [r1, #1]! + 154: e1530002 cmp r3, r2 + 158: 0afffff9 beq 144 + p++, q++; + return (uchar)*p - (uchar)*q; +} + 15c: e0620003 rsb r0, r2, r3 + 160: e28bd000 add sp, fp, #0 + 164: e8bd0800 pop {fp} + 168: e12fff1e bx lr +} + +int +strcmp(const char *p, const char *q) +{ + while(*p && *p == *q) + 16c: e5d12001 ldrb r2, [r1, #1] + 170: eafffff9 b 15c + +00000174 : + return (uchar)*p - (uchar)*q; +} + +uint +strlen(char *s) +{ + 174: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 178: e28db000 add fp, sp, #0 + int n; + + for(n = 0; s[n]; n++) + 17c: e5d03000 ldrb r3, [r0] + 180: e3530000 cmp r3, #0 + 184: 01a00003 moveq r0, r3 + 188: 0a000006 beq 1a8 + 18c: e1a02000 mov r2, r0 + 190: e3a03000 mov r3, #0 + 194: e5f21001 ldrb r1, [r2, #1]! + 198: e2833001 add r3, r3, #1 + 19c: e1a00003 mov r0, r3 + 1a0: e3510000 cmp r1, #0 + 1a4: 1afffffa bne 194 + ; + return n; +} + 1a8: e28bd000 add sp, fp, #0 + 1ac: e8bd0800 pop {fp} + 1b0: e12fff1e bx lr + +000001b4 : +memset(void *dst, int c, uint n) +{ + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 1b4: e3520000 cmp r2, #0 + return n; +} + +void* +memset(void *dst, int c, uint n) +{ + 1b8: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 1bc: e28db000 add fp, sp, #0 + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 1c0: 0a000006 beq 1e0 + 1c4: e6ef1071 uxtb r1, r1 + 1c8: e1a03002 mov r3, r2 +} + +void* +memset(void *dst, int c, uint n) +{ + char *p=dst; + 1cc: e1a0c000 mov ip, r0 + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 1d0: e2533001 subs r3, r3, #1 + 1d4: e4cc1001 strb r1, [ip], #1 + 1d8: 1afffffc bne 1d0 + 1dc: e0800002 add r0, r0, r2 + return (void *)p; +} + 1e0: e28bd000 add sp, fp, #0 + 1e4: e8bd0800 pop {fp} + 1e8: e12fff1e bx lr + +000001ec : + +char* +strchr(const char *s, char c) +{ + 1ec: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 1f0: e28db000 add fp, sp, #0 + for(; *s; s++) + 1f4: e5d03000 ldrb r3, [r0] + 1f8: e3530000 cmp r3, #0 + 1fc: 1a000004 bne 214 + 200: ea000008 b 228 + 204: e5d03001 ldrb r3, [r0, #1] + 208: e2800001 add r0, r0, #1 + 20c: e3530000 cmp r3, #0 + 210: 0a000004 beq 228 + if(*s == c) + 214: e1530001 cmp r3, r1 + 218: 1afffff9 bne 204 + return (char*)s; + return 0; +} + 21c: e28bd000 add sp, fp, #0 + 220: e8bd0800 pop {fp} + 224: e12fff1e bx lr +strchr(const char *s, char c) +{ + for(; *s; s++) + if(*s == c) + return (char*)s; + return 0; + 228: e1a00003 mov r0, r3 + 22c: eafffffa b 21c + +00000230 : +} + +char* +gets(char *buf, int max) +{ + 230: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + 234: e28db018 add fp, sp, #24 + 238: e24dd00c sub sp, sp, #12 + 23c: e1a08000 mov r8, r0 + 240: e1a07001 mov r7, r1 + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 244: e1a06000 mov r6, r0 + 248: e3a05000 mov r5, #0 + 24c: ea000008 b 274 + cc = read(0, &c, 1); + 250: eb000079 bl 43c + if(cc < 1) + 254: e3500000 cmp r0, #0 + 258: da00000b ble 28c + break; + buf[i++] = c; + 25c: e55b301d ldrb r3, [fp, #-29] + if(c == '\n' || c == '\r') + 260: e1a05004 mov r5, r4 + 264: e353000a cmp r3, #10 + 268: 1353000d cmpne r3, #13 + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + if(cc < 1) + break; + buf[i++] = c; + 26c: e4c63001 strb r3, [r6], #1 + if(c == '\n' || c == '\r') + 270: 0a00000a beq 2a0 +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + 274: e3a02001 mov r2, #1 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 278: e0854002 add r4, r5, r2 + 27c: e1540007 cmp r4, r7 + cc = read(0, &c, 1); + 280: e3a00000 mov r0, #0 + 284: e24b101d sub r1, fp, #29 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 288: bafffff0 blt 250 + break; + buf[i++] = c; + if(c == '\n' || c == '\r') + break; + } + buf[i] = '\0'; + 28c: e3a03000 mov r3, #0 + 290: e7c83005 strb r3, [r8, r5] + return buf; +} + 294: e1a00008 mov r0, r8 + 298: e24bd018 sub sp, fp, #24 + 29c: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 2a0: e1a05004 mov r5, r4 + 2a4: eafffff8 b 28c + +000002a8 : + return buf; +} + +int +stat(char *n, struct stat *st) +{ + 2a8: e92d4830 push {r4, r5, fp, lr} + 2ac: e1a05001 mov r5, r1 + 2b0: e28db00c add fp, sp, #12 + int fd; + int r; + + fd = open(n, O_RDONLY); + 2b4: e3a01000 mov r1, #0 + 2b8: eb0000a0 bl 540 + if(fd < 0) + 2bc: e2504000 subs r4, r0, #0 + return -1; + 2c0: b3e05000 mvnlt r5, #0 +{ + int fd; + int r; + + fd = open(n, O_RDONLY); + if(fd < 0) + 2c4: ba000004 blt 2dc + return -1; + r = fstat(fd, st); + 2c8: e1a01005 mov r1, r5 + 2cc: eb0000c2 bl 5dc + 2d0: e1a05000 mov r5, r0 + close(fd); + 2d4: e1a00004 mov r0, r4 + 2d8: eb000071 bl 4a4 + return r; +} + 2dc: e1a00005 mov r0, r5 + 2e0: e8bd8830 pop {r4, r5, fp, pc} + +000002e4 : + +int +atoi(const char *s) +{ + 2e4: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 2e8: e28db000 add fp, sp, #0 + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 2ec: e5d03000 ldrb r3, [r0] + 2f0: e2432030 sub r2, r3, #48 ; 0x30 + 2f4: e6ef2072 uxtb r2, r2 + 2f8: e3520009 cmp r2, #9 +int +atoi(const char *s) +{ + int n; + + n = 0; + 2fc: 83a00000 movhi r0, #0 + while('0' <= *s && *s <= '9') + 300: 8a000009 bhi 32c + 304: e1a02000 mov r2, r0 +int +atoi(const char *s) +{ + int n; + + n = 0; + 308: e3a00000 mov r0, #0 + while('0' <= *s && *s <= '9') + n = n*10 + *s++ - '0'; + 30c: e0800100 add r0, r0, r0, lsl #2 + 310: e0830080 add r0, r3, r0, lsl #1 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 314: e5f23001 ldrb r3, [r2, #1]! + n = n*10 + *s++ - '0'; + 318: e2400030 sub r0, r0, #48 ; 0x30 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 31c: e2431030 sub r1, r3, #48 ; 0x30 + 320: e6ef1071 uxtb r1, r1 + 324: e3510009 cmp r1, #9 + 328: 9afffff7 bls 30c + n = n*10 + *s++ - '0'; + return n; +} + 32c: e28bd000 add sp, fp, #0 + 330: e8bd0800 pop {fp} + 334: e12fff1e bx lr + +00000338 : +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 338: e3520000 cmp r2, #0 + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) +{ + 33c: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 340: e28db000 add fp, sp, #0 + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 344: da000005 ble 360 + n = n*10 + *s++ - '0'; + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) + 348: e0802002 add r2, r0, r2 +{ + char *dst, *src; + + dst = vdst; + 34c: e1a03000 mov r3, r0 + src = vsrc; + while(n-- > 0) + *dst++ = *src++; + 350: e4d1c001 ldrb ip, [r1], #1 + 354: e4c3c001 strb ip, [r3], #1 +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 358: e1530002 cmp r3, r2 + 35c: 1afffffb bne 350 + *dst++ = *src++; + return vdst; +} + 360: e28bd000 add sp, fp, #0 + 364: e8bd0800 pop {fp} + 368: e12fff1e bx lr + +0000036c : + 36c: e92d4000 push {lr} + 370: e92d0008 push {r3} + 374: e92d0004 push {r2} + 378: e92d0002 push {r1} + 37c: e92d0001 push {r0} + 380: e3a00001 mov r0, #1 + 384: ef000040 svc 0x00000040 + 388: e8bd0002 pop {r1} + 38c: e8bd0002 pop {r1} + 390: e8bd0004 pop {r2} + 394: e8bd0008 pop {r3} + 398: e8bd4000 pop {lr} + 39c: e12fff1e bx lr + +000003a0 : + 3a0: e92d4000 push {lr} + 3a4: e92d0008 push {r3} + 3a8: e92d0004 push {r2} + 3ac: e92d0002 push {r1} + 3b0: e92d0001 push {r0} + 3b4: e3a00002 mov r0, #2 + 3b8: ef000040 svc 0x00000040 + 3bc: e8bd0002 pop {r1} + 3c0: e8bd0002 pop {r1} + 3c4: e8bd0004 pop {r2} + 3c8: e8bd0008 pop {r3} + 3cc: e8bd4000 pop {lr} + 3d0: e12fff1e bx lr + +000003d4 : + 3d4: e92d4000 push {lr} + 3d8: e92d0008 push {r3} + 3dc: e92d0004 push {r2} + 3e0: e92d0002 push {r1} + 3e4: e92d0001 push {r0} + 3e8: e3a00003 mov r0, #3 + 3ec: ef000040 svc 0x00000040 + 3f0: e8bd0002 pop {r1} + 3f4: e8bd0002 pop {r1} + 3f8: e8bd0004 pop {r2} + 3fc: e8bd0008 pop {r3} + 400: e8bd4000 pop {lr} + 404: e12fff1e bx lr + +00000408 : + 408: e92d4000 push {lr} + 40c: e92d0008 push {r3} + 410: e92d0004 push {r2} + 414: e92d0002 push {r1} + 418: e92d0001 push {r0} + 41c: e3a00004 mov r0, #4 + 420: ef000040 svc 0x00000040 + 424: e8bd0002 pop {r1} + 428: e8bd0002 pop {r1} + 42c: e8bd0004 pop {r2} + 430: e8bd0008 pop {r3} + 434: e8bd4000 pop {lr} + 438: e12fff1e bx lr + +0000043c : + 43c: e92d4000 push {lr} + 440: e92d0008 push {r3} + 444: e92d0004 push {r2} + 448: e92d0002 push {r1} + 44c: e92d0001 push {r0} + 450: e3a00005 mov r0, #5 + 454: ef000040 svc 0x00000040 + 458: e8bd0002 pop {r1} + 45c: e8bd0002 pop {r1} + 460: e8bd0004 pop {r2} + 464: e8bd0008 pop {r3} + 468: e8bd4000 pop {lr} + 46c: e12fff1e bx lr + +00000470 : + 470: e92d4000 push {lr} + 474: e92d0008 push {r3} + 478: e92d0004 push {r2} + 47c: e92d0002 push {r1} + 480: e92d0001 push {r0} + 484: e3a00010 mov r0, #16 + 488: ef000040 svc 0x00000040 + 48c: e8bd0002 pop {r1} + 490: e8bd0002 pop {r1} + 494: e8bd0004 pop {r2} + 498: e8bd0008 pop {r3} + 49c: e8bd4000 pop {lr} + 4a0: e12fff1e bx lr + +000004a4 : + 4a4: e92d4000 push {lr} + 4a8: e92d0008 push {r3} + 4ac: e92d0004 push {r2} + 4b0: e92d0002 push {r1} + 4b4: e92d0001 push {r0} + 4b8: e3a00015 mov r0, #21 + 4bc: ef000040 svc 0x00000040 + 4c0: e8bd0002 pop {r1} + 4c4: e8bd0002 pop {r1} + 4c8: e8bd0004 pop {r2} + 4cc: e8bd0008 pop {r3} + 4d0: e8bd4000 pop {lr} + 4d4: e12fff1e bx lr + +000004d8 : + 4d8: e92d4000 push {lr} + 4dc: e92d0008 push {r3} + 4e0: e92d0004 push {r2} + 4e4: e92d0002 push {r1} + 4e8: e92d0001 push {r0} + 4ec: e3a00006 mov r0, #6 + 4f0: ef000040 svc 0x00000040 + 4f4: e8bd0002 pop {r1} + 4f8: e8bd0002 pop {r1} + 4fc: e8bd0004 pop {r2} + 500: e8bd0008 pop {r3} + 504: e8bd4000 pop {lr} + 508: e12fff1e bx lr + +0000050c : + 50c: e92d4000 push {lr} + 510: e92d0008 push {r3} + 514: e92d0004 push {r2} + 518: e92d0002 push {r1} + 51c: e92d0001 push {r0} + 520: e3a00007 mov r0, #7 + 524: ef000040 svc 0x00000040 + 528: e8bd0002 pop {r1} + 52c: e8bd0002 pop {r1} + 530: e8bd0004 pop {r2} + 534: e8bd0008 pop {r3} + 538: e8bd4000 pop {lr} + 53c: e12fff1e bx lr + +00000540 : + 540: e92d4000 push {lr} + 544: e92d0008 push {r3} + 548: e92d0004 push {r2} + 54c: e92d0002 push {r1} + 550: e92d0001 push {r0} + 554: e3a0000f mov r0, #15 + 558: ef000040 svc 0x00000040 + 55c: e8bd0002 pop {r1} + 560: e8bd0002 pop {r1} + 564: e8bd0004 pop {r2} + 568: e8bd0008 pop {r3} + 56c: e8bd4000 pop {lr} + 570: e12fff1e bx lr + +00000574 : + 574: e92d4000 push {lr} + 578: e92d0008 push {r3} + 57c: e92d0004 push {r2} + 580: e92d0002 push {r1} + 584: e92d0001 push {r0} + 588: e3a00011 mov r0, #17 + 58c: ef000040 svc 0x00000040 + 590: e8bd0002 pop {r1} + 594: e8bd0002 pop {r1} + 598: e8bd0004 pop {r2} + 59c: e8bd0008 pop {r3} + 5a0: e8bd4000 pop {lr} + 5a4: e12fff1e bx lr + +000005a8 : + 5a8: e92d4000 push {lr} + 5ac: e92d0008 push {r3} + 5b0: e92d0004 push {r2} + 5b4: e92d0002 push {r1} + 5b8: e92d0001 push {r0} + 5bc: e3a00012 mov r0, #18 + 5c0: ef000040 svc 0x00000040 + 5c4: e8bd0002 pop {r1} + 5c8: e8bd0002 pop {r1} + 5cc: e8bd0004 pop {r2} + 5d0: e8bd0008 pop {r3} + 5d4: e8bd4000 pop {lr} + 5d8: e12fff1e bx lr + +000005dc : + 5dc: e92d4000 push {lr} + 5e0: e92d0008 push {r3} + 5e4: e92d0004 push {r2} + 5e8: e92d0002 push {r1} + 5ec: e92d0001 push {r0} + 5f0: e3a00008 mov r0, #8 + 5f4: ef000040 svc 0x00000040 + 5f8: e8bd0002 pop {r1} + 5fc: e8bd0002 pop {r1} + 600: e8bd0004 pop {r2} + 604: e8bd0008 pop {r3} + 608: e8bd4000 pop {lr} + 60c: e12fff1e bx lr + +00000610 : + 610: e92d4000 push {lr} + 614: e92d0008 push {r3} + 618: e92d0004 push {r2} + 61c: e92d0002 push {r1} + 620: e92d0001 push {r0} + 624: e3a00013 mov r0, #19 + 628: ef000040 svc 0x00000040 + 62c: e8bd0002 pop {r1} + 630: e8bd0002 pop {r1} + 634: e8bd0004 pop {r2} + 638: e8bd0008 pop {r3} + 63c: e8bd4000 pop {lr} + 640: e12fff1e bx lr + +00000644 : + 644: e92d4000 push {lr} + 648: e92d0008 push {r3} + 64c: e92d0004 push {r2} + 650: e92d0002 push {r1} + 654: e92d0001 push {r0} + 658: e3a00014 mov r0, #20 + 65c: ef000040 svc 0x00000040 + 660: e8bd0002 pop {r1} + 664: e8bd0002 pop {r1} + 668: e8bd0004 pop {r2} + 66c: e8bd0008 pop {r3} + 670: e8bd4000 pop {lr} + 674: e12fff1e bx lr + +00000678 : + 678: e92d4000 push {lr} + 67c: e92d0008 push {r3} + 680: e92d0004 push {r2} + 684: e92d0002 push {r1} + 688: e92d0001 push {r0} + 68c: e3a00009 mov r0, #9 + 690: ef000040 svc 0x00000040 + 694: e8bd0002 pop {r1} + 698: e8bd0002 pop {r1} + 69c: e8bd0004 pop {r2} + 6a0: e8bd0008 pop {r3} + 6a4: e8bd4000 pop {lr} + 6a8: e12fff1e bx lr + +000006ac : + 6ac: e92d4000 push {lr} + 6b0: e92d0008 push {r3} + 6b4: e92d0004 push {r2} + 6b8: e92d0002 push {r1} + 6bc: e92d0001 push {r0} + 6c0: e3a0000a mov r0, #10 + 6c4: ef000040 svc 0x00000040 + 6c8: e8bd0002 pop {r1} + 6cc: e8bd0002 pop {r1} + 6d0: e8bd0004 pop {r2} + 6d4: e8bd0008 pop {r3} + 6d8: e8bd4000 pop {lr} + 6dc: e12fff1e bx lr + +000006e0 : + 6e0: e92d4000 push {lr} + 6e4: e92d0008 push {r3} + 6e8: e92d0004 push {r2} + 6ec: e92d0002 push {r1} + 6f0: e92d0001 push {r0} + 6f4: e3a0000b mov r0, #11 + 6f8: ef000040 svc 0x00000040 + 6fc: e8bd0002 pop {r1} + 700: e8bd0002 pop {r1} + 704: e8bd0004 pop {r2} + 708: e8bd0008 pop {r3} + 70c: e8bd4000 pop {lr} + 710: e12fff1e bx lr + +00000714 : + 714: e92d4000 push {lr} + 718: e92d0008 push {r3} + 71c: e92d0004 push {r2} + 720: e92d0002 push {r1} + 724: e92d0001 push {r0} + 728: e3a0000c mov r0, #12 + 72c: ef000040 svc 0x00000040 + 730: e8bd0002 pop {r1} + 734: e8bd0002 pop {r1} + 738: e8bd0004 pop {r2} + 73c: e8bd0008 pop {r3} + 740: e8bd4000 pop {lr} + 744: e12fff1e bx lr + +00000748 : + 748: e92d4000 push {lr} + 74c: e92d0008 push {r3} + 750: e92d0004 push {r2} + 754: e92d0002 push {r1} + 758: e92d0001 push {r0} + 75c: e3a0000d mov r0, #13 + 760: ef000040 svc 0x00000040 + 764: e8bd0002 pop {r1} + 768: e8bd0002 pop {r1} + 76c: e8bd0004 pop {r2} + 770: e8bd0008 pop {r3} + 774: e8bd4000 pop {lr} + 778: e12fff1e bx lr + +0000077c : + 77c: e92d4000 push {lr} + 780: e92d0008 push {r3} + 784: e92d0004 push {r2} + 788: e92d0002 push {r1} + 78c: e92d0001 push {r0} + 790: e3a0000e mov r0, #14 + 794: ef000040 svc 0x00000040 + 798: e8bd0002 pop {r1} + 79c: e8bd0002 pop {r1} + 7a0: e8bd0004 pop {r2} + 7a4: e8bd0008 pop {r3} + 7a8: e8bd4000 pop {lr} + 7ac: e12fff1e bx lr diff -r 000000000000 -r c450faca55f4 uprogs/forktest.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/forktest.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,56 @@ +// Test that fork fails gracefully. +// Tiny executable so that the limit can be filling the proc table. + +#include "types.h" +#include "stat.h" +#include "user.h" + +#define N 1000 + +void +printf(int fd, char *s, ...) +{ + write(fd, s, strlen(s)); +} + +void +forktest(void) +{ + int n, pid; + + printf(1, "fork test\n"); + + for(n=0; n 0; n--){ + if(wait() < 0){ + printf(1, "wait stopped early\n"); + exit(); + } + } + + if(wait() != -1){ + printf(1, "wait got too many\n"); + exit(); + } + + printf(1, "fork test OK\n"); +} + +int +main(void) +{ + forktest(); + exit(); +} diff -r 000000000000 -r c450faca55f4 uprogs/fs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/fs.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,55 @@ +// On-disk file system format. +// Both the kernel and user programs use this header file. + +// Block 0 is unused. +// Block 1 is super block. +// Blocks 2 through sb.ninodes/IPB hold inodes. +// Then free bitmap blocks holding sb.size bits. +// Then sb.nblocks data blocks. +// Then sb.nlog log blocks. + +#define ROOTINO 1 // root i-number +#define BSIZE 512 // block size + +// File system super block +struct superblock { + uint size; // Size of file system image (blocks) + uint nblocks; // Number of data blocks + uint ninodes; // Number of inodes. + uint nlog; // Number of log blocks +}; + +#define NDIRECT 12 +#define NINDIRECT (BSIZE / sizeof(uint)) +#define MAXFILE (NDIRECT + NINDIRECT) + +// On-disk inode structure +struct dinode { + short type; // File type + short major; // Major device number (T_DEV only) + short minor; // Minor device number (T_DEV only) + short nlink; // Number of links to inode in file system + uint size; // Size of file (bytes) + uint addrs[NDIRECT+1]; // Data block addresses +}; + +// Inodes per block. +#define IPB (BSIZE / sizeof(struct dinode)) + +// Block containing inode i +#define IBLOCK(i) ((i) / IPB + 2) + +// Bitmap bits per block +#define BPB (BSIZE*8) + +// Block containing bit for block b +#define BBLOCK(b, ninodes) (b/BPB + (ninodes)/IPB + 3) + +// Directory is a file containing a sequence of dirent structures. +#define DIRSIZ 14 + +struct dirent { + ushort inum; + char name[DIRSIZ]; +}; + diff -r 000000000000 -r c450faca55f4 uprogs/grep.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/grep.asm Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,2205 @@ + +_grep: file format elf32-littlearm + + +Disassembly of section .text: + +00000000
: +main(int argc, char *argv[]) +{ + int fd, i; + char *pattern; + + if(argc <= 1){ + 0: e3500001 cmp r0, #1 + } +} + +int +main(int argc, char *argv[]) +{ + 4: e92d4df0 push {r4, r5, r6, r7, r8, sl, fp, lr} + 8: e1a08000 mov r8, r0 + c: e28db01c add fp, sp, #28 + int fd, i; + char *pattern; + + if(argc <= 1){ + 10: da00001d ble 8c + printf(2, "usage: grep pattern [file ...]\n"); + exit(); + } + pattern = argv[1]; + + if(argc <= 2){ + 14: e3500002 cmp r0, #2 + + if(argc <= 1){ + printf(2, "usage: grep pattern [file ...]\n"); + exit(); + } + pattern = argv[1]; + 18: e591a004 ldr sl, [r1, #4] + } + } +} + +int +main(int argc, char *argv[]) + 1c: 12814008 addne r4, r1, #8 + 20: 13a05002 movne r5, #2 + printf(2, "usage: grep pattern [file ...]\n"); + exit(); + } + pattern = argv[1]; + + if(argc <= 2){ + 24: 0a000014 beq 7c + grep(pattern, 0); + exit(); + } + + for(i = 2; i < argc; i++){ + if((fd = open(argv[i], 0)) < 0){ + 28: e5940000 ldr r0, [r4] + 2c: e3a01000 mov r1, #0 + 30: eb0001c7 bl 754 + 34: e1a07004 mov r7, r4 + 38: e2844004 add r4, r4, #4 + 3c: e2506000 subs r6, r0, #0 + 40: ba000008 blt 68 + printf(1, "grep: cannot open %s\n", argv[i]); + exit(); + } + grep(pattern, fd); + 44: e1a01006 mov r1, r6 + 48: e1a0000a mov r0, sl + 4c: eb00006f bl 210 + if(argc <= 2){ + grep(pattern, 0); + exit(); + } + + for(i = 2; i < argc; i++){ + 50: e2855001 add r5, r5, #1 + if((fd = open(argv[i], 0)) < 0){ + printf(1, "grep: cannot open %s\n", argv[i]); + exit(); + } + grep(pattern, fd); + close(fd); + 54: e1a00006 mov r0, r6 + 58: eb000196 bl 6b8 + if(argc <= 2){ + grep(pattern, 0); + exit(); + } + + for(i = 2; i < argc; i++){ + 5c: e1580005 cmp r8, r5 + 60: cafffff0 bgt 28 + exit(); + } + grep(pattern, fd); + close(fd); + } + exit(); + 64: eb000152 bl 5b4 + exit(); + } + + for(i = 2; i < argc; i++){ + if((fd = open(argv[i], 0)) < 0){ + printf(1, "grep: cannot open %s\n", argv[i]); + 68: e3a00001 mov r0, #1 + 6c: e59f1028 ldr r1, [pc, #40] ; 9c + 70: e5972000 ldr r2, [r7] + 74: eb0002a1 bl b00 + exit(); + 78: eb00014d bl 5b4 + exit(); + } + pattern = argv[1]; + + if(argc <= 2){ + grep(pattern, 0); + 7c: e1a0000a mov r0, sl + 80: e3a01000 mov r1, #0 + 84: eb000061 bl 210 + exit(); + 88: eb000149 bl 5b4 +{ + int fd, i; + char *pattern; + + if(argc <= 1){ + printf(2, "usage: grep pattern [file ...]\n"); + 8c: e3a00002 mov r0, #2 + 90: e59f1008 ldr r1, [pc, #8] ; a0 + 94: eb000299 bl b00 + exit(); + 98: eb000145 bl 5b4 + 9c: 00000e08 .word 0x00000e08 + a0: 00000de8 .word 0x00000de8 + +000000a4 : + return 0; +} + +// matchstar: search for c*re at beginning of text +int matchstar(int c, char *re, char *text) +{ + a4: e92d4878 push {r3, r4, r5, r6, fp, lr} + a8: e1a04000 mov r4, r0 + ac: e28db014 add fp, sp, #20 + b0: e1a05001 mov r5, r1 + b4: e1a06002 mov r6, r2 + do{ // a * matches zero or more instances + if(matchhere(re, text)) + b8: e1a01006 mov r1, r6 + bc: e1a00005 mov r0, r5 + c0: eb00000d bl fc + c4: e3500000 cmp r0, #0 + c8: 1a000007 bne ec + return 1; + }while(*text!='\0' && (*text++==c || c=='.')); + cc: e4d63001 ldrb r3, [r6], #1 + d0: e3530000 cmp r3, #0 + d4: 0a000006 beq f4 + d8: e1530004 cmp r3, r4 + dc: 0afffff5 beq b8 + e0: e354002e cmp r4, #46 ; 0x2e + e4: 0afffff3 beq b8 + e8: e8bd8878 pop {r3, r4, r5, r6, fp, pc} +// matchstar: search for c*re at beginning of text +int matchstar(int c, char *re, char *text) +{ + do{ // a * matches zero or more instances + if(matchhere(re, text)) + return 1; + ec: e3a00001 mov r0, #1 + f0: e8bd8878 pop {r3, r4, r5, r6, fp, pc} + }while(*text!='\0' && (*text++==c || c=='.')); + return 0; + f4: e1a00003 mov r0, r3 +} + f8: e8bd8878 pop {r3, r4, r5, r6, fp, pc} + +000000fc : + return 0; +} + +// matchhere: search for re at beginning of text +int matchhere(char *re, char *text) +{ + fc: e92d0810 push {r4, fp} + 100: e1a03000 mov r3, r0 + if(re[0] == '\0') + 104: e5d00000 ldrb r0, [r0] + return 0; +} + +// matchhere: search for re at beginning of text +int matchhere(char *re, char *text) +{ + 108: e28db004 add fp, sp, #4 + 10c: e1a02001 mov r2, r1 + if(re[0] == '\0') + 110: e3500000 cmp r0, #0 + 114: 0a00001c beq 18c + return 1; + if(re[1] == '*') + 118: e5d3c001 ldrb ip, [r3, #1] + 11c: e35c002a cmp ip, #42 ; 0x2a + }while(*text++ != '\0'); + return 0; +} + +// matchhere: search for re at beginning of text +int matchhere(char *re, char *text) + 120: 12834002 addne r4, r3, #2 +{ + if(re[0] == '\0') + return 1; + if(re[1] == '*') + return matchstar(re[0], re+2, text); + 124: 11a01001 movne r1, r1 +// matchhere: search for re at beginning of text +int matchhere(char *re, char *text) +{ + if(re[0] == '\0') + return 1; + if(re[1] == '*') + 128: 1a00000f bne 16c + 12c: ea00001a b 19c + return matchstar(re[0], re+2, text); + if(re[0] == '$' && re[1] == '\0') + return *text == '\0'; + if(*text!='\0' && (re[0]=='.' || re[0]==*text)) + 130: e4d12001 ldrb r2, [r1], #1 + 134: e3520000 cmp r2, #0 + 138: 0a00001b beq 1ac + 13c: e350002e cmp r0, #46 ; 0x2e + 140: 0a000001 beq 14c + 144: e1500002 cmp r0, r2 + 148: 1a000019 bne 1b4 +} + +// matchhere: search for re at beginning of text +int matchhere(char *re, char *text) +{ + if(re[0] == '\0') + 14c: e5d30001 ldrb r0, [r3, #1] + if(re[1] == '*') + return matchstar(re[0], re+2, text); + if(re[0] == '$' && re[1] == '\0') + return *text == '\0'; + if(*text!='\0' && (re[0]=='.' || re[0]==*text)) + return matchhere(re+1, text+1); + 150: e1a02001 mov r2, r1 + 154: e2833001 add r3, r3, #1 +} + +// matchhere: search for re at beginning of text +int matchhere(char *re, char *text) +{ + if(re[0] == '\0') + 158: e3500000 cmp r0, #0 + 15c: 0a00000a beq 18c + return 1; + if(re[1] == '*') + 160: e4d4c001 ldrb ip, [r4], #1 + 164: e35c002a cmp ip, #42 ; 0x2a + 168: 0a00000b beq 19c + return matchstar(re[0], re+2, text); + if(re[0] == '$' && re[1] == '\0') + 16c: e3500024 cmp r0, #36 ; 0x24 + 170: 1affffee bne 130 + 174: e35c0000 cmp ip, #0 + 178: 1affffec bne 130 + return *text == '\0'; + 17c: e5d10000 ldrb r0, [r1] + 180: e2700001 rsbs r0, r0, #1 + 184: 33a00000 movcc r0, #0 + 188: ea000000 b 190 + +// matchhere: search for re at beginning of text +int matchhere(char *re, char *text) +{ + if(re[0] == '\0') + return 1; + 18c: e3a00001 mov r0, #1 + if(re[0] == '$' && re[1] == '\0') + return *text == '\0'; + if(*text!='\0' && (re[0]=='.' || re[0]==*text)) + return matchhere(re+1, text+1); + return 0; +} + 190: e24bd004 sub sp, fp, #4 + 194: e8bd0810 pop {r4, fp} + 198: e12fff1e bx lr +int matchhere(char *re, char *text) +{ + if(re[0] == '\0') + return 1; + if(re[1] == '*') + return matchstar(re[0], re+2, text); + 19c: e2831002 add r1, r3, #2 + if(re[0] == '$' && re[1] == '\0') + return *text == '\0'; + if(*text!='\0' && (re[0]=='.' || re[0]==*text)) + return matchhere(re+1, text+1); + return 0; +} + 1a0: e24bd004 sub sp, fp, #4 + 1a4: e8bd0810 pop {r4, fp} +int matchhere(char *re, char *text) +{ + if(re[0] == '\0') + return 1; + if(re[1] == '*') + return matchstar(re[0], re+2, text); + 1a8: eaffffbd b a4 + if(re[0] == '$' && re[1] == '\0') + return *text == '\0'; + if(*text!='\0' && (re[0]=='.' || re[0]==*text)) + return matchhere(re+1, text+1); + return 0; + 1ac: e1a00002 mov r0, r2 + 1b0: eafffff6 b 190 + 1b4: e3a00000 mov r0, #0 + 1b8: eafffff4 b 190 + +000001bc : +int matchhere(char*, char*); +int matchstar(int, char*, char*); + +int +match(char *re, char *text) +{ + 1bc: e92d4830 push {r4, r5, fp, lr} + 1c0: e1a05000 mov r5, r0 + if(re[0] == '^') + 1c4: e5d03000 ldrb r3, [r0] +int matchhere(char*, char*); +int matchstar(int, char*, char*); + +int +match(char *re, char *text) +{ + 1c8: e28db00c add fp, sp, #12 + 1cc: e1a04001 mov r4, r1 + if(re[0] == '^') + 1d0: e353005e cmp r3, #94 ; 0x5e + 1d4: 0a00000a beq 204 + return matchhere(re+1, text); + do{ // must look at empty string + if(matchhere(re, text)) + 1d8: e1a01004 mov r1, r4 + 1dc: e1a00005 mov r0, r5 + 1e0: ebffffc5 bl fc + 1e4: e3500000 cmp r0, #0 + 1e8: 1a000003 bne 1fc + return 1; + }while(*text++ != '\0'); + 1ec: e4d40001 ldrb r0, [r4], #1 + 1f0: e3500000 cmp r0, #0 + 1f4: 1afffff7 bne 1d8 + 1f8: e8bd8830 pop {r4, r5, fp, pc} +{ + if(re[0] == '^') + return matchhere(re+1, text); + do{ // must look at empty string + if(matchhere(re, text)) + return 1; + 1fc: e3a00001 mov r0, #1 + }while(*text++ != '\0'); + return 0; +} + 200: e8bd8830 pop {r4, r5, fp, pc} + +int +match(char *re, char *text) +{ + if(re[0] == '^') + return matchhere(re+1, text); + 204: e2800001 add r0, r0, #1 + do{ // must look at empty string + if(matchhere(re, text)) + return 1; + }while(*text++ != '\0'); + return 0; +} + 208: e8bd4830 pop {r4, r5, fp, lr} + +int +match(char *re, char *text) +{ + if(re[0] == '^') + return matchhere(re+1, text); + 20c: eaffffba b fc + +00000210 : +char buf[1024]; +int match(char*, char*); + +void +grep(char *pattern, int fd) +{ + 210: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + int n, m; + char *p, *q; + + m = 0; + 214: e3a07000 mov r7, #0 + 218: e59fa0f0 ldr sl, [pc, #240] ; 310 +char buf[1024]; +int match(char*, char*); + +void +grep(char *pattern, int fd) +{ + 21c: e28db020 add fp, sp, #32 + 220: e1a05000 mov r5, r0 + m = 0; + while((n = read(fd, buf+m, sizeof(buf)-m)) > 0){ + m += n; + p = buf; + while((q = strchr(p, '\n')) != 0){ + *q = 0; + 224: e1a06007 mov r6, r7 +char buf[1024]; +int match(char*, char*); + +void +grep(char *pattern, int fd) +{ + 228: e24dd00c sub sp, sp, #12 + 22c: e50b102c str r1, [fp, #-44] ; 0x2c + int n, m; + char *p, *q; + + m = 0; + while((n = read(fd, buf+m, sizeof(buf)-m)) > 0){ + 230: e51b002c ldr r0, [fp, #-44] ; 0x2c + 234: e08a1007 add r1, sl, r7 + 238: e2672b01 rsb r2, r7, #1024 ; 0x400 + 23c: eb000103 bl 650 + 240: e3500000 cmp r0, #0 + 244: e50b0028 str r0, [fp, #-40] ; 0x28 + 248: da00002e ble 308 + 24c: e59f90bc ldr r9, [pc, #188] ; 310 + m += n; + p = buf; + while((q = strchr(p, '\n')) != 0){ + 250: e3a0800a mov r8, #10 + 254: e3a0100a mov r1, #10 + 258: e1a00009 mov r0, r9 + 25c: eb000067 bl 400 + *q = 0; + if(match(pattern, p)){ + 260: e1a01009 mov r1, r9 + + m = 0; + while((n = read(fd, buf+m, sizeof(buf)-m)) > 0){ + m += n; + p = buf; + while((q = strchr(p, '\n')) != 0){ + 264: e2504000 subs r4, r0, #0 + *q = 0; + if(match(pattern, p)){ + 268: e1a00005 mov r0, r5 + + m = 0; + while((n = read(fd, buf+m, sizeof(buf)-m)) > 0){ + m += n; + p = buf; + while((q = strchr(p, '\n')) != 0){ + 26c: 0a000011 beq 2b8 + *q = 0; + 270: e5c46000 strb r6, [r4] + if(match(pattern, p)){ + 274: ebffffd0 bl 1bc + 278: e3500000 cmp r0, #0 + 27c: 02849001 addeq r9, r4, #1 + 280: 0afffff3 beq 254 + *q = '\n'; + 284: e4c48001 strb r8, [r4], #1 + write(1, p, q+1 - p); + 288: e1a01009 mov r1, r9 + 28c: e0692004 rsb r2, r9, r4 + 290: e3a00001 mov r0, #1 + 294: e1a09004 mov r9, r4 + 298: eb0000f9 bl 684 + + m = 0; + while((n = read(fd, buf+m, sizeof(buf)-m)) > 0){ + m += n; + p = buf; + while((q = strchr(p, '\n')) != 0){ + 29c: e3a0100a mov r1, #10 + 2a0: e1a00009 mov r0, r9 + 2a4: eb000055 bl 400 + *q = 0; + if(match(pattern, p)){ + 2a8: e1a01009 mov r1, r9 + + m = 0; + while((n = read(fd, buf+m, sizeof(buf)-m)) > 0){ + m += n; + p = buf; + while((q = strchr(p, '\n')) != 0){ + 2ac: e2504000 subs r4, r0, #0 + *q = 0; + if(match(pattern, p)){ + 2b0: e1a00005 mov r0, r5 + + m = 0; + while((n = read(fd, buf+m, sizeof(buf)-m)) > 0){ + m += n; + p = buf; + while((q = strchr(p, '\n')) != 0){ + 2b4: 1affffed bne 270 + *q = '\n'; + write(1, p, q+1 - p); + } + p = q+1; + } + if(p == buf) + 2b8: e159000a cmp r9, sl + m = 0; + 2bc: 01a07004 moveq r7, r4 + *q = '\n'; + write(1, p, q+1 - p); + } + p = q+1; + } + if(p == buf) + 2c0: 0affffda beq 230 + int n, m; + char *p, *q; + + m = 0; + while((n = read(fd, buf+m, sizeof(buf)-m)) > 0){ + m += n; + 2c4: e51b3028 ldr r3, [fp, #-40] ; 0x28 + 2c8: e0877003 add r7, r7, r3 + } + p = q+1; + } + if(p == buf) + m = 0; + if(m > 0){ + 2cc: e3570000 cmp r7, #0 + 2d0: daffffd6 ble 230 + m -= p - buf; + 2d4: e59f2034 ldr r2, [pc, #52] ; 310 + memmove(buf, p, m); + 2d8: e59f0030 ldr r0, [pc, #48] ; 310 + p = q+1; + } + if(p == buf) + m = 0; + if(m > 0){ + m -= p - buf; + 2dc: e0693002 rsb r3, r9, r2 + 2e0: e0877003 add r7, r7, r3 + memmove(buf, p, m); + 2e4: e1a02007 mov r2, r7 + 2e8: eb000097 bl 54c +{ + int n, m; + char *p, *q; + + m = 0; + while((n = read(fd, buf+m, sizeof(buf)-m)) > 0){ + 2ec: e51b002c ldr r0, [fp, #-44] ; 0x2c + 2f0: e08a1007 add r1, sl, r7 + 2f4: e2672b01 rsb r2, r7, #1024 ; 0x400 + 2f8: eb0000d4 bl 650 + 2fc: e3500000 cmp r0, #0 + 300: e50b0028 str r0, [fp, #-40] ; 0x28 + 304: caffffd0 bgt 24c + if(m > 0){ + m -= p - buf; + memmove(buf, p, m); + } + } +} + 308: e24bd020 sub sp, fp, #32 + 30c: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} + 310: 00000e48 .word 0x00000e48 + +00000314 : +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 314: e52db004 push {fp} ; (str fp, [sp, #-4]!) + char *os; + + os = s; + while((*s++ = *t++) != 0) + 318: e1a02000 mov r2, r0 +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 31c: e28db000 add fp, sp, #0 + char *os; + + os = s; + while((*s++ = *t++) != 0) + 320: e4d13001 ldrb r3, [r1], #1 + 324: e3530000 cmp r3, #0 + 328: e4c23001 strb r3, [r2], #1 + 32c: 1afffffb bne 320 + ; + return os; +} + 330: e28bd000 add sp, fp, #0 + 334: e8bd0800 pop {fp} + 338: e12fff1e bx lr + +0000033c : + +int +strcmp(const char *p, const char *q) +{ + 33c: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 340: e28db000 add fp, sp, #0 + while(*p && *p == *q) + 344: e5d03000 ldrb r3, [r0] + 348: e5d12000 ldrb r2, [r1] + 34c: e3530000 cmp r3, #0 + 350: 1a000004 bne 368 + 354: ea000005 b 370 + 358: e5f03001 ldrb r3, [r0, #1]! + 35c: e3530000 cmp r3, #0 + 360: 0a000006 beq 380 + 364: e5f12001 ldrb r2, [r1, #1]! + 368: e1530002 cmp r3, r2 + 36c: 0afffff9 beq 358 + p++, q++; + return (uchar)*p - (uchar)*q; +} + 370: e0620003 rsb r0, r2, r3 + 374: e28bd000 add sp, fp, #0 + 378: e8bd0800 pop {fp} + 37c: e12fff1e bx lr +} + +int +strcmp(const char *p, const char *q) +{ + while(*p && *p == *q) + 380: e5d12001 ldrb r2, [r1, #1] + 384: eafffff9 b 370 + +00000388 : + return (uchar)*p - (uchar)*q; +} + +uint +strlen(char *s) +{ + 388: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 38c: e28db000 add fp, sp, #0 + int n; + + for(n = 0; s[n]; n++) + 390: e5d03000 ldrb r3, [r0] + 394: e3530000 cmp r3, #0 + 398: 01a00003 moveq r0, r3 + 39c: 0a000006 beq 3bc + 3a0: e1a02000 mov r2, r0 + 3a4: e3a03000 mov r3, #0 + 3a8: e5f21001 ldrb r1, [r2, #1]! + 3ac: e2833001 add r3, r3, #1 + 3b0: e1a00003 mov r0, r3 + 3b4: e3510000 cmp r1, #0 + 3b8: 1afffffa bne 3a8 + ; + return n; +} + 3bc: e28bd000 add sp, fp, #0 + 3c0: e8bd0800 pop {fp} + 3c4: e12fff1e bx lr + +000003c8 : +memset(void *dst, int c, uint n) +{ + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 3c8: e3520000 cmp r2, #0 + return n; +} + +void* +memset(void *dst, int c, uint n) +{ + 3cc: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 3d0: e28db000 add fp, sp, #0 + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 3d4: 0a000006 beq 3f4 + 3d8: e6ef1071 uxtb r1, r1 + 3dc: e1a03002 mov r3, r2 +} + +void* +memset(void *dst, int c, uint n) +{ + char *p=dst; + 3e0: e1a0c000 mov ip, r0 + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 3e4: e2533001 subs r3, r3, #1 + 3e8: e4cc1001 strb r1, [ip], #1 + 3ec: 1afffffc bne 3e4 + 3f0: e0800002 add r0, r0, r2 + return (void *)p; +} + 3f4: e28bd000 add sp, fp, #0 + 3f8: e8bd0800 pop {fp} + 3fc: e12fff1e bx lr + +00000400 : + +char* +strchr(const char *s, char c) +{ + 400: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 404: e28db000 add fp, sp, #0 + for(; *s; s++) + 408: e5d03000 ldrb r3, [r0] + 40c: e3530000 cmp r3, #0 + 410: 1a000004 bne 428 + 414: ea000008 b 43c + 418: e5d03001 ldrb r3, [r0, #1] + 41c: e2800001 add r0, r0, #1 + 420: e3530000 cmp r3, #0 + 424: 0a000004 beq 43c + if(*s == c) + 428: e1530001 cmp r3, r1 + 42c: 1afffff9 bne 418 + return (char*)s; + return 0; +} + 430: e28bd000 add sp, fp, #0 + 434: e8bd0800 pop {fp} + 438: e12fff1e bx lr +strchr(const char *s, char c) +{ + for(; *s; s++) + if(*s == c) + return (char*)s; + return 0; + 43c: e1a00003 mov r0, r3 + 440: eafffffa b 430 + +00000444 : +} + +char* +gets(char *buf, int max) +{ + 444: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + 448: e28db018 add fp, sp, #24 + 44c: e24dd00c sub sp, sp, #12 + 450: e1a08000 mov r8, r0 + 454: e1a07001 mov r7, r1 + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 458: e1a06000 mov r6, r0 + 45c: e3a05000 mov r5, #0 + 460: ea000008 b 488 + cc = read(0, &c, 1); + 464: eb000079 bl 650 + if(cc < 1) + 468: e3500000 cmp r0, #0 + 46c: da00000b ble 4a0 + break; + buf[i++] = c; + 470: e55b301d ldrb r3, [fp, #-29] + if(c == '\n' || c == '\r') + 474: e1a05004 mov r5, r4 + 478: e353000a cmp r3, #10 + 47c: 1353000d cmpne r3, #13 + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + if(cc < 1) + break; + buf[i++] = c; + 480: e4c63001 strb r3, [r6], #1 + if(c == '\n' || c == '\r') + 484: 0a00000a beq 4b4 +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + 488: e3a02001 mov r2, #1 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 48c: e0854002 add r4, r5, r2 + 490: e1540007 cmp r4, r7 + cc = read(0, &c, 1); + 494: e3a00000 mov r0, #0 + 498: e24b101d sub r1, fp, #29 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 49c: bafffff0 blt 464 + break; + buf[i++] = c; + if(c == '\n' || c == '\r') + break; + } + buf[i] = '\0'; + 4a0: e3a03000 mov r3, #0 + 4a4: e7c83005 strb r3, [r8, r5] + return buf; +} + 4a8: e1a00008 mov r0, r8 + 4ac: e24bd018 sub sp, fp, #24 + 4b0: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 4b4: e1a05004 mov r5, r4 + 4b8: eafffff8 b 4a0 + +000004bc : + return buf; +} + +int +stat(char *n, struct stat *st) +{ + 4bc: e92d4830 push {r4, r5, fp, lr} + 4c0: e1a05001 mov r5, r1 + 4c4: e28db00c add fp, sp, #12 + int fd; + int r; + + fd = open(n, O_RDONLY); + 4c8: e3a01000 mov r1, #0 + 4cc: eb0000a0 bl 754 + if(fd < 0) + 4d0: e2504000 subs r4, r0, #0 + return -1; + 4d4: b3e05000 mvnlt r5, #0 +{ + int fd; + int r; + + fd = open(n, O_RDONLY); + if(fd < 0) + 4d8: ba000004 blt 4f0 + return -1; + r = fstat(fd, st); + 4dc: e1a01005 mov r1, r5 + 4e0: eb0000c2 bl 7f0 + 4e4: e1a05000 mov r5, r0 + close(fd); + 4e8: e1a00004 mov r0, r4 + 4ec: eb000071 bl 6b8 + return r; +} + 4f0: e1a00005 mov r0, r5 + 4f4: e8bd8830 pop {r4, r5, fp, pc} + +000004f8 : + +int +atoi(const char *s) +{ + 4f8: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 4fc: e28db000 add fp, sp, #0 + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 500: e5d03000 ldrb r3, [r0] + 504: e2432030 sub r2, r3, #48 ; 0x30 + 508: e6ef2072 uxtb r2, r2 + 50c: e3520009 cmp r2, #9 +int +atoi(const char *s) +{ + int n; + + n = 0; + 510: 83a00000 movhi r0, #0 + while('0' <= *s && *s <= '9') + 514: 8a000009 bhi 540 + 518: e1a02000 mov r2, r0 +int +atoi(const char *s) +{ + int n; + + n = 0; + 51c: e3a00000 mov r0, #0 + while('0' <= *s && *s <= '9') + n = n*10 + *s++ - '0'; + 520: e0800100 add r0, r0, r0, lsl #2 + 524: e0830080 add r0, r3, r0, lsl #1 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 528: e5f23001 ldrb r3, [r2, #1]! + n = n*10 + *s++ - '0'; + 52c: e2400030 sub r0, r0, #48 ; 0x30 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 530: e2431030 sub r1, r3, #48 ; 0x30 + 534: e6ef1071 uxtb r1, r1 + 538: e3510009 cmp r1, #9 + 53c: 9afffff7 bls 520 + n = n*10 + *s++ - '0'; + return n; +} + 540: e28bd000 add sp, fp, #0 + 544: e8bd0800 pop {fp} + 548: e12fff1e bx lr + +0000054c : +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 54c: e3520000 cmp r2, #0 + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) +{ + 550: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 554: e28db000 add fp, sp, #0 + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 558: da000005 ble 574 + n = n*10 + *s++ - '0'; + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) + 55c: e0802002 add r2, r0, r2 +{ + char *dst, *src; + + dst = vdst; + 560: e1a03000 mov r3, r0 + src = vsrc; + while(n-- > 0) + *dst++ = *src++; + 564: e4d1c001 ldrb ip, [r1], #1 + 568: e4c3c001 strb ip, [r3], #1 +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 56c: e1530002 cmp r3, r2 + 570: 1afffffb bne 564 + *dst++ = *src++; + return vdst; +} + 574: e28bd000 add sp, fp, #0 + 578: e8bd0800 pop {fp} + 57c: e12fff1e bx lr + +00000580 : + 580: e92d4000 push {lr} + 584: e92d0008 push {r3} + 588: e92d0004 push {r2} + 58c: e92d0002 push {r1} + 590: e92d0001 push {r0} + 594: e3a00001 mov r0, #1 + 598: ef000040 svc 0x00000040 + 59c: e8bd0002 pop {r1} + 5a0: e8bd0002 pop {r1} + 5a4: e8bd0004 pop {r2} + 5a8: e8bd0008 pop {r3} + 5ac: e8bd4000 pop {lr} + 5b0: e12fff1e bx lr + +000005b4 : + 5b4: e92d4000 push {lr} + 5b8: e92d0008 push {r3} + 5bc: e92d0004 push {r2} + 5c0: e92d0002 push {r1} + 5c4: e92d0001 push {r0} + 5c8: e3a00002 mov r0, #2 + 5cc: ef000040 svc 0x00000040 + 5d0: e8bd0002 pop {r1} + 5d4: e8bd0002 pop {r1} + 5d8: e8bd0004 pop {r2} + 5dc: e8bd0008 pop {r3} + 5e0: e8bd4000 pop {lr} + 5e4: e12fff1e bx lr + +000005e8 : + 5e8: e92d4000 push {lr} + 5ec: e92d0008 push {r3} + 5f0: e92d0004 push {r2} + 5f4: e92d0002 push {r1} + 5f8: e92d0001 push {r0} + 5fc: e3a00003 mov r0, #3 + 600: ef000040 svc 0x00000040 + 604: e8bd0002 pop {r1} + 608: e8bd0002 pop {r1} + 60c: e8bd0004 pop {r2} + 610: e8bd0008 pop {r3} + 614: e8bd4000 pop {lr} + 618: e12fff1e bx lr + +0000061c : + 61c: e92d4000 push {lr} + 620: e92d0008 push {r3} + 624: e92d0004 push {r2} + 628: e92d0002 push {r1} + 62c: e92d0001 push {r0} + 630: e3a00004 mov r0, #4 + 634: ef000040 svc 0x00000040 + 638: e8bd0002 pop {r1} + 63c: e8bd0002 pop {r1} + 640: e8bd0004 pop {r2} + 644: e8bd0008 pop {r3} + 648: e8bd4000 pop {lr} + 64c: e12fff1e bx lr + +00000650 : + 650: e92d4000 push {lr} + 654: e92d0008 push {r3} + 658: e92d0004 push {r2} + 65c: e92d0002 push {r1} + 660: e92d0001 push {r0} + 664: e3a00005 mov r0, #5 + 668: ef000040 svc 0x00000040 + 66c: e8bd0002 pop {r1} + 670: e8bd0002 pop {r1} + 674: e8bd0004 pop {r2} + 678: e8bd0008 pop {r3} + 67c: e8bd4000 pop {lr} + 680: e12fff1e bx lr + +00000684 : + 684: e92d4000 push {lr} + 688: e92d0008 push {r3} + 68c: e92d0004 push {r2} + 690: e92d0002 push {r1} + 694: e92d0001 push {r0} + 698: e3a00010 mov r0, #16 + 69c: ef000040 svc 0x00000040 + 6a0: e8bd0002 pop {r1} + 6a4: e8bd0002 pop {r1} + 6a8: e8bd0004 pop {r2} + 6ac: e8bd0008 pop {r3} + 6b0: e8bd4000 pop {lr} + 6b4: e12fff1e bx lr + +000006b8 : + 6b8: e92d4000 push {lr} + 6bc: e92d0008 push {r3} + 6c0: e92d0004 push {r2} + 6c4: e92d0002 push {r1} + 6c8: e92d0001 push {r0} + 6cc: e3a00015 mov r0, #21 + 6d0: ef000040 svc 0x00000040 + 6d4: e8bd0002 pop {r1} + 6d8: e8bd0002 pop {r1} + 6dc: e8bd0004 pop {r2} + 6e0: e8bd0008 pop {r3} + 6e4: e8bd4000 pop {lr} + 6e8: e12fff1e bx lr + +000006ec : + 6ec: e92d4000 push {lr} + 6f0: e92d0008 push {r3} + 6f4: e92d0004 push {r2} + 6f8: e92d0002 push {r1} + 6fc: e92d0001 push {r0} + 700: e3a00006 mov r0, #6 + 704: ef000040 svc 0x00000040 + 708: e8bd0002 pop {r1} + 70c: e8bd0002 pop {r1} + 710: e8bd0004 pop {r2} + 714: e8bd0008 pop {r3} + 718: e8bd4000 pop {lr} + 71c: e12fff1e bx lr + +00000720 : + 720: e92d4000 push {lr} + 724: e92d0008 push {r3} + 728: e92d0004 push {r2} + 72c: e92d0002 push {r1} + 730: e92d0001 push {r0} + 734: e3a00007 mov r0, #7 + 738: ef000040 svc 0x00000040 + 73c: e8bd0002 pop {r1} + 740: e8bd0002 pop {r1} + 744: e8bd0004 pop {r2} + 748: e8bd0008 pop {r3} + 74c: e8bd4000 pop {lr} + 750: e12fff1e bx lr + +00000754 : + 754: e92d4000 push {lr} + 758: e92d0008 push {r3} + 75c: e92d0004 push {r2} + 760: e92d0002 push {r1} + 764: e92d0001 push {r0} + 768: e3a0000f mov r0, #15 + 76c: ef000040 svc 0x00000040 + 770: e8bd0002 pop {r1} + 774: e8bd0002 pop {r1} + 778: e8bd0004 pop {r2} + 77c: e8bd0008 pop {r3} + 780: e8bd4000 pop {lr} + 784: e12fff1e bx lr + +00000788 : + 788: e92d4000 push {lr} + 78c: e92d0008 push {r3} + 790: e92d0004 push {r2} + 794: e92d0002 push {r1} + 798: e92d0001 push {r0} + 79c: e3a00011 mov r0, #17 + 7a0: ef000040 svc 0x00000040 + 7a4: e8bd0002 pop {r1} + 7a8: e8bd0002 pop {r1} + 7ac: e8bd0004 pop {r2} + 7b0: e8bd0008 pop {r3} + 7b4: e8bd4000 pop {lr} + 7b8: e12fff1e bx lr + +000007bc : + 7bc: e92d4000 push {lr} + 7c0: e92d0008 push {r3} + 7c4: e92d0004 push {r2} + 7c8: e92d0002 push {r1} + 7cc: e92d0001 push {r0} + 7d0: e3a00012 mov r0, #18 + 7d4: ef000040 svc 0x00000040 + 7d8: e8bd0002 pop {r1} + 7dc: e8bd0002 pop {r1} + 7e0: e8bd0004 pop {r2} + 7e4: e8bd0008 pop {r3} + 7e8: e8bd4000 pop {lr} + 7ec: e12fff1e bx lr + +000007f0 : + 7f0: e92d4000 push {lr} + 7f4: e92d0008 push {r3} + 7f8: e92d0004 push {r2} + 7fc: e92d0002 push {r1} + 800: e92d0001 push {r0} + 804: e3a00008 mov r0, #8 + 808: ef000040 svc 0x00000040 + 80c: e8bd0002 pop {r1} + 810: e8bd0002 pop {r1} + 814: e8bd0004 pop {r2} + 818: e8bd0008 pop {r3} + 81c: e8bd4000 pop {lr} + 820: e12fff1e bx lr + +00000824 : + 824: e92d4000 push {lr} + 828: e92d0008 push {r3} + 82c: e92d0004 push {r2} + 830: e92d0002 push {r1} + 834: e92d0001 push {r0} + 838: e3a00013 mov r0, #19 + 83c: ef000040 svc 0x00000040 + 840: e8bd0002 pop {r1} + 844: e8bd0002 pop {r1} + 848: e8bd0004 pop {r2} + 84c: e8bd0008 pop {r3} + 850: e8bd4000 pop {lr} + 854: e12fff1e bx lr + +00000858 : + 858: e92d4000 push {lr} + 85c: e92d0008 push {r3} + 860: e92d0004 push {r2} + 864: e92d0002 push {r1} + 868: e92d0001 push {r0} + 86c: e3a00014 mov r0, #20 + 870: ef000040 svc 0x00000040 + 874: e8bd0002 pop {r1} + 878: e8bd0002 pop {r1} + 87c: e8bd0004 pop {r2} + 880: e8bd0008 pop {r3} + 884: e8bd4000 pop {lr} + 888: e12fff1e bx lr + +0000088c : + 88c: e92d4000 push {lr} + 890: e92d0008 push {r3} + 894: e92d0004 push {r2} + 898: e92d0002 push {r1} + 89c: e92d0001 push {r0} + 8a0: e3a00009 mov r0, #9 + 8a4: ef000040 svc 0x00000040 + 8a8: e8bd0002 pop {r1} + 8ac: e8bd0002 pop {r1} + 8b0: e8bd0004 pop {r2} + 8b4: e8bd0008 pop {r3} + 8b8: e8bd4000 pop {lr} + 8bc: e12fff1e bx lr + +000008c0 : + 8c0: e92d4000 push {lr} + 8c4: e92d0008 push {r3} + 8c8: e92d0004 push {r2} + 8cc: e92d0002 push {r1} + 8d0: e92d0001 push {r0} + 8d4: e3a0000a mov r0, #10 + 8d8: ef000040 svc 0x00000040 + 8dc: e8bd0002 pop {r1} + 8e0: e8bd0002 pop {r1} + 8e4: e8bd0004 pop {r2} + 8e8: e8bd0008 pop {r3} + 8ec: e8bd4000 pop {lr} + 8f0: e12fff1e bx lr + +000008f4 : + 8f4: e92d4000 push {lr} + 8f8: e92d0008 push {r3} + 8fc: e92d0004 push {r2} + 900: e92d0002 push {r1} + 904: e92d0001 push {r0} + 908: e3a0000b mov r0, #11 + 90c: ef000040 svc 0x00000040 + 910: e8bd0002 pop {r1} + 914: e8bd0002 pop {r1} + 918: e8bd0004 pop {r2} + 91c: e8bd0008 pop {r3} + 920: e8bd4000 pop {lr} + 924: e12fff1e bx lr + +00000928 : + 928: e92d4000 push {lr} + 92c: e92d0008 push {r3} + 930: e92d0004 push {r2} + 934: e92d0002 push {r1} + 938: e92d0001 push {r0} + 93c: e3a0000c mov r0, #12 + 940: ef000040 svc 0x00000040 + 944: e8bd0002 pop {r1} + 948: e8bd0002 pop {r1} + 94c: e8bd0004 pop {r2} + 950: e8bd0008 pop {r3} + 954: e8bd4000 pop {lr} + 958: e12fff1e bx lr + +0000095c : + 95c: e92d4000 push {lr} + 960: e92d0008 push {r3} + 964: e92d0004 push {r2} + 968: e92d0002 push {r1} + 96c: e92d0001 push {r0} + 970: e3a0000d mov r0, #13 + 974: ef000040 svc 0x00000040 + 978: e8bd0002 pop {r1} + 97c: e8bd0002 pop {r1} + 980: e8bd0004 pop {r2} + 984: e8bd0008 pop {r3} + 988: e8bd4000 pop {lr} + 98c: e12fff1e bx lr + +00000990 : + 990: e92d4000 push {lr} + 994: e92d0008 push {r3} + 998: e92d0004 push {r2} + 99c: e92d0002 push {r1} + 9a0: e92d0001 push {r0} + 9a4: e3a0000e mov r0, #14 + 9a8: ef000040 svc 0x00000040 + 9ac: e8bd0002 pop {r1} + 9b0: e8bd0002 pop {r1} + 9b4: e8bd0004 pop {r2} + 9b8: e8bd0008 pop {r3} + 9bc: e8bd4000 pop {lr} + 9c0: e12fff1e bx lr + +000009c4 : +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 9c4: e92d4800 push {fp, lr} + 9c8: e28db004 add fp, sp, #4 + 9cc: e24b3004 sub r3, fp, #4 + 9d0: e24dd008 sub sp, sp, #8 + write(fd, &c, 1); + 9d4: e3a02001 mov r2, #1 +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 9d8: e5631001 strb r1, [r3, #-1]! + write(fd, &c, 1); + 9dc: e1a01003 mov r1, r3 + 9e0: ebffff27 bl 684 +} + 9e4: e24bd004 sub sp, fp, #4 + 9e8: e8bd8800 pop {fp, pc} + +000009ec : + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 9ec: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 9f0: e1a04000 mov r4, r0 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 9f4: e1a00fa1 lsr r0, r1, #31 + 9f8: e3530000 cmp r3, #0 + 9fc: 03a03000 moveq r3, #0 + a00: 12003001 andne r3, r0, #1 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + a04: e28db020 add fp, sp, #32 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + a08: e3530000 cmp r3, #0 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + a0c: e24dd014 sub sp, sp, #20 + a10: e59f909c ldr r9, [pc, #156] ; ab4 + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + x = -xx; + a14: 12611000 rsbne r1, r1, #0 + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + a18: 13a03001 movne r3, #1 + } else { + x = xx; + } + + b = base; + i = 0; + a1c: e3a0a000 mov sl, #0 + a20: e24b6034 sub r6, fp, #52 ; 0x34 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + a24: e3a08001 mov r8, #1 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + a28: e3a07000 mov r7, #0 + int i; + + for(i=31;i>=0;i--){ + a2c: e3a0001f mov r0, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + a30: e1a0c007 mov ip, r7 + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + a34: e1a0e031 lsr lr, r1, r0 + a38: e20ee001 and lr, lr, #1 + a3c: e18ec08c orr ip, lr, ip, lsl #1 + if(r >= d) { + a40: e152000c cmp r2, ip + r = r - d; + q = q | (1 << i); + a44: 91877018 orrls r7, r7, r8, lsl r0 + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + a48: 9062c00c rsbls ip, r2, ip +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + a4c: e2500001 subs r0, r0, #1 + a50: 2afffff7 bcs a34 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + a54: e0000792 mul r0, r2, r7 + }while((x = y) != 0); + a58: e3570000 cmp r7, #0 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + a5c: e0601001 rsb r1, r0, r1 + a60: e28a5001 add r5, sl, #1 + a64: e7d91001 ldrb r1, [r9, r1] + a68: e7c6100a strb r1, [r6, sl] + }while((x = y) != 0); + a6c: 11a01007 movne r1, r7 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + a70: 11a0a005 movne sl, r5 + a74: 1affffeb bne a28 + }while((x = y) != 0); + if(neg) + a78: e3530000 cmp r3, #0 + buf[i++] = '-'; + a7c: 124b2024 subne r2, fp, #36 ; 0x24 + a80: 10823005 addne r3, r2, r5 + a84: 128a5002 addne r5, sl, #2 + + while(--i >= 0) + a88: e2455001 sub r5, r5, #1 + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + a8c: 13a0202d movne r2, #45 ; 0x2d + a90: 15432010 strbne r2, [r3, #-16] + + while(--i >= 0) + putc(fd, buf[i]); + a94: e7d61005 ldrb r1, [r6, r5] + a98: e1a00004 mov r0, r4 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + a9c: e2455001 sub r5, r5, #1 + putc(fd, buf[i]); + aa0: ebffffc7 bl 9c4 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + aa4: e3750001 cmn r5, #1 + aa8: 1afffff9 bne a94 + putc(fd, buf[i]); +} + aac: e24bd020 sub sp, fp, #32 + ab0: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} + ab4: 00000e20 .word 0x00000e20 + +00000ab8
: + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + ab8: e3a03000 mov r3, #0 +{ + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + abc: e92d0830 push {r4, r5, fp} + ac0: e1a02000 mov r2, r0 + ac4: e28db008 add fp, sp, #8 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + ac8: e3a0c01f mov ip, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + acc: e1a00003 mov r0, r3 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + ad0: e3a05001 mov r5, #1 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + ad4: e1a04c32 lsr r4, r2, ip + ad8: e2044001 and r4, r4, #1 + adc: e1843083 orr r3, r4, r3, lsl #1 + if(r >= d) { + ae0: e1530001 cmp r3, r1 + r = r - d; + q = q | (1 << i); + ae4: 21800c15 orrcs r0, r0, r5, lsl ip + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + ae8: 20613003 rsbcs r3, r1, r3 +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + aec: e25cc001 subs ip, ip, #1 + af0: 2afffff7 bcs ad4 + r = r - d; + q = q | (1 << i); + } + } + return q; +} + af4: e24bd008 sub sp, fp, #8 + af8: e8bd0830 pop {r4, r5, fp} + afc: e12fff1e bx lr + +00000b00 : +} + +// Print to the given fd. Only understands %d, %x, %p, %s. +void +printf(int fd, char *fmt, ...) +{ + b00: e92d000e push {r1, r2, r3} + b04: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + b08: e28db020 add fp, sp, #32 + b0c: e1a05000 mov r5, r0 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + b10: e59b4004 ldr r4, [fp, #4] + b14: e5d48000 ldrb r8, [r4] + b18: e3580000 cmp r8, #0 + b1c: 0a000027 beq bc0 + ap++; + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + b20: e59f712c ldr r7, [pc, #300] ; c54 + char *s; + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + b24: e28b6008 add r6, fp, #8 +{ + char *s; + int c, i, state; + uint *ap; + + state = 0; + b28: e3a0a000 mov sl, #0 + b2c: ea000008 b b54 + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + b30: e3580025 cmp r8, #37 ; 0x25 + state = '%'; + b34: 01a0a008 moveq sl, r8 + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + b38: 0a000002 beq b48 + state = '%'; + } else { + putc(fd, c); + b3c: e1a00005 mov r0, r5 + b40: e1a01008 mov r1, r8 + b44: ebffff9e bl 9c4 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + b48: e5f48001 ldrb r8, [r4, #1]! + b4c: e3580000 cmp r8, #0 + b50: 0a00001a beq bc0 + c = fmt[i] & 0xff; + if(state == 0){ + b54: e35a0000 cmp sl, #0 + b58: 0afffff4 beq b30 + if(c == '%'){ + state = '%'; + } else { + putc(fd, c); + } + } else if(state == '%'){ + b5c: e35a0025 cmp sl, #37 ; 0x25 + b60: 1afffff8 bne b48 + if(c == 'd'){ + b64: e3580064 cmp r8, #100 ; 0x64 + b68: 0a00002c beq c20 + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + b6c: e3580078 cmp r8, #120 ; 0x78 + b70: 13580070 cmpne r8, #112 ; 0x70 + b74: 13a09000 movne r9, #0 + b78: 03a09001 moveq r9, #1 + b7c: 0a000013 beq bd0 + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + b80: e3580073 cmp r8, #115 ; 0x73 + b84: 0a000018 beq bec + s = "(null)"; + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + b88: e3580063 cmp r8, #99 ; 0x63 + b8c: 0a00002a beq c3c + putc(fd, *ap); + ap++; + } else if(c == '%'){ + b90: e3580025 cmp r8, #37 ; 0x25 + putc(fd, c); + b94: e1a0100a mov r1, sl + b98: e1a00005 mov r0, r5 + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + ap++; + } else if(c == '%'){ + b9c: 0a000002 beq bac + putc(fd, c); + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + ba0: ebffff87 bl 9c4 + putc(fd, c); + ba4: e1a00005 mov r0, r5 + ba8: e1a01008 mov r1, r8 + bac: ebffff84 bl 9c4 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + bb0: e5f48001 ldrb r8, [r4, #1]! + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + bb4: e1a0a009 mov sl, r9 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + bb8: e3580000 cmp r8, #0 + bbc: 1affffe4 bne b54 + putc(fd, c); + } + state = 0; + } + } +} + bc0: e24bd020 sub sp, fp, #32 + bc4: e8bd4ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, lr} + bc8: e28dd00c add sp, sp, #12 + bcc: e12fff1e bx lr + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + bd0: e1a00005 mov r0, r5 + bd4: e4961004 ldr r1, [r6], #4 + bd8: e3a02010 mov r2, #16 + bdc: e3a03000 mov r3, #0 + be0: ebffff81 bl 9ec + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + be4: e3a0a000 mov sl, #0 + be8: eaffffd6 b b48 + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + s = (char*)*ap; + bec: e4968004 ldr r8, [r6], #4 + ap++; + if(s == 0) + s = "(null)"; + bf0: e3580000 cmp r8, #0 + bf4: 01a08007 moveq r8, r7 + while(*s != 0){ + bf8: e5d81000 ldrb r1, [r8] + bfc: e3510000 cmp r1, #0 + c00: 0a000004 beq c18 + putc(fd, *s); + c04: e1a00005 mov r0, r5 + c08: ebffff6d bl 9c4 + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + while(*s != 0){ + c0c: e5f81001 ldrb r1, [r8, #1]! + c10: e3510000 cmp r1, #0 + c14: 1afffffa bne c04 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + c18: e1a0a001 mov sl, r1 + c1c: eaffffc9 b b48 + } else { + putc(fd, c); + } + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + c20: e1a00005 mov r0, r5 + c24: e4961004 ldr r1, [r6], #4 + c28: e3a0200a mov r2, #10 + c2c: e3a03001 mov r3, #1 + c30: ebffff6d bl 9ec + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + c34: e3a0a000 mov sl, #0 + c38: eaffffc2 b b48 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + c3c: e4961004 ldr r1, [r6], #4 + c40: e1a00005 mov r0, r5 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + c44: e1a0a009 mov sl, r9 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + c48: e6ef1071 uxtb r1, r1 + c4c: ebffff5c bl 9c4 + c50: eaffffbc b b48 + c54: 00000e34 .word 0x00000e34 + +00000c58 : +free(void *ap) +{ + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + c58: e59f3098 ldr r3, [pc, #152] ; cf8 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + c5c: e92d0830 push {r4, r5, fp} + Header *bp, *p; + + bp = (Header*)ap - 1; + c60: e240c008 sub ip, r0, #8 + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + c64: e5932000 ldr r2, [r3] +static Header base; +static Header *freep; + +void +free(void *ap) +{ + c68: e28db008 add fp, sp, #8 + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + c6c: e152000c cmp r2, ip + c70: e5921000 ldr r1, [r2] + c74: 2a000001 bcs c80 + c78: e15c0001 cmp ip, r1 + c7c: 3a000007 bcc ca0 + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + c80: e1520001 cmp r2, r1 + c84: 3a000003 bcc c98 + c88: e152000c cmp r2, ip + c8c: 3a000003 bcc ca0 + c90: e15c0001 cmp ip, r1 + c94: 3a000001 bcc ca0 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + c98: e1a02001 mov r2, r1 + c9c: eafffff2 b c6c + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + ca0: e5104004 ldr r4, [r0, #-4] + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + freep = p; + ca4: e5832000 str r2, [r3] + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + ca8: e08c5184 add r5, ip, r4, lsl #3 + cac: e1550001 cmp r5, r1 + bp->s.size += p->s.ptr->s.size; + cb0: 05911004 ldreq r1, [r1, #4] + cb4: 00814004 addeq r4, r1, r4 + cb8: 05004004 streq r4, [r0, #-4] + bp->s.ptr = p->s.ptr->s.ptr; + cbc: 05921000 ldreq r1, [r2] + cc0: 05911000 ldreq r1, [r1] + } else + bp->s.ptr = p->s.ptr; + cc4: e5001008 str r1, [r0, #-8] + if(p + p->s.size == bp){ + cc8: e5921004 ldr r1, [r2, #4] + ccc: e0824181 add r4, r2, r1, lsl #3 + cd0: e15c0004 cmp ip, r4 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + cd4: 1582c000 strne ip, [r2] + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + } else + bp->s.ptr = p->s.ptr; + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + cd8: 0510c004 ldreq ip, [r0, #-4] + cdc: 008c1001 addeq r1, ip, r1 + ce0: 05821004 streq r1, [r2, #4] + p->s.ptr = bp->s.ptr; + ce4: 05101008 ldreq r1, [r0, #-8] + ce8: 05821000 streq r1, [r2] + } else + p->s.ptr = bp; + freep = p; +} + cec: e24bd008 sub sp, fp, #8 + cf0: e8bd0830 pop {r4, r5, fp} + cf4: e12fff1e bx lr + cf8: 00000e3c .word 0x00000e3c + +00000cfc : + return freep; +} + +void* +malloc(uint nbytes) +{ + cfc: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + d00: e2804007 add r4, r0, #7 + if((prevp = freep) == 0){ + d04: e59f50d4 ldr r5, [pc, #212] ; de0 +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + d08: e1a041a4 lsr r4, r4, #3 + return freep; +} + +void* +malloc(uint nbytes) +{ + d0c: e28db01c add fp, sp, #28 + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + d10: e5953000 ldr r3, [r5] +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + d14: e2844001 add r4, r4, #1 + if((prevp = freep) == 0){ + d18: e3530000 cmp r3, #0 + d1c: 0a00002b beq dd0 + d20: e5930000 ldr r0, [r3] + d24: e5902004 ldr r2, [r0, #4] + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + d28: e1520004 cmp r2, r4 + d2c: 2a00001b bcs da0 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + d30: e59f80ac ldr r8, [pc, #172] ; de4 + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + d34: e1a07184 lsl r7, r4, #3 + d38: ea000003 b d4c + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + d3c: e5930000 ldr r0, [r3] + if(p->s.size >= nunits){ + d40: e5902004 ldr r2, [r0, #4] + d44: e1540002 cmp r4, r2 + d48: 9a000014 bls da0 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + d4c: e5952000 ldr r2, [r5] + d50: e1a03000 mov r3, r0 + d54: e1500002 cmp r0, r2 + d58: 1afffff7 bne d3c +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + d5c: e1540008 cmp r4, r8 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + d60: 81a00007 movhi r0, r7 + d64: 93a00902 movls r0, #32768 ; 0x8000 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + d68: 81a06004 movhi r6, r4 + d6c: 93a06a01 movls r6, #4096 ; 0x1000 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + d70: ebfffeec bl 928 + d74: e1a03000 mov r3, r0 + if(p == (char*)-1) + d78: e3730001 cmn r3, #1 + return 0; + hp = (Header*)p; + hp->s.size = nu; + free((void*)(hp + 1)); + d7c: e2800008 add r0, r0, #8 + Header *hp; + + if(nu < 4096) + nu = 4096; + p = sbrk(nu * sizeof(Header)); + if(p == (char*)-1) + d80: 0a000010 beq dc8 + return 0; + hp = (Header*)p; + hp->s.size = nu; + d84: e5836004 str r6, [r3, #4] + free((void*)(hp + 1)); + d88: ebffffb2 bl c58 + return freep; + d8c: e5953000 ldr r3, [r5] + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + if((p = morecore(nunits)) == 0) + d90: e3530000 cmp r3, #0 + d94: 1affffe8 bne d3c + return 0; + d98: e1a00003 mov r0, r3 + } +} + d9c: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + da0: e1540002 cmp r4, r2 + prevp->s.ptr = p->s.ptr; + else { + p->s.size -= nunits; + da4: 10642002 rsbne r2, r4, r2 + da8: 15802004 strne r2, [r0, #4] + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + dac: 05902000 ldreq r2, [r0] + else { + p->s.size -= nunits; + p += p->s.size; + db0: 10800182 addne r0, r0, r2, lsl #3 + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + db4: 05832000 streq r2, [r3] + else { + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + db8: 15804004 strne r4, [r0, #4] + } + freep = prevp; + dbc: e5853000 str r3, [r5] + return (void*)(p + 1); + dc0: e2800008 add r0, r0, #8 + dc4: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + } + if(p == freep) + if((p = morecore(nunits)) == 0) + return 0; + dc8: e3a00000 mov r0, #0 + dcc: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + dd0: e2850004 add r0, r5, #4 + dd4: e5850000 str r0, [r5] + base.s.size = 0; + dd8: e9850009 stmib r5, {r0, r3} + ddc: eaffffd3 b d30 + de0: 00000e3c .word 0x00000e3c + de4: 00000fff .word 0x00000fff diff -r 000000000000 -r c450faca55f4 uprogs/grep.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/grep.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,106 @@ +// Simple grep. Only supports ^ . * $ operators. + +#include "types.h" +#include "stat.h" +#include "user.h" + +char buf[1024]; +int match(char*, char*); + +void +grep(char *pattern, int fd) +{ + int n, m; + char *p, *q; + + m = 0; + while((n = read(fd, buf+m, sizeof(buf)-m)) > 0){ + m += n; + p = buf; + while((q = strchr(p, '\n')) != 0){ + *q = 0; + if(match(pattern, p)){ + *q = '\n'; + write(1, p, q+1 - p); + } + p = q+1; + } + if(p == buf) + m = 0; + if(m > 0){ + m -= p - buf; + memmove(buf, p, m); + } + } +} + +int +main(int argc, char *argv[]) +{ + int fd, i; + char *pattern; + + if(argc <= 1){ + printf(2, "usage: grep pattern [file ...]\n"); + exit(); + } + pattern = argv[1]; + + if(argc <= 2){ + grep(pattern, 0); + exit(); + } + + for(i = 2; i < argc; i++){ + if((fd = open(argv[i], 0)) < 0){ + printf(1, "grep: cannot open %s\n", argv[i]); + exit(); + } + grep(pattern, fd); + close(fd); + } + exit(); +} + +// Regexp matcher from Kernighan & Pike, +// The Practice of Programming, Chapter 9. + +int matchhere(char*, char*); +int matchstar(int, char*, char*); + +int +match(char *re, char *text) +{ + if(re[0] == '^') + return matchhere(re+1, text); + do{ // must look at empty string + if(matchhere(re, text)) + return 1; + }while(*text++ != '\0'); + return 0; +} + +// matchhere: search for re at beginning of text +int matchhere(char *re, char *text) +{ + if(re[0] == '\0') + return 1; + if(re[1] == '*') + return matchstar(re[0], re+2, text); + if(re[0] == '$' && re[1] == '\0') + return *text == '\0'; + if(*text!='\0' && (re[0]=='.' || re[0]==*text)) + return matchhere(re+1, text+1); + return 0; +} + +// matchstar: search for c*re at beginning of text +int matchstar(int c, char *re, char *text) +{ + do{ // a * matches zero or more instances + if(matchhere(re, text)) + return 1; + }while(*text!='\0' && (*text++==c || c=='.')); + return 0; +} + diff -r 000000000000 -r c450faca55f4 uprogs/grep.sym --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/grep.sym Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,69 @@ +00000000 .text +00000de8 .rodata +00000e3c .bss +00000000 .comment +00000000 .ARM.attributes +00000000 .debug_aranges +00000000 .debug_info +00000000 .debug_abbrev +00000000 .debug_line +00000000 .debug_frame +00000000 .debug_str +00000000 .debug_loc +00000000 .debug_ranges +00000000 grep.c +00000000 ulib.c +00000000 printf.c +000009c4 putc +000009ec printint +00000e20 digits.993 +00000000 umalloc.c +00000e3c freep +00000e40 base +00000314 strcpy +00000b00 printf +0000054c memmove +000000fc matchhere +00000788 mknod +00001248 _bss_end__ +00000444 gets +000008f4 getpid +00000210 grep +00000cfc malloc +0000095c sleep +00000e3c __bss_start__ +0000061c pipe +00000684 write +000007f0 fstat +000006ec kill +0000088c chdir +00000720 exec +00001248 __bss_end__ +000005e8 wait +00000650 read +000007bc unlink +00000580 fork +00000928 sbrk +00000990 uptime +00000e3c __bss_start +000003c8 memset +00000000 main +00001248 __end__ +000000a4 matchstar +0000033c strcmp +000008c0 dup +00000e48 buf +000004bc stat +00000e3c _edata +00001248 _end +000001bc match +00000824 link +000005b4 exit +000004f8 atoi +00000388 strlen +00000754 open +00000ab8 div +00000400 strchr +00000858 mkdir +000006b8 close +00000c58 free diff -r 000000000000 -r c450faca55f4 uprogs/init.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/init.asm Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,1731 @@ + +_init: file format elf32-littlearm + + +Disassembly of section .text: + +00000000
: + +char *argv[] = { "sh", 0 }; + +int +main(void) +{ + 0: e92d4818 push {r3, r4, fp, lr} + int pid, wpid; + + if(open("console", O_RDWR) < 0){ + 4: e3a01002 mov r1, #2 + +char *argv[] = { "sh", 0 }; + +int +main(void) +{ + 8: e28db00c add fp, sp, #12 + int pid, wpid; + + if(open("console", O_RDWR) < 0){ + c: e59f00a4 ldr r0, [pc, #164] ; b8 + 10: eb00013f bl 514 + 14: e3500000 cmp r0, #0 + 18: ba00001e blt 98 + mknod("console", 1, 1); + open("console", O_RDWR); + } + dup(0); // stdout + 1c: e3a00000 mov r0, #0 + 20: eb000196 bl 680 + dup(0); // stderr + 24: e3a00000 mov r0, #0 + 28: eb000194 bl 680 + + for(;;){ + printf(1, "init: starting sh\n"); + 2c: e3a00001 mov r0, #1 + 30: e59f1084 ldr r1, [pc, #132] ; bc + 34: eb000221 bl 8c0 + pid = fork(); + 38: eb0000c0 bl 340 + if(pid < 0){ + 3c: e2504000 subs r4, r0, #0 + 40: ba000009 blt 6c + printf(1, "init: fork failed\n"); + exit(); + } + if(pid == 0){ + 44: 0a00000c beq 7c + exec("sh", argv); + printf(1, "init: exec sh failed\n"); + exit(); + } + while((wpid=wait()) >= 0 && wpid != pid) + 48: eb0000d6 bl 3a8 + 4c: e3500000 cmp r0, #0 + 50: bafffff5 blt 2c + 54: e1500004 cmp r0, r4 + 58: 0afffff3 beq 2c + printf(1, "zombie!\n"); + 5c: e3a00001 mov r0, #1 + 60: e59f1058 ldr r1, [pc, #88] ; c0 + 64: eb000215 bl 8c0 + 68: eafffff6 b 48 + + for(;;){ + printf(1, "init: starting sh\n"); + pid = fork(); + if(pid < 0){ + printf(1, "init: fork failed\n"); + 6c: e3a00001 mov r0, #1 + 70: e59f104c ldr r1, [pc, #76] ; c4 + 74: eb000211 bl 8c0 + exit(); + 78: eb0000bd bl 374 + } + if(pid == 0){ + exec("sh", argv); + 7c: e59f1044 ldr r1, [pc, #68] ; c8 + 80: e59f0044 ldr r0, [pc, #68] ; cc + 84: eb000115 bl 4e0 + printf(1, "init: exec sh failed\n"); + 88: e3a00001 mov r0, #1 + 8c: e59f103c ldr r1, [pc, #60] ; d0 + 90: eb00020a bl 8c0 + exit(); + 94: eb0000b6 bl 374 +main(void) +{ + int pid, wpid; + + if(open("console", O_RDWR) < 0){ + mknod("console", 1, 1); + 98: e3a01001 mov r1, #1 + 9c: e1a02001 mov r2, r1 + a0: e59f0010 ldr r0, [pc, #16] ; b8 + a4: eb000127 bl 548 + open("console", O_RDWR); + a8: e3a01002 mov r1, #2 + ac: e59f0004 ldr r0, [pc, #4] ; b8 + b0: eb000117 bl 514 + b4: eaffffd8 b 1c + b8: 00000ba8 .word 0x00000ba8 + bc: 00000bb0 .word 0x00000bb0 + c0: 00000bf4 .word 0x00000bf4 + c4: 00000bc4 .word 0x00000bc4 + c8: 00000c1c .word 0x00000c1c + cc: 00000bd8 .word 0x00000bd8 + d0: 00000bdc .word 0x00000bdc + +000000d4 : +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + d4: e52db004 push {fp} ; (str fp, [sp, #-4]!) + char *os; + + os = s; + while((*s++ = *t++) != 0) + d8: e1a02000 mov r2, r0 +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + dc: e28db000 add fp, sp, #0 + char *os; + + os = s; + while((*s++ = *t++) != 0) + e0: e4d13001 ldrb r3, [r1], #1 + e4: e3530000 cmp r3, #0 + e8: e4c23001 strb r3, [r2], #1 + ec: 1afffffb bne e0 + ; + return os; +} + f0: e28bd000 add sp, fp, #0 + f4: e8bd0800 pop {fp} + f8: e12fff1e bx lr + +000000fc : + +int +strcmp(const char *p, const char *q) +{ + fc: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 100: e28db000 add fp, sp, #0 + while(*p && *p == *q) + 104: e5d03000 ldrb r3, [r0] + 108: e5d12000 ldrb r2, [r1] + 10c: e3530000 cmp r3, #0 + 110: 1a000004 bne 128 + 114: ea000005 b 130 + 118: e5f03001 ldrb r3, [r0, #1]! + 11c: e3530000 cmp r3, #0 + 120: 0a000006 beq 140 + 124: e5f12001 ldrb r2, [r1, #1]! + 128: e1530002 cmp r3, r2 + 12c: 0afffff9 beq 118 + p++, q++; + return (uchar)*p - (uchar)*q; +} + 130: e0620003 rsb r0, r2, r3 + 134: e28bd000 add sp, fp, #0 + 138: e8bd0800 pop {fp} + 13c: e12fff1e bx lr +} + +int +strcmp(const char *p, const char *q) +{ + while(*p && *p == *q) + 140: e5d12001 ldrb r2, [r1, #1] + 144: eafffff9 b 130 + +00000148 : + return (uchar)*p - (uchar)*q; +} + +uint +strlen(char *s) +{ + 148: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 14c: e28db000 add fp, sp, #0 + int n; + + for(n = 0; s[n]; n++) + 150: e5d03000 ldrb r3, [r0] + 154: e3530000 cmp r3, #0 + 158: 01a00003 moveq r0, r3 + 15c: 0a000006 beq 17c + 160: e1a02000 mov r2, r0 + 164: e3a03000 mov r3, #0 + 168: e5f21001 ldrb r1, [r2, #1]! + 16c: e2833001 add r3, r3, #1 + 170: e1a00003 mov r0, r3 + 174: e3510000 cmp r1, #0 + 178: 1afffffa bne 168 + ; + return n; +} + 17c: e28bd000 add sp, fp, #0 + 180: e8bd0800 pop {fp} + 184: e12fff1e bx lr + +00000188 : +memset(void *dst, int c, uint n) +{ + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 188: e3520000 cmp r2, #0 + return n; +} + +void* +memset(void *dst, int c, uint n) +{ + 18c: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 190: e28db000 add fp, sp, #0 + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 194: 0a000006 beq 1b4 + 198: e6ef1071 uxtb r1, r1 + 19c: e1a03002 mov r3, r2 +} + +void* +memset(void *dst, int c, uint n) +{ + char *p=dst; + 1a0: e1a0c000 mov ip, r0 + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 1a4: e2533001 subs r3, r3, #1 + 1a8: e4cc1001 strb r1, [ip], #1 + 1ac: 1afffffc bne 1a4 + 1b0: e0800002 add r0, r0, r2 + return (void *)p; +} + 1b4: e28bd000 add sp, fp, #0 + 1b8: e8bd0800 pop {fp} + 1bc: e12fff1e bx lr + +000001c0 : + +char* +strchr(const char *s, char c) +{ + 1c0: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 1c4: e28db000 add fp, sp, #0 + for(; *s; s++) + 1c8: e5d03000 ldrb r3, [r0] + 1cc: e3530000 cmp r3, #0 + 1d0: 1a000004 bne 1e8 + 1d4: ea000008 b 1fc + 1d8: e5d03001 ldrb r3, [r0, #1] + 1dc: e2800001 add r0, r0, #1 + 1e0: e3530000 cmp r3, #0 + 1e4: 0a000004 beq 1fc + if(*s == c) + 1e8: e1530001 cmp r3, r1 + 1ec: 1afffff9 bne 1d8 + return (char*)s; + return 0; +} + 1f0: e28bd000 add sp, fp, #0 + 1f4: e8bd0800 pop {fp} + 1f8: e12fff1e bx lr +strchr(const char *s, char c) +{ + for(; *s; s++) + if(*s == c) + return (char*)s; + return 0; + 1fc: e1a00003 mov r0, r3 + 200: eafffffa b 1f0 + +00000204 : +} + +char* +gets(char *buf, int max) +{ + 204: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + 208: e28db018 add fp, sp, #24 + 20c: e24dd00c sub sp, sp, #12 + 210: e1a08000 mov r8, r0 + 214: e1a07001 mov r7, r1 + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 218: e1a06000 mov r6, r0 + 21c: e3a05000 mov r5, #0 + 220: ea000008 b 248 + cc = read(0, &c, 1); + 224: eb000079 bl 410 + if(cc < 1) + 228: e3500000 cmp r0, #0 + 22c: da00000b ble 260 + break; + buf[i++] = c; + 230: e55b301d ldrb r3, [fp, #-29] + if(c == '\n' || c == '\r') + 234: e1a05004 mov r5, r4 + 238: e353000a cmp r3, #10 + 23c: 1353000d cmpne r3, #13 + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + if(cc < 1) + break; + buf[i++] = c; + 240: e4c63001 strb r3, [r6], #1 + if(c == '\n' || c == '\r') + 244: 0a00000a beq 274 +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + 248: e3a02001 mov r2, #1 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 24c: e0854002 add r4, r5, r2 + 250: e1540007 cmp r4, r7 + cc = read(0, &c, 1); + 254: e3a00000 mov r0, #0 + 258: e24b101d sub r1, fp, #29 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 25c: bafffff0 blt 224 + break; + buf[i++] = c; + if(c == '\n' || c == '\r') + break; + } + buf[i] = '\0'; + 260: e3a03000 mov r3, #0 + 264: e7c83005 strb r3, [r8, r5] + return buf; +} + 268: e1a00008 mov r0, r8 + 26c: e24bd018 sub sp, fp, #24 + 270: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 274: e1a05004 mov r5, r4 + 278: eafffff8 b 260 + +0000027c : + return buf; +} + +int +stat(char *n, struct stat *st) +{ + 27c: e92d4830 push {r4, r5, fp, lr} + 280: e1a05001 mov r5, r1 + 284: e28db00c add fp, sp, #12 + int fd; + int r; + + fd = open(n, O_RDONLY); + 288: e3a01000 mov r1, #0 + 28c: eb0000a0 bl 514 + if(fd < 0) + 290: e2504000 subs r4, r0, #0 + return -1; + 294: b3e05000 mvnlt r5, #0 +{ + int fd; + int r; + + fd = open(n, O_RDONLY); + if(fd < 0) + 298: ba000004 blt 2b0 + return -1; + r = fstat(fd, st); + 29c: e1a01005 mov r1, r5 + 2a0: eb0000c2 bl 5b0 + 2a4: e1a05000 mov r5, r0 + close(fd); + 2a8: e1a00004 mov r0, r4 + 2ac: eb000071 bl 478 + return r; +} + 2b0: e1a00005 mov r0, r5 + 2b4: e8bd8830 pop {r4, r5, fp, pc} + +000002b8 : + +int +atoi(const char *s) +{ + 2b8: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 2bc: e28db000 add fp, sp, #0 + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 2c0: e5d03000 ldrb r3, [r0] + 2c4: e2432030 sub r2, r3, #48 ; 0x30 + 2c8: e6ef2072 uxtb r2, r2 + 2cc: e3520009 cmp r2, #9 +int +atoi(const char *s) +{ + int n; + + n = 0; + 2d0: 83a00000 movhi r0, #0 + while('0' <= *s && *s <= '9') + 2d4: 8a000009 bhi 300 + 2d8: e1a02000 mov r2, r0 +int +atoi(const char *s) +{ + int n; + + n = 0; + 2dc: e3a00000 mov r0, #0 + while('0' <= *s && *s <= '9') + n = n*10 + *s++ - '0'; + 2e0: e0800100 add r0, r0, r0, lsl #2 + 2e4: e0830080 add r0, r3, r0, lsl #1 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 2e8: e5f23001 ldrb r3, [r2, #1]! + n = n*10 + *s++ - '0'; + 2ec: e2400030 sub r0, r0, #48 ; 0x30 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 2f0: e2431030 sub r1, r3, #48 ; 0x30 + 2f4: e6ef1071 uxtb r1, r1 + 2f8: e3510009 cmp r1, #9 + 2fc: 9afffff7 bls 2e0 + n = n*10 + *s++ - '0'; + return n; +} + 300: e28bd000 add sp, fp, #0 + 304: e8bd0800 pop {fp} + 308: e12fff1e bx lr + +0000030c : +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 30c: e3520000 cmp r2, #0 + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) +{ + 310: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 314: e28db000 add fp, sp, #0 + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 318: da000005 ble 334 + n = n*10 + *s++ - '0'; + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) + 31c: e0802002 add r2, r0, r2 +{ + char *dst, *src; + + dst = vdst; + 320: e1a03000 mov r3, r0 + src = vsrc; + while(n-- > 0) + *dst++ = *src++; + 324: e4d1c001 ldrb ip, [r1], #1 + 328: e4c3c001 strb ip, [r3], #1 +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 32c: e1530002 cmp r3, r2 + 330: 1afffffb bne 324 + *dst++ = *src++; + return vdst; +} + 334: e28bd000 add sp, fp, #0 + 338: e8bd0800 pop {fp} + 33c: e12fff1e bx lr + +00000340 : + 340: e92d4000 push {lr} + 344: e92d0008 push {r3} + 348: e92d0004 push {r2} + 34c: e92d0002 push {r1} + 350: e92d0001 push {r0} + 354: e3a00001 mov r0, #1 + 358: ef000040 svc 0x00000040 + 35c: e8bd0002 pop {r1} + 360: e8bd0002 pop {r1} + 364: e8bd0004 pop {r2} + 368: e8bd0008 pop {r3} + 36c: e8bd4000 pop {lr} + 370: e12fff1e bx lr + +00000374 : + 374: e92d4000 push {lr} + 378: e92d0008 push {r3} + 37c: e92d0004 push {r2} + 380: e92d0002 push {r1} + 384: e92d0001 push {r0} + 388: e3a00002 mov r0, #2 + 38c: ef000040 svc 0x00000040 + 390: e8bd0002 pop {r1} + 394: e8bd0002 pop {r1} + 398: e8bd0004 pop {r2} + 39c: e8bd0008 pop {r3} + 3a0: e8bd4000 pop {lr} + 3a4: e12fff1e bx lr + +000003a8 : + 3a8: e92d4000 push {lr} + 3ac: e92d0008 push {r3} + 3b0: e92d0004 push {r2} + 3b4: e92d0002 push {r1} + 3b8: e92d0001 push {r0} + 3bc: e3a00003 mov r0, #3 + 3c0: ef000040 svc 0x00000040 + 3c4: e8bd0002 pop {r1} + 3c8: e8bd0002 pop {r1} + 3cc: e8bd0004 pop {r2} + 3d0: e8bd0008 pop {r3} + 3d4: e8bd4000 pop {lr} + 3d8: e12fff1e bx lr + +000003dc : + 3dc: e92d4000 push {lr} + 3e0: e92d0008 push {r3} + 3e4: e92d0004 push {r2} + 3e8: e92d0002 push {r1} + 3ec: e92d0001 push {r0} + 3f0: e3a00004 mov r0, #4 + 3f4: ef000040 svc 0x00000040 + 3f8: e8bd0002 pop {r1} + 3fc: e8bd0002 pop {r1} + 400: e8bd0004 pop {r2} + 404: e8bd0008 pop {r3} + 408: e8bd4000 pop {lr} + 40c: e12fff1e bx lr + +00000410 : + 410: e92d4000 push {lr} + 414: e92d0008 push {r3} + 418: e92d0004 push {r2} + 41c: e92d0002 push {r1} + 420: e92d0001 push {r0} + 424: e3a00005 mov r0, #5 + 428: ef000040 svc 0x00000040 + 42c: e8bd0002 pop {r1} + 430: e8bd0002 pop {r1} + 434: e8bd0004 pop {r2} + 438: e8bd0008 pop {r3} + 43c: e8bd4000 pop {lr} + 440: e12fff1e bx lr + +00000444 : + 444: e92d4000 push {lr} + 448: e92d0008 push {r3} + 44c: e92d0004 push {r2} + 450: e92d0002 push {r1} + 454: e92d0001 push {r0} + 458: e3a00010 mov r0, #16 + 45c: ef000040 svc 0x00000040 + 460: e8bd0002 pop {r1} + 464: e8bd0002 pop {r1} + 468: e8bd0004 pop {r2} + 46c: e8bd0008 pop {r3} + 470: e8bd4000 pop {lr} + 474: e12fff1e bx lr + +00000478 : + 478: e92d4000 push {lr} + 47c: e92d0008 push {r3} + 480: e92d0004 push {r2} + 484: e92d0002 push {r1} + 488: e92d0001 push {r0} + 48c: e3a00015 mov r0, #21 + 490: ef000040 svc 0x00000040 + 494: e8bd0002 pop {r1} + 498: e8bd0002 pop {r1} + 49c: e8bd0004 pop {r2} + 4a0: e8bd0008 pop {r3} + 4a4: e8bd4000 pop {lr} + 4a8: e12fff1e bx lr + +000004ac : + 4ac: e92d4000 push {lr} + 4b0: e92d0008 push {r3} + 4b4: e92d0004 push {r2} + 4b8: e92d0002 push {r1} + 4bc: e92d0001 push {r0} + 4c0: e3a00006 mov r0, #6 + 4c4: ef000040 svc 0x00000040 + 4c8: e8bd0002 pop {r1} + 4cc: e8bd0002 pop {r1} + 4d0: e8bd0004 pop {r2} + 4d4: e8bd0008 pop {r3} + 4d8: e8bd4000 pop {lr} + 4dc: e12fff1e bx lr + +000004e0 : + 4e0: e92d4000 push {lr} + 4e4: e92d0008 push {r3} + 4e8: e92d0004 push {r2} + 4ec: e92d0002 push {r1} + 4f0: e92d0001 push {r0} + 4f4: e3a00007 mov r0, #7 + 4f8: ef000040 svc 0x00000040 + 4fc: e8bd0002 pop {r1} + 500: e8bd0002 pop {r1} + 504: e8bd0004 pop {r2} + 508: e8bd0008 pop {r3} + 50c: e8bd4000 pop {lr} + 510: e12fff1e bx lr + +00000514 : + 514: e92d4000 push {lr} + 518: e92d0008 push {r3} + 51c: e92d0004 push {r2} + 520: e92d0002 push {r1} + 524: e92d0001 push {r0} + 528: e3a0000f mov r0, #15 + 52c: ef000040 svc 0x00000040 + 530: e8bd0002 pop {r1} + 534: e8bd0002 pop {r1} + 538: e8bd0004 pop {r2} + 53c: e8bd0008 pop {r3} + 540: e8bd4000 pop {lr} + 544: e12fff1e bx lr + +00000548 : + 548: e92d4000 push {lr} + 54c: e92d0008 push {r3} + 550: e92d0004 push {r2} + 554: e92d0002 push {r1} + 558: e92d0001 push {r0} + 55c: e3a00011 mov r0, #17 + 560: ef000040 svc 0x00000040 + 564: e8bd0002 pop {r1} + 568: e8bd0002 pop {r1} + 56c: e8bd0004 pop {r2} + 570: e8bd0008 pop {r3} + 574: e8bd4000 pop {lr} + 578: e12fff1e bx lr + +0000057c : + 57c: e92d4000 push {lr} + 580: e92d0008 push {r3} + 584: e92d0004 push {r2} + 588: e92d0002 push {r1} + 58c: e92d0001 push {r0} + 590: e3a00012 mov r0, #18 + 594: ef000040 svc 0x00000040 + 598: e8bd0002 pop {r1} + 59c: e8bd0002 pop {r1} + 5a0: e8bd0004 pop {r2} + 5a4: e8bd0008 pop {r3} + 5a8: e8bd4000 pop {lr} + 5ac: e12fff1e bx lr + +000005b0 : + 5b0: e92d4000 push {lr} + 5b4: e92d0008 push {r3} + 5b8: e92d0004 push {r2} + 5bc: e92d0002 push {r1} + 5c0: e92d0001 push {r0} + 5c4: e3a00008 mov r0, #8 + 5c8: ef000040 svc 0x00000040 + 5cc: e8bd0002 pop {r1} + 5d0: e8bd0002 pop {r1} + 5d4: e8bd0004 pop {r2} + 5d8: e8bd0008 pop {r3} + 5dc: e8bd4000 pop {lr} + 5e0: e12fff1e bx lr + +000005e4 : + 5e4: e92d4000 push {lr} + 5e8: e92d0008 push {r3} + 5ec: e92d0004 push {r2} + 5f0: e92d0002 push {r1} + 5f4: e92d0001 push {r0} + 5f8: e3a00013 mov r0, #19 + 5fc: ef000040 svc 0x00000040 + 600: e8bd0002 pop {r1} + 604: e8bd0002 pop {r1} + 608: e8bd0004 pop {r2} + 60c: e8bd0008 pop {r3} + 610: e8bd4000 pop {lr} + 614: e12fff1e bx lr + +00000618 : + 618: e92d4000 push {lr} + 61c: e92d0008 push {r3} + 620: e92d0004 push {r2} + 624: e92d0002 push {r1} + 628: e92d0001 push {r0} + 62c: e3a00014 mov r0, #20 + 630: ef000040 svc 0x00000040 + 634: e8bd0002 pop {r1} + 638: e8bd0002 pop {r1} + 63c: e8bd0004 pop {r2} + 640: e8bd0008 pop {r3} + 644: e8bd4000 pop {lr} + 648: e12fff1e bx lr + +0000064c : + 64c: e92d4000 push {lr} + 650: e92d0008 push {r3} + 654: e92d0004 push {r2} + 658: e92d0002 push {r1} + 65c: e92d0001 push {r0} + 660: e3a00009 mov r0, #9 + 664: ef000040 svc 0x00000040 + 668: e8bd0002 pop {r1} + 66c: e8bd0002 pop {r1} + 670: e8bd0004 pop {r2} + 674: e8bd0008 pop {r3} + 678: e8bd4000 pop {lr} + 67c: e12fff1e bx lr + +00000680 : + 680: e92d4000 push {lr} + 684: e92d0008 push {r3} + 688: e92d0004 push {r2} + 68c: e92d0002 push {r1} + 690: e92d0001 push {r0} + 694: e3a0000a mov r0, #10 + 698: ef000040 svc 0x00000040 + 69c: e8bd0002 pop {r1} + 6a0: e8bd0002 pop {r1} + 6a4: e8bd0004 pop {r2} + 6a8: e8bd0008 pop {r3} + 6ac: e8bd4000 pop {lr} + 6b0: e12fff1e bx lr + +000006b4 : + 6b4: e92d4000 push {lr} + 6b8: e92d0008 push {r3} + 6bc: e92d0004 push {r2} + 6c0: e92d0002 push {r1} + 6c4: e92d0001 push {r0} + 6c8: e3a0000b mov r0, #11 + 6cc: ef000040 svc 0x00000040 + 6d0: e8bd0002 pop {r1} + 6d4: e8bd0002 pop {r1} + 6d8: e8bd0004 pop {r2} + 6dc: e8bd0008 pop {r3} + 6e0: e8bd4000 pop {lr} + 6e4: e12fff1e bx lr + +000006e8 : + 6e8: e92d4000 push {lr} + 6ec: e92d0008 push {r3} + 6f0: e92d0004 push {r2} + 6f4: e92d0002 push {r1} + 6f8: e92d0001 push {r0} + 6fc: e3a0000c mov r0, #12 + 700: ef000040 svc 0x00000040 + 704: e8bd0002 pop {r1} + 708: e8bd0002 pop {r1} + 70c: e8bd0004 pop {r2} + 710: e8bd0008 pop {r3} + 714: e8bd4000 pop {lr} + 718: e12fff1e bx lr + +0000071c : + 71c: e92d4000 push {lr} + 720: e92d0008 push {r3} + 724: e92d0004 push {r2} + 728: e92d0002 push {r1} + 72c: e92d0001 push {r0} + 730: e3a0000d mov r0, #13 + 734: ef000040 svc 0x00000040 + 738: e8bd0002 pop {r1} + 73c: e8bd0002 pop {r1} + 740: e8bd0004 pop {r2} + 744: e8bd0008 pop {r3} + 748: e8bd4000 pop {lr} + 74c: e12fff1e bx lr + +00000750 : + 750: e92d4000 push {lr} + 754: e92d0008 push {r3} + 758: e92d0004 push {r2} + 75c: e92d0002 push {r1} + 760: e92d0001 push {r0} + 764: e3a0000e mov r0, #14 + 768: ef000040 svc 0x00000040 + 76c: e8bd0002 pop {r1} + 770: e8bd0002 pop {r1} + 774: e8bd0004 pop {r2} + 778: e8bd0008 pop {r3} + 77c: e8bd4000 pop {lr} + 780: e12fff1e bx lr + +00000784 : +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 784: e92d4800 push {fp, lr} + 788: e28db004 add fp, sp, #4 + 78c: e24b3004 sub r3, fp, #4 + 790: e24dd008 sub sp, sp, #8 + write(fd, &c, 1); + 794: e3a02001 mov r2, #1 +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 798: e5631001 strb r1, [r3, #-1]! + write(fd, &c, 1); + 79c: e1a01003 mov r1, r3 + 7a0: ebffff27 bl 444 +} + 7a4: e24bd004 sub sp, fp, #4 + 7a8: e8bd8800 pop {fp, pc} + +000007ac : + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 7ac: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 7b0: e1a04000 mov r4, r0 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 7b4: e1a00fa1 lsr r0, r1, #31 + 7b8: e3530000 cmp r3, #0 + 7bc: 03a03000 moveq r3, #0 + 7c0: 12003001 andne r3, r0, #1 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 7c4: e28db020 add fp, sp, #32 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 7c8: e3530000 cmp r3, #0 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 7cc: e24dd014 sub sp, sp, #20 + 7d0: e59f909c ldr r9, [pc, #156] ; 874 + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + x = -xx; + 7d4: 12611000 rsbne r1, r1, #0 + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + 7d8: 13a03001 movne r3, #1 + } else { + x = xx; + } + + b = base; + i = 0; + 7dc: e3a0a000 mov sl, #0 + 7e0: e24b6034 sub r6, fp, #52 ; 0x34 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 7e4: e3a08001 mov r8, #1 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 7e8: e3a07000 mov r7, #0 + int i; + + for(i=31;i>=0;i--){ + 7ec: e3a0001f mov r0, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 7f0: e1a0c007 mov ip, r7 + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 7f4: e1a0e031 lsr lr, r1, r0 + 7f8: e20ee001 and lr, lr, #1 + 7fc: e18ec08c orr ip, lr, ip, lsl #1 + if(r >= d) { + 800: e152000c cmp r2, ip + r = r - d; + q = q | (1 << i); + 804: 91877018 orrls r7, r7, r8, lsl r0 + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 808: 9062c00c rsbls ip, r2, ip +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 80c: e2500001 subs r0, r0, #1 + 810: 2afffff7 bcs 7f4 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 814: e0000792 mul r0, r2, r7 + }while((x = y) != 0); + 818: e3570000 cmp r7, #0 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 81c: e0601001 rsb r1, r0, r1 + 820: e28a5001 add r5, sl, #1 + 824: e7d91001 ldrb r1, [r9, r1] + 828: e7c6100a strb r1, [r6, sl] + }while((x = y) != 0); + 82c: 11a01007 movne r1, r7 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 830: 11a0a005 movne sl, r5 + 834: 1affffeb bne 7e8 + }while((x = y) != 0); + if(neg) + 838: e3530000 cmp r3, #0 + buf[i++] = '-'; + 83c: 124b2024 subne r2, fp, #36 ; 0x24 + 840: 10823005 addne r3, r2, r5 + 844: 128a5002 addne r5, sl, #2 + + while(--i >= 0) + 848: e2455001 sub r5, r5, #1 + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + 84c: 13a0202d movne r2, #45 ; 0x2d + 850: 15432010 strbne r2, [r3, #-16] + + while(--i >= 0) + putc(fd, buf[i]); + 854: e7d61005 ldrb r1, [r6, r5] + 858: e1a00004 mov r0, r4 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 85c: e2455001 sub r5, r5, #1 + putc(fd, buf[i]); + 860: ebffffc7 bl 784 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 864: e3750001 cmn r5, #1 + 868: 1afffff9 bne 854 + putc(fd, buf[i]); +} + 86c: e24bd020 sub sp, fp, #32 + 870: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} + 874: 00000c00 .word 0x00000c00 + +00000878
: + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 878: e3a03000 mov r3, #0 +{ + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + 87c: e92d0830 push {r4, r5, fp} + 880: e1a02000 mov r2, r0 + 884: e28db008 add fp, sp, #8 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 888: e3a0c01f mov ip, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 88c: e1a00003 mov r0, r3 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 890: e3a05001 mov r5, #1 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 894: e1a04c32 lsr r4, r2, ip + 898: e2044001 and r4, r4, #1 + 89c: e1843083 orr r3, r4, r3, lsl #1 + if(r >= d) { + 8a0: e1530001 cmp r3, r1 + r = r - d; + q = q | (1 << i); + 8a4: 21800c15 orrcs r0, r0, r5, lsl ip + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 8a8: 20613003 rsbcs r3, r1, r3 +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 8ac: e25cc001 subs ip, ip, #1 + 8b0: 2afffff7 bcs 894 + r = r - d; + q = q | (1 << i); + } + } + return q; +} + 8b4: e24bd008 sub sp, fp, #8 + 8b8: e8bd0830 pop {r4, r5, fp} + 8bc: e12fff1e bx lr + +000008c0 : +} + +// Print to the given fd. Only understands %d, %x, %p, %s. +void +printf(int fd, char *fmt, ...) +{ + 8c0: e92d000e push {r1, r2, r3} + 8c4: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 8c8: e28db020 add fp, sp, #32 + 8cc: e1a05000 mov r5, r0 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 8d0: e59b4004 ldr r4, [fp, #4] + 8d4: e5d48000 ldrb r8, [r4] + 8d8: e3580000 cmp r8, #0 + 8dc: 0a000027 beq 980 + ap++; + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + 8e0: e59f712c ldr r7, [pc, #300] ; a14 + char *s; + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + 8e4: e28b6008 add r6, fp, #8 +{ + char *s; + int c, i, state; + uint *ap; + + state = 0; + 8e8: e3a0a000 mov sl, #0 + 8ec: ea000008 b 914 + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 8f0: e3580025 cmp r8, #37 ; 0x25 + state = '%'; + 8f4: 01a0a008 moveq sl, r8 + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 8f8: 0a000002 beq 908 + state = '%'; + } else { + putc(fd, c); + 8fc: e1a00005 mov r0, r5 + 900: e1a01008 mov r1, r8 + 904: ebffff9e bl 784 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 908: e5f48001 ldrb r8, [r4, #1]! + 90c: e3580000 cmp r8, #0 + 910: 0a00001a beq 980 + c = fmt[i] & 0xff; + if(state == 0){ + 914: e35a0000 cmp sl, #0 + 918: 0afffff4 beq 8f0 + if(c == '%'){ + state = '%'; + } else { + putc(fd, c); + } + } else if(state == '%'){ + 91c: e35a0025 cmp sl, #37 ; 0x25 + 920: 1afffff8 bne 908 + if(c == 'd'){ + 924: e3580064 cmp r8, #100 ; 0x64 + 928: 0a00002c beq 9e0 + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + 92c: e3580078 cmp r8, #120 ; 0x78 + 930: 13580070 cmpne r8, #112 ; 0x70 + 934: 13a09000 movne r9, #0 + 938: 03a09001 moveq r9, #1 + 93c: 0a000013 beq 990 + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + 940: e3580073 cmp r8, #115 ; 0x73 + 944: 0a000018 beq 9ac + s = "(null)"; + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + 948: e3580063 cmp r8, #99 ; 0x63 + 94c: 0a00002a beq 9fc + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 950: e3580025 cmp r8, #37 ; 0x25 + putc(fd, c); + 954: e1a0100a mov r1, sl + 958: e1a00005 mov r0, r5 + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 95c: 0a000002 beq 96c + putc(fd, c); + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + 960: ebffff87 bl 784 + putc(fd, c); + 964: e1a00005 mov r0, r5 + 968: e1a01008 mov r1, r8 + 96c: ebffff84 bl 784 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 970: e5f48001 ldrb r8, [r4, #1]! + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 974: e1a0a009 mov sl, r9 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 978: e3580000 cmp r8, #0 + 97c: 1affffe4 bne 914 + putc(fd, c); + } + state = 0; + } + } +} + 980: e24bd020 sub sp, fp, #32 + 984: e8bd4ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 988: e28dd00c add sp, sp, #12 + 98c: e12fff1e bx lr + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + 990: e1a00005 mov r0, r5 + 994: e4961004 ldr r1, [r6], #4 + 998: e3a02010 mov r2, #16 + 99c: e3a03000 mov r3, #0 + 9a0: ebffff81 bl 7ac + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 9a4: e3a0a000 mov sl, #0 + 9a8: eaffffd6 b 908 + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + s = (char*)*ap; + 9ac: e4968004 ldr r8, [r6], #4 + ap++; + if(s == 0) + s = "(null)"; + 9b0: e3580000 cmp r8, #0 + 9b4: 01a08007 moveq r8, r7 + while(*s != 0){ + 9b8: e5d81000 ldrb r1, [r8] + 9bc: e3510000 cmp r1, #0 + 9c0: 0a000004 beq 9d8 + putc(fd, *s); + 9c4: e1a00005 mov r0, r5 + 9c8: ebffff6d bl 784 + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + while(*s != 0){ + 9cc: e5f81001 ldrb r1, [r8, #1]! + 9d0: e3510000 cmp r1, #0 + 9d4: 1afffffa bne 9c4 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 9d8: e1a0a001 mov sl, r1 + 9dc: eaffffc9 b 908 + } else { + putc(fd, c); + } + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + 9e0: e1a00005 mov r0, r5 + 9e4: e4961004 ldr r1, [r6], #4 + 9e8: e3a0200a mov r2, #10 + 9ec: e3a03001 mov r3, #1 + 9f0: ebffff6d bl 7ac + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 9f4: e3a0a000 mov sl, #0 + 9f8: eaffffc2 b 908 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 9fc: e4961004 ldr r1, [r6], #4 + a00: e1a00005 mov r0, r5 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + a04: e1a0a009 mov sl, r9 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + a08: e6ef1071 uxtb r1, r1 + a0c: ebffff5c bl 784 + a10: eaffffbc b 908 + a14: 00000c14 .word 0x00000c14 + +00000a18 : +free(void *ap) +{ + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + a18: e59f3098 ldr r3, [pc, #152] ; ab8 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + a1c: e92d0830 push {r4, r5, fp} + Header *bp, *p; + + bp = (Header*)ap - 1; + a20: e240c008 sub ip, r0, #8 + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + a24: e5932000 ldr r2, [r3] +static Header base; +static Header *freep; + +void +free(void *ap) +{ + a28: e28db008 add fp, sp, #8 + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + a2c: e152000c cmp r2, ip + a30: e5921000 ldr r1, [r2] + a34: 2a000001 bcs a40 + a38: e15c0001 cmp ip, r1 + a3c: 3a000007 bcc a60 + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + a40: e1520001 cmp r2, r1 + a44: 3a000003 bcc a58 + a48: e152000c cmp r2, ip + a4c: 3a000003 bcc a60 + a50: e15c0001 cmp ip, r1 + a54: 3a000001 bcc a60 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + a58: e1a02001 mov r2, r1 + a5c: eafffff2 b a2c + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + a60: e5104004 ldr r4, [r0, #-4] + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + freep = p; + a64: e5832000 str r2, [r3] + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + a68: e08c5184 add r5, ip, r4, lsl #3 + a6c: e1550001 cmp r5, r1 + bp->s.size += p->s.ptr->s.size; + a70: 05911004 ldreq r1, [r1, #4] + a74: 00814004 addeq r4, r1, r4 + a78: 05004004 streq r4, [r0, #-4] + bp->s.ptr = p->s.ptr->s.ptr; + a7c: 05921000 ldreq r1, [r2] + a80: 05911000 ldreq r1, [r1] + } else + bp->s.ptr = p->s.ptr; + a84: e5001008 str r1, [r0, #-8] + if(p + p->s.size == bp){ + a88: e5921004 ldr r1, [r2, #4] + a8c: e0824181 add r4, r2, r1, lsl #3 + a90: e15c0004 cmp ip, r4 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + a94: 1582c000 strne ip, [r2] + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + } else + bp->s.ptr = p->s.ptr; + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + a98: 0510c004 ldreq ip, [r0, #-4] + a9c: 008c1001 addeq r1, ip, r1 + aa0: 05821004 streq r1, [r2, #4] + p->s.ptr = bp->s.ptr; + aa4: 05101008 ldreq r1, [r0, #-8] + aa8: 05821000 streq r1, [r2] + } else + p->s.ptr = bp; + freep = p; +} + aac: e24bd008 sub sp, fp, #8 + ab0: e8bd0830 pop {r4, r5, fp} + ab4: e12fff1e bx lr + ab8: 00000c24 .word 0x00000c24 + +00000abc : + return freep; +} + +void* +malloc(uint nbytes) +{ + abc: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + ac0: e2804007 add r4, r0, #7 + if((prevp = freep) == 0){ + ac4: e59f50d4 ldr r5, [pc, #212] ; ba0 +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + ac8: e1a041a4 lsr r4, r4, #3 + return freep; +} + +void* +malloc(uint nbytes) +{ + acc: e28db01c add fp, sp, #28 + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + ad0: e5953000 ldr r3, [r5] +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + ad4: e2844001 add r4, r4, #1 + if((prevp = freep) == 0){ + ad8: e3530000 cmp r3, #0 + adc: 0a00002b beq b90 + ae0: e5930000 ldr r0, [r3] + ae4: e5902004 ldr r2, [r0, #4] + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + ae8: e1520004 cmp r2, r4 + aec: 2a00001b bcs b60 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + af0: e59f80ac ldr r8, [pc, #172] ; ba4 + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + af4: e1a07184 lsl r7, r4, #3 + af8: ea000003 b b0c + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + afc: e5930000 ldr r0, [r3] + if(p->s.size >= nunits){ + b00: e5902004 ldr r2, [r0, #4] + b04: e1540002 cmp r4, r2 + b08: 9a000014 bls b60 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + b0c: e5952000 ldr r2, [r5] + b10: e1a03000 mov r3, r0 + b14: e1500002 cmp r0, r2 + b18: 1afffff7 bne afc +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + b1c: e1540008 cmp r4, r8 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + b20: 81a00007 movhi r0, r7 + b24: 93a00902 movls r0, #32768 ; 0x8000 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + b28: 81a06004 movhi r6, r4 + b2c: 93a06a01 movls r6, #4096 ; 0x1000 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + b30: ebfffeec bl 6e8 + b34: e1a03000 mov r3, r0 + if(p == (char*)-1) + b38: e3730001 cmn r3, #1 + return 0; + hp = (Header*)p; + hp->s.size = nu; + free((void*)(hp + 1)); + b3c: e2800008 add r0, r0, #8 + Header *hp; + + if(nu < 4096) + nu = 4096; + p = sbrk(nu * sizeof(Header)); + if(p == (char*)-1) + b40: 0a000010 beq b88 + return 0; + hp = (Header*)p; + hp->s.size = nu; + b44: e5836004 str r6, [r3, #4] + free((void*)(hp + 1)); + b48: ebffffb2 bl a18 + return freep; + b4c: e5953000 ldr r3, [r5] + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + if((p = morecore(nunits)) == 0) + b50: e3530000 cmp r3, #0 + b54: 1affffe8 bne afc + return 0; + b58: e1a00003 mov r0, r3 + } +} + b5c: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + b60: e1540002 cmp r4, r2 + prevp->s.ptr = p->s.ptr; + else { + p->s.size -= nunits; + b64: 10642002 rsbne r2, r4, r2 + b68: 15802004 strne r2, [r0, #4] + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + b6c: 05902000 ldreq r2, [r0] + else { + p->s.size -= nunits; + p += p->s.size; + b70: 10800182 addne r0, r0, r2, lsl #3 + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + b74: 05832000 streq r2, [r3] + else { + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + b78: 15804004 strne r4, [r0, #4] + } + freep = prevp; + b7c: e5853000 str r3, [r5] + return (void*)(p + 1); + b80: e2800008 add r0, r0, #8 + b84: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + } + if(p == freep) + if((p = morecore(nunits)) == 0) + return 0; + b88: e3a00000 mov r0, #0 + b8c: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + b90: e2850004 add r0, r5, #4 + b94: e5850000 str r0, [r5] + base.s.size = 0; + b98: e9850009 stmib r5, {r0, r3} + b9c: eaffffd3 b af0 + ba0: 00000c24 .word 0x00000c24 + ba4: 00000fff .word 0x00000fff diff -r 000000000000 -r c450faca55f4 uprogs/init.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/init.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,37 @@ +// init: The initial user-level program + +#include "types.h" +#include "stat.h" +#include "user.h" +#include "fcntl.h" + +char *argv[] = { "sh", 0 }; + +int +main(void) +{ + int pid, wpid; + + if(open("console", O_RDWR) < 0){ + mknod("console", 1, 1); + open("console", O_RDWR); + } + dup(0); // stdout + dup(0); // stderr + + for(;;){ + printf(1, "init: starting sh\n"); + pid = fork(); + if(pid < 0){ + printf(1, "init: fork failed\n"); + exit(); + } + if(pid == 0){ + exec("sh", argv); + printf(1, "init: exec sh failed\n"); + exit(); + } + while((wpid=wait()) >= 0 && wpid != pid) + printf(1, "zombie!\n"); + } +} diff -r 000000000000 -r c450faca55f4 uprogs/init.sym --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/init.sym Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,66 @@ +00000000 .text +00000ba8 .rodata +00000c1c .data +00000c24 .bss +00000000 .comment +00000000 .ARM.attributes +00000000 .debug_aranges +00000000 .debug_info +00000000 .debug_abbrev +00000000 .debug_line +00000000 .debug_frame +00000000 .debug_str +00000000 .debug_loc +00000000 .debug_ranges +00000000 init.c +00000000 ulib.c +00000000 printf.c +00000784 putc +000007ac printint +00000c00 digits.993 +00000000 umalloc.c +00000c24 freep +00000c28 base +000000d4 strcpy +000008c0 printf +00000c1c argv +0000030c memmove +00000548 mknod +00000c30 _bss_end__ +00000204 gets +000006b4 getpid +00000abc malloc +0000071c sleep +00000c24 __bss_start__ +000003dc pipe +00000444 write +000005b0 fstat +000004ac kill +0000064c chdir +000004e0 exec +00000c30 __bss_end__ +000003a8 wait +00000410 read +0000057c unlink +00000340 fork +000006e8 sbrk +00000750 uptime +00000c24 __bss_start +00000188 memset +00000000 main +00000c30 __end__ +000000fc strcmp +00000680 dup +0000027c stat +00000c24 _edata +00000c30 _end +000005e4 link +00000374 exit +000002b8 atoi +00000148 strlen +00000514 open +00000878 div +000001c0 strchr +00000618 mkdir +00000478 close +00000a18 free diff -r 000000000000 -r c450faca55f4 uprogs/initcode Binary file uprogs/initcode has changed diff -r 000000000000 -r c450faca55f4 uprogs/initcode.S --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/initcode.S Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,37 @@ +# Initial process execs /init. + +#include "syscall.h" +#include "traps.h" + + +# exec(init, argv) +.globl start +start: + push {lr} + ldr r0, =argv + push {r0} + ldr r0, =init + push {r0} + mov r0, #SYS_exec + swi #T_SYSCALL + pop {lr} + pop {lr} + pop {lr} + bx lr + +# for(;;) exit(); +exit: + mov r11, #SYS_exit + swi #T_SYSCALL + bl exit + +# char init[] = "/init\0"; +init: + .string "/init\0" + +# char *argv[] = { init, 0 }; +.p2align 2 +argv: + .long init + .long 0 + diff -r 000000000000 -r c450faca55f4 uprogs/initcode.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/initcode.asm Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,64 @@ + +initcode.o: file format elf32-littlearm + + +Disassembly of section .text: + +00000000 : + + +# exec(init, argv) +.globl start +start: + push {lr} + 0: e92d4000 push {lr} + ldr r0, =argv + 4: e59f003c ldr r0, [pc, #60] ; 48 + push {r0} + 8: e92d0001 push {r0} + ldr r0, =init + c: e59f0038 ldr r0, [pc, #56] ; 4c + push {r0} + 10: e92d0001 push {r0} + mov r0, #SYS_exec + 14: e3a00007 mov r0, #7 + swi #T_SYSCALL + 18: ef000040 svc 0x00000040 + pop {lr} + 1c: e8bd4000 pop {lr} + pop {lr} + 20: e8bd4000 pop {lr} + pop {lr} + 24: e8bd4000 pop {lr} + bx lr + 28: e12fff1e bx lr + +0000002c : + +# for(;;) exit(); +exit: + mov r11, #SYS_exit + 2c: e3a0b002 mov fp, #2 + swi #T_SYSCALL + 30: ef000040 svc 0x00000040 + bl exit + 34: ebfffffc bl 2c + +00000038 : + 38: 696e692f .word 0x696e692f + 3c: 0074 .short 0x0074 + ... + +00000040 : + 40: 00000038 andeq r0, r0, r8, lsr r0 + 44: 00000000 andeq r0, r0, r0 + +# exec(init, argv) +.globl start +start: + push {lr} + ldr r0, =argv + 48: 00000040 andeq r0, r0, r0, asr #32 + push {r0} + ldr r0, =init + 4c: 00000038 andeq r0, r0, r8, lsr r0 diff -r 000000000000 -r c450faca55f4 uprogs/initcode.out Binary file uprogs/initcode.out has changed diff -r 000000000000 -r c450faca55f4 uprogs/kill.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/kill.asm Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,1694 @@ + +_kill: file format elf32-littlearm + + +Disassembly of section .text: + +00000000
: +#include "stat.h" +#include "user.h" + +int +main(int argc, char **argv) +{ + 0: e92d4878 push {r3, r4, r5, r6, fp, lr} + int i; + + if(argc < 1){ + 4: e2504000 subs r4, r0, #0 +#include "stat.h" +#include "user.h" + +int +main(int argc, char **argv) +{ + 8: e28db014 add fp, sp, #20 + int i; + + if(argc < 1){ + c: da00000a ble 3c + printf(2, "usage: kill pid...\n"); + exit(); + } + for(i=1; i + kill(atoi(argv[i])); + 20: e5b60004 ldr r0, [r6, #4]! + 24: eb000082 bl 234 + + if(argc < 1){ + printf(2, "usage: kill pid...\n"); + exit(); + } + for(i=1; i + + if(argc < 1){ + printf(2, "usage: kill pid...\n"); + exit(); + } + for(i=1; i + kill(atoi(argv[i])); + exit(); + 38: eb0000ac bl 2f0 +main(int argc, char **argv) +{ + int i; + + if(argc < 1){ + printf(2, "usage: kill pid...\n"); + 3c: e3a00002 mov r0, #2 + 40: e59f1004 ldr r1, [pc, #4] ; 4c + 44: eb0001fc bl 83c + exit(); + 48: eb0000a8 bl 2f0 + 4c: 00000b24 .word 0x00000b24 + +00000050 : +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 50: e52db004 push {fp} ; (str fp, [sp, #-4]!) + char *os; + + os = s; + while((*s++ = *t++) != 0) + 54: e1a02000 mov r2, r0 +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 58: e28db000 add fp, sp, #0 + char *os; + + os = s; + while((*s++ = *t++) != 0) + 5c: e4d13001 ldrb r3, [r1], #1 + 60: e3530000 cmp r3, #0 + 64: e4c23001 strb r3, [r2], #1 + 68: 1afffffb bne 5c + ; + return os; +} + 6c: e28bd000 add sp, fp, #0 + 70: e8bd0800 pop {fp} + 74: e12fff1e bx lr + +00000078 : + +int +strcmp(const char *p, const char *q) +{ + 78: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 7c: e28db000 add fp, sp, #0 + while(*p && *p == *q) + 80: e5d03000 ldrb r3, [r0] + 84: e5d12000 ldrb r2, [r1] + 88: e3530000 cmp r3, #0 + 8c: 1a000004 bne a4 + 90: ea000005 b ac + 94: e5f03001 ldrb r3, [r0, #1]! + 98: e3530000 cmp r3, #0 + 9c: 0a000006 beq bc + a0: e5f12001 ldrb r2, [r1, #1]! + a4: e1530002 cmp r3, r2 + a8: 0afffff9 beq 94 + p++, q++; + return (uchar)*p - (uchar)*q; +} + ac: e0620003 rsb r0, r2, r3 + b0: e28bd000 add sp, fp, #0 + b4: e8bd0800 pop {fp} + b8: e12fff1e bx lr +} + +int +strcmp(const char *p, const char *q) +{ + while(*p && *p == *q) + bc: e5d12001 ldrb r2, [r1, #1] + c0: eafffff9 b ac + +000000c4 : + return (uchar)*p - (uchar)*q; +} + +uint +strlen(char *s) +{ + c4: e52db004 push {fp} ; (str fp, [sp, #-4]!) + c8: e28db000 add fp, sp, #0 + int n; + + for(n = 0; s[n]; n++) + cc: e5d03000 ldrb r3, [r0] + d0: e3530000 cmp r3, #0 + d4: 01a00003 moveq r0, r3 + d8: 0a000006 beq f8 + dc: e1a02000 mov r2, r0 + e0: e3a03000 mov r3, #0 + e4: e5f21001 ldrb r1, [r2, #1]! + e8: e2833001 add r3, r3, #1 + ec: e1a00003 mov r0, r3 + f0: e3510000 cmp r1, #0 + f4: 1afffffa bne e4 + ; + return n; +} + f8: e28bd000 add sp, fp, #0 + fc: e8bd0800 pop {fp} + 100: e12fff1e bx lr + +00000104 : +memset(void *dst, int c, uint n) +{ + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 104: e3520000 cmp r2, #0 + return n; +} + +void* +memset(void *dst, int c, uint n) +{ + 108: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 10c: e28db000 add fp, sp, #0 + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 110: 0a000006 beq 130 + 114: e6ef1071 uxtb r1, r1 + 118: e1a03002 mov r3, r2 +} + +void* +memset(void *dst, int c, uint n) +{ + char *p=dst; + 11c: e1a0c000 mov ip, r0 + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 120: e2533001 subs r3, r3, #1 + 124: e4cc1001 strb r1, [ip], #1 + 128: 1afffffc bne 120 + 12c: e0800002 add r0, r0, r2 + return (void *)p; +} + 130: e28bd000 add sp, fp, #0 + 134: e8bd0800 pop {fp} + 138: e12fff1e bx lr + +0000013c : + +char* +strchr(const char *s, char c) +{ + 13c: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 140: e28db000 add fp, sp, #0 + for(; *s; s++) + 144: e5d03000 ldrb r3, [r0] + 148: e3530000 cmp r3, #0 + 14c: 1a000004 bne 164 + 150: ea000008 b 178 + 154: e5d03001 ldrb r3, [r0, #1] + 158: e2800001 add r0, r0, #1 + 15c: e3530000 cmp r3, #0 + 160: 0a000004 beq 178 + if(*s == c) + 164: e1530001 cmp r3, r1 + 168: 1afffff9 bne 154 + return (char*)s; + return 0; +} + 16c: e28bd000 add sp, fp, #0 + 170: e8bd0800 pop {fp} + 174: e12fff1e bx lr +strchr(const char *s, char c) +{ + for(; *s; s++) + if(*s == c) + return (char*)s; + return 0; + 178: e1a00003 mov r0, r3 + 17c: eafffffa b 16c + +00000180 : +} + +char* +gets(char *buf, int max) +{ + 180: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + 184: e28db018 add fp, sp, #24 + 188: e24dd00c sub sp, sp, #12 + 18c: e1a08000 mov r8, r0 + 190: e1a07001 mov r7, r1 + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 194: e1a06000 mov r6, r0 + 198: e3a05000 mov r5, #0 + 19c: ea000008 b 1c4 + cc = read(0, &c, 1); + 1a0: eb000079 bl 38c + if(cc < 1) + 1a4: e3500000 cmp r0, #0 + 1a8: da00000b ble 1dc + break; + buf[i++] = c; + 1ac: e55b301d ldrb r3, [fp, #-29] + if(c == '\n' || c == '\r') + 1b0: e1a05004 mov r5, r4 + 1b4: e353000a cmp r3, #10 + 1b8: 1353000d cmpne r3, #13 + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + if(cc < 1) + break; + buf[i++] = c; + 1bc: e4c63001 strb r3, [r6], #1 + if(c == '\n' || c == '\r') + 1c0: 0a00000a beq 1f0 +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + 1c4: e3a02001 mov r2, #1 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 1c8: e0854002 add r4, r5, r2 + 1cc: e1540007 cmp r4, r7 + cc = read(0, &c, 1); + 1d0: e3a00000 mov r0, #0 + 1d4: e24b101d sub r1, fp, #29 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 1d8: bafffff0 blt 1a0 + break; + buf[i++] = c; + if(c == '\n' || c == '\r') + break; + } + buf[i] = '\0'; + 1dc: e3a03000 mov r3, #0 + 1e0: e7c83005 strb r3, [r8, r5] + return buf; +} + 1e4: e1a00008 mov r0, r8 + 1e8: e24bd018 sub sp, fp, #24 + 1ec: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 1f0: e1a05004 mov r5, r4 + 1f4: eafffff8 b 1dc + +000001f8 : + return buf; +} + +int +stat(char *n, struct stat *st) +{ + 1f8: e92d4830 push {r4, r5, fp, lr} + 1fc: e1a05001 mov r5, r1 + 200: e28db00c add fp, sp, #12 + int fd; + int r; + + fd = open(n, O_RDONLY); + 204: e3a01000 mov r1, #0 + 208: eb0000a0 bl 490 + if(fd < 0) + 20c: e2504000 subs r4, r0, #0 + return -1; + 210: b3e05000 mvnlt r5, #0 +{ + int fd; + int r; + + fd = open(n, O_RDONLY); + if(fd < 0) + 214: ba000004 blt 22c + return -1; + r = fstat(fd, st); + 218: e1a01005 mov r1, r5 + 21c: eb0000c2 bl 52c + 220: e1a05000 mov r5, r0 + close(fd); + 224: e1a00004 mov r0, r4 + 228: eb000071 bl 3f4 + return r; +} + 22c: e1a00005 mov r0, r5 + 230: e8bd8830 pop {r4, r5, fp, pc} + +00000234 : + +int +atoi(const char *s) +{ + 234: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 238: e28db000 add fp, sp, #0 + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 23c: e5d03000 ldrb r3, [r0] + 240: e2432030 sub r2, r3, #48 ; 0x30 + 244: e6ef2072 uxtb r2, r2 + 248: e3520009 cmp r2, #9 +int +atoi(const char *s) +{ + int n; + + n = 0; + 24c: 83a00000 movhi r0, #0 + while('0' <= *s && *s <= '9') + 250: 8a000009 bhi 27c + 254: e1a02000 mov r2, r0 +int +atoi(const char *s) +{ + int n; + + n = 0; + 258: e3a00000 mov r0, #0 + while('0' <= *s && *s <= '9') + n = n*10 + *s++ - '0'; + 25c: e0800100 add r0, r0, r0, lsl #2 + 260: e0830080 add r0, r3, r0, lsl #1 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 264: e5f23001 ldrb r3, [r2, #1]! + n = n*10 + *s++ - '0'; + 268: e2400030 sub r0, r0, #48 ; 0x30 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 26c: e2431030 sub r1, r3, #48 ; 0x30 + 270: e6ef1071 uxtb r1, r1 + 274: e3510009 cmp r1, #9 + 278: 9afffff7 bls 25c + n = n*10 + *s++ - '0'; + return n; +} + 27c: e28bd000 add sp, fp, #0 + 280: e8bd0800 pop {fp} + 284: e12fff1e bx lr + +00000288 : +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 288: e3520000 cmp r2, #0 + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) +{ + 28c: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 290: e28db000 add fp, sp, #0 + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 294: da000005 ble 2b0 + n = n*10 + *s++ - '0'; + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) + 298: e0802002 add r2, r0, r2 +{ + char *dst, *src; + + dst = vdst; + 29c: e1a03000 mov r3, r0 + src = vsrc; + while(n-- > 0) + *dst++ = *src++; + 2a0: e4d1c001 ldrb ip, [r1], #1 + 2a4: e4c3c001 strb ip, [r3], #1 +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 2a8: e1530002 cmp r3, r2 + 2ac: 1afffffb bne 2a0 + *dst++ = *src++; + return vdst; +} + 2b0: e28bd000 add sp, fp, #0 + 2b4: e8bd0800 pop {fp} + 2b8: e12fff1e bx lr + +000002bc : + 2bc: e92d4000 push {lr} + 2c0: e92d0008 push {r3} + 2c4: e92d0004 push {r2} + 2c8: e92d0002 push {r1} + 2cc: e92d0001 push {r0} + 2d0: e3a00001 mov r0, #1 + 2d4: ef000040 svc 0x00000040 + 2d8: e8bd0002 pop {r1} + 2dc: e8bd0002 pop {r1} + 2e0: e8bd0004 pop {r2} + 2e4: e8bd0008 pop {r3} + 2e8: e8bd4000 pop {lr} + 2ec: e12fff1e bx lr + +000002f0 : + 2f0: e92d4000 push {lr} + 2f4: e92d0008 push {r3} + 2f8: e92d0004 push {r2} + 2fc: e92d0002 push {r1} + 300: e92d0001 push {r0} + 304: e3a00002 mov r0, #2 + 308: ef000040 svc 0x00000040 + 30c: e8bd0002 pop {r1} + 310: e8bd0002 pop {r1} + 314: e8bd0004 pop {r2} + 318: e8bd0008 pop {r3} + 31c: e8bd4000 pop {lr} + 320: e12fff1e bx lr + +00000324 : + 324: e92d4000 push {lr} + 328: e92d0008 push {r3} + 32c: e92d0004 push {r2} + 330: e92d0002 push {r1} + 334: e92d0001 push {r0} + 338: e3a00003 mov r0, #3 + 33c: ef000040 svc 0x00000040 + 340: e8bd0002 pop {r1} + 344: e8bd0002 pop {r1} + 348: e8bd0004 pop {r2} + 34c: e8bd0008 pop {r3} + 350: e8bd4000 pop {lr} + 354: e12fff1e bx lr + +00000358 : + 358: e92d4000 push {lr} + 35c: e92d0008 push {r3} + 360: e92d0004 push {r2} + 364: e92d0002 push {r1} + 368: e92d0001 push {r0} + 36c: e3a00004 mov r0, #4 + 370: ef000040 svc 0x00000040 + 374: e8bd0002 pop {r1} + 378: e8bd0002 pop {r1} + 37c: e8bd0004 pop {r2} + 380: e8bd0008 pop {r3} + 384: e8bd4000 pop {lr} + 388: e12fff1e bx lr + +0000038c : + 38c: e92d4000 push {lr} + 390: e92d0008 push {r3} + 394: e92d0004 push {r2} + 398: e92d0002 push {r1} + 39c: e92d0001 push {r0} + 3a0: e3a00005 mov r0, #5 + 3a4: ef000040 svc 0x00000040 + 3a8: e8bd0002 pop {r1} + 3ac: e8bd0002 pop {r1} + 3b0: e8bd0004 pop {r2} + 3b4: e8bd0008 pop {r3} + 3b8: e8bd4000 pop {lr} + 3bc: e12fff1e bx lr + +000003c0 : + 3c0: e92d4000 push {lr} + 3c4: e92d0008 push {r3} + 3c8: e92d0004 push {r2} + 3cc: e92d0002 push {r1} + 3d0: e92d0001 push {r0} + 3d4: e3a00010 mov r0, #16 + 3d8: ef000040 svc 0x00000040 + 3dc: e8bd0002 pop {r1} + 3e0: e8bd0002 pop {r1} + 3e4: e8bd0004 pop {r2} + 3e8: e8bd0008 pop {r3} + 3ec: e8bd4000 pop {lr} + 3f0: e12fff1e bx lr + +000003f4 : + 3f4: e92d4000 push {lr} + 3f8: e92d0008 push {r3} + 3fc: e92d0004 push {r2} + 400: e92d0002 push {r1} + 404: e92d0001 push {r0} + 408: e3a00015 mov r0, #21 + 40c: ef000040 svc 0x00000040 + 410: e8bd0002 pop {r1} + 414: e8bd0002 pop {r1} + 418: e8bd0004 pop {r2} + 41c: e8bd0008 pop {r3} + 420: e8bd4000 pop {lr} + 424: e12fff1e bx lr + +00000428 : + 428: e92d4000 push {lr} + 42c: e92d0008 push {r3} + 430: e92d0004 push {r2} + 434: e92d0002 push {r1} + 438: e92d0001 push {r0} + 43c: e3a00006 mov r0, #6 + 440: ef000040 svc 0x00000040 + 444: e8bd0002 pop {r1} + 448: e8bd0002 pop {r1} + 44c: e8bd0004 pop {r2} + 450: e8bd0008 pop {r3} + 454: e8bd4000 pop {lr} + 458: e12fff1e bx lr + +0000045c : + 45c: e92d4000 push {lr} + 460: e92d0008 push {r3} + 464: e92d0004 push {r2} + 468: e92d0002 push {r1} + 46c: e92d0001 push {r0} + 470: e3a00007 mov r0, #7 + 474: ef000040 svc 0x00000040 + 478: e8bd0002 pop {r1} + 47c: e8bd0002 pop {r1} + 480: e8bd0004 pop {r2} + 484: e8bd0008 pop {r3} + 488: e8bd4000 pop {lr} + 48c: e12fff1e bx lr + +00000490 : + 490: e92d4000 push {lr} + 494: e92d0008 push {r3} + 498: e92d0004 push {r2} + 49c: e92d0002 push {r1} + 4a0: e92d0001 push {r0} + 4a4: e3a0000f mov r0, #15 + 4a8: ef000040 svc 0x00000040 + 4ac: e8bd0002 pop {r1} + 4b0: e8bd0002 pop {r1} + 4b4: e8bd0004 pop {r2} + 4b8: e8bd0008 pop {r3} + 4bc: e8bd4000 pop {lr} + 4c0: e12fff1e bx lr + +000004c4 : + 4c4: e92d4000 push {lr} + 4c8: e92d0008 push {r3} + 4cc: e92d0004 push {r2} + 4d0: e92d0002 push {r1} + 4d4: e92d0001 push {r0} + 4d8: e3a00011 mov r0, #17 + 4dc: ef000040 svc 0x00000040 + 4e0: e8bd0002 pop {r1} + 4e4: e8bd0002 pop {r1} + 4e8: e8bd0004 pop {r2} + 4ec: e8bd0008 pop {r3} + 4f0: e8bd4000 pop {lr} + 4f4: e12fff1e bx lr + +000004f8 : + 4f8: e92d4000 push {lr} + 4fc: e92d0008 push {r3} + 500: e92d0004 push {r2} + 504: e92d0002 push {r1} + 508: e92d0001 push {r0} + 50c: e3a00012 mov r0, #18 + 510: ef000040 svc 0x00000040 + 514: e8bd0002 pop {r1} + 518: e8bd0002 pop {r1} + 51c: e8bd0004 pop {r2} + 520: e8bd0008 pop {r3} + 524: e8bd4000 pop {lr} + 528: e12fff1e bx lr + +0000052c : + 52c: e92d4000 push {lr} + 530: e92d0008 push {r3} + 534: e92d0004 push {r2} + 538: e92d0002 push {r1} + 53c: e92d0001 push {r0} + 540: e3a00008 mov r0, #8 + 544: ef000040 svc 0x00000040 + 548: e8bd0002 pop {r1} + 54c: e8bd0002 pop {r1} + 550: e8bd0004 pop {r2} + 554: e8bd0008 pop {r3} + 558: e8bd4000 pop {lr} + 55c: e12fff1e bx lr + +00000560 : + 560: e92d4000 push {lr} + 564: e92d0008 push {r3} + 568: e92d0004 push {r2} + 56c: e92d0002 push {r1} + 570: e92d0001 push {r0} + 574: e3a00013 mov r0, #19 + 578: ef000040 svc 0x00000040 + 57c: e8bd0002 pop {r1} + 580: e8bd0002 pop {r1} + 584: e8bd0004 pop {r2} + 588: e8bd0008 pop {r3} + 58c: e8bd4000 pop {lr} + 590: e12fff1e bx lr + +00000594 : + 594: e92d4000 push {lr} + 598: e92d0008 push {r3} + 59c: e92d0004 push {r2} + 5a0: e92d0002 push {r1} + 5a4: e92d0001 push {r0} + 5a8: e3a00014 mov r0, #20 + 5ac: ef000040 svc 0x00000040 + 5b0: e8bd0002 pop {r1} + 5b4: e8bd0002 pop {r1} + 5b8: e8bd0004 pop {r2} + 5bc: e8bd0008 pop {r3} + 5c0: e8bd4000 pop {lr} + 5c4: e12fff1e bx lr + +000005c8 : + 5c8: e92d4000 push {lr} + 5cc: e92d0008 push {r3} + 5d0: e92d0004 push {r2} + 5d4: e92d0002 push {r1} + 5d8: e92d0001 push {r0} + 5dc: e3a00009 mov r0, #9 + 5e0: ef000040 svc 0x00000040 + 5e4: e8bd0002 pop {r1} + 5e8: e8bd0002 pop {r1} + 5ec: e8bd0004 pop {r2} + 5f0: e8bd0008 pop {r3} + 5f4: e8bd4000 pop {lr} + 5f8: e12fff1e bx lr + +000005fc : + 5fc: e92d4000 push {lr} + 600: e92d0008 push {r3} + 604: e92d0004 push {r2} + 608: e92d0002 push {r1} + 60c: e92d0001 push {r0} + 610: e3a0000a mov r0, #10 + 614: ef000040 svc 0x00000040 + 618: e8bd0002 pop {r1} + 61c: e8bd0002 pop {r1} + 620: e8bd0004 pop {r2} + 624: e8bd0008 pop {r3} + 628: e8bd4000 pop {lr} + 62c: e12fff1e bx lr + +00000630 : + 630: e92d4000 push {lr} + 634: e92d0008 push {r3} + 638: e92d0004 push {r2} + 63c: e92d0002 push {r1} + 640: e92d0001 push {r0} + 644: e3a0000b mov r0, #11 + 648: ef000040 svc 0x00000040 + 64c: e8bd0002 pop {r1} + 650: e8bd0002 pop {r1} + 654: e8bd0004 pop {r2} + 658: e8bd0008 pop {r3} + 65c: e8bd4000 pop {lr} + 660: e12fff1e bx lr + +00000664 : + 664: e92d4000 push {lr} + 668: e92d0008 push {r3} + 66c: e92d0004 push {r2} + 670: e92d0002 push {r1} + 674: e92d0001 push {r0} + 678: e3a0000c mov r0, #12 + 67c: ef000040 svc 0x00000040 + 680: e8bd0002 pop {r1} + 684: e8bd0002 pop {r1} + 688: e8bd0004 pop {r2} + 68c: e8bd0008 pop {r3} + 690: e8bd4000 pop {lr} + 694: e12fff1e bx lr + +00000698 : + 698: e92d4000 push {lr} + 69c: e92d0008 push {r3} + 6a0: e92d0004 push {r2} + 6a4: e92d0002 push {r1} + 6a8: e92d0001 push {r0} + 6ac: e3a0000d mov r0, #13 + 6b0: ef000040 svc 0x00000040 + 6b4: e8bd0002 pop {r1} + 6b8: e8bd0002 pop {r1} + 6bc: e8bd0004 pop {r2} + 6c0: e8bd0008 pop {r3} + 6c4: e8bd4000 pop {lr} + 6c8: e12fff1e bx lr + +000006cc : + 6cc: e92d4000 push {lr} + 6d0: e92d0008 push {r3} + 6d4: e92d0004 push {r2} + 6d8: e92d0002 push {r1} + 6dc: e92d0001 push {r0} + 6e0: e3a0000e mov r0, #14 + 6e4: ef000040 svc 0x00000040 + 6e8: e8bd0002 pop {r1} + 6ec: e8bd0002 pop {r1} + 6f0: e8bd0004 pop {r2} + 6f4: e8bd0008 pop {r3} + 6f8: e8bd4000 pop {lr} + 6fc: e12fff1e bx lr + +00000700 : +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 700: e92d4800 push {fp, lr} + 704: e28db004 add fp, sp, #4 + 708: e24b3004 sub r3, fp, #4 + 70c: e24dd008 sub sp, sp, #8 + write(fd, &c, 1); + 710: e3a02001 mov r2, #1 +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 714: e5631001 strb r1, [r3, #-1]! + write(fd, &c, 1); + 718: e1a01003 mov r1, r3 + 71c: ebffff27 bl 3c0 +} + 720: e24bd004 sub sp, fp, #4 + 724: e8bd8800 pop {fp, pc} + +00000728 : + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 728: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 72c: e1a04000 mov r4, r0 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 730: e1a00fa1 lsr r0, r1, #31 + 734: e3530000 cmp r3, #0 + 738: 03a03000 moveq r3, #0 + 73c: 12003001 andne r3, r0, #1 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 740: e28db020 add fp, sp, #32 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 744: e3530000 cmp r3, #0 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 748: e24dd014 sub sp, sp, #20 + 74c: e59f909c ldr r9, [pc, #156] ; 7f0 + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + x = -xx; + 750: 12611000 rsbne r1, r1, #0 + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + 754: 13a03001 movne r3, #1 + } else { + x = xx; + } + + b = base; + i = 0; + 758: e3a0a000 mov sl, #0 + 75c: e24b6034 sub r6, fp, #52 ; 0x34 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 760: e3a08001 mov r8, #1 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 764: e3a07000 mov r7, #0 + int i; + + for(i=31;i>=0;i--){ + 768: e3a0001f mov r0, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 76c: e1a0c007 mov ip, r7 + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 770: e1a0e031 lsr lr, r1, r0 + 774: e20ee001 and lr, lr, #1 + 778: e18ec08c orr ip, lr, ip, lsl #1 + if(r >= d) { + 77c: e152000c cmp r2, ip + r = r - d; + q = q | (1 << i); + 780: 91877018 orrls r7, r7, r8, lsl r0 + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 784: 9062c00c rsbls ip, r2, ip +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 788: e2500001 subs r0, r0, #1 + 78c: 2afffff7 bcs 770 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 790: e0000792 mul r0, r2, r7 + }while((x = y) != 0); + 794: e3570000 cmp r7, #0 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 798: e0601001 rsb r1, r0, r1 + 79c: e28a5001 add r5, sl, #1 + 7a0: e7d91001 ldrb r1, [r9, r1] + 7a4: e7c6100a strb r1, [r6, sl] + }while((x = y) != 0); + 7a8: 11a01007 movne r1, r7 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 7ac: 11a0a005 movne sl, r5 + 7b0: 1affffeb bne 764 + }while((x = y) != 0); + if(neg) + 7b4: e3530000 cmp r3, #0 + buf[i++] = '-'; + 7b8: 124b2024 subne r2, fp, #36 ; 0x24 + 7bc: 10823005 addne r3, r2, r5 + 7c0: 128a5002 addne r5, sl, #2 + + while(--i >= 0) + 7c4: e2455001 sub r5, r5, #1 + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + 7c8: 13a0202d movne r2, #45 ; 0x2d + 7cc: 15432010 strbne r2, [r3, #-16] + + while(--i >= 0) + putc(fd, buf[i]); + 7d0: e7d61005 ldrb r1, [r6, r5] + 7d4: e1a00004 mov r0, r4 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 7d8: e2455001 sub r5, r5, #1 + putc(fd, buf[i]); + 7dc: ebffffc7 bl 700 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 7e0: e3750001 cmn r5, #1 + 7e4: 1afffff9 bne 7d0 + putc(fd, buf[i]); +} + 7e8: e24bd020 sub sp, fp, #32 + 7ec: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} + 7f0: 00000b38 .word 0x00000b38 + +000007f4
: + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 7f4: e3a03000 mov r3, #0 +{ + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + 7f8: e92d0830 push {r4, r5, fp} + 7fc: e1a02000 mov r2, r0 + 800: e28db008 add fp, sp, #8 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 804: e3a0c01f mov ip, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 808: e1a00003 mov r0, r3 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 80c: e3a05001 mov r5, #1 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 810: e1a04c32 lsr r4, r2, ip + 814: e2044001 and r4, r4, #1 + 818: e1843083 orr r3, r4, r3, lsl #1 + if(r >= d) { + 81c: e1530001 cmp r3, r1 + r = r - d; + q = q | (1 << i); + 820: 21800c15 orrcs r0, r0, r5, lsl ip + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 824: 20613003 rsbcs r3, r1, r3 +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 828: e25cc001 subs ip, ip, #1 + 82c: 2afffff7 bcs 810 + r = r - d; + q = q | (1 << i); + } + } + return q; +} + 830: e24bd008 sub sp, fp, #8 + 834: e8bd0830 pop {r4, r5, fp} + 838: e12fff1e bx lr + +0000083c : +} + +// Print to the given fd. Only understands %d, %x, %p, %s. +void +printf(int fd, char *fmt, ...) +{ + 83c: e92d000e push {r1, r2, r3} + 840: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 844: e28db020 add fp, sp, #32 + 848: e1a05000 mov r5, r0 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 84c: e59b4004 ldr r4, [fp, #4] + 850: e5d48000 ldrb r8, [r4] + 854: e3580000 cmp r8, #0 + 858: 0a000027 beq 8fc + ap++; + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + 85c: e59f712c ldr r7, [pc, #300] ; 990 + char *s; + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + 860: e28b6008 add r6, fp, #8 +{ + char *s; + int c, i, state; + uint *ap; + + state = 0; + 864: e3a0a000 mov sl, #0 + 868: ea000008 b 890 + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 86c: e3580025 cmp r8, #37 ; 0x25 + state = '%'; + 870: 01a0a008 moveq sl, r8 + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 874: 0a000002 beq 884 + state = '%'; + } else { + putc(fd, c); + 878: e1a00005 mov r0, r5 + 87c: e1a01008 mov r1, r8 + 880: ebffff9e bl 700 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 884: e5f48001 ldrb r8, [r4, #1]! + 888: e3580000 cmp r8, #0 + 88c: 0a00001a beq 8fc + c = fmt[i] & 0xff; + if(state == 0){ + 890: e35a0000 cmp sl, #0 + 894: 0afffff4 beq 86c + if(c == '%'){ + state = '%'; + } else { + putc(fd, c); + } + } else if(state == '%'){ + 898: e35a0025 cmp sl, #37 ; 0x25 + 89c: 1afffff8 bne 884 + if(c == 'd'){ + 8a0: e3580064 cmp r8, #100 ; 0x64 + 8a4: 0a00002c beq 95c + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + 8a8: e3580078 cmp r8, #120 ; 0x78 + 8ac: 13580070 cmpne r8, #112 ; 0x70 + 8b0: 13a09000 movne r9, #0 + 8b4: 03a09001 moveq r9, #1 + 8b8: 0a000013 beq 90c + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + 8bc: e3580073 cmp r8, #115 ; 0x73 + 8c0: 0a000018 beq 928 + s = "(null)"; + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + 8c4: e3580063 cmp r8, #99 ; 0x63 + 8c8: 0a00002a beq 978 + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 8cc: e3580025 cmp r8, #37 ; 0x25 + putc(fd, c); + 8d0: e1a0100a mov r1, sl + 8d4: e1a00005 mov r0, r5 + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 8d8: 0a000002 beq 8e8 + putc(fd, c); + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + 8dc: ebffff87 bl 700 + putc(fd, c); + 8e0: e1a00005 mov r0, r5 + 8e4: e1a01008 mov r1, r8 + 8e8: ebffff84 bl 700 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 8ec: e5f48001 ldrb r8, [r4, #1]! + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 8f0: e1a0a009 mov sl, r9 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 8f4: e3580000 cmp r8, #0 + 8f8: 1affffe4 bne 890 + putc(fd, c); + } + state = 0; + } + } +} + 8fc: e24bd020 sub sp, fp, #32 + 900: e8bd4ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 904: e28dd00c add sp, sp, #12 + 908: e12fff1e bx lr + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + 90c: e1a00005 mov r0, r5 + 910: e4961004 ldr r1, [r6], #4 + 914: e3a02010 mov r2, #16 + 918: e3a03000 mov r3, #0 + 91c: ebffff81 bl 728 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 920: e3a0a000 mov sl, #0 + 924: eaffffd6 b 884 + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + s = (char*)*ap; + 928: e4968004 ldr r8, [r6], #4 + ap++; + if(s == 0) + s = "(null)"; + 92c: e3580000 cmp r8, #0 + 930: 01a08007 moveq r8, r7 + while(*s != 0){ + 934: e5d81000 ldrb r1, [r8] + 938: e3510000 cmp r1, #0 + 93c: 0a000004 beq 954 + putc(fd, *s); + 940: e1a00005 mov r0, r5 + 944: ebffff6d bl 700 + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + while(*s != 0){ + 948: e5f81001 ldrb r1, [r8, #1]! + 94c: e3510000 cmp r1, #0 + 950: 1afffffa bne 940 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 954: e1a0a001 mov sl, r1 + 958: eaffffc9 b 884 + } else { + putc(fd, c); + } + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + 95c: e1a00005 mov r0, r5 + 960: e4961004 ldr r1, [r6], #4 + 964: e3a0200a mov r2, #10 + 968: e3a03001 mov r3, #1 + 96c: ebffff6d bl 728 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 970: e3a0a000 mov sl, #0 + 974: eaffffc2 b 884 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 978: e4961004 ldr r1, [r6], #4 + 97c: e1a00005 mov r0, r5 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 980: e1a0a009 mov sl, r9 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 984: e6ef1071 uxtb r1, r1 + 988: ebffff5c bl 700 + 98c: eaffffbc b 884 + 990: 00000b4c .word 0x00000b4c + +00000994 : +free(void *ap) +{ + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 994: e59f3098 ldr r3, [pc, #152] ; a34 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 998: e92d0830 push {r4, r5, fp} + Header *bp, *p; + + bp = (Header*)ap - 1; + 99c: e240c008 sub ip, r0, #8 + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 9a0: e5932000 ldr r2, [r3] +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 9a4: e28db008 add fp, sp, #8 + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 9a8: e152000c cmp r2, ip + 9ac: e5921000 ldr r1, [r2] + 9b0: 2a000001 bcs 9bc + 9b4: e15c0001 cmp ip, r1 + 9b8: 3a000007 bcc 9dc + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + 9bc: e1520001 cmp r2, r1 + 9c0: 3a000003 bcc 9d4 + 9c4: e152000c cmp r2, ip + 9c8: 3a000003 bcc 9dc + 9cc: e15c0001 cmp ip, r1 + 9d0: 3a000001 bcc 9dc +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 9d4: e1a02001 mov r2, r1 + 9d8: eafffff2 b 9a8 + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + 9dc: e5104004 ldr r4, [r0, #-4] + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + freep = p; + 9e0: e5832000 str r2, [r3] + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + 9e4: e08c5184 add r5, ip, r4, lsl #3 + 9e8: e1550001 cmp r5, r1 + bp->s.size += p->s.ptr->s.size; + 9ec: 05911004 ldreq r1, [r1, #4] + 9f0: 00814004 addeq r4, r1, r4 + 9f4: 05004004 streq r4, [r0, #-4] + bp->s.ptr = p->s.ptr->s.ptr; + 9f8: 05921000 ldreq r1, [r2] + 9fc: 05911000 ldreq r1, [r1] + } else + bp->s.ptr = p->s.ptr; + a00: e5001008 str r1, [r0, #-8] + if(p + p->s.size == bp){ + a04: e5921004 ldr r1, [r2, #4] + a08: e0824181 add r4, r2, r1, lsl #3 + a0c: e15c0004 cmp ip, r4 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + a10: 1582c000 strne ip, [r2] + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + } else + bp->s.ptr = p->s.ptr; + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + a14: 0510c004 ldreq ip, [r0, #-4] + a18: 008c1001 addeq r1, ip, r1 + a1c: 05821004 streq r1, [r2, #4] + p->s.ptr = bp->s.ptr; + a20: 05101008 ldreq r1, [r0, #-8] + a24: 05821000 streq r1, [r2] + } else + p->s.ptr = bp; + freep = p; +} + a28: e24bd008 sub sp, fp, #8 + a2c: e8bd0830 pop {r4, r5, fp} + a30: e12fff1e bx lr + a34: 00000b54 .word 0x00000b54 + +00000a38 : + return freep; +} + +void* +malloc(uint nbytes) +{ + a38: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + a3c: e2804007 add r4, r0, #7 + if((prevp = freep) == 0){ + a40: e59f50d4 ldr r5, [pc, #212] ; b1c +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + a44: e1a041a4 lsr r4, r4, #3 + return freep; +} + +void* +malloc(uint nbytes) +{ + a48: e28db01c add fp, sp, #28 + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + a4c: e5953000 ldr r3, [r5] +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + a50: e2844001 add r4, r4, #1 + if((prevp = freep) == 0){ + a54: e3530000 cmp r3, #0 + a58: 0a00002b beq b0c + a5c: e5930000 ldr r0, [r3] + a60: e5902004 ldr r2, [r0, #4] + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + a64: e1520004 cmp r2, r4 + a68: 2a00001b bcs adc +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + a6c: e59f80ac ldr r8, [pc, #172] ; b20 + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + a70: e1a07184 lsl r7, r4, #3 + a74: ea000003 b a88 + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + a78: e5930000 ldr r0, [r3] + if(p->s.size >= nunits){ + a7c: e5902004 ldr r2, [r0, #4] + a80: e1540002 cmp r4, r2 + a84: 9a000014 bls adc + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + a88: e5952000 ldr r2, [r5] + a8c: e1a03000 mov r3, r0 + a90: e1500002 cmp r0, r2 + a94: 1afffff7 bne a78 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + a98: e1540008 cmp r4, r8 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + a9c: 81a00007 movhi r0, r7 + aa0: 93a00902 movls r0, #32768 ; 0x8000 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + aa4: 81a06004 movhi r6, r4 + aa8: 93a06a01 movls r6, #4096 ; 0x1000 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + aac: ebfffeec bl 664 + ab0: e1a03000 mov r3, r0 + if(p == (char*)-1) + ab4: e3730001 cmn r3, #1 + return 0; + hp = (Header*)p; + hp->s.size = nu; + free((void*)(hp + 1)); + ab8: e2800008 add r0, r0, #8 + Header *hp; + + if(nu < 4096) + nu = 4096; + p = sbrk(nu * sizeof(Header)); + if(p == (char*)-1) + abc: 0a000010 beq b04 + return 0; + hp = (Header*)p; + hp->s.size = nu; + ac0: e5836004 str r6, [r3, #4] + free((void*)(hp + 1)); + ac4: ebffffb2 bl 994 + return freep; + ac8: e5953000 ldr r3, [r5] + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + if((p = morecore(nunits)) == 0) + acc: e3530000 cmp r3, #0 + ad0: 1affffe8 bne a78 + return 0; + ad4: e1a00003 mov r0, r3 + } +} + ad8: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + adc: e1540002 cmp r4, r2 + prevp->s.ptr = p->s.ptr; + else { + p->s.size -= nunits; + ae0: 10642002 rsbne r2, r4, r2 + ae4: 15802004 strne r2, [r0, #4] + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + ae8: 05902000 ldreq r2, [r0] + else { + p->s.size -= nunits; + p += p->s.size; + aec: 10800182 addne r0, r0, r2, lsl #3 + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + af0: 05832000 streq r2, [r3] + else { + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + af4: 15804004 strne r4, [r0, #4] + } + freep = prevp; + af8: e5853000 str r3, [r5] + return (void*)(p + 1); + afc: e2800008 add r0, r0, #8 + b00: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + } + if(p == freep) + if((p = morecore(nunits)) == 0) + return 0; + b04: e3a00000 mov r0, #0 + b08: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + b0c: e2850004 add r0, r5, #4 + b10: e5850000 str r0, [r5] + base.s.size = 0; + b14: e9850009 stmib r5, {r0, r3} + b18: eaffffd3 b a6c + b1c: 00000b54 .word 0x00000b54 + b20: 00000fff .word 0x00000fff diff -r 000000000000 -r c450faca55f4 uprogs/kill.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/kill.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,17 @@ +#include "types.h" +#include "stat.h" +#include "user.h" + +int +main(int argc, char **argv) +{ + int i; + + if(argc < 1){ + printf(2, "usage: kill pid...\n"); + exit(); + } + for(i=1; i: +#include "user.h" + +int +main(int argc, char *argv[]) +{ + if(argc != 3){ + 0: e3500003 cmp r0, #3 +#include "stat.h" +#include "user.h" + +int +main(int argc, char *argv[]) +{ + 4: e92d4818 push {r3, r4, fp, lr} + 8: e1a04001 mov r4, r1 + c: e28db00c add fp, sp, #12 + if(argc != 3){ + 10: 0a000003 beq 24 + printf(2, "Usage: ln old new\n"); + 14: e3a00002 mov r0, #2 + 18: e59f102c ldr r1, [pc, #44] ; 4c + 1c: eb000207 bl 840 + exit(); + 20: eb0000b3 bl 2f4 + } + if(link(argv[1], argv[2]) < 0) + 24: e9910003 ldmib r1, {r0, r1} + 28: eb00014d bl 564 + 2c: e3500000 cmp r0, #0 + 30: ba000000 blt 38 + printf(2, "link %s %s: failed\n", argv[1], argv[2]); + exit(); + 34: eb0000ae bl 2f4 + if(argc != 3){ + printf(2, "Usage: ln old new\n"); + exit(); + } + if(link(argv[1], argv[2]) < 0) + printf(2, "link %s %s: failed\n", argv[1], argv[2]); + 38: e3a00002 mov r0, #2 + 3c: e59f100c ldr r1, [pc, #12] ; 50 + 40: e994000c ldmib r4, {r2, r3} + 44: eb0001fd bl 840 + exit(); + 48: eb0000a9 bl 2f4 + 4c: 00000b28 .word 0x00000b28 + 50: 00000b3c .word 0x00000b3c + +00000054 : +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 54: e52db004 push {fp} ; (str fp, [sp, #-4]!) + char *os; + + os = s; + while((*s++ = *t++) != 0) + 58: e1a02000 mov r2, r0 +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 5c: e28db000 add fp, sp, #0 + char *os; + + os = s; + while((*s++ = *t++) != 0) + 60: e4d13001 ldrb r3, [r1], #1 + 64: e3530000 cmp r3, #0 + 68: e4c23001 strb r3, [r2], #1 + 6c: 1afffffb bne 60 + ; + return os; +} + 70: e28bd000 add sp, fp, #0 + 74: e8bd0800 pop {fp} + 78: e12fff1e bx lr + +0000007c : + +int +strcmp(const char *p, const char *q) +{ + 7c: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 80: e28db000 add fp, sp, #0 + while(*p && *p == *q) + 84: e5d03000 ldrb r3, [r0] + 88: e5d12000 ldrb r2, [r1] + 8c: e3530000 cmp r3, #0 + 90: 1a000004 bne a8 + 94: ea000005 b b0 + 98: e5f03001 ldrb r3, [r0, #1]! + 9c: e3530000 cmp r3, #0 + a0: 0a000006 beq c0 + a4: e5f12001 ldrb r2, [r1, #1]! + a8: e1530002 cmp r3, r2 + ac: 0afffff9 beq 98 + p++, q++; + return (uchar)*p - (uchar)*q; +} + b0: e0620003 rsb r0, r2, r3 + b4: e28bd000 add sp, fp, #0 + b8: e8bd0800 pop {fp} + bc: e12fff1e bx lr +} + +int +strcmp(const char *p, const char *q) +{ + while(*p && *p == *q) + c0: e5d12001 ldrb r2, [r1, #1] + c4: eafffff9 b b0 + +000000c8 : + return (uchar)*p - (uchar)*q; +} + +uint +strlen(char *s) +{ + c8: e52db004 push {fp} ; (str fp, [sp, #-4]!) + cc: e28db000 add fp, sp, #0 + int n; + + for(n = 0; s[n]; n++) + d0: e5d03000 ldrb r3, [r0] + d4: e3530000 cmp r3, #0 + d8: 01a00003 moveq r0, r3 + dc: 0a000006 beq fc + e0: e1a02000 mov r2, r0 + e4: e3a03000 mov r3, #0 + e8: e5f21001 ldrb r1, [r2, #1]! + ec: e2833001 add r3, r3, #1 + f0: e1a00003 mov r0, r3 + f4: e3510000 cmp r1, #0 + f8: 1afffffa bne e8 + ; + return n; +} + fc: e28bd000 add sp, fp, #0 + 100: e8bd0800 pop {fp} + 104: e12fff1e bx lr + +00000108 : +memset(void *dst, int c, uint n) +{ + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 108: e3520000 cmp r2, #0 + return n; +} + +void* +memset(void *dst, int c, uint n) +{ + 10c: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 110: e28db000 add fp, sp, #0 + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 114: 0a000006 beq 134 + 118: e6ef1071 uxtb r1, r1 + 11c: e1a03002 mov r3, r2 +} + +void* +memset(void *dst, int c, uint n) +{ + char *p=dst; + 120: e1a0c000 mov ip, r0 + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 124: e2533001 subs r3, r3, #1 + 128: e4cc1001 strb r1, [ip], #1 + 12c: 1afffffc bne 124 + 130: e0800002 add r0, r0, r2 + return (void *)p; +} + 134: e28bd000 add sp, fp, #0 + 138: e8bd0800 pop {fp} + 13c: e12fff1e bx lr + +00000140 : + +char* +strchr(const char *s, char c) +{ + 140: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 144: e28db000 add fp, sp, #0 + for(; *s; s++) + 148: e5d03000 ldrb r3, [r0] + 14c: e3530000 cmp r3, #0 + 150: 1a000004 bne 168 + 154: ea000008 b 17c + 158: e5d03001 ldrb r3, [r0, #1] + 15c: e2800001 add r0, r0, #1 + 160: e3530000 cmp r3, #0 + 164: 0a000004 beq 17c + if(*s == c) + 168: e1530001 cmp r3, r1 + 16c: 1afffff9 bne 158 + return (char*)s; + return 0; +} + 170: e28bd000 add sp, fp, #0 + 174: e8bd0800 pop {fp} + 178: e12fff1e bx lr +strchr(const char *s, char c) +{ + for(; *s; s++) + if(*s == c) + return (char*)s; + return 0; + 17c: e1a00003 mov r0, r3 + 180: eafffffa b 170 + +00000184 : +} + +char* +gets(char *buf, int max) +{ + 184: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + 188: e28db018 add fp, sp, #24 + 18c: e24dd00c sub sp, sp, #12 + 190: e1a08000 mov r8, r0 + 194: e1a07001 mov r7, r1 + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 198: e1a06000 mov r6, r0 + 19c: e3a05000 mov r5, #0 + 1a0: ea000008 b 1c8 + cc = read(0, &c, 1); + 1a4: eb000079 bl 390 + if(cc < 1) + 1a8: e3500000 cmp r0, #0 + 1ac: da00000b ble 1e0 + break; + buf[i++] = c; + 1b0: e55b301d ldrb r3, [fp, #-29] + if(c == '\n' || c == '\r') + 1b4: e1a05004 mov r5, r4 + 1b8: e353000a cmp r3, #10 + 1bc: 1353000d cmpne r3, #13 + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + if(cc < 1) + break; + buf[i++] = c; + 1c0: e4c63001 strb r3, [r6], #1 + if(c == '\n' || c == '\r') + 1c4: 0a00000a beq 1f4 +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + 1c8: e3a02001 mov r2, #1 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 1cc: e0854002 add r4, r5, r2 + 1d0: e1540007 cmp r4, r7 + cc = read(0, &c, 1); + 1d4: e3a00000 mov r0, #0 + 1d8: e24b101d sub r1, fp, #29 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 1dc: bafffff0 blt 1a4 + break; + buf[i++] = c; + if(c == '\n' || c == '\r') + break; + } + buf[i] = '\0'; + 1e0: e3a03000 mov r3, #0 + 1e4: e7c83005 strb r3, [r8, r5] + return buf; +} + 1e8: e1a00008 mov r0, r8 + 1ec: e24bd018 sub sp, fp, #24 + 1f0: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 1f4: e1a05004 mov r5, r4 + 1f8: eafffff8 b 1e0 + +000001fc : + return buf; +} + +int +stat(char *n, struct stat *st) +{ + 1fc: e92d4830 push {r4, r5, fp, lr} + 200: e1a05001 mov r5, r1 + 204: e28db00c add fp, sp, #12 + int fd; + int r; + + fd = open(n, O_RDONLY); + 208: e3a01000 mov r1, #0 + 20c: eb0000a0 bl 494 + if(fd < 0) + 210: e2504000 subs r4, r0, #0 + return -1; + 214: b3e05000 mvnlt r5, #0 +{ + int fd; + int r; + + fd = open(n, O_RDONLY); + if(fd < 0) + 218: ba000004 blt 230 + return -1; + r = fstat(fd, st); + 21c: e1a01005 mov r1, r5 + 220: eb0000c2 bl 530 + 224: e1a05000 mov r5, r0 + close(fd); + 228: e1a00004 mov r0, r4 + 22c: eb000071 bl 3f8 + return r; +} + 230: e1a00005 mov r0, r5 + 234: e8bd8830 pop {r4, r5, fp, pc} + +00000238 : + +int +atoi(const char *s) +{ + 238: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 23c: e28db000 add fp, sp, #0 + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 240: e5d03000 ldrb r3, [r0] + 244: e2432030 sub r2, r3, #48 ; 0x30 + 248: e6ef2072 uxtb r2, r2 + 24c: e3520009 cmp r2, #9 +int +atoi(const char *s) +{ + int n; + + n = 0; + 250: 83a00000 movhi r0, #0 + while('0' <= *s && *s <= '9') + 254: 8a000009 bhi 280 + 258: e1a02000 mov r2, r0 +int +atoi(const char *s) +{ + int n; + + n = 0; + 25c: e3a00000 mov r0, #0 + while('0' <= *s && *s <= '9') + n = n*10 + *s++ - '0'; + 260: e0800100 add r0, r0, r0, lsl #2 + 264: e0830080 add r0, r3, r0, lsl #1 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 268: e5f23001 ldrb r3, [r2, #1]! + n = n*10 + *s++ - '0'; + 26c: e2400030 sub r0, r0, #48 ; 0x30 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 270: e2431030 sub r1, r3, #48 ; 0x30 + 274: e6ef1071 uxtb r1, r1 + 278: e3510009 cmp r1, #9 + 27c: 9afffff7 bls 260 + n = n*10 + *s++ - '0'; + return n; +} + 280: e28bd000 add sp, fp, #0 + 284: e8bd0800 pop {fp} + 288: e12fff1e bx lr + +0000028c : +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 28c: e3520000 cmp r2, #0 + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) +{ + 290: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 294: e28db000 add fp, sp, #0 + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 298: da000005 ble 2b4 + n = n*10 + *s++ - '0'; + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) + 29c: e0802002 add r2, r0, r2 +{ + char *dst, *src; + + dst = vdst; + 2a0: e1a03000 mov r3, r0 + src = vsrc; + while(n-- > 0) + *dst++ = *src++; + 2a4: e4d1c001 ldrb ip, [r1], #1 + 2a8: e4c3c001 strb ip, [r3], #1 +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 2ac: e1530002 cmp r3, r2 + 2b0: 1afffffb bne 2a4 + *dst++ = *src++; + return vdst; +} + 2b4: e28bd000 add sp, fp, #0 + 2b8: e8bd0800 pop {fp} + 2bc: e12fff1e bx lr + +000002c0 : + 2c0: e92d4000 push {lr} + 2c4: e92d0008 push {r3} + 2c8: e92d0004 push {r2} + 2cc: e92d0002 push {r1} + 2d0: e92d0001 push {r0} + 2d4: e3a00001 mov r0, #1 + 2d8: ef000040 svc 0x00000040 + 2dc: e8bd0002 pop {r1} + 2e0: e8bd0002 pop {r1} + 2e4: e8bd0004 pop {r2} + 2e8: e8bd0008 pop {r3} + 2ec: e8bd4000 pop {lr} + 2f0: e12fff1e bx lr + +000002f4 : + 2f4: e92d4000 push {lr} + 2f8: e92d0008 push {r3} + 2fc: e92d0004 push {r2} + 300: e92d0002 push {r1} + 304: e92d0001 push {r0} + 308: e3a00002 mov r0, #2 + 30c: ef000040 svc 0x00000040 + 310: e8bd0002 pop {r1} + 314: e8bd0002 pop {r1} + 318: e8bd0004 pop {r2} + 31c: e8bd0008 pop {r3} + 320: e8bd4000 pop {lr} + 324: e12fff1e bx lr + +00000328 : + 328: e92d4000 push {lr} + 32c: e92d0008 push {r3} + 330: e92d0004 push {r2} + 334: e92d0002 push {r1} + 338: e92d0001 push {r0} + 33c: e3a00003 mov r0, #3 + 340: ef000040 svc 0x00000040 + 344: e8bd0002 pop {r1} + 348: e8bd0002 pop {r1} + 34c: e8bd0004 pop {r2} + 350: e8bd0008 pop {r3} + 354: e8bd4000 pop {lr} + 358: e12fff1e bx lr + +0000035c : + 35c: e92d4000 push {lr} + 360: e92d0008 push {r3} + 364: e92d0004 push {r2} + 368: e92d0002 push {r1} + 36c: e92d0001 push {r0} + 370: e3a00004 mov r0, #4 + 374: ef000040 svc 0x00000040 + 378: e8bd0002 pop {r1} + 37c: e8bd0002 pop {r1} + 380: e8bd0004 pop {r2} + 384: e8bd0008 pop {r3} + 388: e8bd4000 pop {lr} + 38c: e12fff1e bx lr + +00000390 : + 390: e92d4000 push {lr} + 394: e92d0008 push {r3} + 398: e92d0004 push {r2} + 39c: e92d0002 push {r1} + 3a0: e92d0001 push {r0} + 3a4: e3a00005 mov r0, #5 + 3a8: ef000040 svc 0x00000040 + 3ac: e8bd0002 pop {r1} + 3b0: e8bd0002 pop {r1} + 3b4: e8bd0004 pop {r2} + 3b8: e8bd0008 pop {r3} + 3bc: e8bd4000 pop {lr} + 3c0: e12fff1e bx lr + +000003c4 : + 3c4: e92d4000 push {lr} + 3c8: e92d0008 push {r3} + 3cc: e92d0004 push {r2} + 3d0: e92d0002 push {r1} + 3d4: e92d0001 push {r0} + 3d8: e3a00010 mov r0, #16 + 3dc: ef000040 svc 0x00000040 + 3e0: e8bd0002 pop {r1} + 3e4: e8bd0002 pop {r1} + 3e8: e8bd0004 pop {r2} + 3ec: e8bd0008 pop {r3} + 3f0: e8bd4000 pop {lr} + 3f4: e12fff1e bx lr + +000003f8 : + 3f8: e92d4000 push {lr} + 3fc: e92d0008 push {r3} + 400: e92d0004 push {r2} + 404: e92d0002 push {r1} + 408: e92d0001 push {r0} + 40c: e3a00015 mov r0, #21 + 410: ef000040 svc 0x00000040 + 414: e8bd0002 pop {r1} + 418: e8bd0002 pop {r1} + 41c: e8bd0004 pop {r2} + 420: e8bd0008 pop {r3} + 424: e8bd4000 pop {lr} + 428: e12fff1e bx lr + +0000042c : + 42c: e92d4000 push {lr} + 430: e92d0008 push {r3} + 434: e92d0004 push {r2} + 438: e92d0002 push {r1} + 43c: e92d0001 push {r0} + 440: e3a00006 mov r0, #6 + 444: ef000040 svc 0x00000040 + 448: e8bd0002 pop {r1} + 44c: e8bd0002 pop {r1} + 450: e8bd0004 pop {r2} + 454: e8bd0008 pop {r3} + 458: e8bd4000 pop {lr} + 45c: e12fff1e bx lr + +00000460 : + 460: e92d4000 push {lr} + 464: e92d0008 push {r3} + 468: e92d0004 push {r2} + 46c: e92d0002 push {r1} + 470: e92d0001 push {r0} + 474: e3a00007 mov r0, #7 + 478: ef000040 svc 0x00000040 + 47c: e8bd0002 pop {r1} + 480: e8bd0002 pop {r1} + 484: e8bd0004 pop {r2} + 488: e8bd0008 pop {r3} + 48c: e8bd4000 pop {lr} + 490: e12fff1e bx lr + +00000494 : + 494: e92d4000 push {lr} + 498: e92d0008 push {r3} + 49c: e92d0004 push {r2} + 4a0: e92d0002 push {r1} + 4a4: e92d0001 push {r0} + 4a8: e3a0000f mov r0, #15 + 4ac: ef000040 svc 0x00000040 + 4b0: e8bd0002 pop {r1} + 4b4: e8bd0002 pop {r1} + 4b8: e8bd0004 pop {r2} + 4bc: e8bd0008 pop {r3} + 4c0: e8bd4000 pop {lr} + 4c4: e12fff1e bx lr + +000004c8 : + 4c8: e92d4000 push {lr} + 4cc: e92d0008 push {r3} + 4d0: e92d0004 push {r2} + 4d4: e92d0002 push {r1} + 4d8: e92d0001 push {r0} + 4dc: e3a00011 mov r0, #17 + 4e0: ef000040 svc 0x00000040 + 4e4: e8bd0002 pop {r1} + 4e8: e8bd0002 pop {r1} + 4ec: e8bd0004 pop {r2} + 4f0: e8bd0008 pop {r3} + 4f4: e8bd4000 pop {lr} + 4f8: e12fff1e bx lr + +000004fc : + 4fc: e92d4000 push {lr} + 500: e92d0008 push {r3} + 504: e92d0004 push {r2} + 508: e92d0002 push {r1} + 50c: e92d0001 push {r0} + 510: e3a00012 mov r0, #18 + 514: ef000040 svc 0x00000040 + 518: e8bd0002 pop {r1} + 51c: e8bd0002 pop {r1} + 520: e8bd0004 pop {r2} + 524: e8bd0008 pop {r3} + 528: e8bd4000 pop {lr} + 52c: e12fff1e bx lr + +00000530 : + 530: e92d4000 push {lr} + 534: e92d0008 push {r3} + 538: e92d0004 push {r2} + 53c: e92d0002 push {r1} + 540: e92d0001 push {r0} + 544: e3a00008 mov r0, #8 + 548: ef000040 svc 0x00000040 + 54c: e8bd0002 pop {r1} + 550: e8bd0002 pop {r1} + 554: e8bd0004 pop {r2} + 558: e8bd0008 pop {r3} + 55c: e8bd4000 pop {lr} + 560: e12fff1e bx lr + +00000564 : + 564: e92d4000 push {lr} + 568: e92d0008 push {r3} + 56c: e92d0004 push {r2} + 570: e92d0002 push {r1} + 574: e92d0001 push {r0} + 578: e3a00013 mov r0, #19 + 57c: ef000040 svc 0x00000040 + 580: e8bd0002 pop {r1} + 584: e8bd0002 pop {r1} + 588: e8bd0004 pop {r2} + 58c: e8bd0008 pop {r3} + 590: e8bd4000 pop {lr} + 594: e12fff1e bx lr + +00000598 : + 598: e92d4000 push {lr} + 59c: e92d0008 push {r3} + 5a0: e92d0004 push {r2} + 5a4: e92d0002 push {r1} + 5a8: e92d0001 push {r0} + 5ac: e3a00014 mov r0, #20 + 5b0: ef000040 svc 0x00000040 + 5b4: e8bd0002 pop {r1} + 5b8: e8bd0002 pop {r1} + 5bc: e8bd0004 pop {r2} + 5c0: e8bd0008 pop {r3} + 5c4: e8bd4000 pop {lr} + 5c8: e12fff1e bx lr + +000005cc : + 5cc: e92d4000 push {lr} + 5d0: e92d0008 push {r3} + 5d4: e92d0004 push {r2} + 5d8: e92d0002 push {r1} + 5dc: e92d0001 push {r0} + 5e0: e3a00009 mov r0, #9 + 5e4: ef000040 svc 0x00000040 + 5e8: e8bd0002 pop {r1} + 5ec: e8bd0002 pop {r1} + 5f0: e8bd0004 pop {r2} + 5f4: e8bd0008 pop {r3} + 5f8: e8bd4000 pop {lr} + 5fc: e12fff1e bx lr + +00000600 : + 600: e92d4000 push {lr} + 604: e92d0008 push {r3} + 608: e92d0004 push {r2} + 60c: e92d0002 push {r1} + 610: e92d0001 push {r0} + 614: e3a0000a mov r0, #10 + 618: ef000040 svc 0x00000040 + 61c: e8bd0002 pop {r1} + 620: e8bd0002 pop {r1} + 624: e8bd0004 pop {r2} + 628: e8bd0008 pop {r3} + 62c: e8bd4000 pop {lr} + 630: e12fff1e bx lr + +00000634 : + 634: e92d4000 push {lr} + 638: e92d0008 push {r3} + 63c: e92d0004 push {r2} + 640: e92d0002 push {r1} + 644: e92d0001 push {r0} + 648: e3a0000b mov r0, #11 + 64c: ef000040 svc 0x00000040 + 650: e8bd0002 pop {r1} + 654: e8bd0002 pop {r1} + 658: e8bd0004 pop {r2} + 65c: e8bd0008 pop {r3} + 660: e8bd4000 pop {lr} + 664: e12fff1e bx lr + +00000668 : + 668: e92d4000 push {lr} + 66c: e92d0008 push {r3} + 670: e92d0004 push {r2} + 674: e92d0002 push {r1} + 678: e92d0001 push {r0} + 67c: e3a0000c mov r0, #12 + 680: ef000040 svc 0x00000040 + 684: e8bd0002 pop {r1} + 688: e8bd0002 pop {r1} + 68c: e8bd0004 pop {r2} + 690: e8bd0008 pop {r3} + 694: e8bd4000 pop {lr} + 698: e12fff1e bx lr + +0000069c : + 69c: e92d4000 push {lr} + 6a0: e92d0008 push {r3} + 6a4: e92d0004 push {r2} + 6a8: e92d0002 push {r1} + 6ac: e92d0001 push {r0} + 6b0: e3a0000d mov r0, #13 + 6b4: ef000040 svc 0x00000040 + 6b8: e8bd0002 pop {r1} + 6bc: e8bd0002 pop {r1} + 6c0: e8bd0004 pop {r2} + 6c4: e8bd0008 pop {r3} + 6c8: e8bd4000 pop {lr} + 6cc: e12fff1e bx lr + +000006d0 : + 6d0: e92d4000 push {lr} + 6d4: e92d0008 push {r3} + 6d8: e92d0004 push {r2} + 6dc: e92d0002 push {r1} + 6e0: e92d0001 push {r0} + 6e4: e3a0000e mov r0, #14 + 6e8: ef000040 svc 0x00000040 + 6ec: e8bd0002 pop {r1} + 6f0: e8bd0002 pop {r1} + 6f4: e8bd0004 pop {r2} + 6f8: e8bd0008 pop {r3} + 6fc: e8bd4000 pop {lr} + 700: e12fff1e bx lr + +00000704 : +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 704: e92d4800 push {fp, lr} + 708: e28db004 add fp, sp, #4 + 70c: e24b3004 sub r3, fp, #4 + 710: e24dd008 sub sp, sp, #8 + write(fd, &c, 1); + 714: e3a02001 mov r2, #1 +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 718: e5631001 strb r1, [r3, #-1]! + write(fd, &c, 1); + 71c: e1a01003 mov r1, r3 + 720: ebffff27 bl 3c4 +} + 724: e24bd004 sub sp, fp, #4 + 728: e8bd8800 pop {fp, pc} + +0000072c : + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 72c: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 730: e1a04000 mov r4, r0 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 734: e1a00fa1 lsr r0, r1, #31 + 738: e3530000 cmp r3, #0 + 73c: 03a03000 moveq r3, #0 + 740: 12003001 andne r3, r0, #1 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 744: e28db020 add fp, sp, #32 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 748: e3530000 cmp r3, #0 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 74c: e24dd014 sub sp, sp, #20 + 750: e59f909c ldr r9, [pc, #156] ; 7f4 + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + x = -xx; + 754: 12611000 rsbne r1, r1, #0 + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + 758: 13a03001 movne r3, #1 + } else { + x = xx; + } + + b = base; + i = 0; + 75c: e3a0a000 mov sl, #0 + 760: e24b6034 sub r6, fp, #52 ; 0x34 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 764: e3a08001 mov r8, #1 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 768: e3a07000 mov r7, #0 + int i; + + for(i=31;i>=0;i--){ + 76c: e3a0001f mov r0, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 770: e1a0c007 mov ip, r7 + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 774: e1a0e031 lsr lr, r1, r0 + 778: e20ee001 and lr, lr, #1 + 77c: e18ec08c orr ip, lr, ip, lsl #1 + if(r >= d) { + 780: e152000c cmp r2, ip + r = r - d; + q = q | (1 << i); + 784: 91877018 orrls r7, r7, r8, lsl r0 + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 788: 9062c00c rsbls ip, r2, ip +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 78c: e2500001 subs r0, r0, #1 + 790: 2afffff7 bcs 774 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 794: e0000792 mul r0, r2, r7 + }while((x = y) != 0); + 798: e3570000 cmp r7, #0 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 79c: e0601001 rsb r1, r0, r1 + 7a0: e28a5001 add r5, sl, #1 + 7a4: e7d91001 ldrb r1, [r9, r1] + 7a8: e7c6100a strb r1, [r6, sl] + }while((x = y) != 0); + 7ac: 11a01007 movne r1, r7 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 7b0: 11a0a005 movne sl, r5 + 7b4: 1affffeb bne 768 + }while((x = y) != 0); + if(neg) + 7b8: e3530000 cmp r3, #0 + buf[i++] = '-'; + 7bc: 124b2024 subne r2, fp, #36 ; 0x24 + 7c0: 10823005 addne r3, r2, r5 + 7c4: 128a5002 addne r5, sl, #2 + + while(--i >= 0) + 7c8: e2455001 sub r5, r5, #1 + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + 7cc: 13a0202d movne r2, #45 ; 0x2d + 7d0: 15432010 strbne r2, [r3, #-16] + + while(--i >= 0) + putc(fd, buf[i]); + 7d4: e7d61005 ldrb r1, [r6, r5] + 7d8: e1a00004 mov r0, r4 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 7dc: e2455001 sub r5, r5, #1 + putc(fd, buf[i]); + 7e0: ebffffc7 bl 704 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 7e4: e3750001 cmn r5, #1 + 7e8: 1afffff9 bne 7d4 + putc(fd, buf[i]); +} + 7ec: e24bd020 sub sp, fp, #32 + 7f0: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} + 7f4: 00000b50 .word 0x00000b50 + +000007f8
: + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 7f8: e3a03000 mov r3, #0 +{ + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + 7fc: e92d0830 push {r4, r5, fp} + 800: e1a02000 mov r2, r0 + 804: e28db008 add fp, sp, #8 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 808: e3a0c01f mov ip, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 80c: e1a00003 mov r0, r3 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 810: e3a05001 mov r5, #1 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 814: e1a04c32 lsr r4, r2, ip + 818: e2044001 and r4, r4, #1 + 81c: e1843083 orr r3, r4, r3, lsl #1 + if(r >= d) { + 820: e1530001 cmp r3, r1 + r = r - d; + q = q | (1 << i); + 824: 21800c15 orrcs r0, r0, r5, lsl ip + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 828: 20613003 rsbcs r3, r1, r3 +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 82c: e25cc001 subs ip, ip, #1 + 830: 2afffff7 bcs 814 + r = r - d; + q = q | (1 << i); + } + } + return q; +} + 834: e24bd008 sub sp, fp, #8 + 838: e8bd0830 pop {r4, r5, fp} + 83c: e12fff1e bx lr + +00000840 : +} + +// Print to the given fd. Only understands %d, %x, %p, %s. +void +printf(int fd, char *fmt, ...) +{ + 840: e92d000e push {r1, r2, r3} + 844: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 848: e28db020 add fp, sp, #32 + 84c: e1a05000 mov r5, r0 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 850: e59b4004 ldr r4, [fp, #4] + 854: e5d48000 ldrb r8, [r4] + 858: e3580000 cmp r8, #0 + 85c: 0a000027 beq 900 + ap++; + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + 860: e59f712c ldr r7, [pc, #300] ; 994 + char *s; + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + 864: e28b6008 add r6, fp, #8 +{ + char *s; + int c, i, state; + uint *ap; + + state = 0; + 868: e3a0a000 mov sl, #0 + 86c: ea000008 b 894 + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 870: e3580025 cmp r8, #37 ; 0x25 + state = '%'; + 874: 01a0a008 moveq sl, r8 + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 878: 0a000002 beq 888 + state = '%'; + } else { + putc(fd, c); + 87c: e1a00005 mov r0, r5 + 880: e1a01008 mov r1, r8 + 884: ebffff9e bl 704 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 888: e5f48001 ldrb r8, [r4, #1]! + 88c: e3580000 cmp r8, #0 + 890: 0a00001a beq 900 + c = fmt[i] & 0xff; + if(state == 0){ + 894: e35a0000 cmp sl, #0 + 898: 0afffff4 beq 870 + if(c == '%'){ + state = '%'; + } else { + putc(fd, c); + } + } else if(state == '%'){ + 89c: e35a0025 cmp sl, #37 ; 0x25 + 8a0: 1afffff8 bne 888 + if(c == 'd'){ + 8a4: e3580064 cmp r8, #100 ; 0x64 + 8a8: 0a00002c beq 960 + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + 8ac: e3580078 cmp r8, #120 ; 0x78 + 8b0: 13580070 cmpne r8, #112 ; 0x70 + 8b4: 13a09000 movne r9, #0 + 8b8: 03a09001 moveq r9, #1 + 8bc: 0a000013 beq 910 + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + 8c0: e3580073 cmp r8, #115 ; 0x73 + 8c4: 0a000018 beq 92c + s = "(null)"; + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + 8c8: e3580063 cmp r8, #99 ; 0x63 + 8cc: 0a00002a beq 97c + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 8d0: e3580025 cmp r8, #37 ; 0x25 + putc(fd, c); + 8d4: e1a0100a mov r1, sl + 8d8: e1a00005 mov r0, r5 + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 8dc: 0a000002 beq 8ec + putc(fd, c); + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + 8e0: ebffff87 bl 704 + putc(fd, c); + 8e4: e1a00005 mov r0, r5 + 8e8: e1a01008 mov r1, r8 + 8ec: ebffff84 bl 704 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 8f0: e5f48001 ldrb r8, [r4, #1]! + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 8f4: e1a0a009 mov sl, r9 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 8f8: e3580000 cmp r8, #0 + 8fc: 1affffe4 bne 894 + putc(fd, c); + } + state = 0; + } + } +} + 900: e24bd020 sub sp, fp, #32 + 904: e8bd4ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 908: e28dd00c add sp, sp, #12 + 90c: e12fff1e bx lr + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + 910: e1a00005 mov r0, r5 + 914: e4961004 ldr r1, [r6], #4 + 918: e3a02010 mov r2, #16 + 91c: e3a03000 mov r3, #0 + 920: ebffff81 bl 72c + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 924: e3a0a000 mov sl, #0 + 928: eaffffd6 b 888 + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + s = (char*)*ap; + 92c: e4968004 ldr r8, [r6], #4 + ap++; + if(s == 0) + s = "(null)"; + 930: e3580000 cmp r8, #0 + 934: 01a08007 moveq r8, r7 + while(*s != 0){ + 938: e5d81000 ldrb r1, [r8] + 93c: e3510000 cmp r1, #0 + 940: 0a000004 beq 958 + putc(fd, *s); + 944: e1a00005 mov r0, r5 + 948: ebffff6d bl 704 + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + while(*s != 0){ + 94c: e5f81001 ldrb r1, [r8, #1]! + 950: e3510000 cmp r1, #0 + 954: 1afffffa bne 944 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 958: e1a0a001 mov sl, r1 + 95c: eaffffc9 b 888 + } else { + putc(fd, c); + } + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + 960: e1a00005 mov r0, r5 + 964: e4961004 ldr r1, [r6], #4 + 968: e3a0200a mov r2, #10 + 96c: e3a03001 mov r3, #1 + 970: ebffff6d bl 72c + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 974: e3a0a000 mov sl, #0 + 978: eaffffc2 b 888 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 97c: e4961004 ldr r1, [r6], #4 + 980: e1a00005 mov r0, r5 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 984: e1a0a009 mov sl, r9 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 988: e6ef1071 uxtb r1, r1 + 98c: ebffff5c bl 704 + 990: eaffffbc b 888 + 994: 00000b64 .word 0x00000b64 + +00000998 : +free(void *ap) +{ + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 998: e59f3098 ldr r3, [pc, #152] ; a38 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 99c: e92d0830 push {r4, r5, fp} + Header *bp, *p; + + bp = (Header*)ap - 1; + 9a0: e240c008 sub ip, r0, #8 + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 9a4: e5932000 ldr r2, [r3] +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 9a8: e28db008 add fp, sp, #8 + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 9ac: e152000c cmp r2, ip + 9b0: e5921000 ldr r1, [r2] + 9b4: 2a000001 bcs 9c0 + 9b8: e15c0001 cmp ip, r1 + 9bc: 3a000007 bcc 9e0 + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + 9c0: e1520001 cmp r2, r1 + 9c4: 3a000003 bcc 9d8 + 9c8: e152000c cmp r2, ip + 9cc: 3a000003 bcc 9e0 + 9d0: e15c0001 cmp ip, r1 + 9d4: 3a000001 bcc 9e0 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 9d8: e1a02001 mov r2, r1 + 9dc: eafffff2 b 9ac + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + 9e0: e5104004 ldr r4, [r0, #-4] + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + freep = p; + 9e4: e5832000 str r2, [r3] + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + 9e8: e08c5184 add r5, ip, r4, lsl #3 + 9ec: e1550001 cmp r5, r1 + bp->s.size += p->s.ptr->s.size; + 9f0: 05911004 ldreq r1, [r1, #4] + 9f4: 00814004 addeq r4, r1, r4 + 9f8: 05004004 streq r4, [r0, #-4] + bp->s.ptr = p->s.ptr->s.ptr; + 9fc: 05921000 ldreq r1, [r2] + a00: 05911000 ldreq r1, [r1] + } else + bp->s.ptr = p->s.ptr; + a04: e5001008 str r1, [r0, #-8] + if(p + p->s.size == bp){ + a08: e5921004 ldr r1, [r2, #4] + a0c: e0824181 add r4, r2, r1, lsl #3 + a10: e15c0004 cmp ip, r4 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + a14: 1582c000 strne ip, [r2] + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + } else + bp->s.ptr = p->s.ptr; + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + a18: 0510c004 ldreq ip, [r0, #-4] + a1c: 008c1001 addeq r1, ip, r1 + a20: 05821004 streq r1, [r2, #4] + p->s.ptr = bp->s.ptr; + a24: 05101008 ldreq r1, [r0, #-8] + a28: 05821000 streq r1, [r2] + } else + p->s.ptr = bp; + freep = p; +} + a2c: e24bd008 sub sp, fp, #8 + a30: e8bd0830 pop {r4, r5, fp} + a34: e12fff1e bx lr + a38: 00000b6c .word 0x00000b6c + +00000a3c : + return freep; +} + +void* +malloc(uint nbytes) +{ + a3c: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + a40: e2804007 add r4, r0, #7 + if((prevp = freep) == 0){ + a44: e59f50d4 ldr r5, [pc, #212] ; b20 +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + a48: e1a041a4 lsr r4, r4, #3 + return freep; +} + +void* +malloc(uint nbytes) +{ + a4c: e28db01c add fp, sp, #28 + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + a50: e5953000 ldr r3, [r5] +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + a54: e2844001 add r4, r4, #1 + if((prevp = freep) == 0){ + a58: e3530000 cmp r3, #0 + a5c: 0a00002b beq b10 + a60: e5930000 ldr r0, [r3] + a64: e5902004 ldr r2, [r0, #4] + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + a68: e1520004 cmp r2, r4 + a6c: 2a00001b bcs ae0 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + a70: e59f80ac ldr r8, [pc, #172] ; b24 + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + a74: e1a07184 lsl r7, r4, #3 + a78: ea000003 b a8c + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + a7c: e5930000 ldr r0, [r3] + if(p->s.size >= nunits){ + a80: e5902004 ldr r2, [r0, #4] + a84: e1540002 cmp r4, r2 + a88: 9a000014 bls ae0 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + a8c: e5952000 ldr r2, [r5] + a90: e1a03000 mov r3, r0 + a94: e1500002 cmp r0, r2 + a98: 1afffff7 bne a7c +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + a9c: e1540008 cmp r4, r8 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + aa0: 81a00007 movhi r0, r7 + aa4: 93a00902 movls r0, #32768 ; 0x8000 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + aa8: 81a06004 movhi r6, r4 + aac: 93a06a01 movls r6, #4096 ; 0x1000 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + ab0: ebfffeec bl 668 + ab4: e1a03000 mov r3, r0 + if(p == (char*)-1) + ab8: e3730001 cmn r3, #1 + return 0; + hp = (Header*)p; + hp->s.size = nu; + free((void*)(hp + 1)); + abc: e2800008 add r0, r0, #8 + Header *hp; + + if(nu < 4096) + nu = 4096; + p = sbrk(nu * sizeof(Header)); + if(p == (char*)-1) + ac0: 0a000010 beq b08 + return 0; + hp = (Header*)p; + hp->s.size = nu; + ac4: e5836004 str r6, [r3, #4] + free((void*)(hp + 1)); + ac8: ebffffb2 bl 998 + return freep; + acc: e5953000 ldr r3, [r5] + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + if((p = morecore(nunits)) == 0) + ad0: e3530000 cmp r3, #0 + ad4: 1affffe8 bne a7c + return 0; + ad8: e1a00003 mov r0, r3 + } +} + adc: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + ae0: e1540002 cmp r4, r2 + prevp->s.ptr = p->s.ptr; + else { + p->s.size -= nunits; + ae4: 10642002 rsbne r2, r4, r2 + ae8: 15802004 strne r2, [r0, #4] + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + aec: 05902000 ldreq r2, [r0] + else { + p->s.size -= nunits; + p += p->s.size; + af0: 10800182 addne r0, r0, r2, lsl #3 + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + af4: 05832000 streq r2, [r3] + else { + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + af8: 15804004 strne r4, [r0, #4] + } + freep = prevp; + afc: e5853000 str r3, [r5] + return (void*)(p + 1); + b00: e2800008 add r0, r0, #8 + b04: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + } + if(p == freep) + if((p = morecore(nunits)) == 0) + return 0; + b08: e3a00000 mov r0, #0 + b0c: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + b10: e2850004 add r0, r5, #4 + b14: e5850000 str r0, [r5] + base.s.size = 0; + b18: e9850009 stmib r5, {r0, r3} + b1c: eaffffd3 b a70 + b20: 00000b6c .word 0x00000b6c + b24: 00000fff .word 0x00000fff diff -r 000000000000 -r c450faca55f4 uprogs/ln.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/ln.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,15 @@ +#include "types.h" +#include "stat.h" +#include "user.h" + +int +main(int argc, char *argv[]) +{ + if(argc != 3){ + printf(2, "Usage: ln old new\n"); + exit(); + } + if(link(argv[1], argv[2]) < 0) + printf(2, "link %s %s: failed\n", argv[1], argv[2]); + exit(); +} diff -r 000000000000 -r c450faca55f4 uprogs/ln.sym --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/ln.sym Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,64 @@ +00000000 .text +00000b28 .rodata +00000b6c .bss +00000000 .comment +00000000 .ARM.attributes +00000000 .debug_aranges +00000000 .debug_info +00000000 .debug_abbrev +00000000 .debug_line +00000000 .debug_frame +00000000 .debug_str +00000000 .debug_loc +00000000 .debug_ranges +00000000 ln.c +00000000 ulib.c +00000000 printf.c +00000704 putc +0000072c printint +00000b50 digits.993 +00000000 umalloc.c +00000b6c freep +00000b70 base +00000054 strcpy +00000840 printf +0000028c memmove +000004c8 mknod +00000b78 _bss_end__ +00000184 gets +00000634 getpid +00000a3c malloc +0000069c sleep +00000b6c __bss_start__ +0000035c pipe +000003c4 write +00000530 fstat +0000042c kill +000005cc chdir +00000460 exec +00000b78 __bss_end__ +00000328 wait +00000390 read +000004fc unlink +000002c0 fork +00000668 sbrk +000006d0 uptime +00000b6c __bss_start +00000108 memset +00000000 main +00000b78 __end__ +0000007c strcmp +00000600 dup +000001fc stat +00000b6c _edata +00000b78 _end +00000564 link +000002f4 exit +00000238 atoi +000000c8 strlen +00000494 open +000007f8 div +00000140 strchr +00000598 mkdir +000003f8 close +00000998 free diff -r 000000000000 -r c450faca55f4 uprogs/ls.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/ls.asm Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,1997 @@ + +_ls: file format elf32-littlearm + + +Disassembly of section .text: + +00000000
: +int +main(int argc, char *argv[]) +{ + int i; + + if(argc < 2){ + 0: e3500001 cmp r0, #1 + close(fd); +} + +int +main(int argc, char *argv[]) +{ + 4: e92d4878 push {r3, r4, r5, r6, fp, lr} + 8: e1a04000 mov r4, r0 + c: e28db014 add fp, sp, #20 + int i; + + if(argc < 2){ + ls("."); + exit(); + 10: c1a06001 movgt r6, r1 +int +main(int argc, char *argv[]) +{ + int i; + + if(argc < 2){ + 14: c3a05001 movgt r5, #1 + 18: da000005 ble 34 + ls("."); + exit(); + } + for(i=1; i + + if(argc < 2){ + ls("."); + exit(); + } + for(i=1; i + ls(argv[i]); + exit(); + 30: eb00013e bl 530 +main(int argc, char *argv[]) +{ + int i; + + if(argc < 2){ + ls("."); + 34: e59f0004 ldr r0, [pc, #4] ; 40 + 38: eb00002b bl ec + exit(); + 3c: eb00013b bl 530 + 40: 00000db0 .word 0x00000db0 + +00000044 : +#include "user.h" +#include "fs.h" + +char* +fmtname(char *path) +{ + 44: e92d4878 push {r3, r4, r5, r6, fp, lr} + 48: e28db014 add fp, sp, #20 + 4c: e1a05000 mov r5, r0 + static char buf[DIRSIZ+1]; + char *p; + + // Find first character after last slash. + for(p=path+strlen(path); p >= path && *p != '/'; p--) + 50: eb0000ab bl 304 + 54: e0954000 adds r4, r5, r0 + 58: 2a00000a bcs 88 + 5c: e7d53000 ldrb r3, [r5, r0] + 60: e353002f cmp r3, #47 ; 0x2f + 64: 0a000007 beq 88 + 68: e1a03004 mov r3, r4 + 6c: ea000002 b 7c + 70: e5732001 ldrb r2, [r3, #-1]! + 74: e352002f cmp r2, #47 ; 0x2f + 78: 0a000002 beq 88 + 7c: e2444001 sub r4, r4, #1 + 80: e1550004 cmp r5, r4 + 84: 9afffff9 bls 70 + ; + p++; + 88: e2844001 add r4, r4, #1 + + // Return blank-padded name. + if(strlen(p) >= DIRSIZ) + 8c: e1a00004 mov r0, r4 + 90: eb00009b bl 304 + 94: e350000d cmp r0, #13 + 98: 8a000010 bhi e0 + return p; + memmove(buf, p, strlen(p)); + 9c: e1a00004 mov r0, r4 + a0: eb000097 bl 304 + a4: e59f503c ldr r5, [pc, #60] ; e8 + a8: e1a01004 mov r1, r4 + ac: e1a02000 mov r2, r0 + b0: e1a00005 mov r0, r5 + b4: eb000103 bl 4c8 + memset(buf+strlen(p), ' ', DIRSIZ-strlen(p)); + b8: e1a00004 mov r0, r4 + bc: eb000090 bl 304 + c0: e1a06000 mov r6, r0 + c4: e1a00004 mov r0, r4 + c8: eb00008d bl 304 + cc: e3a01020 mov r1, #32 + return buf; + d0: e1a04005 mov r4, r5 + + // Return blank-padded name. + if(strlen(p) >= DIRSIZ) + return p; + memmove(buf, p, strlen(p)); + memset(buf+strlen(p), ' ', DIRSIZ-strlen(p)); + d4: e260200e rsb r2, r0, #14 + d8: e0850006 add r0, r5, r6 + dc: eb000098 bl 344 + return buf; +} + e0: e1a00004 mov r0, r4 + e4: e8bd8878 pop {r3, r4, r5, r6, fp, pc} + e8: 00000dd0 .word 0x00000dd0 + +000000ec : + +void +ls(char *path) +{ + ec: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + f0: e28db018 add fp, sp, #24 + f4: e24ddf8d sub sp, sp, #564 ; 0x234 + char buf[512], *p; + int fd; + struct dirent de; + struct stat st; + + if((fd = open(path, 0)) < 0){ + f8: e3a01000 mov r1, #0 + return buf; +} + +void +ls(char *path) +{ + fc: e1a06000 mov r6, r0 + char buf[512], *p; + int fd; + struct dirent de; + struct stat st; + + if((fd = open(path, 0)) < 0){ + 100: eb000172 bl 6d0 + 104: e2504000 subs r4, r0, #0 + 108: ba00004b blt 23c + printf(2, "ls: cannot open %s\n", path); + return; + } + + if(fstat(fd, &st) < 0){ + 10c: e24b1040 sub r1, fp, #64 ; 0x40 + 110: eb000195 bl 76c + 114: e3500000 cmp r0, #0 + 118: ba000051 blt 264 + printf(2, "ls: cannot stat %s\n", path); + close(fd); + return; + } + + switch(st.type){ + 11c: e15b54f0 ldrsh r5, [fp, #-64] ; 0xffffffc0 + 120: e3550001 cmp r5, #1 + 124: 0a000011 beq 170 + 128: e3550002 cmp r5, #2 + 12c: 0a000003 beq 140 + } + printf(1, "%s %d %d %d\n", fmtname(buf), st.type, st.ino, st.size); + } + break; + } + close(fd); + 130: e1a00004 mov r0, r4 + 134: eb00013e bl 634 +} + 138: e24bd018 sub sp, fp, #24 + 13c: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} + return; + } + + switch(st.type){ + case T_FILE: + printf(1, "%s %d %d %d\n", fmtname(path), st.type, st.ino, st.size); + 140: e1a00006 mov r0, r6 + 144: ebffffbe bl 44 + 148: e51bc038 ldr ip, [fp, #-56] ; 0x38 + 14c: e15b34f0 ldrsh r3, [fp, #-64] ; 0xffffffc0 + 150: e58dc000 str ip, [sp] + 154: e51bc030 ldr ip, [fp, #-48] ; 0x30 + 158: e59f1120 ldr r1, [pc, #288] ; 280 + 15c: e58dc004 str ip, [sp, #4] + 160: e1a02000 mov r2, r0 + 164: e3a00001 mov r0, #1 + 168: eb000243 bl a7c + break; + 16c: eaffffef b 130 + + case T_DIR: + if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){ + 170: e1a00006 mov r0, r6 + 174: eb000062 bl 304 + 178: e2800010 add r0, r0, #16 + 17c: e3500c02 cmp r0, #512 ; 0x200 + 180: 8a000029 bhi 22c + printf(1, "ls: path too long\n"); + break; + } + strcpy(buf, path); + 184: e24b5d09 sub r5, fp, #576 ; 0x240 + 188: e1a01006 mov r1, r6 + 18c: e1a00005 mov r0, r5 + 190: eb00003e bl 290 + p = buf+strlen(buf); + 194: e1a00005 mov r0, r5 + 198: eb000059 bl 304 + *p++ = '/'; + while(read(fd, &de, sizeof(de)) == sizeof(de)){ + if(de.inum == 0) + continue; + memmove(p, de.name, DIRSIZ); + p[DIRSIZ] = 0; + 19c: e3a08000 mov r8, #0 + printf(1, "ls: path too long\n"); + break; + } + strcpy(buf, path); + p = buf+strlen(buf); + *p++ = '/'; + 1a0: e3a0302f mov r3, #47 ; 0x2f + if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){ + printf(1, "ls: path too long\n"); + break; + } + strcpy(buf, path); + p = buf+strlen(buf); + 1a4: e0856000 add r6, r5, r0 + *p++ = '/'; + 1a8: e2867001 add r7, r6, #1 + 1ac: e7c53000 strb r3, [r5, r0] + while(read(fd, &de, sizeof(de)) == sizeof(de)){ + 1b0: e24b102c sub r1, fp, #44 ; 0x2c + 1b4: e1a00004 mov r0, r4 + 1b8: e3a02010 mov r2, #16 + 1bc: eb000102 bl 5cc + 1c0: e3500010 cmp r0, #16 + 1c4: 1affffd9 bne 130 + if(de.inum == 0) + 1c8: e15b32bc ldrh r3, [fp, #-44] ; 0xffffffd4 + 1cc: e3530000 cmp r3, #0 + 1d0: 0afffff6 beq 1b0 + continue; + memmove(p, de.name, DIRSIZ); + 1d4: e3a0200e mov r2, #14 + 1d8: e24b102a sub r1, fp, #42 ; 0x2a + 1dc: e1a00007 mov r0, r7 + 1e0: eb0000b8 bl 4c8 + p[DIRSIZ] = 0; + if(stat(buf, &st) < 0){ + 1e4: e24b1040 sub r1, fp, #64 ; 0x40 + 1e8: e1a00005 mov r0, r5 + *p++ = '/'; + while(read(fd, &de, sizeof(de)) == sizeof(de)){ + if(de.inum == 0) + continue; + memmove(p, de.name, DIRSIZ); + p[DIRSIZ] = 0; + 1ec: e5c6800f strb r8, [r6, #15] + if(stat(buf, &st) < 0){ + 1f0: eb000090 bl 438 + 1f4: e3500000 cmp r0, #0 + printf(1, "ls: cannot stat %s\n", buf); + continue; + } + printf(1, "%s %d %d %d\n", fmtname(buf), st.type, st.ino, st.size); + 1f8: e1a00005 mov r0, r5 + while(read(fd, &de, sizeof(de)) == sizeof(de)){ + if(de.inum == 0) + continue; + memmove(p, de.name, DIRSIZ); + p[DIRSIZ] = 0; + if(stat(buf, &st) < 0){ + 1fc: ba000013 blt 250 + printf(1, "ls: cannot stat %s\n", buf); + continue; + } + printf(1, "%s %d %d %d\n", fmtname(buf), st.type, st.ino, st.size); + 200: ebffff8f bl 44 + 204: e51bc038 ldr ip, [fp, #-56] ; 0x38 + 208: e15b34f0 ldrsh r3, [fp, #-64] ; 0xffffffc0 + 20c: e58dc000 str ip, [sp] + 210: e51bc030 ldr ip, [fp, #-48] ; 0x30 + 214: e59f1064 ldr r1, [pc, #100] ; 280 + 218: e58dc004 str ip, [sp, #4] + 21c: e1a02000 mov r2, r0 + 220: e3a00001 mov r0, #1 + 224: eb000214 bl a7c + 228: eaffffe0 b 1b0 + printf(1, "%s %d %d %d\n", fmtname(path), st.type, st.ino, st.size); + break; + + case T_DIR: + if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){ + printf(1, "ls: path too long\n"); + 22c: e1a00005 mov r0, r5 + 230: e59f104c ldr r1, [pc, #76] ; 284 + 234: eb000210 bl a7c + break; + 238: eaffffbc b 130 + int fd; + struct dirent de; + struct stat st; + + if((fd = open(path, 0)) < 0){ + printf(2, "ls: cannot open %s\n", path); + 23c: e3a00002 mov r0, #2 + 240: e59f1040 ldr r1, [pc, #64] ; 288 + 244: e1a02006 mov r2, r6 + 248: eb00020b bl a7c + return; + 24c: eaffffb9 b 138 + if(de.inum == 0) + continue; + memmove(p, de.name, DIRSIZ); + p[DIRSIZ] = 0; + if(stat(buf, &st) < 0){ + printf(1, "ls: cannot stat %s\n", buf); + 250: e3a00001 mov r0, #1 + 254: e59f1030 ldr r1, [pc, #48] ; 28c + 258: e1a02005 mov r2, r5 + 25c: eb000206 bl a7c + continue; + 260: eaffffd2 b 1b0 + printf(2, "ls: cannot open %s\n", path); + return; + } + + if(fstat(fd, &st) < 0){ + printf(2, "ls: cannot stat %s\n", path); + 264: e59f1020 ldr r1, [pc, #32] ; 28c + 268: e1a02006 mov r2, r6 + 26c: e3a00002 mov r0, #2 + 270: eb000201 bl a7c + close(fd); + 274: e1a00004 mov r0, r4 + 278: eb0000ed bl 634 + return; + 27c: eaffffad b 138 + 280: 00000d8c .word 0x00000d8c + 284: 00000d9c .word 0x00000d9c + 288: 00000d64 .word 0x00000d64 + 28c: 00000d78 .word 0x00000d78 + +00000290 : +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 290: e52db004 push {fp} ; (str fp, [sp, #-4]!) + char *os; + + os = s; + while((*s++ = *t++) != 0) + 294: e1a02000 mov r2, r0 +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 298: e28db000 add fp, sp, #0 + char *os; + + os = s; + while((*s++ = *t++) != 0) + 29c: e4d13001 ldrb r3, [r1], #1 + 2a0: e3530000 cmp r3, #0 + 2a4: e4c23001 strb r3, [r2], #1 + 2a8: 1afffffb bne 29c + ; + return os; +} + 2ac: e28bd000 add sp, fp, #0 + 2b0: e8bd0800 pop {fp} + 2b4: e12fff1e bx lr + +000002b8 : + +int +strcmp(const char *p, const char *q) +{ + 2b8: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 2bc: e28db000 add fp, sp, #0 + while(*p && *p == *q) + 2c0: e5d03000 ldrb r3, [r0] + 2c4: e5d12000 ldrb r2, [r1] + 2c8: e3530000 cmp r3, #0 + 2cc: 1a000004 bne 2e4 + 2d0: ea000005 b 2ec + 2d4: e5f03001 ldrb r3, [r0, #1]! + 2d8: e3530000 cmp r3, #0 + 2dc: 0a000006 beq 2fc + 2e0: e5f12001 ldrb r2, [r1, #1]! + 2e4: e1530002 cmp r3, r2 + 2e8: 0afffff9 beq 2d4 + p++, q++; + return (uchar)*p - (uchar)*q; +} + 2ec: e0620003 rsb r0, r2, r3 + 2f0: e28bd000 add sp, fp, #0 + 2f4: e8bd0800 pop {fp} + 2f8: e12fff1e bx lr +} + +int +strcmp(const char *p, const char *q) +{ + while(*p && *p == *q) + 2fc: e5d12001 ldrb r2, [r1, #1] + 300: eafffff9 b 2ec + +00000304 : + return (uchar)*p - (uchar)*q; +} + +uint +strlen(char *s) +{ + 304: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 308: e28db000 add fp, sp, #0 + int n; + + for(n = 0; s[n]; n++) + 30c: e5d03000 ldrb r3, [r0] + 310: e3530000 cmp r3, #0 + 314: 01a00003 moveq r0, r3 + 318: 0a000006 beq 338 + 31c: e1a02000 mov r2, r0 + 320: e3a03000 mov r3, #0 + 324: e5f21001 ldrb r1, [r2, #1]! + 328: e2833001 add r3, r3, #1 + 32c: e1a00003 mov r0, r3 + 330: e3510000 cmp r1, #0 + 334: 1afffffa bne 324 + ; + return n; +} + 338: e28bd000 add sp, fp, #0 + 33c: e8bd0800 pop {fp} + 340: e12fff1e bx lr + +00000344 : +memset(void *dst, int c, uint n) +{ + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 344: e3520000 cmp r2, #0 + return n; +} + +void* +memset(void *dst, int c, uint n) +{ + 348: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 34c: e28db000 add fp, sp, #0 + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 350: 0a000006 beq 370 + 354: e6ef1071 uxtb r1, r1 + 358: e1a03002 mov r3, r2 +} + +void* +memset(void *dst, int c, uint n) +{ + char *p=dst; + 35c: e1a0c000 mov ip, r0 + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 360: e2533001 subs r3, r3, #1 + 364: e4cc1001 strb r1, [ip], #1 + 368: 1afffffc bne 360 + 36c: e0800002 add r0, r0, r2 + return (void *)p; +} + 370: e28bd000 add sp, fp, #0 + 374: e8bd0800 pop {fp} + 378: e12fff1e bx lr + +0000037c : + +char* +strchr(const char *s, char c) +{ + 37c: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 380: e28db000 add fp, sp, #0 + for(; *s; s++) + 384: e5d03000 ldrb r3, [r0] + 388: e3530000 cmp r3, #0 + 38c: 1a000004 bne 3a4 + 390: ea000008 b 3b8 + 394: e5d03001 ldrb r3, [r0, #1] + 398: e2800001 add r0, r0, #1 + 39c: e3530000 cmp r3, #0 + 3a0: 0a000004 beq 3b8 + if(*s == c) + 3a4: e1530001 cmp r3, r1 + 3a8: 1afffff9 bne 394 + return (char*)s; + return 0; +} + 3ac: e28bd000 add sp, fp, #0 + 3b0: e8bd0800 pop {fp} + 3b4: e12fff1e bx lr +strchr(const char *s, char c) +{ + for(; *s; s++) + if(*s == c) + return (char*)s; + return 0; + 3b8: e1a00003 mov r0, r3 + 3bc: eafffffa b 3ac + +000003c0 : +} + +char* +gets(char *buf, int max) +{ + 3c0: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + 3c4: e28db018 add fp, sp, #24 + 3c8: e24dd00c sub sp, sp, #12 + 3cc: e1a08000 mov r8, r0 + 3d0: e1a07001 mov r7, r1 + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 3d4: e1a06000 mov r6, r0 + 3d8: e3a05000 mov r5, #0 + 3dc: ea000008 b 404 + cc = read(0, &c, 1); + 3e0: eb000079 bl 5cc + if(cc < 1) + 3e4: e3500000 cmp r0, #0 + 3e8: da00000b ble 41c + break; + buf[i++] = c; + 3ec: e55b301d ldrb r3, [fp, #-29] + if(c == '\n' || c == '\r') + 3f0: e1a05004 mov r5, r4 + 3f4: e353000a cmp r3, #10 + 3f8: 1353000d cmpne r3, #13 + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + if(cc < 1) + break; + buf[i++] = c; + 3fc: e4c63001 strb r3, [r6], #1 + if(c == '\n' || c == '\r') + 400: 0a00000a beq 430 +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + 404: e3a02001 mov r2, #1 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 408: e0854002 add r4, r5, r2 + 40c: e1540007 cmp r4, r7 + cc = read(0, &c, 1); + 410: e3a00000 mov r0, #0 + 414: e24b101d sub r1, fp, #29 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 418: bafffff0 blt 3e0 + break; + buf[i++] = c; + if(c == '\n' || c == '\r') + break; + } + buf[i] = '\0'; + 41c: e3a03000 mov r3, #0 + 420: e7c83005 strb r3, [r8, r5] + return buf; +} + 424: e1a00008 mov r0, r8 + 428: e24bd018 sub sp, fp, #24 + 42c: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 430: e1a05004 mov r5, r4 + 434: eafffff8 b 41c + +00000438 : + return buf; +} + +int +stat(char *n, struct stat *st) +{ + 438: e92d4830 push {r4, r5, fp, lr} + 43c: e1a05001 mov r5, r1 + 440: e28db00c add fp, sp, #12 + int fd; + int r; + + fd = open(n, O_RDONLY); + 444: e3a01000 mov r1, #0 + 448: eb0000a0 bl 6d0 + if(fd < 0) + 44c: e2504000 subs r4, r0, #0 + return -1; + 450: b3e05000 mvnlt r5, #0 +{ + int fd; + int r; + + fd = open(n, O_RDONLY); + if(fd < 0) + 454: ba000004 blt 46c + return -1; + r = fstat(fd, st); + 458: e1a01005 mov r1, r5 + 45c: eb0000c2 bl 76c + 460: e1a05000 mov r5, r0 + close(fd); + 464: e1a00004 mov r0, r4 + 468: eb000071 bl 634 + return r; +} + 46c: e1a00005 mov r0, r5 + 470: e8bd8830 pop {r4, r5, fp, pc} + +00000474 : + +int +atoi(const char *s) +{ + 474: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 478: e28db000 add fp, sp, #0 + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 47c: e5d03000 ldrb r3, [r0] + 480: e2432030 sub r2, r3, #48 ; 0x30 + 484: e6ef2072 uxtb r2, r2 + 488: e3520009 cmp r2, #9 +int +atoi(const char *s) +{ + int n; + + n = 0; + 48c: 83a00000 movhi r0, #0 + while('0' <= *s && *s <= '9') + 490: 8a000009 bhi 4bc + 494: e1a02000 mov r2, r0 +int +atoi(const char *s) +{ + int n; + + n = 0; + 498: e3a00000 mov r0, #0 + while('0' <= *s && *s <= '9') + n = n*10 + *s++ - '0'; + 49c: e0800100 add r0, r0, r0, lsl #2 + 4a0: e0830080 add r0, r3, r0, lsl #1 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 4a4: e5f23001 ldrb r3, [r2, #1]! + n = n*10 + *s++ - '0'; + 4a8: e2400030 sub r0, r0, #48 ; 0x30 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 4ac: e2431030 sub r1, r3, #48 ; 0x30 + 4b0: e6ef1071 uxtb r1, r1 + 4b4: e3510009 cmp r1, #9 + 4b8: 9afffff7 bls 49c + n = n*10 + *s++ - '0'; + return n; +} + 4bc: e28bd000 add sp, fp, #0 + 4c0: e8bd0800 pop {fp} + 4c4: e12fff1e bx lr + +000004c8 : +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 4c8: e3520000 cmp r2, #0 + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) +{ + 4cc: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 4d0: e28db000 add fp, sp, #0 + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 4d4: da000005 ble 4f0 + n = n*10 + *s++ - '0'; + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) + 4d8: e0802002 add r2, r0, r2 +{ + char *dst, *src; + + dst = vdst; + 4dc: e1a03000 mov r3, r0 + src = vsrc; + while(n-- > 0) + *dst++ = *src++; + 4e0: e4d1c001 ldrb ip, [r1], #1 + 4e4: e4c3c001 strb ip, [r3], #1 +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 4e8: e1530002 cmp r3, r2 + 4ec: 1afffffb bne 4e0 + *dst++ = *src++; + return vdst; +} + 4f0: e28bd000 add sp, fp, #0 + 4f4: e8bd0800 pop {fp} + 4f8: e12fff1e bx lr + +000004fc : + 4fc: e92d4000 push {lr} + 500: e92d0008 push {r3} + 504: e92d0004 push {r2} + 508: e92d0002 push {r1} + 50c: e92d0001 push {r0} + 510: e3a00001 mov r0, #1 + 514: ef000040 svc 0x00000040 + 518: e8bd0002 pop {r1} + 51c: e8bd0002 pop {r1} + 520: e8bd0004 pop {r2} + 524: e8bd0008 pop {r3} + 528: e8bd4000 pop {lr} + 52c: e12fff1e bx lr + +00000530 : + 530: e92d4000 push {lr} + 534: e92d0008 push {r3} + 538: e92d0004 push {r2} + 53c: e92d0002 push {r1} + 540: e92d0001 push {r0} + 544: e3a00002 mov r0, #2 + 548: ef000040 svc 0x00000040 + 54c: e8bd0002 pop {r1} + 550: e8bd0002 pop {r1} + 554: e8bd0004 pop {r2} + 558: e8bd0008 pop {r3} + 55c: e8bd4000 pop {lr} + 560: e12fff1e bx lr + +00000564 : + 564: e92d4000 push {lr} + 568: e92d0008 push {r3} + 56c: e92d0004 push {r2} + 570: e92d0002 push {r1} + 574: e92d0001 push {r0} + 578: e3a00003 mov r0, #3 + 57c: ef000040 svc 0x00000040 + 580: e8bd0002 pop {r1} + 584: e8bd0002 pop {r1} + 588: e8bd0004 pop {r2} + 58c: e8bd0008 pop {r3} + 590: e8bd4000 pop {lr} + 594: e12fff1e bx lr + +00000598 : + 598: e92d4000 push {lr} + 59c: e92d0008 push {r3} + 5a0: e92d0004 push {r2} + 5a4: e92d0002 push {r1} + 5a8: e92d0001 push {r0} + 5ac: e3a00004 mov r0, #4 + 5b0: ef000040 svc 0x00000040 + 5b4: e8bd0002 pop {r1} + 5b8: e8bd0002 pop {r1} + 5bc: e8bd0004 pop {r2} + 5c0: e8bd0008 pop {r3} + 5c4: e8bd4000 pop {lr} + 5c8: e12fff1e bx lr + +000005cc : + 5cc: e92d4000 push {lr} + 5d0: e92d0008 push {r3} + 5d4: e92d0004 push {r2} + 5d8: e92d0002 push {r1} + 5dc: e92d0001 push {r0} + 5e0: e3a00005 mov r0, #5 + 5e4: ef000040 svc 0x00000040 + 5e8: e8bd0002 pop {r1} + 5ec: e8bd0002 pop {r1} + 5f0: e8bd0004 pop {r2} + 5f4: e8bd0008 pop {r3} + 5f8: e8bd4000 pop {lr} + 5fc: e12fff1e bx lr + +00000600 : + 600: e92d4000 push {lr} + 604: e92d0008 push {r3} + 608: e92d0004 push {r2} + 60c: e92d0002 push {r1} + 610: e92d0001 push {r0} + 614: e3a00010 mov r0, #16 + 618: ef000040 svc 0x00000040 + 61c: e8bd0002 pop {r1} + 620: e8bd0002 pop {r1} + 624: e8bd0004 pop {r2} + 628: e8bd0008 pop {r3} + 62c: e8bd4000 pop {lr} + 630: e12fff1e bx lr + +00000634 : + 634: e92d4000 push {lr} + 638: e92d0008 push {r3} + 63c: e92d0004 push {r2} + 640: e92d0002 push {r1} + 644: e92d0001 push {r0} + 648: e3a00015 mov r0, #21 + 64c: ef000040 svc 0x00000040 + 650: e8bd0002 pop {r1} + 654: e8bd0002 pop {r1} + 658: e8bd0004 pop {r2} + 65c: e8bd0008 pop {r3} + 660: e8bd4000 pop {lr} + 664: e12fff1e bx lr + +00000668 : + 668: e92d4000 push {lr} + 66c: e92d0008 push {r3} + 670: e92d0004 push {r2} + 674: e92d0002 push {r1} + 678: e92d0001 push {r0} + 67c: e3a00006 mov r0, #6 + 680: ef000040 svc 0x00000040 + 684: e8bd0002 pop {r1} + 688: e8bd0002 pop {r1} + 68c: e8bd0004 pop {r2} + 690: e8bd0008 pop {r3} + 694: e8bd4000 pop {lr} + 698: e12fff1e bx lr + +0000069c : + 69c: e92d4000 push {lr} + 6a0: e92d0008 push {r3} + 6a4: e92d0004 push {r2} + 6a8: e92d0002 push {r1} + 6ac: e92d0001 push {r0} + 6b0: e3a00007 mov r0, #7 + 6b4: ef000040 svc 0x00000040 + 6b8: e8bd0002 pop {r1} + 6bc: e8bd0002 pop {r1} + 6c0: e8bd0004 pop {r2} + 6c4: e8bd0008 pop {r3} + 6c8: e8bd4000 pop {lr} + 6cc: e12fff1e bx lr + +000006d0 : + 6d0: e92d4000 push {lr} + 6d4: e92d0008 push {r3} + 6d8: e92d0004 push {r2} + 6dc: e92d0002 push {r1} + 6e0: e92d0001 push {r0} + 6e4: e3a0000f mov r0, #15 + 6e8: ef000040 svc 0x00000040 + 6ec: e8bd0002 pop {r1} + 6f0: e8bd0002 pop {r1} + 6f4: e8bd0004 pop {r2} + 6f8: e8bd0008 pop {r3} + 6fc: e8bd4000 pop {lr} + 700: e12fff1e bx lr + +00000704 : + 704: e92d4000 push {lr} + 708: e92d0008 push {r3} + 70c: e92d0004 push {r2} + 710: e92d0002 push {r1} + 714: e92d0001 push {r0} + 718: e3a00011 mov r0, #17 + 71c: ef000040 svc 0x00000040 + 720: e8bd0002 pop {r1} + 724: e8bd0002 pop {r1} + 728: e8bd0004 pop {r2} + 72c: e8bd0008 pop {r3} + 730: e8bd4000 pop {lr} + 734: e12fff1e bx lr + +00000738 : + 738: e92d4000 push {lr} + 73c: e92d0008 push {r3} + 740: e92d0004 push {r2} + 744: e92d0002 push {r1} + 748: e92d0001 push {r0} + 74c: e3a00012 mov r0, #18 + 750: ef000040 svc 0x00000040 + 754: e8bd0002 pop {r1} + 758: e8bd0002 pop {r1} + 75c: e8bd0004 pop {r2} + 760: e8bd0008 pop {r3} + 764: e8bd4000 pop {lr} + 768: e12fff1e bx lr + +0000076c : + 76c: e92d4000 push {lr} + 770: e92d0008 push {r3} + 774: e92d0004 push {r2} + 778: e92d0002 push {r1} + 77c: e92d0001 push {r0} + 780: e3a00008 mov r0, #8 + 784: ef000040 svc 0x00000040 + 788: e8bd0002 pop {r1} + 78c: e8bd0002 pop {r1} + 790: e8bd0004 pop {r2} + 794: e8bd0008 pop {r3} + 798: e8bd4000 pop {lr} + 79c: e12fff1e bx lr + +000007a0 : + 7a0: e92d4000 push {lr} + 7a4: e92d0008 push {r3} + 7a8: e92d0004 push {r2} + 7ac: e92d0002 push {r1} + 7b0: e92d0001 push {r0} + 7b4: e3a00013 mov r0, #19 + 7b8: ef000040 svc 0x00000040 + 7bc: e8bd0002 pop {r1} + 7c0: e8bd0002 pop {r1} + 7c4: e8bd0004 pop {r2} + 7c8: e8bd0008 pop {r3} + 7cc: e8bd4000 pop {lr} + 7d0: e12fff1e bx lr + +000007d4 : + 7d4: e92d4000 push {lr} + 7d8: e92d0008 push {r3} + 7dc: e92d0004 push {r2} + 7e0: e92d0002 push {r1} + 7e4: e92d0001 push {r0} + 7e8: e3a00014 mov r0, #20 + 7ec: ef000040 svc 0x00000040 + 7f0: e8bd0002 pop {r1} + 7f4: e8bd0002 pop {r1} + 7f8: e8bd0004 pop {r2} + 7fc: e8bd0008 pop {r3} + 800: e8bd4000 pop {lr} + 804: e12fff1e bx lr + +00000808 : + 808: e92d4000 push {lr} + 80c: e92d0008 push {r3} + 810: e92d0004 push {r2} + 814: e92d0002 push {r1} + 818: e92d0001 push {r0} + 81c: e3a00009 mov r0, #9 + 820: ef000040 svc 0x00000040 + 824: e8bd0002 pop {r1} + 828: e8bd0002 pop {r1} + 82c: e8bd0004 pop {r2} + 830: e8bd0008 pop {r3} + 834: e8bd4000 pop {lr} + 838: e12fff1e bx lr + +0000083c : + 83c: e92d4000 push {lr} + 840: e92d0008 push {r3} + 844: e92d0004 push {r2} + 848: e92d0002 push {r1} + 84c: e92d0001 push {r0} + 850: e3a0000a mov r0, #10 + 854: ef000040 svc 0x00000040 + 858: e8bd0002 pop {r1} + 85c: e8bd0002 pop {r1} + 860: e8bd0004 pop {r2} + 864: e8bd0008 pop {r3} + 868: e8bd4000 pop {lr} + 86c: e12fff1e bx lr + +00000870 : + 870: e92d4000 push {lr} + 874: e92d0008 push {r3} + 878: e92d0004 push {r2} + 87c: e92d0002 push {r1} + 880: e92d0001 push {r0} + 884: e3a0000b mov r0, #11 + 888: ef000040 svc 0x00000040 + 88c: e8bd0002 pop {r1} + 890: e8bd0002 pop {r1} + 894: e8bd0004 pop {r2} + 898: e8bd0008 pop {r3} + 89c: e8bd4000 pop {lr} + 8a0: e12fff1e bx lr + +000008a4 : + 8a4: e92d4000 push {lr} + 8a8: e92d0008 push {r3} + 8ac: e92d0004 push {r2} + 8b0: e92d0002 push {r1} + 8b4: e92d0001 push {r0} + 8b8: e3a0000c mov r0, #12 + 8bc: ef000040 svc 0x00000040 + 8c0: e8bd0002 pop {r1} + 8c4: e8bd0002 pop {r1} + 8c8: e8bd0004 pop {r2} + 8cc: e8bd0008 pop {r3} + 8d0: e8bd4000 pop {lr} + 8d4: e12fff1e bx lr + +000008d8 : + 8d8: e92d4000 push {lr} + 8dc: e92d0008 push {r3} + 8e0: e92d0004 push {r2} + 8e4: e92d0002 push {r1} + 8e8: e92d0001 push {r0} + 8ec: e3a0000d mov r0, #13 + 8f0: ef000040 svc 0x00000040 + 8f4: e8bd0002 pop {r1} + 8f8: e8bd0002 pop {r1} + 8fc: e8bd0004 pop {r2} + 900: e8bd0008 pop {r3} + 904: e8bd4000 pop {lr} + 908: e12fff1e bx lr + +0000090c : + 90c: e92d4000 push {lr} + 910: e92d0008 push {r3} + 914: e92d0004 push {r2} + 918: e92d0002 push {r1} + 91c: e92d0001 push {r0} + 920: e3a0000e mov r0, #14 + 924: ef000040 svc 0x00000040 + 928: e8bd0002 pop {r1} + 92c: e8bd0002 pop {r1} + 930: e8bd0004 pop {r2} + 934: e8bd0008 pop {r3} + 938: e8bd4000 pop {lr} + 93c: e12fff1e bx lr + +00000940 : +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 940: e92d4800 push {fp, lr} + 944: e28db004 add fp, sp, #4 + 948: e24b3004 sub r3, fp, #4 + 94c: e24dd008 sub sp, sp, #8 + write(fd, &c, 1); + 950: e3a02001 mov r2, #1 +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 954: e5631001 strb r1, [r3, #-1]! + write(fd, &c, 1); + 958: e1a01003 mov r1, r3 + 95c: ebffff27 bl 600 +} + 960: e24bd004 sub sp, fp, #4 + 964: e8bd8800 pop {fp, pc} + +00000968 : + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 968: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 96c: e1a04000 mov r4, r0 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 970: e1a00fa1 lsr r0, r1, #31 + 974: e3530000 cmp r3, #0 + 978: 03a03000 moveq r3, #0 + 97c: 12003001 andne r3, r0, #1 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 980: e28db020 add fp, sp, #32 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 984: e3530000 cmp r3, #0 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 988: e24dd014 sub sp, sp, #20 + 98c: e59f909c ldr r9, [pc, #156] ; a30 + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + x = -xx; + 990: 12611000 rsbne r1, r1, #0 + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + 994: 13a03001 movne r3, #1 + } else { + x = xx; + } + + b = base; + i = 0; + 998: e3a0a000 mov sl, #0 + 99c: e24b6034 sub r6, fp, #52 ; 0x34 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 9a0: e3a08001 mov r8, #1 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 9a4: e3a07000 mov r7, #0 + int i; + + for(i=31;i>=0;i--){ + 9a8: e3a0001f mov r0, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 9ac: e1a0c007 mov ip, r7 + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 9b0: e1a0e031 lsr lr, r1, r0 + 9b4: e20ee001 and lr, lr, #1 + 9b8: e18ec08c orr ip, lr, ip, lsl #1 + if(r >= d) { + 9bc: e152000c cmp r2, ip + r = r - d; + q = q | (1 << i); + 9c0: 91877018 orrls r7, r7, r8, lsl r0 + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 9c4: 9062c00c rsbls ip, r2, ip +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 9c8: e2500001 subs r0, r0, #1 + 9cc: 2afffff7 bcs 9b0 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 9d0: e0000792 mul r0, r2, r7 + }while((x = y) != 0); + 9d4: e3570000 cmp r7, #0 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 9d8: e0601001 rsb r1, r0, r1 + 9dc: e28a5001 add r5, sl, #1 + 9e0: e7d91001 ldrb r1, [r9, r1] + 9e4: e7c6100a strb r1, [r6, sl] + }while((x = y) != 0); + 9e8: 11a01007 movne r1, r7 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 9ec: 11a0a005 movne sl, r5 + 9f0: 1affffeb bne 9a4 + }while((x = y) != 0); + if(neg) + 9f4: e3530000 cmp r3, #0 + buf[i++] = '-'; + 9f8: 124b2024 subne r2, fp, #36 ; 0x24 + 9fc: 10823005 addne r3, r2, r5 + a00: 128a5002 addne r5, sl, #2 + + while(--i >= 0) + a04: e2455001 sub r5, r5, #1 + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + a08: 13a0202d movne r2, #45 ; 0x2d + a0c: 15432010 strbne r2, [r3, #-16] + + while(--i >= 0) + putc(fd, buf[i]); + a10: e7d61005 ldrb r1, [r6, r5] + a14: e1a00004 mov r0, r4 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + a18: e2455001 sub r5, r5, #1 + putc(fd, buf[i]); + a1c: ebffffc7 bl 940 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + a20: e3750001 cmn r5, #1 + a24: 1afffff9 bne a10 + putc(fd, buf[i]); +} + a28: e24bd020 sub sp, fp, #32 + a2c: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} + a30: 00000db4 .word 0x00000db4 + +00000a34
: + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + a34: e3a03000 mov r3, #0 +{ + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + a38: e92d0830 push {r4, r5, fp} + a3c: e1a02000 mov r2, r0 + a40: e28db008 add fp, sp, #8 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + a44: e3a0c01f mov ip, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + a48: e1a00003 mov r0, r3 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + a4c: e3a05001 mov r5, #1 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + a50: e1a04c32 lsr r4, r2, ip + a54: e2044001 and r4, r4, #1 + a58: e1843083 orr r3, r4, r3, lsl #1 + if(r >= d) { + a5c: e1530001 cmp r3, r1 + r = r - d; + q = q | (1 << i); + a60: 21800c15 orrcs r0, r0, r5, lsl ip + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + a64: 20613003 rsbcs r3, r1, r3 +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + a68: e25cc001 subs ip, ip, #1 + a6c: 2afffff7 bcs a50 + r = r - d; + q = q | (1 << i); + } + } + return q; +} + a70: e24bd008 sub sp, fp, #8 + a74: e8bd0830 pop {r4, r5, fp} + a78: e12fff1e bx lr + +00000a7c : +} + +// Print to the given fd. Only understands %d, %x, %p, %s. +void +printf(int fd, char *fmt, ...) +{ + a7c: e92d000e push {r1, r2, r3} + a80: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + a84: e28db020 add fp, sp, #32 + a88: e1a05000 mov r5, r0 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + a8c: e59b4004 ldr r4, [fp, #4] + a90: e5d48000 ldrb r8, [r4] + a94: e3580000 cmp r8, #0 + a98: 0a000027 beq b3c + ap++; + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + a9c: e59f712c ldr r7, [pc, #300] ; bd0 + char *s; + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + aa0: e28b6008 add r6, fp, #8 +{ + char *s; + int c, i, state; + uint *ap; + + state = 0; + aa4: e3a0a000 mov sl, #0 + aa8: ea000008 b ad0 + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + aac: e3580025 cmp r8, #37 ; 0x25 + state = '%'; + ab0: 01a0a008 moveq sl, r8 + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + ab4: 0a000002 beq ac4 + state = '%'; + } else { + putc(fd, c); + ab8: e1a00005 mov r0, r5 + abc: e1a01008 mov r1, r8 + ac0: ebffff9e bl 940 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + ac4: e5f48001 ldrb r8, [r4, #1]! + ac8: e3580000 cmp r8, #0 + acc: 0a00001a beq b3c + c = fmt[i] & 0xff; + if(state == 0){ + ad0: e35a0000 cmp sl, #0 + ad4: 0afffff4 beq aac + if(c == '%'){ + state = '%'; + } else { + putc(fd, c); + } + } else if(state == '%'){ + ad8: e35a0025 cmp sl, #37 ; 0x25 + adc: 1afffff8 bne ac4 + if(c == 'd'){ + ae0: e3580064 cmp r8, #100 ; 0x64 + ae4: 0a00002c beq b9c + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + ae8: e3580078 cmp r8, #120 ; 0x78 + aec: 13580070 cmpne r8, #112 ; 0x70 + af0: 13a09000 movne r9, #0 + af4: 03a09001 moveq r9, #1 + af8: 0a000013 beq b4c + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + afc: e3580073 cmp r8, #115 ; 0x73 + b00: 0a000018 beq b68 + s = "(null)"; + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + b04: e3580063 cmp r8, #99 ; 0x63 + b08: 0a00002a beq bb8 + putc(fd, *ap); + ap++; + } else if(c == '%'){ + b0c: e3580025 cmp r8, #37 ; 0x25 + putc(fd, c); + b10: e1a0100a mov r1, sl + b14: e1a00005 mov r0, r5 + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + ap++; + } else if(c == '%'){ + b18: 0a000002 beq b28 + putc(fd, c); + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + b1c: ebffff87 bl 940 + putc(fd, c); + b20: e1a00005 mov r0, r5 + b24: e1a01008 mov r1, r8 + b28: ebffff84 bl 940 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + b2c: e5f48001 ldrb r8, [r4, #1]! + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + b30: e1a0a009 mov sl, r9 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + b34: e3580000 cmp r8, #0 + b38: 1affffe4 bne ad0 + putc(fd, c); + } + state = 0; + } + } +} + b3c: e24bd020 sub sp, fp, #32 + b40: e8bd4ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, lr} + b44: e28dd00c add sp, sp, #12 + b48: e12fff1e bx lr + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + b4c: e1a00005 mov r0, r5 + b50: e4961004 ldr r1, [r6], #4 + b54: e3a02010 mov r2, #16 + b58: e3a03000 mov r3, #0 + b5c: ebffff81 bl 968 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + b60: e3a0a000 mov sl, #0 + b64: eaffffd6 b ac4 + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + s = (char*)*ap; + b68: e4968004 ldr r8, [r6], #4 + ap++; + if(s == 0) + s = "(null)"; + b6c: e3580000 cmp r8, #0 + b70: 01a08007 moveq r8, r7 + while(*s != 0){ + b74: e5d81000 ldrb r1, [r8] + b78: e3510000 cmp r1, #0 + b7c: 0a000004 beq b94 + putc(fd, *s); + b80: e1a00005 mov r0, r5 + b84: ebffff6d bl 940 + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + while(*s != 0){ + b88: e5f81001 ldrb r1, [r8, #1]! + b8c: e3510000 cmp r1, #0 + b90: 1afffffa bne b80 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + b94: e1a0a001 mov sl, r1 + b98: eaffffc9 b ac4 + } else { + putc(fd, c); + } + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + b9c: e1a00005 mov r0, r5 + ba0: e4961004 ldr r1, [r6], #4 + ba4: e3a0200a mov r2, #10 + ba8: e3a03001 mov r3, #1 + bac: ebffff6d bl 968 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + bb0: e3a0a000 mov sl, #0 + bb4: eaffffc2 b ac4 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + bb8: e4961004 ldr r1, [r6], #4 + bbc: e1a00005 mov r0, r5 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + bc0: e1a0a009 mov sl, r9 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + bc4: e6ef1071 uxtb r1, r1 + bc8: ebffff5c bl 940 + bcc: eaffffbc b ac4 + bd0: 00000dc8 .word 0x00000dc8 + +00000bd4 : +free(void *ap) +{ + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + bd4: e59f3098 ldr r3, [pc, #152] ; c74 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + bd8: e92d0830 push {r4, r5, fp} + Header *bp, *p; + + bp = (Header*)ap - 1; + bdc: e240c008 sub ip, r0, #8 + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + be0: e5932000 ldr r2, [r3] +static Header base; +static Header *freep; + +void +free(void *ap) +{ + be4: e28db008 add fp, sp, #8 + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + be8: e152000c cmp r2, ip + bec: e5921000 ldr r1, [r2] + bf0: 2a000001 bcs bfc + bf4: e15c0001 cmp ip, r1 + bf8: 3a000007 bcc c1c + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + bfc: e1520001 cmp r2, r1 + c00: 3a000003 bcc c14 + c04: e152000c cmp r2, ip + c08: 3a000003 bcc c1c + c0c: e15c0001 cmp ip, r1 + c10: 3a000001 bcc c1c +static Header base; +static Header *freep; + +void +free(void *ap) +{ + c14: e1a02001 mov r2, r1 + c18: eafffff2 b be8 + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + c1c: e5104004 ldr r4, [r0, #-4] + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + freep = p; + c20: e5832000 str r2, [r3] + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + c24: e08c5184 add r5, ip, r4, lsl #3 + c28: e1550001 cmp r5, r1 + bp->s.size += p->s.ptr->s.size; + c2c: 05911004 ldreq r1, [r1, #4] + c30: 00814004 addeq r4, r1, r4 + c34: 05004004 streq r4, [r0, #-4] + bp->s.ptr = p->s.ptr->s.ptr; + c38: 05921000 ldreq r1, [r2] + c3c: 05911000 ldreq r1, [r1] + } else + bp->s.ptr = p->s.ptr; + c40: e5001008 str r1, [r0, #-8] + if(p + p->s.size == bp){ + c44: e5921004 ldr r1, [r2, #4] + c48: e0824181 add r4, r2, r1, lsl #3 + c4c: e15c0004 cmp ip, r4 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + c50: 1582c000 strne ip, [r2] + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + } else + bp->s.ptr = p->s.ptr; + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + c54: 0510c004 ldreq ip, [r0, #-4] + c58: 008c1001 addeq r1, ip, r1 + c5c: 05821004 streq r1, [r2, #4] + p->s.ptr = bp->s.ptr; + c60: 05101008 ldreq r1, [r0, #-8] + c64: 05821000 streq r1, [r2] + } else + p->s.ptr = bp; + freep = p; +} + c68: e24bd008 sub sp, fp, #8 + c6c: e8bd0830 pop {r4, r5, fp} + c70: e12fff1e bx lr + c74: 00000de0 .word 0x00000de0 + +00000c78 : + return freep; +} + +void* +malloc(uint nbytes) +{ + c78: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + c7c: e2804007 add r4, r0, #7 + if((prevp = freep) == 0){ + c80: e59f50d4 ldr r5, [pc, #212] ; d5c +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + c84: e1a041a4 lsr r4, r4, #3 + return freep; +} + +void* +malloc(uint nbytes) +{ + c88: e28db01c add fp, sp, #28 + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + c8c: e5953000 ldr r3, [r5] +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + c90: e2844001 add r4, r4, #1 + if((prevp = freep) == 0){ + c94: e3530000 cmp r3, #0 + c98: 0a00002b beq d4c + c9c: e5930000 ldr r0, [r3] + ca0: e5902004 ldr r2, [r0, #4] + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + ca4: e1520004 cmp r2, r4 + ca8: 2a00001b bcs d1c +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + cac: e59f80ac ldr r8, [pc, #172] ; d60 + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + cb0: e1a07184 lsl r7, r4, #3 + cb4: ea000003 b cc8 + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + cb8: e5930000 ldr r0, [r3] + if(p->s.size >= nunits){ + cbc: e5902004 ldr r2, [r0, #4] + cc0: e1540002 cmp r4, r2 + cc4: 9a000014 bls d1c + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + cc8: e5952000 ldr r2, [r5] + ccc: e1a03000 mov r3, r0 + cd0: e1500002 cmp r0, r2 + cd4: 1afffff7 bne cb8 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + cd8: e1540008 cmp r4, r8 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + cdc: 81a00007 movhi r0, r7 + ce0: 93a00902 movls r0, #32768 ; 0x8000 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + ce4: 81a06004 movhi r6, r4 + ce8: 93a06a01 movls r6, #4096 ; 0x1000 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + cec: ebfffeec bl 8a4 + cf0: e1a03000 mov r3, r0 + if(p == (char*)-1) + cf4: e3730001 cmn r3, #1 + return 0; + hp = (Header*)p; + hp->s.size = nu; + free((void*)(hp + 1)); + cf8: e2800008 add r0, r0, #8 + Header *hp; + + if(nu < 4096) + nu = 4096; + p = sbrk(nu * sizeof(Header)); + if(p == (char*)-1) + cfc: 0a000010 beq d44 + return 0; + hp = (Header*)p; + hp->s.size = nu; + d00: e5836004 str r6, [r3, #4] + free((void*)(hp + 1)); + d04: ebffffb2 bl bd4 + return freep; + d08: e5953000 ldr r3, [r5] + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + if((p = morecore(nunits)) == 0) + d0c: e3530000 cmp r3, #0 + d10: 1affffe8 bne cb8 + return 0; + d14: e1a00003 mov r0, r3 + } +} + d18: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + d1c: e1540002 cmp r4, r2 + prevp->s.ptr = p->s.ptr; + else { + p->s.size -= nunits; + d20: 10642002 rsbne r2, r4, r2 + d24: 15802004 strne r2, [r0, #4] + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + d28: 05902000 ldreq r2, [r0] + else { + p->s.size -= nunits; + p += p->s.size; + d2c: 10800182 addne r0, r0, r2, lsl #3 + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + d30: 05832000 streq r2, [r3] + else { + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + d34: 15804004 strne r4, [r0, #4] + } + freep = prevp; + d38: e5853000 str r3, [r5] + return (void*)(p + 1); + d3c: e2800008 add r0, r0, #8 + d40: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + } + if(p == freep) + if((p = morecore(nunits)) == 0) + return 0; + d44: e3a00000 mov r0, #0 + d48: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + d4c: e2850004 add r0, r5, #4 + d50: e5850000 str r0, [r5] + base.s.size = 0; + d54: e9850009 stmib r5, {r0, r3} + d58: eaffffd3 b cac + d5c: 00000de0 .word 0x00000de0 + d60: 00000fff .word 0x00000fff diff -r 000000000000 -r c450faca55f4 uprogs/ls.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/ls.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,85 @@ +#include "types.h" +#include "stat.h" +#include "user.h" +#include "fs.h" + +char* +fmtname(char *path) +{ + static char buf[DIRSIZ+1]; + char *p; + + // Find first character after last slash. + for(p=path+strlen(path); p >= path && *p != '/'; p--) + ; + p++; + + // Return blank-padded name. + if(strlen(p) >= DIRSIZ) + return p; + memmove(buf, p, strlen(p)); + memset(buf+strlen(p), ' ', DIRSIZ-strlen(p)); + return buf; +} + +void +ls(char *path) +{ + char buf[512], *p; + int fd; + struct dirent de; + struct stat st; + + if((fd = open(path, 0)) < 0){ + printf(2, "ls: cannot open %s\n", path); + return; + } + + if(fstat(fd, &st) < 0){ + printf(2, "ls: cannot stat %s\n", path); + close(fd); + return; + } + + switch(st.type){ + case T_FILE: + printf(1, "%s %d %d %d\n", fmtname(path), st.type, st.ino, st.size); + break; + + case T_DIR: + if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){ + printf(1, "ls: path too long\n"); + break; + } + strcpy(buf, path); + p = buf+strlen(buf); + *p++ = '/'; + while(read(fd, &de, sizeof(de)) == sizeof(de)){ + if(de.inum == 0) + continue; + memmove(p, de.name, DIRSIZ); + p[DIRSIZ] = 0; + if(stat(buf, &st) < 0){ + printf(1, "ls: cannot stat %s\n", buf); + continue; + } + printf(1, "%s %d %d %d\n", fmtname(buf), st.type, st.ino, st.size); + } + break; + } + close(fd); +} + +int +main(int argc, char *argv[]) +{ + int i; + + if(argc < 2){ + ls("."); + exit(); + } + for(i=1; i: +int +main(int argc, char *argv[]) +{ + int i; + + if(argc < 2){ + 0: e3500001 cmp r0, #1 +#include "stat.h" +#include "user.h" + +int +main(int argc, char *argv[]) +{ + 4: e92d48f0 push {r4, r5, r6, r7, fp, lr} + 8: e1a05000 mov r5, r0 + c: e28db014 add fp, sp, #20 +#include "types.h" +#include "stat.h" +#include "user.h" + +int +main(int argc, char *argv[]) + 10: c2816004 addgt r6, r1, #4 + 14: c3a07001 movgt r7, #1 +{ + int i; + + if(argc < 2){ + 18: da00000e ble 58 + printf(2, "Usage: mkdir files...\n"); + exit(); + } + + for(i = 1; i < argc; i++){ + if(mkdir(argv[i]) < 0){ + 1c: e1a04006 mov r4, r6 + 20: e2866004 add r6, r6, #4 + 24: e5940000 ldr r0, [r4] + 28: eb000161 bl 5b4 + 2c: e3500000 cmp r0, #0 + 30: ba000003 blt 44 + if(argc < 2){ + printf(2, "Usage: mkdir files...\n"); + exit(); + } + + for(i = 1; i < argc; i++){ + 34: e2877001 add r7, r7, #1 + 38: e1570005 cmp r7, r5 + 3c: 1afffff6 bne 1c + printf(2, "mkdir: %s failed to create\n", argv[i]); + break; + } + } + + exit(); + 40: eb0000b2 bl 310 + exit(); + } + + for(i = 1; i < argc; i++){ + if(mkdir(argv[i]) < 0){ + printf(2, "mkdir: %s failed to create\n", argv[i]); + 44: e3a00002 mov r0, #2 + 48: e59f1018 ldr r1, [pc, #24] ; 68 + 4c: e5942000 ldr r2, [r4] + 50: eb000201 bl 85c + break; + } + } + + exit(); + 54: eb0000ad bl 310 +main(int argc, char *argv[]) +{ + int i; + + if(argc < 2){ + printf(2, "Usage: mkdir files...\n"); + 58: e3a00002 mov r0, #2 + 5c: e59f1008 ldr r1, [pc, #8] ; 6c + 60: eb0001fd bl 85c + exit(); + 64: eb0000a9 bl 310 + 68: 00000b5c .word 0x00000b5c + 6c: 00000b44 .word 0x00000b44 + +00000070 : +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 70: e52db004 push {fp} ; (str fp, [sp, #-4]!) + char *os; + + os = s; + while((*s++ = *t++) != 0) + 74: e1a02000 mov r2, r0 +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 78: e28db000 add fp, sp, #0 + char *os; + + os = s; + while((*s++ = *t++) != 0) + 7c: e4d13001 ldrb r3, [r1], #1 + 80: e3530000 cmp r3, #0 + 84: e4c23001 strb r3, [r2], #1 + 88: 1afffffb bne 7c + ; + return os; +} + 8c: e28bd000 add sp, fp, #0 + 90: e8bd0800 pop {fp} + 94: e12fff1e bx lr + +00000098 : + +int +strcmp(const char *p, const char *q) +{ + 98: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 9c: e28db000 add fp, sp, #0 + while(*p && *p == *q) + a0: e5d03000 ldrb r3, [r0] + a4: e5d12000 ldrb r2, [r1] + a8: e3530000 cmp r3, #0 + ac: 1a000004 bne c4 + b0: ea000005 b cc + b4: e5f03001 ldrb r3, [r0, #1]! + b8: e3530000 cmp r3, #0 + bc: 0a000006 beq dc + c0: e5f12001 ldrb r2, [r1, #1]! + c4: e1530002 cmp r3, r2 + c8: 0afffff9 beq b4 + p++, q++; + return (uchar)*p - (uchar)*q; +} + cc: e0620003 rsb r0, r2, r3 + d0: e28bd000 add sp, fp, #0 + d4: e8bd0800 pop {fp} + d8: e12fff1e bx lr +} + +int +strcmp(const char *p, const char *q) +{ + while(*p && *p == *q) + dc: e5d12001 ldrb r2, [r1, #1] + e0: eafffff9 b cc + +000000e4 : + return (uchar)*p - (uchar)*q; +} + +uint +strlen(char *s) +{ + e4: e52db004 push {fp} ; (str fp, [sp, #-4]!) + e8: e28db000 add fp, sp, #0 + int n; + + for(n = 0; s[n]; n++) + ec: e5d03000 ldrb r3, [r0] + f0: e3530000 cmp r3, #0 + f4: 01a00003 moveq r0, r3 + f8: 0a000006 beq 118 + fc: e1a02000 mov r2, r0 + 100: e3a03000 mov r3, #0 + 104: e5f21001 ldrb r1, [r2, #1]! + 108: e2833001 add r3, r3, #1 + 10c: e1a00003 mov r0, r3 + 110: e3510000 cmp r1, #0 + 114: 1afffffa bne 104 + ; + return n; +} + 118: e28bd000 add sp, fp, #0 + 11c: e8bd0800 pop {fp} + 120: e12fff1e bx lr + +00000124 : +memset(void *dst, int c, uint n) +{ + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 124: e3520000 cmp r2, #0 + return n; +} + +void* +memset(void *dst, int c, uint n) +{ + 128: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 12c: e28db000 add fp, sp, #0 + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 130: 0a000006 beq 150 + 134: e6ef1071 uxtb r1, r1 + 138: e1a03002 mov r3, r2 +} + +void* +memset(void *dst, int c, uint n) +{ + char *p=dst; + 13c: e1a0c000 mov ip, r0 + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 140: e2533001 subs r3, r3, #1 + 144: e4cc1001 strb r1, [ip], #1 + 148: 1afffffc bne 140 + 14c: e0800002 add r0, r0, r2 + return (void *)p; +} + 150: e28bd000 add sp, fp, #0 + 154: e8bd0800 pop {fp} + 158: e12fff1e bx lr + +0000015c : + +char* +strchr(const char *s, char c) +{ + 15c: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 160: e28db000 add fp, sp, #0 + for(; *s; s++) + 164: e5d03000 ldrb r3, [r0] + 168: e3530000 cmp r3, #0 + 16c: 1a000004 bne 184 + 170: ea000008 b 198 + 174: e5d03001 ldrb r3, [r0, #1] + 178: e2800001 add r0, r0, #1 + 17c: e3530000 cmp r3, #0 + 180: 0a000004 beq 198 + if(*s == c) + 184: e1530001 cmp r3, r1 + 188: 1afffff9 bne 174 + return (char*)s; + return 0; +} + 18c: e28bd000 add sp, fp, #0 + 190: e8bd0800 pop {fp} + 194: e12fff1e bx lr +strchr(const char *s, char c) +{ + for(; *s; s++) + if(*s == c) + return (char*)s; + return 0; + 198: e1a00003 mov r0, r3 + 19c: eafffffa b 18c + +000001a0 : +} + +char* +gets(char *buf, int max) +{ + 1a0: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + 1a4: e28db018 add fp, sp, #24 + 1a8: e24dd00c sub sp, sp, #12 + 1ac: e1a08000 mov r8, r0 + 1b0: e1a07001 mov r7, r1 + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 1b4: e1a06000 mov r6, r0 + 1b8: e3a05000 mov r5, #0 + 1bc: ea000008 b 1e4 + cc = read(0, &c, 1); + 1c0: eb000079 bl 3ac + if(cc < 1) + 1c4: e3500000 cmp r0, #0 + 1c8: da00000b ble 1fc + break; + buf[i++] = c; + 1cc: e55b301d ldrb r3, [fp, #-29] + if(c == '\n' || c == '\r') + 1d0: e1a05004 mov r5, r4 + 1d4: e353000a cmp r3, #10 + 1d8: 1353000d cmpne r3, #13 + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + if(cc < 1) + break; + buf[i++] = c; + 1dc: e4c63001 strb r3, [r6], #1 + if(c == '\n' || c == '\r') + 1e0: 0a00000a beq 210 +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + 1e4: e3a02001 mov r2, #1 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 1e8: e0854002 add r4, r5, r2 + 1ec: e1540007 cmp r4, r7 + cc = read(0, &c, 1); + 1f0: e3a00000 mov r0, #0 + 1f4: e24b101d sub r1, fp, #29 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 1f8: bafffff0 blt 1c0 + break; + buf[i++] = c; + if(c == '\n' || c == '\r') + break; + } + buf[i] = '\0'; + 1fc: e3a03000 mov r3, #0 + 200: e7c83005 strb r3, [r8, r5] + return buf; +} + 204: e1a00008 mov r0, r8 + 208: e24bd018 sub sp, fp, #24 + 20c: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 210: e1a05004 mov r5, r4 + 214: eafffff8 b 1fc + +00000218 : + return buf; +} + +int +stat(char *n, struct stat *st) +{ + 218: e92d4830 push {r4, r5, fp, lr} + 21c: e1a05001 mov r5, r1 + 220: e28db00c add fp, sp, #12 + int fd; + int r; + + fd = open(n, O_RDONLY); + 224: e3a01000 mov r1, #0 + 228: eb0000a0 bl 4b0 + if(fd < 0) + 22c: e2504000 subs r4, r0, #0 + return -1; + 230: b3e05000 mvnlt r5, #0 +{ + int fd; + int r; + + fd = open(n, O_RDONLY); + if(fd < 0) + 234: ba000004 blt 24c + return -1; + r = fstat(fd, st); + 238: e1a01005 mov r1, r5 + 23c: eb0000c2 bl 54c + 240: e1a05000 mov r5, r0 + close(fd); + 244: e1a00004 mov r0, r4 + 248: eb000071 bl 414 + return r; +} + 24c: e1a00005 mov r0, r5 + 250: e8bd8830 pop {r4, r5, fp, pc} + +00000254 : + +int +atoi(const char *s) +{ + 254: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 258: e28db000 add fp, sp, #0 + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 25c: e5d03000 ldrb r3, [r0] + 260: e2432030 sub r2, r3, #48 ; 0x30 + 264: e6ef2072 uxtb r2, r2 + 268: e3520009 cmp r2, #9 +int +atoi(const char *s) +{ + int n; + + n = 0; + 26c: 83a00000 movhi r0, #0 + while('0' <= *s && *s <= '9') + 270: 8a000009 bhi 29c + 274: e1a02000 mov r2, r0 +int +atoi(const char *s) +{ + int n; + + n = 0; + 278: e3a00000 mov r0, #0 + while('0' <= *s && *s <= '9') + n = n*10 + *s++ - '0'; + 27c: e0800100 add r0, r0, r0, lsl #2 + 280: e0830080 add r0, r3, r0, lsl #1 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 284: e5f23001 ldrb r3, [r2, #1]! + n = n*10 + *s++ - '0'; + 288: e2400030 sub r0, r0, #48 ; 0x30 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 28c: e2431030 sub r1, r3, #48 ; 0x30 + 290: e6ef1071 uxtb r1, r1 + 294: e3510009 cmp r1, #9 + 298: 9afffff7 bls 27c + n = n*10 + *s++ - '0'; + return n; +} + 29c: e28bd000 add sp, fp, #0 + 2a0: e8bd0800 pop {fp} + 2a4: e12fff1e bx lr + +000002a8 : +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 2a8: e3520000 cmp r2, #0 + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) +{ + 2ac: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 2b0: e28db000 add fp, sp, #0 + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 2b4: da000005 ble 2d0 + n = n*10 + *s++ - '0'; + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) + 2b8: e0802002 add r2, r0, r2 +{ + char *dst, *src; + + dst = vdst; + 2bc: e1a03000 mov r3, r0 + src = vsrc; + while(n-- > 0) + *dst++ = *src++; + 2c0: e4d1c001 ldrb ip, [r1], #1 + 2c4: e4c3c001 strb ip, [r3], #1 +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 2c8: e1530002 cmp r3, r2 + 2cc: 1afffffb bne 2c0 + *dst++ = *src++; + return vdst; +} + 2d0: e28bd000 add sp, fp, #0 + 2d4: e8bd0800 pop {fp} + 2d8: e12fff1e bx lr + +000002dc : + 2dc: e92d4000 push {lr} + 2e0: e92d0008 push {r3} + 2e4: e92d0004 push {r2} + 2e8: e92d0002 push {r1} + 2ec: e92d0001 push {r0} + 2f0: e3a00001 mov r0, #1 + 2f4: ef000040 svc 0x00000040 + 2f8: e8bd0002 pop {r1} + 2fc: e8bd0002 pop {r1} + 300: e8bd0004 pop {r2} + 304: e8bd0008 pop {r3} + 308: e8bd4000 pop {lr} + 30c: e12fff1e bx lr + +00000310 : + 310: e92d4000 push {lr} + 314: e92d0008 push {r3} + 318: e92d0004 push {r2} + 31c: e92d0002 push {r1} + 320: e92d0001 push {r0} + 324: e3a00002 mov r0, #2 + 328: ef000040 svc 0x00000040 + 32c: e8bd0002 pop {r1} + 330: e8bd0002 pop {r1} + 334: e8bd0004 pop {r2} + 338: e8bd0008 pop {r3} + 33c: e8bd4000 pop {lr} + 340: e12fff1e bx lr + +00000344 : + 344: e92d4000 push {lr} + 348: e92d0008 push {r3} + 34c: e92d0004 push {r2} + 350: e92d0002 push {r1} + 354: e92d0001 push {r0} + 358: e3a00003 mov r0, #3 + 35c: ef000040 svc 0x00000040 + 360: e8bd0002 pop {r1} + 364: e8bd0002 pop {r1} + 368: e8bd0004 pop {r2} + 36c: e8bd0008 pop {r3} + 370: e8bd4000 pop {lr} + 374: e12fff1e bx lr + +00000378 : + 378: e92d4000 push {lr} + 37c: e92d0008 push {r3} + 380: e92d0004 push {r2} + 384: e92d0002 push {r1} + 388: e92d0001 push {r0} + 38c: e3a00004 mov r0, #4 + 390: ef000040 svc 0x00000040 + 394: e8bd0002 pop {r1} + 398: e8bd0002 pop {r1} + 39c: e8bd0004 pop {r2} + 3a0: e8bd0008 pop {r3} + 3a4: e8bd4000 pop {lr} + 3a8: e12fff1e bx lr + +000003ac : + 3ac: e92d4000 push {lr} + 3b0: e92d0008 push {r3} + 3b4: e92d0004 push {r2} + 3b8: e92d0002 push {r1} + 3bc: e92d0001 push {r0} + 3c0: e3a00005 mov r0, #5 + 3c4: ef000040 svc 0x00000040 + 3c8: e8bd0002 pop {r1} + 3cc: e8bd0002 pop {r1} + 3d0: e8bd0004 pop {r2} + 3d4: e8bd0008 pop {r3} + 3d8: e8bd4000 pop {lr} + 3dc: e12fff1e bx lr + +000003e0 : + 3e0: e92d4000 push {lr} + 3e4: e92d0008 push {r3} + 3e8: e92d0004 push {r2} + 3ec: e92d0002 push {r1} + 3f0: e92d0001 push {r0} + 3f4: e3a00010 mov r0, #16 + 3f8: ef000040 svc 0x00000040 + 3fc: e8bd0002 pop {r1} + 400: e8bd0002 pop {r1} + 404: e8bd0004 pop {r2} + 408: e8bd0008 pop {r3} + 40c: e8bd4000 pop {lr} + 410: e12fff1e bx lr + +00000414 : + 414: e92d4000 push {lr} + 418: e92d0008 push {r3} + 41c: e92d0004 push {r2} + 420: e92d0002 push {r1} + 424: e92d0001 push {r0} + 428: e3a00015 mov r0, #21 + 42c: ef000040 svc 0x00000040 + 430: e8bd0002 pop {r1} + 434: e8bd0002 pop {r1} + 438: e8bd0004 pop {r2} + 43c: e8bd0008 pop {r3} + 440: e8bd4000 pop {lr} + 444: e12fff1e bx lr + +00000448 : + 448: e92d4000 push {lr} + 44c: e92d0008 push {r3} + 450: e92d0004 push {r2} + 454: e92d0002 push {r1} + 458: e92d0001 push {r0} + 45c: e3a00006 mov r0, #6 + 460: ef000040 svc 0x00000040 + 464: e8bd0002 pop {r1} + 468: e8bd0002 pop {r1} + 46c: e8bd0004 pop {r2} + 470: e8bd0008 pop {r3} + 474: e8bd4000 pop {lr} + 478: e12fff1e bx lr + +0000047c : + 47c: e92d4000 push {lr} + 480: e92d0008 push {r3} + 484: e92d0004 push {r2} + 488: e92d0002 push {r1} + 48c: e92d0001 push {r0} + 490: e3a00007 mov r0, #7 + 494: ef000040 svc 0x00000040 + 498: e8bd0002 pop {r1} + 49c: e8bd0002 pop {r1} + 4a0: e8bd0004 pop {r2} + 4a4: e8bd0008 pop {r3} + 4a8: e8bd4000 pop {lr} + 4ac: e12fff1e bx lr + +000004b0 : + 4b0: e92d4000 push {lr} + 4b4: e92d0008 push {r3} + 4b8: e92d0004 push {r2} + 4bc: e92d0002 push {r1} + 4c0: e92d0001 push {r0} + 4c4: e3a0000f mov r0, #15 + 4c8: ef000040 svc 0x00000040 + 4cc: e8bd0002 pop {r1} + 4d0: e8bd0002 pop {r1} + 4d4: e8bd0004 pop {r2} + 4d8: e8bd0008 pop {r3} + 4dc: e8bd4000 pop {lr} + 4e0: e12fff1e bx lr + +000004e4 : + 4e4: e92d4000 push {lr} + 4e8: e92d0008 push {r3} + 4ec: e92d0004 push {r2} + 4f0: e92d0002 push {r1} + 4f4: e92d0001 push {r0} + 4f8: e3a00011 mov r0, #17 + 4fc: ef000040 svc 0x00000040 + 500: e8bd0002 pop {r1} + 504: e8bd0002 pop {r1} + 508: e8bd0004 pop {r2} + 50c: e8bd0008 pop {r3} + 510: e8bd4000 pop {lr} + 514: e12fff1e bx lr + +00000518 : + 518: e92d4000 push {lr} + 51c: e92d0008 push {r3} + 520: e92d0004 push {r2} + 524: e92d0002 push {r1} + 528: e92d0001 push {r0} + 52c: e3a00012 mov r0, #18 + 530: ef000040 svc 0x00000040 + 534: e8bd0002 pop {r1} + 538: e8bd0002 pop {r1} + 53c: e8bd0004 pop {r2} + 540: e8bd0008 pop {r3} + 544: e8bd4000 pop {lr} + 548: e12fff1e bx lr + +0000054c : + 54c: e92d4000 push {lr} + 550: e92d0008 push {r3} + 554: e92d0004 push {r2} + 558: e92d0002 push {r1} + 55c: e92d0001 push {r0} + 560: e3a00008 mov r0, #8 + 564: ef000040 svc 0x00000040 + 568: e8bd0002 pop {r1} + 56c: e8bd0002 pop {r1} + 570: e8bd0004 pop {r2} + 574: e8bd0008 pop {r3} + 578: e8bd4000 pop {lr} + 57c: e12fff1e bx lr + +00000580 : + 580: e92d4000 push {lr} + 584: e92d0008 push {r3} + 588: e92d0004 push {r2} + 58c: e92d0002 push {r1} + 590: e92d0001 push {r0} + 594: e3a00013 mov r0, #19 + 598: ef000040 svc 0x00000040 + 59c: e8bd0002 pop {r1} + 5a0: e8bd0002 pop {r1} + 5a4: e8bd0004 pop {r2} + 5a8: e8bd0008 pop {r3} + 5ac: e8bd4000 pop {lr} + 5b0: e12fff1e bx lr + +000005b4 : + 5b4: e92d4000 push {lr} + 5b8: e92d0008 push {r3} + 5bc: e92d0004 push {r2} + 5c0: e92d0002 push {r1} + 5c4: e92d0001 push {r0} + 5c8: e3a00014 mov r0, #20 + 5cc: ef000040 svc 0x00000040 + 5d0: e8bd0002 pop {r1} + 5d4: e8bd0002 pop {r1} + 5d8: e8bd0004 pop {r2} + 5dc: e8bd0008 pop {r3} + 5e0: e8bd4000 pop {lr} + 5e4: e12fff1e bx lr + +000005e8 : + 5e8: e92d4000 push {lr} + 5ec: e92d0008 push {r3} + 5f0: e92d0004 push {r2} + 5f4: e92d0002 push {r1} + 5f8: e92d0001 push {r0} + 5fc: e3a00009 mov r0, #9 + 600: ef000040 svc 0x00000040 + 604: e8bd0002 pop {r1} + 608: e8bd0002 pop {r1} + 60c: e8bd0004 pop {r2} + 610: e8bd0008 pop {r3} + 614: e8bd4000 pop {lr} + 618: e12fff1e bx lr + +0000061c : + 61c: e92d4000 push {lr} + 620: e92d0008 push {r3} + 624: e92d0004 push {r2} + 628: e92d0002 push {r1} + 62c: e92d0001 push {r0} + 630: e3a0000a mov r0, #10 + 634: ef000040 svc 0x00000040 + 638: e8bd0002 pop {r1} + 63c: e8bd0002 pop {r1} + 640: e8bd0004 pop {r2} + 644: e8bd0008 pop {r3} + 648: e8bd4000 pop {lr} + 64c: e12fff1e bx lr + +00000650 : + 650: e92d4000 push {lr} + 654: e92d0008 push {r3} + 658: e92d0004 push {r2} + 65c: e92d0002 push {r1} + 660: e92d0001 push {r0} + 664: e3a0000b mov r0, #11 + 668: ef000040 svc 0x00000040 + 66c: e8bd0002 pop {r1} + 670: e8bd0002 pop {r1} + 674: e8bd0004 pop {r2} + 678: e8bd0008 pop {r3} + 67c: e8bd4000 pop {lr} + 680: e12fff1e bx lr + +00000684 : + 684: e92d4000 push {lr} + 688: e92d0008 push {r3} + 68c: e92d0004 push {r2} + 690: e92d0002 push {r1} + 694: e92d0001 push {r0} + 698: e3a0000c mov r0, #12 + 69c: ef000040 svc 0x00000040 + 6a0: e8bd0002 pop {r1} + 6a4: e8bd0002 pop {r1} + 6a8: e8bd0004 pop {r2} + 6ac: e8bd0008 pop {r3} + 6b0: e8bd4000 pop {lr} + 6b4: e12fff1e bx lr + +000006b8 : + 6b8: e92d4000 push {lr} + 6bc: e92d0008 push {r3} + 6c0: e92d0004 push {r2} + 6c4: e92d0002 push {r1} + 6c8: e92d0001 push {r0} + 6cc: e3a0000d mov r0, #13 + 6d0: ef000040 svc 0x00000040 + 6d4: e8bd0002 pop {r1} + 6d8: e8bd0002 pop {r1} + 6dc: e8bd0004 pop {r2} + 6e0: e8bd0008 pop {r3} + 6e4: e8bd4000 pop {lr} + 6e8: e12fff1e bx lr + +000006ec : + 6ec: e92d4000 push {lr} + 6f0: e92d0008 push {r3} + 6f4: e92d0004 push {r2} + 6f8: e92d0002 push {r1} + 6fc: e92d0001 push {r0} + 700: e3a0000e mov r0, #14 + 704: ef000040 svc 0x00000040 + 708: e8bd0002 pop {r1} + 70c: e8bd0002 pop {r1} + 710: e8bd0004 pop {r2} + 714: e8bd0008 pop {r3} + 718: e8bd4000 pop {lr} + 71c: e12fff1e bx lr + +00000720 : +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 720: e92d4800 push {fp, lr} + 724: e28db004 add fp, sp, #4 + 728: e24b3004 sub r3, fp, #4 + 72c: e24dd008 sub sp, sp, #8 + write(fd, &c, 1); + 730: e3a02001 mov r2, #1 +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 734: e5631001 strb r1, [r3, #-1]! + write(fd, &c, 1); + 738: e1a01003 mov r1, r3 + 73c: ebffff27 bl 3e0 +} + 740: e24bd004 sub sp, fp, #4 + 744: e8bd8800 pop {fp, pc} + +00000748 : + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 748: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 74c: e1a04000 mov r4, r0 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 750: e1a00fa1 lsr r0, r1, #31 + 754: e3530000 cmp r3, #0 + 758: 03a03000 moveq r3, #0 + 75c: 12003001 andne r3, r0, #1 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 760: e28db020 add fp, sp, #32 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 764: e3530000 cmp r3, #0 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 768: e24dd014 sub sp, sp, #20 + 76c: e59f909c ldr r9, [pc, #156] ; 810 + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + x = -xx; + 770: 12611000 rsbne r1, r1, #0 + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + 774: 13a03001 movne r3, #1 + } else { + x = xx; + } + + b = base; + i = 0; + 778: e3a0a000 mov sl, #0 + 77c: e24b6034 sub r6, fp, #52 ; 0x34 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 780: e3a08001 mov r8, #1 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 784: e3a07000 mov r7, #0 + int i; + + for(i=31;i>=0;i--){ + 788: e3a0001f mov r0, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 78c: e1a0c007 mov ip, r7 + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 790: e1a0e031 lsr lr, r1, r0 + 794: e20ee001 and lr, lr, #1 + 798: e18ec08c orr ip, lr, ip, lsl #1 + if(r >= d) { + 79c: e152000c cmp r2, ip + r = r - d; + q = q | (1 << i); + 7a0: 91877018 orrls r7, r7, r8, lsl r0 + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 7a4: 9062c00c rsbls ip, r2, ip +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 7a8: e2500001 subs r0, r0, #1 + 7ac: 2afffff7 bcs 790 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 7b0: e0000792 mul r0, r2, r7 + }while((x = y) != 0); + 7b4: e3570000 cmp r7, #0 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 7b8: e0601001 rsb r1, r0, r1 + 7bc: e28a5001 add r5, sl, #1 + 7c0: e7d91001 ldrb r1, [r9, r1] + 7c4: e7c6100a strb r1, [r6, sl] + }while((x = y) != 0); + 7c8: 11a01007 movne r1, r7 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 7cc: 11a0a005 movne sl, r5 + 7d0: 1affffeb bne 784 + }while((x = y) != 0); + if(neg) + 7d4: e3530000 cmp r3, #0 + buf[i++] = '-'; + 7d8: 124b2024 subne r2, fp, #36 ; 0x24 + 7dc: 10823005 addne r3, r2, r5 + 7e0: 128a5002 addne r5, sl, #2 + + while(--i >= 0) + 7e4: e2455001 sub r5, r5, #1 + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + 7e8: 13a0202d movne r2, #45 ; 0x2d + 7ec: 15432010 strbne r2, [r3, #-16] + + while(--i >= 0) + putc(fd, buf[i]); + 7f0: e7d61005 ldrb r1, [r6, r5] + 7f4: e1a00004 mov r0, r4 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 7f8: e2455001 sub r5, r5, #1 + putc(fd, buf[i]); + 7fc: ebffffc7 bl 720 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 800: e3750001 cmn r5, #1 + 804: 1afffff9 bne 7f0 + putc(fd, buf[i]); +} + 808: e24bd020 sub sp, fp, #32 + 80c: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} + 810: 00000b78 .word 0x00000b78 + +00000814
: + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 814: e3a03000 mov r3, #0 +{ + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + 818: e92d0830 push {r4, r5, fp} + 81c: e1a02000 mov r2, r0 + 820: e28db008 add fp, sp, #8 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 824: e3a0c01f mov ip, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 828: e1a00003 mov r0, r3 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 82c: e3a05001 mov r5, #1 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 830: e1a04c32 lsr r4, r2, ip + 834: e2044001 and r4, r4, #1 + 838: e1843083 orr r3, r4, r3, lsl #1 + if(r >= d) { + 83c: e1530001 cmp r3, r1 + r = r - d; + q = q | (1 << i); + 840: 21800c15 orrcs r0, r0, r5, lsl ip + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 844: 20613003 rsbcs r3, r1, r3 +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 848: e25cc001 subs ip, ip, #1 + 84c: 2afffff7 bcs 830 + r = r - d; + q = q | (1 << i); + } + } + return q; +} + 850: e24bd008 sub sp, fp, #8 + 854: e8bd0830 pop {r4, r5, fp} + 858: e12fff1e bx lr + +0000085c : +} + +// Print to the given fd. Only understands %d, %x, %p, %s. +void +printf(int fd, char *fmt, ...) +{ + 85c: e92d000e push {r1, r2, r3} + 860: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 864: e28db020 add fp, sp, #32 + 868: e1a05000 mov r5, r0 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 86c: e59b4004 ldr r4, [fp, #4] + 870: e5d48000 ldrb r8, [r4] + 874: e3580000 cmp r8, #0 + 878: 0a000027 beq 91c + ap++; + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + 87c: e59f712c ldr r7, [pc, #300] ; 9b0 + char *s; + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + 880: e28b6008 add r6, fp, #8 +{ + char *s; + int c, i, state; + uint *ap; + + state = 0; + 884: e3a0a000 mov sl, #0 + 888: ea000008 b 8b0 + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 88c: e3580025 cmp r8, #37 ; 0x25 + state = '%'; + 890: 01a0a008 moveq sl, r8 + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 894: 0a000002 beq 8a4 + state = '%'; + } else { + putc(fd, c); + 898: e1a00005 mov r0, r5 + 89c: e1a01008 mov r1, r8 + 8a0: ebffff9e bl 720 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 8a4: e5f48001 ldrb r8, [r4, #1]! + 8a8: e3580000 cmp r8, #0 + 8ac: 0a00001a beq 91c + c = fmt[i] & 0xff; + if(state == 0){ + 8b0: e35a0000 cmp sl, #0 + 8b4: 0afffff4 beq 88c + if(c == '%'){ + state = '%'; + } else { + putc(fd, c); + } + } else if(state == '%'){ + 8b8: e35a0025 cmp sl, #37 ; 0x25 + 8bc: 1afffff8 bne 8a4 + if(c == 'd'){ + 8c0: e3580064 cmp r8, #100 ; 0x64 + 8c4: 0a00002c beq 97c + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + 8c8: e3580078 cmp r8, #120 ; 0x78 + 8cc: 13580070 cmpne r8, #112 ; 0x70 + 8d0: 13a09000 movne r9, #0 + 8d4: 03a09001 moveq r9, #1 + 8d8: 0a000013 beq 92c + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + 8dc: e3580073 cmp r8, #115 ; 0x73 + 8e0: 0a000018 beq 948 + s = "(null)"; + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + 8e4: e3580063 cmp r8, #99 ; 0x63 + 8e8: 0a00002a beq 998 + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 8ec: e3580025 cmp r8, #37 ; 0x25 + putc(fd, c); + 8f0: e1a0100a mov r1, sl + 8f4: e1a00005 mov r0, r5 + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 8f8: 0a000002 beq 908 + putc(fd, c); + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + 8fc: ebffff87 bl 720 + putc(fd, c); + 900: e1a00005 mov r0, r5 + 904: e1a01008 mov r1, r8 + 908: ebffff84 bl 720 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 90c: e5f48001 ldrb r8, [r4, #1]! + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 910: e1a0a009 mov sl, r9 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 914: e3580000 cmp r8, #0 + 918: 1affffe4 bne 8b0 + putc(fd, c); + } + state = 0; + } + } +} + 91c: e24bd020 sub sp, fp, #32 + 920: e8bd4ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 924: e28dd00c add sp, sp, #12 + 928: e12fff1e bx lr + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + 92c: e1a00005 mov r0, r5 + 930: e4961004 ldr r1, [r6], #4 + 934: e3a02010 mov r2, #16 + 938: e3a03000 mov r3, #0 + 93c: ebffff81 bl 748 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 940: e3a0a000 mov sl, #0 + 944: eaffffd6 b 8a4 + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + s = (char*)*ap; + 948: e4968004 ldr r8, [r6], #4 + ap++; + if(s == 0) + s = "(null)"; + 94c: e3580000 cmp r8, #0 + 950: 01a08007 moveq r8, r7 + while(*s != 0){ + 954: e5d81000 ldrb r1, [r8] + 958: e3510000 cmp r1, #0 + 95c: 0a000004 beq 974 + putc(fd, *s); + 960: e1a00005 mov r0, r5 + 964: ebffff6d bl 720 + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + while(*s != 0){ + 968: e5f81001 ldrb r1, [r8, #1]! + 96c: e3510000 cmp r1, #0 + 970: 1afffffa bne 960 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 974: e1a0a001 mov sl, r1 + 978: eaffffc9 b 8a4 + } else { + putc(fd, c); + } + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + 97c: e1a00005 mov r0, r5 + 980: e4961004 ldr r1, [r6], #4 + 984: e3a0200a mov r2, #10 + 988: e3a03001 mov r3, #1 + 98c: ebffff6d bl 748 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 990: e3a0a000 mov sl, #0 + 994: eaffffc2 b 8a4 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 998: e4961004 ldr r1, [r6], #4 + 99c: e1a00005 mov r0, r5 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 9a0: e1a0a009 mov sl, r9 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 9a4: e6ef1071 uxtb r1, r1 + 9a8: ebffff5c bl 720 + 9ac: eaffffbc b 8a4 + 9b0: 00000b8c .word 0x00000b8c + +000009b4 : +free(void *ap) +{ + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 9b4: e59f3098 ldr r3, [pc, #152] ; a54 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 9b8: e92d0830 push {r4, r5, fp} + Header *bp, *p; + + bp = (Header*)ap - 1; + 9bc: e240c008 sub ip, r0, #8 + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 9c0: e5932000 ldr r2, [r3] +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 9c4: e28db008 add fp, sp, #8 + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 9c8: e152000c cmp r2, ip + 9cc: e5921000 ldr r1, [r2] + 9d0: 2a000001 bcs 9dc + 9d4: e15c0001 cmp ip, r1 + 9d8: 3a000007 bcc 9fc + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + 9dc: e1520001 cmp r2, r1 + 9e0: 3a000003 bcc 9f4 + 9e4: e152000c cmp r2, ip + 9e8: 3a000003 bcc 9fc + 9ec: e15c0001 cmp ip, r1 + 9f0: 3a000001 bcc 9fc +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 9f4: e1a02001 mov r2, r1 + 9f8: eafffff2 b 9c8 + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + 9fc: e5104004 ldr r4, [r0, #-4] + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + freep = p; + a00: e5832000 str r2, [r3] + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + a04: e08c5184 add r5, ip, r4, lsl #3 + a08: e1550001 cmp r5, r1 + bp->s.size += p->s.ptr->s.size; + a0c: 05911004 ldreq r1, [r1, #4] + a10: 00814004 addeq r4, r1, r4 + a14: 05004004 streq r4, [r0, #-4] + bp->s.ptr = p->s.ptr->s.ptr; + a18: 05921000 ldreq r1, [r2] + a1c: 05911000 ldreq r1, [r1] + } else + bp->s.ptr = p->s.ptr; + a20: e5001008 str r1, [r0, #-8] + if(p + p->s.size == bp){ + a24: e5921004 ldr r1, [r2, #4] + a28: e0824181 add r4, r2, r1, lsl #3 + a2c: e15c0004 cmp ip, r4 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + a30: 1582c000 strne ip, [r2] + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + } else + bp->s.ptr = p->s.ptr; + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + a34: 0510c004 ldreq ip, [r0, #-4] + a38: 008c1001 addeq r1, ip, r1 + a3c: 05821004 streq r1, [r2, #4] + p->s.ptr = bp->s.ptr; + a40: 05101008 ldreq r1, [r0, #-8] + a44: 05821000 streq r1, [r2] + } else + p->s.ptr = bp; + freep = p; +} + a48: e24bd008 sub sp, fp, #8 + a4c: e8bd0830 pop {r4, r5, fp} + a50: e12fff1e bx lr + a54: 00000b94 .word 0x00000b94 + +00000a58 : + return freep; +} + +void* +malloc(uint nbytes) +{ + a58: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + a5c: e2804007 add r4, r0, #7 + if((prevp = freep) == 0){ + a60: e59f50d4 ldr r5, [pc, #212] ; b3c +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + a64: e1a041a4 lsr r4, r4, #3 + return freep; +} + +void* +malloc(uint nbytes) +{ + a68: e28db01c add fp, sp, #28 + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + a6c: e5953000 ldr r3, [r5] +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + a70: e2844001 add r4, r4, #1 + if((prevp = freep) == 0){ + a74: e3530000 cmp r3, #0 + a78: 0a00002b beq b2c + a7c: e5930000 ldr r0, [r3] + a80: e5902004 ldr r2, [r0, #4] + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + a84: e1520004 cmp r2, r4 + a88: 2a00001b bcs afc +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + a8c: e59f80ac ldr r8, [pc, #172] ; b40 + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + a90: e1a07184 lsl r7, r4, #3 + a94: ea000003 b aa8 + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + a98: e5930000 ldr r0, [r3] + if(p->s.size >= nunits){ + a9c: e5902004 ldr r2, [r0, #4] + aa0: e1540002 cmp r4, r2 + aa4: 9a000014 bls afc + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + aa8: e5952000 ldr r2, [r5] + aac: e1a03000 mov r3, r0 + ab0: e1500002 cmp r0, r2 + ab4: 1afffff7 bne a98 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + ab8: e1540008 cmp r4, r8 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + abc: 81a00007 movhi r0, r7 + ac0: 93a00902 movls r0, #32768 ; 0x8000 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + ac4: 81a06004 movhi r6, r4 + ac8: 93a06a01 movls r6, #4096 ; 0x1000 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + acc: ebfffeec bl 684 + ad0: e1a03000 mov r3, r0 + if(p == (char*)-1) + ad4: e3730001 cmn r3, #1 + return 0; + hp = (Header*)p; + hp->s.size = nu; + free((void*)(hp + 1)); + ad8: e2800008 add r0, r0, #8 + Header *hp; + + if(nu < 4096) + nu = 4096; + p = sbrk(nu * sizeof(Header)); + if(p == (char*)-1) + adc: 0a000010 beq b24 + return 0; + hp = (Header*)p; + hp->s.size = nu; + ae0: e5836004 str r6, [r3, #4] + free((void*)(hp + 1)); + ae4: ebffffb2 bl 9b4 + return freep; + ae8: e5953000 ldr r3, [r5] + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + if((p = morecore(nunits)) == 0) + aec: e3530000 cmp r3, #0 + af0: 1affffe8 bne a98 + return 0; + af4: e1a00003 mov r0, r3 + } +} + af8: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + afc: e1540002 cmp r4, r2 + prevp->s.ptr = p->s.ptr; + else { + p->s.size -= nunits; + b00: 10642002 rsbne r2, r4, r2 + b04: 15802004 strne r2, [r0, #4] + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + b08: 05902000 ldreq r2, [r0] + else { + p->s.size -= nunits; + p += p->s.size; + b0c: 10800182 addne r0, r0, r2, lsl #3 + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + b10: 05832000 streq r2, [r3] + else { + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + b14: 15804004 strne r4, [r0, #4] + } + freep = prevp; + b18: e5853000 str r3, [r5] + return (void*)(p + 1); + b1c: e2800008 add r0, r0, #8 + b20: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + } + if(p == freep) + if((p = morecore(nunits)) == 0) + return 0; + b24: e3a00000 mov r0, #0 + b28: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + b2c: e2850004 add r0, r5, #4 + b30: e5850000 str r0, [r5] + base.s.size = 0; + b34: e9850009 stmib r5, {r0, r3} + b38: eaffffd3 b a8c + b3c: 00000b94 .word 0x00000b94 + b40: 00000fff .word 0x00000fff diff -r 000000000000 -r c450faca55f4 uprogs/mkdir.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/mkdir.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,23 @@ +#include "types.h" +#include "stat.h" +#include "user.h" + +int +main(int argc, char *argv[]) +{ + int i; + + if(argc < 2){ + printf(2, "Usage: mkdir files...\n"); + exit(); + } + + for(i = 1; i < argc; i++){ + if(mkdir(argv[i]) < 0){ + printf(2, "mkdir: %s failed to create\n", argv[i]); + break; + } + } + + exit(); +} diff -r 000000000000 -r c450faca55f4 uprogs/mkdir.sym --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/mkdir.sym Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,64 @@ +00000000 .text +00000b44 .rodata +00000b94 .bss +00000000 .comment +00000000 .ARM.attributes +00000000 .debug_aranges +00000000 .debug_info +00000000 .debug_abbrev +00000000 .debug_line +00000000 .debug_frame +00000000 .debug_str +00000000 .debug_loc +00000000 .debug_ranges +00000000 mkdir.c +00000000 ulib.c +00000000 printf.c +00000720 putc +00000748 printint +00000b78 digits.993 +00000000 umalloc.c +00000b94 freep +00000b98 base +00000070 strcpy +0000085c printf +000002a8 memmove +000004e4 mknod +00000ba0 _bss_end__ +000001a0 gets +00000650 getpid +00000a58 malloc +000006b8 sleep +00000b94 __bss_start__ +00000378 pipe +000003e0 write +0000054c fstat +00000448 kill +000005e8 chdir +0000047c exec +00000ba0 __bss_end__ +00000344 wait +000003ac read +00000518 unlink +000002dc fork +00000684 sbrk +000006ec uptime +00000b94 __bss_start +00000124 memset +00000000 main +00000ba0 __end__ +00000098 strcmp +0000061c dup +00000218 stat +00000b94 _edata +00000ba0 _end +00000580 link +00000310 exit +00000254 atoi +000000e4 strlen +000004b0 open +00000814 div +0000015c strchr +000005b4 mkdir +00000414 close +000009b4 free diff -r 000000000000 -r c450faca55f4 uprogs/mkfs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/mkfs.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,298 @@ +#include +#include +#include +#include +#include +#include + +#define stat xv6_stat // avoid clash with host struct stat +#include "types.h" +#include "fs.h" +#include "stat.h" +#include "param.h" + +#define static_assert(a, b) do { switch (0) case 0: case (a): ; } while (0) + +int nblocks = 985; +int nlog = LOGSIZE; +int ninodes = 200; +int size = 1024; + +int fsfd; +struct superblock sb; +char zeroes[512]; +uint freeblock; +uint usedblocks; +uint bitblocks; +uint freeinode = 1; + +void balloc(int); +void wsect(uint, void*); +void winode(uint, struct dinode*); +void rinode(uint inum, struct dinode *ip); +void rsect(uint sec, void *buf); +uint ialloc(ushort type); +void iappend(uint inum, void *p, int n); + +// convert to intel byte order +ushort +xshort(ushort x) +{ + ushort y; + uchar *a = (uchar*)&y; + a[0] = x; + a[1] = x >> 8; + return y; +} + +uint +xint(uint x) +{ + uint y; + uchar *a = (uchar*)&y; + a[0] = x; + a[1] = x >> 8; + a[2] = x >> 16; + a[3] = x >> 24; + return y; +} + +int +main(int argc, char *argv[]) +{ + int i, cc, fd; + uint rootino, inum, off; + struct dirent de; + char buf[512]; + struct dinode din; + + + static_assert(sizeof(int) == 4, "Integers must be 4 bytes!"); + + if(argc < 2){ + fprintf(stderr, "Usage: mkfs fs.img files...\n"); + exit(1); + } + + assert((512 % sizeof(struct dinode)) == 0); + assert((512 % sizeof(struct dirent)) == 0); + + fsfd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666); + if(fsfd < 0){ + perror(argv[1]); + exit(1); + } + + sb.size = xint(size); + sb.nblocks = xint(nblocks); // so whole disk is size sectors + sb.ninodes = xint(ninodes); + sb.nlog = xint(nlog); + + bitblocks = size/(512*8) + 1; + usedblocks = ninodes / IPB + 3 + bitblocks; + freeblock = usedblocks; + + printf("used %d (bit %d ninode %zu) free %u log %u total %d\n", usedblocks, + bitblocks, ninodes/IPB + 1, freeblock, nlog, nblocks+usedblocks+nlog); + + assert(nblocks + usedblocks + nlog == size); + + for(i = 0; i < nblocks + usedblocks + nlog; i++) + wsect(i, zeroes); + + memset(buf, 0, sizeof(buf)); + memmove(buf, &sb, sizeof(sb)); + wsect(1, buf); + + rootino = ialloc(T_DIR); + assert(rootino == ROOTINO); + + bzero(&de, sizeof(de)); + de.inum = xshort(rootino); + strcpy(de.name, "."); + iappend(rootino, &de, sizeof(de)); + + bzero(&de, sizeof(de)); + de.inum = xshort(rootino); + strcpy(de.name, ".."); + iappend(rootino, &de, sizeof(de)); + + for(i = 2; i < argc; i++){ + assert(index(argv[i], '/') == 0); + + if((fd = open(argv[i], 0)) < 0){ + perror(argv[i]); + exit(1); + } + + // Skip leading _ in name when writing to file system. + // The binaries are named _rm, _cat, etc. to keep the + // build operating system from trying to execute them + // in place of system binaries like rm and cat. + if(argv[i][0] == '_') + ++argv[i]; + + inum = ialloc(T_FILE); + + bzero(&de, sizeof(de)); + de.inum = xshort(inum); + strncpy(de.name, argv[i], DIRSIZ); + iappend(rootino, &de, sizeof(de)); + + while((cc = read(fd, buf, sizeof(buf))) > 0) + iappend(inum, buf, cc); + + close(fd); + } + + // fix size of root inode dir + rinode(rootino, &din); + off = xint(din.size); + off = ((off/BSIZE) + 1) * BSIZE; + din.size = xint(off); + winode(rootino, &din); + + balloc(usedblocks); + + exit(0); +} + +void +wsect(uint sec, void *buf) +{ + if(lseek(fsfd, sec * 512L, 0) != sec * 512L){ + perror("lseek"); + exit(1); + } + if(write(fsfd, buf, 512) != 512){ + perror("write"); + exit(1); + } +} + +uint +i2b(uint inum) +{ + return (inum / IPB) + 2; +} + +void +winode(uint inum, struct dinode *ip) +{ + char buf[512]; + uint bn; + struct dinode *dip; + + bn = i2b(inum); + rsect(bn, buf); + dip = ((struct dinode*)buf) + (inum % IPB); + *dip = *ip; + wsect(bn, buf); +} + +void +rinode(uint inum, struct dinode *ip) +{ + char buf[512]; + uint bn; + struct dinode *dip; + + bn = i2b(inum); + rsect(bn, buf); + dip = ((struct dinode*)buf) + (inum % IPB); + *ip = *dip; +} + +void +rsect(uint sec, void *buf) +{ + if(lseek(fsfd, sec * 512L, 0) != sec * 512L){ + perror("lseek"); + exit(1); + } + if(read(fsfd, buf, 512) != 512){ + perror("read"); + exit(1); + } +} + +uint +ialloc(ushort type) +{ + uint inum = freeinode++; + struct dinode din; + + bzero(&din, sizeof(din)); + din.type = xshort(type); + din.nlink = xshort(1); + din.size = xint(0); + winode(inum, &din); + return inum; +} + +void +balloc(int used) +{ + uchar buf[512]; + int i; + + printf("balloc: first %d blocks have been allocated\n", used); + assert(used < 512*8); + bzero(buf, 512); + for(i = 0; i < used; i++){ + buf[i/8] = buf[i/8] | (0x1 << (i%8)); + } + printf("balloc: write bitmap block at sector %zu\n", ninodes/IPB + 3); + wsect(ninodes / IPB + 3, buf); +} + +#define min(a, b) ((a) < (b) ? (a) : (b)) + +void +iappend(uint inum, void *xp, int n) +{ + char *p = (char*)xp; + uint fbn, off, n1; + struct dinode din; + char buf[512]; + uint indirect[NINDIRECT]; + uint x; + + rinode(inum, &din); + + off = xint(din.size); + while(n > 0){ + fbn = off / 512; + assert(fbn < MAXFILE); + if(fbn < NDIRECT){ + if(xint(din.addrs[fbn]) == 0){ + din.addrs[fbn] = xint(freeblock++); + usedblocks++; + } + x = xint(din.addrs[fbn]); + } else { + if(xint(din.addrs[NDIRECT]) == 0){ + // printf("allocate indirect block\n"); + din.addrs[NDIRECT] = xint(freeblock++); + usedblocks++; + } + // printf("read indirect block\n"); + rsect(xint(din.addrs[NDIRECT]), (char*)indirect); + if(indirect[fbn - NDIRECT] == 0){ + indirect[fbn - NDIRECT] = xint(freeblock++); + usedblocks++; + wsect(xint(din.addrs[NDIRECT]), (char*)indirect); + } + x = xint(indirect[fbn-NDIRECT]); + } + n1 = min(n, (fbn + 1) * 512 - off); + rsect(x, buf); + bcopy(p, buf + off - (fbn * 512), n1); + wsect(x, buf); + n -= n1; + off += n1; + p += n1; + } + din.size = xint(off); + winode(inum, &din); +} diff -r 000000000000 -r c450faca55f4 uprogs/mmu.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/mmu.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,86 @@ +#define MByte 0x100000 +#define L1 0x4000 +#define L2 0x3000 + +#define CACHELINESIZE 32 + +#define FEXT(d, o, w) (((d)>>(o)) & ((1<<(w))-1)) +#define L1X(va) FEXT((va), 20, 12) +#define L2X(va) FEXT((va), 12, 8) + +/* + * page table entries. +*/ + +#define Mbz (0<<4) +#define Fault 0x00000000 /* L[12] pte: unmapped */ + +#define Coarse (Mbz|1) /* L1 */ +#define Section (Mbz|2) /* L1 1MB */ +#define Fine (Mbz|3) /* L1 */ + +#define Large 0x00000001 /* L2 64KB */ +#define Small 0x00000002 /* L2 4KB */ +#define Tiny 0x00000003 /* L2 1KB: not in v7 */ +#define Buffered 0x00000004 /* L[12]: write-back not -thru */ +#define Cached 0x00000008 /* L[12] */ +#define Dom0 0 + +#define Noaccess 0 /* AP, DAC */ +#define Krw 1 /* AP */ +/* armv7 deprecates AP[2] == 1 & AP[1:0] == 2 (Uro), prefers 3 (new in v7) */ +#define Uro 2 /* AP */ +#define Urw 3 /* AP */ +#define Client 1 /* DAC */ +#define Manager 3 /* DAC */ + +#define F(v, o, w) (((v) & ((1<<(w))-1))<<(o)) +#define AP(n, v) F((v), ((n)*2)+4, 2) +#define L1AP(ap) (AP(3, (ap))) +#define L2AP(ap) (AP(3, (ap))|AP(2, (ap))|AP(1, (ap))|AP(0, (ap))) /* pre-armv7 */ +#define DAC(n, v) F((v), (n)*2, 2) + +#define HVECTORS 0xffff0000 + +// A virtual address 'la' has a three-part structure as follows: +// +// +--------12------+-------8--------+---------12----------+ +// | Page Directory | Page Table | Offset within Page | +// | Index | Index | | +// +----------------+----------------+---------------------+ +// \--- PDX(va) --/ \--- PTX(va) --/ + +// page directory index +#define PDX(va) (((uint)(va) >> PDXSHIFT) & 0xFFF) + +// page table index +#define PTX(va) (((uint)(va) >> PTXSHIFT) & 0xFF) + +// construct virtual address from indexes and offset +#define PGADDR(d, t, o) ((uint)((d) << PDXSHIFT | (t) << PTXSHIFT | (o))) + +// Address in page table or page directory entry +#define PTE_ADDR(pte) ((uint)(pte) & ~0xFFF) +#define PTE_FLAGS(pte) ((uint)(pte) & 0xFFF) + +// Page directory and page table constants. +#define NPDENTRIES 1024 // # directory entries per page directory +#define NPTENTRIES 1024 // # PTEs per page table +#define PGSIZE 4096 // bytes mapped by a page + +#define PGSHIFT 12 // log2(PGSIZE) +#define PTXSHIFT 12 // offset of PTX in a linear address +#define PDXSHIFT 20 // offset of PDX in a linear address + + +#define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1)) +#define PGROUNDDOWN(a) (((a)) & ~(PGSIZE-1)) + +#define PGDIR_BASE P2V(L1) + +#define KVML1ATTR Dom0|L1AP(Urw)|Section|Cached|Buffered + +#define UVML1ATTR Dom0|Coarse +#define UVML2ATTR L2AP(Urw)|Cached|Buffered|Small + +#define USER_MODE 0 diff -r 000000000000 -r c450faca55f4 uprogs/param.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/param.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,12 @@ +#define NPROC 64 // maximum number of processes +#define KSTACKSIZE 4096 // size of per-process kernel stack +#define NCPU 8 // maximum number of CPUs +#define NOFILE 16 // open files per process +#define NFILE 100 // open files per system +#define NBUF 10 // size of disk block cache +#define NINODE 50 // maximum number of active i-nodes +#define NDEV 10 // maximum major device number +#define ROOTDEV 1 // device number of file system root disk +#define MAXARG 32 // max exec arguments +#define LOGSIZE 10 // max data sectors in on-disk log + diff -r 000000000000 -r c450faca55f4 uprogs/printf.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/printf.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,103 @@ +#include "types.h" +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + } + } + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + static char digits[] = "0123456789ABCDEF"; + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + x = -xx; + } else { + x = xx; + } + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + putc(fd, buf[i]); +} + +// Print to the given fd. Only understands %d, %x, %p, %s. +void +printf(int fd, char *fmt, ...) +{ + char *s; + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + state = '%'; + } else { + putc(fd, c); + } + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + ap++; + } else if(c == '%'){ + putc(fd, c); + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + } + } +} diff -r 000000000000 -r c450faca55f4 uprogs/proc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/proc.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,82 @@ +// Segments in proc->gdt. +#define NSEGS 7 + +// Per-CPU state +struct cpu { + uchar id; // Local APIC ID; index into cpus[] below + struct context *scheduler; // swtch() here to enter scheduler + volatile uint started; // Has the CPU started? + int ncli; // Depth of pushcli nesting. + int intena; // Were interrupts enabled before pushcli? + + // Cpu-local storage variables; see below + struct cpu *cpu; + struct proc *proc; // The currently-running process. +}; + +struct cpu cpus[NCPU]; +//extern int ncpu; + +// Per-CPU variables, holding pointers to the +// current cpu and to the current process. +// The asm suffix tells gcc to use "%gs:0" to refer to cpu +// and "%gs:4" to refer to proc. seginit sets up the +// %gs segment register so that %gs refers to the memory +// holding those two variables in the local cpu's struct cpu. +// This is similar to how thread-local variables are implemented +// in thread libraries such as Linux pthreads. +//extern struct cpu *cpu asm("%gs:0"); // &cpus[cpunum()] +//extern struct proc *proc asm("%gs:4"); // cpus[cpunum()].proc + +#define curr_cpu (&cpus[0]) +#define curr_proc (cpus[0].proc) + +//PAGEBREAK: 17 +// Saved registers for kernel context switches. +// Don't need to save all the segment registers (%cs, etc), +// because they are constant across kernel contexts. +// Don't need to save %eax, %ecx, %edx, because the +// x86 convention is that the caller has saved them. +// Contexts are stored at the bottom of the stack they +// describe; the stack pointer is the address of the context. +// The layout of the context matches the layout of the stack in swtch.S +// at the "Switch stacks" comment. Switch doesn't save eip explicitly, +// but it is on the stack and allocproc() manipulates it. +struct context { + uint r4; + uint r5; + uint r6; + uint r7; + uint r8; + uint r9; + uint r10; + uint r11; + uint r12; + uint lr; + uint pc; +}; + +enum procstate { UNUSED=0, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE }; + +// Per-process state +struct proc { + uint sz; // Size of process memory (bytes) + pde_t* pgdir; // Page table + char *kstack; // Bottom of kernel stack for this process + enum procstate state; // Process state + volatile int pid; // Process ID + struct proc *parent; // Parent process + struct trapframe *tf; // Trap frame for current syscall + struct context *context; // swtch() here to run process + void *chan; // If non-zero, sleeping on chan + int killed; // If non-zero, have been killed + struct file *ofile[NOFILE]; // Open files + struct inode *cwd; // Current directory + char name[16]; // Process name (debugging) +}; + +// Process memory is laid out contiguously, low addresses first: +// text +// original data and bss +// fixed-size stack +// expandable heap diff -r 000000000000 -r c450faca55f4 uprogs/rm.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/rm.asm Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,1707 @@ + +_rm: file format elf32-littlearm + + +Disassembly of section .text: + +00000000
: +int +main(int argc, char *argv[]) +{ + int i; + + if(argc < 2){ + 0: e3500001 cmp r0, #1 +#include "stat.h" +#include "user.h" + +int +main(int argc, char *argv[]) +{ + 4: e92d48f0 push {r4, r5, r6, r7, fp, lr} + 8: e1a05000 mov r5, r0 + c: e28db014 add fp, sp, #20 +#include "types.h" +#include "stat.h" +#include "user.h" + +int +main(int argc, char *argv[]) + 10: c2816004 addgt r6, r1, #4 + 14: c3a07001 movgt r7, #1 +{ + int i; + + if(argc < 2){ + 18: da00000e ble 58 + printf(2, "Usage: rm files...\n"); + exit(); + } + + for(i = 1; i < argc; i++){ + if(unlink(argv[i]) < 0){ + 1c: e1a04006 mov r4, r6 + 20: e2866004 add r6, r6, #4 + 24: e5940000 ldr r0, [r4] + 28: eb00013a bl 518 + 2c: e3500000 cmp r0, #0 + 30: ba000003 blt 44 + if(argc < 2){ + printf(2, "Usage: rm files...\n"); + exit(); + } + + for(i = 1; i < argc; i++){ + 34: e2877001 add r7, r7, #1 + 38: e1570005 cmp r7, r5 + 3c: 1afffff6 bne 1c + printf(2, "rm: %s failed to delete\n", argv[i]); + break; + } + } + + exit(); + 40: eb0000b2 bl 310 + exit(); + } + + for(i = 1; i < argc; i++){ + if(unlink(argv[i]) < 0){ + printf(2, "rm: %s failed to delete\n", argv[i]); + 44: e3a00002 mov r0, #2 + 48: e59f1018 ldr r1, [pc, #24] ; 68 + 4c: e5942000 ldr r2, [r4] + 50: eb000201 bl 85c + break; + } + } + + exit(); + 54: eb0000ad bl 310 +main(int argc, char *argv[]) +{ + int i; + + if(argc < 2){ + printf(2, "Usage: rm files...\n"); + 58: e3a00002 mov r0, #2 + 5c: e59f1008 ldr r1, [pc, #8] ; 6c + 60: eb0001fd bl 85c + exit(); + 64: eb0000a9 bl 310 + 68: 00000b58 .word 0x00000b58 + 6c: 00000b44 .word 0x00000b44 + +00000070 : +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 70: e52db004 push {fp} ; (str fp, [sp, #-4]!) + char *os; + + os = s; + while((*s++ = *t++) != 0) + 74: e1a02000 mov r2, r0 +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 78: e28db000 add fp, sp, #0 + char *os; + + os = s; + while((*s++ = *t++) != 0) + 7c: e4d13001 ldrb r3, [r1], #1 + 80: e3530000 cmp r3, #0 + 84: e4c23001 strb r3, [r2], #1 + 88: 1afffffb bne 7c + ; + return os; +} + 8c: e28bd000 add sp, fp, #0 + 90: e8bd0800 pop {fp} + 94: e12fff1e bx lr + +00000098 : + +int +strcmp(const char *p, const char *q) +{ + 98: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 9c: e28db000 add fp, sp, #0 + while(*p && *p == *q) + a0: e5d03000 ldrb r3, [r0] + a4: e5d12000 ldrb r2, [r1] + a8: e3530000 cmp r3, #0 + ac: 1a000004 bne c4 + b0: ea000005 b cc + b4: e5f03001 ldrb r3, [r0, #1]! + b8: e3530000 cmp r3, #0 + bc: 0a000006 beq dc + c0: e5f12001 ldrb r2, [r1, #1]! + c4: e1530002 cmp r3, r2 + c8: 0afffff9 beq b4 + p++, q++; + return (uchar)*p - (uchar)*q; +} + cc: e0620003 rsb r0, r2, r3 + d0: e28bd000 add sp, fp, #0 + d4: e8bd0800 pop {fp} + d8: e12fff1e bx lr +} + +int +strcmp(const char *p, const char *q) +{ + while(*p && *p == *q) + dc: e5d12001 ldrb r2, [r1, #1] + e0: eafffff9 b cc + +000000e4 : + return (uchar)*p - (uchar)*q; +} + +uint +strlen(char *s) +{ + e4: e52db004 push {fp} ; (str fp, [sp, #-4]!) + e8: e28db000 add fp, sp, #0 + int n; + + for(n = 0; s[n]; n++) + ec: e5d03000 ldrb r3, [r0] + f0: e3530000 cmp r3, #0 + f4: 01a00003 moveq r0, r3 + f8: 0a000006 beq 118 + fc: e1a02000 mov r2, r0 + 100: e3a03000 mov r3, #0 + 104: e5f21001 ldrb r1, [r2, #1]! + 108: e2833001 add r3, r3, #1 + 10c: e1a00003 mov r0, r3 + 110: e3510000 cmp r1, #0 + 114: 1afffffa bne 104 + ; + return n; +} + 118: e28bd000 add sp, fp, #0 + 11c: e8bd0800 pop {fp} + 120: e12fff1e bx lr + +00000124 : +memset(void *dst, int c, uint n) +{ + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 124: e3520000 cmp r2, #0 + return n; +} + +void* +memset(void *dst, int c, uint n) +{ + 128: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 12c: e28db000 add fp, sp, #0 + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 130: 0a000006 beq 150 + 134: e6ef1071 uxtb r1, r1 + 138: e1a03002 mov r3, r2 +} + +void* +memset(void *dst, int c, uint n) +{ + char *p=dst; + 13c: e1a0c000 mov ip, r0 + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 140: e2533001 subs r3, r3, #1 + 144: e4cc1001 strb r1, [ip], #1 + 148: 1afffffc bne 140 + 14c: e0800002 add r0, r0, r2 + return (void *)p; +} + 150: e28bd000 add sp, fp, #0 + 154: e8bd0800 pop {fp} + 158: e12fff1e bx lr + +0000015c : + +char* +strchr(const char *s, char c) +{ + 15c: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 160: e28db000 add fp, sp, #0 + for(; *s; s++) + 164: e5d03000 ldrb r3, [r0] + 168: e3530000 cmp r3, #0 + 16c: 1a000004 bne 184 + 170: ea000008 b 198 + 174: e5d03001 ldrb r3, [r0, #1] + 178: e2800001 add r0, r0, #1 + 17c: e3530000 cmp r3, #0 + 180: 0a000004 beq 198 + if(*s == c) + 184: e1530001 cmp r3, r1 + 188: 1afffff9 bne 174 + return (char*)s; + return 0; +} + 18c: e28bd000 add sp, fp, #0 + 190: e8bd0800 pop {fp} + 194: e12fff1e bx lr +strchr(const char *s, char c) +{ + for(; *s; s++) + if(*s == c) + return (char*)s; + return 0; + 198: e1a00003 mov r0, r3 + 19c: eafffffa b 18c + +000001a0 : +} + +char* +gets(char *buf, int max) +{ + 1a0: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + 1a4: e28db018 add fp, sp, #24 + 1a8: e24dd00c sub sp, sp, #12 + 1ac: e1a08000 mov r8, r0 + 1b0: e1a07001 mov r7, r1 + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 1b4: e1a06000 mov r6, r0 + 1b8: e3a05000 mov r5, #0 + 1bc: ea000008 b 1e4 + cc = read(0, &c, 1); + 1c0: eb000079 bl 3ac + if(cc < 1) + 1c4: e3500000 cmp r0, #0 + 1c8: da00000b ble 1fc + break; + buf[i++] = c; + 1cc: e55b301d ldrb r3, [fp, #-29] + if(c == '\n' || c == '\r') + 1d0: e1a05004 mov r5, r4 + 1d4: e353000a cmp r3, #10 + 1d8: 1353000d cmpne r3, #13 + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + if(cc < 1) + break; + buf[i++] = c; + 1dc: e4c63001 strb r3, [r6], #1 + if(c == '\n' || c == '\r') + 1e0: 0a00000a beq 210 +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + 1e4: e3a02001 mov r2, #1 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 1e8: e0854002 add r4, r5, r2 + 1ec: e1540007 cmp r4, r7 + cc = read(0, &c, 1); + 1f0: e3a00000 mov r0, #0 + 1f4: e24b101d sub r1, fp, #29 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 1f8: bafffff0 blt 1c0 + break; + buf[i++] = c; + if(c == '\n' || c == '\r') + break; + } + buf[i] = '\0'; + 1fc: e3a03000 mov r3, #0 + 200: e7c83005 strb r3, [r8, r5] + return buf; +} + 204: e1a00008 mov r0, r8 + 208: e24bd018 sub sp, fp, #24 + 20c: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 210: e1a05004 mov r5, r4 + 214: eafffff8 b 1fc + +00000218 : + return buf; +} + +int +stat(char *n, struct stat *st) +{ + 218: e92d4830 push {r4, r5, fp, lr} + 21c: e1a05001 mov r5, r1 + 220: e28db00c add fp, sp, #12 + int fd; + int r; + + fd = open(n, O_RDONLY); + 224: e3a01000 mov r1, #0 + 228: eb0000a0 bl 4b0 + if(fd < 0) + 22c: e2504000 subs r4, r0, #0 + return -1; + 230: b3e05000 mvnlt r5, #0 +{ + int fd; + int r; + + fd = open(n, O_RDONLY); + if(fd < 0) + 234: ba000004 blt 24c + return -1; + r = fstat(fd, st); + 238: e1a01005 mov r1, r5 + 23c: eb0000c2 bl 54c + 240: e1a05000 mov r5, r0 + close(fd); + 244: e1a00004 mov r0, r4 + 248: eb000071 bl 414 + return r; +} + 24c: e1a00005 mov r0, r5 + 250: e8bd8830 pop {r4, r5, fp, pc} + +00000254 : + +int +atoi(const char *s) +{ + 254: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 258: e28db000 add fp, sp, #0 + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 25c: e5d03000 ldrb r3, [r0] + 260: e2432030 sub r2, r3, #48 ; 0x30 + 264: e6ef2072 uxtb r2, r2 + 268: e3520009 cmp r2, #9 +int +atoi(const char *s) +{ + int n; + + n = 0; + 26c: 83a00000 movhi r0, #0 + while('0' <= *s && *s <= '9') + 270: 8a000009 bhi 29c + 274: e1a02000 mov r2, r0 +int +atoi(const char *s) +{ + int n; + + n = 0; + 278: e3a00000 mov r0, #0 + while('0' <= *s && *s <= '9') + n = n*10 + *s++ - '0'; + 27c: e0800100 add r0, r0, r0, lsl #2 + 280: e0830080 add r0, r3, r0, lsl #1 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 284: e5f23001 ldrb r3, [r2, #1]! + n = n*10 + *s++ - '0'; + 288: e2400030 sub r0, r0, #48 ; 0x30 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 28c: e2431030 sub r1, r3, #48 ; 0x30 + 290: e6ef1071 uxtb r1, r1 + 294: e3510009 cmp r1, #9 + 298: 9afffff7 bls 27c + n = n*10 + *s++ - '0'; + return n; +} + 29c: e28bd000 add sp, fp, #0 + 2a0: e8bd0800 pop {fp} + 2a4: e12fff1e bx lr + +000002a8 : +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 2a8: e3520000 cmp r2, #0 + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) +{ + 2ac: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 2b0: e28db000 add fp, sp, #0 + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 2b4: da000005 ble 2d0 + n = n*10 + *s++ - '0'; + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) + 2b8: e0802002 add r2, r0, r2 +{ + char *dst, *src; + + dst = vdst; + 2bc: e1a03000 mov r3, r0 + src = vsrc; + while(n-- > 0) + *dst++ = *src++; + 2c0: e4d1c001 ldrb ip, [r1], #1 + 2c4: e4c3c001 strb ip, [r3], #1 +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 2c8: e1530002 cmp r3, r2 + 2cc: 1afffffb bne 2c0 + *dst++ = *src++; + return vdst; +} + 2d0: e28bd000 add sp, fp, #0 + 2d4: e8bd0800 pop {fp} + 2d8: e12fff1e bx lr + +000002dc : + 2dc: e92d4000 push {lr} + 2e0: e92d0008 push {r3} + 2e4: e92d0004 push {r2} + 2e8: e92d0002 push {r1} + 2ec: e92d0001 push {r0} + 2f0: e3a00001 mov r0, #1 + 2f4: ef000040 svc 0x00000040 + 2f8: e8bd0002 pop {r1} + 2fc: e8bd0002 pop {r1} + 300: e8bd0004 pop {r2} + 304: e8bd0008 pop {r3} + 308: e8bd4000 pop {lr} + 30c: e12fff1e bx lr + +00000310 : + 310: e92d4000 push {lr} + 314: e92d0008 push {r3} + 318: e92d0004 push {r2} + 31c: e92d0002 push {r1} + 320: e92d0001 push {r0} + 324: e3a00002 mov r0, #2 + 328: ef000040 svc 0x00000040 + 32c: e8bd0002 pop {r1} + 330: e8bd0002 pop {r1} + 334: e8bd0004 pop {r2} + 338: e8bd0008 pop {r3} + 33c: e8bd4000 pop {lr} + 340: e12fff1e bx lr + +00000344 : + 344: e92d4000 push {lr} + 348: e92d0008 push {r3} + 34c: e92d0004 push {r2} + 350: e92d0002 push {r1} + 354: e92d0001 push {r0} + 358: e3a00003 mov r0, #3 + 35c: ef000040 svc 0x00000040 + 360: e8bd0002 pop {r1} + 364: e8bd0002 pop {r1} + 368: e8bd0004 pop {r2} + 36c: e8bd0008 pop {r3} + 370: e8bd4000 pop {lr} + 374: e12fff1e bx lr + +00000378 : + 378: e92d4000 push {lr} + 37c: e92d0008 push {r3} + 380: e92d0004 push {r2} + 384: e92d0002 push {r1} + 388: e92d0001 push {r0} + 38c: e3a00004 mov r0, #4 + 390: ef000040 svc 0x00000040 + 394: e8bd0002 pop {r1} + 398: e8bd0002 pop {r1} + 39c: e8bd0004 pop {r2} + 3a0: e8bd0008 pop {r3} + 3a4: e8bd4000 pop {lr} + 3a8: e12fff1e bx lr + +000003ac : + 3ac: e92d4000 push {lr} + 3b0: e92d0008 push {r3} + 3b4: e92d0004 push {r2} + 3b8: e92d0002 push {r1} + 3bc: e92d0001 push {r0} + 3c0: e3a00005 mov r0, #5 + 3c4: ef000040 svc 0x00000040 + 3c8: e8bd0002 pop {r1} + 3cc: e8bd0002 pop {r1} + 3d0: e8bd0004 pop {r2} + 3d4: e8bd0008 pop {r3} + 3d8: e8bd4000 pop {lr} + 3dc: e12fff1e bx lr + +000003e0 : + 3e0: e92d4000 push {lr} + 3e4: e92d0008 push {r3} + 3e8: e92d0004 push {r2} + 3ec: e92d0002 push {r1} + 3f0: e92d0001 push {r0} + 3f4: e3a00010 mov r0, #16 + 3f8: ef000040 svc 0x00000040 + 3fc: e8bd0002 pop {r1} + 400: e8bd0002 pop {r1} + 404: e8bd0004 pop {r2} + 408: e8bd0008 pop {r3} + 40c: e8bd4000 pop {lr} + 410: e12fff1e bx lr + +00000414 : + 414: e92d4000 push {lr} + 418: e92d0008 push {r3} + 41c: e92d0004 push {r2} + 420: e92d0002 push {r1} + 424: e92d0001 push {r0} + 428: e3a00015 mov r0, #21 + 42c: ef000040 svc 0x00000040 + 430: e8bd0002 pop {r1} + 434: e8bd0002 pop {r1} + 438: e8bd0004 pop {r2} + 43c: e8bd0008 pop {r3} + 440: e8bd4000 pop {lr} + 444: e12fff1e bx lr + +00000448 : + 448: e92d4000 push {lr} + 44c: e92d0008 push {r3} + 450: e92d0004 push {r2} + 454: e92d0002 push {r1} + 458: e92d0001 push {r0} + 45c: e3a00006 mov r0, #6 + 460: ef000040 svc 0x00000040 + 464: e8bd0002 pop {r1} + 468: e8bd0002 pop {r1} + 46c: e8bd0004 pop {r2} + 470: e8bd0008 pop {r3} + 474: e8bd4000 pop {lr} + 478: e12fff1e bx lr + +0000047c : + 47c: e92d4000 push {lr} + 480: e92d0008 push {r3} + 484: e92d0004 push {r2} + 488: e92d0002 push {r1} + 48c: e92d0001 push {r0} + 490: e3a00007 mov r0, #7 + 494: ef000040 svc 0x00000040 + 498: e8bd0002 pop {r1} + 49c: e8bd0002 pop {r1} + 4a0: e8bd0004 pop {r2} + 4a4: e8bd0008 pop {r3} + 4a8: e8bd4000 pop {lr} + 4ac: e12fff1e bx lr + +000004b0 : + 4b0: e92d4000 push {lr} + 4b4: e92d0008 push {r3} + 4b8: e92d0004 push {r2} + 4bc: e92d0002 push {r1} + 4c0: e92d0001 push {r0} + 4c4: e3a0000f mov r0, #15 + 4c8: ef000040 svc 0x00000040 + 4cc: e8bd0002 pop {r1} + 4d0: e8bd0002 pop {r1} + 4d4: e8bd0004 pop {r2} + 4d8: e8bd0008 pop {r3} + 4dc: e8bd4000 pop {lr} + 4e0: e12fff1e bx lr + +000004e4 : + 4e4: e92d4000 push {lr} + 4e8: e92d0008 push {r3} + 4ec: e92d0004 push {r2} + 4f0: e92d0002 push {r1} + 4f4: e92d0001 push {r0} + 4f8: e3a00011 mov r0, #17 + 4fc: ef000040 svc 0x00000040 + 500: e8bd0002 pop {r1} + 504: e8bd0002 pop {r1} + 508: e8bd0004 pop {r2} + 50c: e8bd0008 pop {r3} + 510: e8bd4000 pop {lr} + 514: e12fff1e bx lr + +00000518 : + 518: e92d4000 push {lr} + 51c: e92d0008 push {r3} + 520: e92d0004 push {r2} + 524: e92d0002 push {r1} + 528: e92d0001 push {r0} + 52c: e3a00012 mov r0, #18 + 530: ef000040 svc 0x00000040 + 534: e8bd0002 pop {r1} + 538: e8bd0002 pop {r1} + 53c: e8bd0004 pop {r2} + 540: e8bd0008 pop {r3} + 544: e8bd4000 pop {lr} + 548: e12fff1e bx lr + +0000054c : + 54c: e92d4000 push {lr} + 550: e92d0008 push {r3} + 554: e92d0004 push {r2} + 558: e92d0002 push {r1} + 55c: e92d0001 push {r0} + 560: e3a00008 mov r0, #8 + 564: ef000040 svc 0x00000040 + 568: e8bd0002 pop {r1} + 56c: e8bd0002 pop {r1} + 570: e8bd0004 pop {r2} + 574: e8bd0008 pop {r3} + 578: e8bd4000 pop {lr} + 57c: e12fff1e bx lr + +00000580 : + 580: e92d4000 push {lr} + 584: e92d0008 push {r3} + 588: e92d0004 push {r2} + 58c: e92d0002 push {r1} + 590: e92d0001 push {r0} + 594: e3a00013 mov r0, #19 + 598: ef000040 svc 0x00000040 + 59c: e8bd0002 pop {r1} + 5a0: e8bd0002 pop {r1} + 5a4: e8bd0004 pop {r2} + 5a8: e8bd0008 pop {r3} + 5ac: e8bd4000 pop {lr} + 5b0: e12fff1e bx lr + +000005b4 : + 5b4: e92d4000 push {lr} + 5b8: e92d0008 push {r3} + 5bc: e92d0004 push {r2} + 5c0: e92d0002 push {r1} + 5c4: e92d0001 push {r0} + 5c8: e3a00014 mov r0, #20 + 5cc: ef000040 svc 0x00000040 + 5d0: e8bd0002 pop {r1} + 5d4: e8bd0002 pop {r1} + 5d8: e8bd0004 pop {r2} + 5dc: e8bd0008 pop {r3} + 5e0: e8bd4000 pop {lr} + 5e4: e12fff1e bx lr + +000005e8 : + 5e8: e92d4000 push {lr} + 5ec: e92d0008 push {r3} + 5f0: e92d0004 push {r2} + 5f4: e92d0002 push {r1} + 5f8: e92d0001 push {r0} + 5fc: e3a00009 mov r0, #9 + 600: ef000040 svc 0x00000040 + 604: e8bd0002 pop {r1} + 608: e8bd0002 pop {r1} + 60c: e8bd0004 pop {r2} + 610: e8bd0008 pop {r3} + 614: e8bd4000 pop {lr} + 618: e12fff1e bx lr + +0000061c : + 61c: e92d4000 push {lr} + 620: e92d0008 push {r3} + 624: e92d0004 push {r2} + 628: e92d0002 push {r1} + 62c: e92d0001 push {r0} + 630: e3a0000a mov r0, #10 + 634: ef000040 svc 0x00000040 + 638: e8bd0002 pop {r1} + 63c: e8bd0002 pop {r1} + 640: e8bd0004 pop {r2} + 644: e8bd0008 pop {r3} + 648: e8bd4000 pop {lr} + 64c: e12fff1e bx lr + +00000650 : + 650: e92d4000 push {lr} + 654: e92d0008 push {r3} + 658: e92d0004 push {r2} + 65c: e92d0002 push {r1} + 660: e92d0001 push {r0} + 664: e3a0000b mov r0, #11 + 668: ef000040 svc 0x00000040 + 66c: e8bd0002 pop {r1} + 670: e8bd0002 pop {r1} + 674: e8bd0004 pop {r2} + 678: e8bd0008 pop {r3} + 67c: e8bd4000 pop {lr} + 680: e12fff1e bx lr + +00000684 : + 684: e92d4000 push {lr} + 688: e92d0008 push {r3} + 68c: e92d0004 push {r2} + 690: e92d0002 push {r1} + 694: e92d0001 push {r0} + 698: e3a0000c mov r0, #12 + 69c: ef000040 svc 0x00000040 + 6a0: e8bd0002 pop {r1} + 6a4: e8bd0002 pop {r1} + 6a8: e8bd0004 pop {r2} + 6ac: e8bd0008 pop {r3} + 6b0: e8bd4000 pop {lr} + 6b4: e12fff1e bx lr + +000006b8 : + 6b8: e92d4000 push {lr} + 6bc: e92d0008 push {r3} + 6c0: e92d0004 push {r2} + 6c4: e92d0002 push {r1} + 6c8: e92d0001 push {r0} + 6cc: e3a0000d mov r0, #13 + 6d0: ef000040 svc 0x00000040 + 6d4: e8bd0002 pop {r1} + 6d8: e8bd0002 pop {r1} + 6dc: e8bd0004 pop {r2} + 6e0: e8bd0008 pop {r3} + 6e4: e8bd4000 pop {lr} + 6e8: e12fff1e bx lr + +000006ec : + 6ec: e92d4000 push {lr} + 6f0: e92d0008 push {r3} + 6f4: e92d0004 push {r2} + 6f8: e92d0002 push {r1} + 6fc: e92d0001 push {r0} + 700: e3a0000e mov r0, #14 + 704: ef000040 svc 0x00000040 + 708: e8bd0002 pop {r1} + 70c: e8bd0002 pop {r1} + 710: e8bd0004 pop {r2} + 714: e8bd0008 pop {r3} + 718: e8bd4000 pop {lr} + 71c: e12fff1e bx lr + +00000720 : +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 720: e92d4800 push {fp, lr} + 724: e28db004 add fp, sp, #4 + 728: e24b3004 sub r3, fp, #4 + 72c: e24dd008 sub sp, sp, #8 + write(fd, &c, 1); + 730: e3a02001 mov r2, #1 +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 734: e5631001 strb r1, [r3, #-1]! + write(fd, &c, 1); + 738: e1a01003 mov r1, r3 + 73c: ebffff27 bl 3e0 +} + 740: e24bd004 sub sp, fp, #4 + 744: e8bd8800 pop {fp, pc} + +00000748 : + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 748: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 74c: e1a04000 mov r4, r0 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 750: e1a00fa1 lsr r0, r1, #31 + 754: e3530000 cmp r3, #0 + 758: 03a03000 moveq r3, #0 + 75c: 12003001 andne r3, r0, #1 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 760: e28db020 add fp, sp, #32 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 764: e3530000 cmp r3, #0 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 768: e24dd014 sub sp, sp, #20 + 76c: e59f909c ldr r9, [pc, #156] ; 810 + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + x = -xx; + 770: 12611000 rsbne r1, r1, #0 + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + 774: 13a03001 movne r3, #1 + } else { + x = xx; + } + + b = base; + i = 0; + 778: e3a0a000 mov sl, #0 + 77c: e24b6034 sub r6, fp, #52 ; 0x34 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 780: e3a08001 mov r8, #1 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 784: e3a07000 mov r7, #0 + int i; + + for(i=31;i>=0;i--){ + 788: e3a0001f mov r0, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 78c: e1a0c007 mov ip, r7 + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 790: e1a0e031 lsr lr, r1, r0 + 794: e20ee001 and lr, lr, #1 + 798: e18ec08c orr ip, lr, ip, lsl #1 + if(r >= d) { + 79c: e152000c cmp r2, ip + r = r - d; + q = q | (1 << i); + 7a0: 91877018 orrls r7, r7, r8, lsl r0 + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 7a4: 9062c00c rsbls ip, r2, ip +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 7a8: e2500001 subs r0, r0, #1 + 7ac: 2afffff7 bcs 790 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 7b0: e0000792 mul r0, r2, r7 + }while((x = y) != 0); + 7b4: e3570000 cmp r7, #0 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 7b8: e0601001 rsb r1, r0, r1 + 7bc: e28a5001 add r5, sl, #1 + 7c0: e7d91001 ldrb r1, [r9, r1] + 7c4: e7c6100a strb r1, [r6, sl] + }while((x = y) != 0); + 7c8: 11a01007 movne r1, r7 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 7cc: 11a0a005 movne sl, r5 + 7d0: 1affffeb bne 784 + }while((x = y) != 0); + if(neg) + 7d4: e3530000 cmp r3, #0 + buf[i++] = '-'; + 7d8: 124b2024 subne r2, fp, #36 ; 0x24 + 7dc: 10823005 addne r3, r2, r5 + 7e0: 128a5002 addne r5, sl, #2 + + while(--i >= 0) + 7e4: e2455001 sub r5, r5, #1 + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + 7e8: 13a0202d movne r2, #45 ; 0x2d + 7ec: 15432010 strbne r2, [r3, #-16] + + while(--i >= 0) + putc(fd, buf[i]); + 7f0: e7d61005 ldrb r1, [r6, r5] + 7f4: e1a00004 mov r0, r4 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 7f8: e2455001 sub r5, r5, #1 + putc(fd, buf[i]); + 7fc: ebffffc7 bl 720 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 800: e3750001 cmn r5, #1 + 804: 1afffff9 bne 7f0 + putc(fd, buf[i]); +} + 808: e24bd020 sub sp, fp, #32 + 80c: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} + 810: 00000b74 .word 0x00000b74 + +00000814
: + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 814: e3a03000 mov r3, #0 +{ + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + 818: e92d0830 push {r4, r5, fp} + 81c: e1a02000 mov r2, r0 + 820: e28db008 add fp, sp, #8 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 824: e3a0c01f mov ip, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 828: e1a00003 mov r0, r3 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 82c: e3a05001 mov r5, #1 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 830: e1a04c32 lsr r4, r2, ip + 834: e2044001 and r4, r4, #1 + 838: e1843083 orr r3, r4, r3, lsl #1 + if(r >= d) { + 83c: e1530001 cmp r3, r1 + r = r - d; + q = q | (1 << i); + 840: 21800c15 orrcs r0, r0, r5, lsl ip + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 844: 20613003 rsbcs r3, r1, r3 +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 848: e25cc001 subs ip, ip, #1 + 84c: 2afffff7 bcs 830 + r = r - d; + q = q | (1 << i); + } + } + return q; +} + 850: e24bd008 sub sp, fp, #8 + 854: e8bd0830 pop {r4, r5, fp} + 858: e12fff1e bx lr + +0000085c : +} + +// Print to the given fd. Only understands %d, %x, %p, %s. +void +printf(int fd, char *fmt, ...) +{ + 85c: e92d000e push {r1, r2, r3} + 860: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 864: e28db020 add fp, sp, #32 + 868: e1a05000 mov r5, r0 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 86c: e59b4004 ldr r4, [fp, #4] + 870: e5d48000 ldrb r8, [r4] + 874: e3580000 cmp r8, #0 + 878: 0a000027 beq 91c + ap++; + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + 87c: e59f712c ldr r7, [pc, #300] ; 9b0 + char *s; + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + 880: e28b6008 add r6, fp, #8 +{ + char *s; + int c, i, state; + uint *ap; + + state = 0; + 884: e3a0a000 mov sl, #0 + 888: ea000008 b 8b0 + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 88c: e3580025 cmp r8, #37 ; 0x25 + state = '%'; + 890: 01a0a008 moveq sl, r8 + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 894: 0a000002 beq 8a4 + state = '%'; + } else { + putc(fd, c); + 898: e1a00005 mov r0, r5 + 89c: e1a01008 mov r1, r8 + 8a0: ebffff9e bl 720 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 8a4: e5f48001 ldrb r8, [r4, #1]! + 8a8: e3580000 cmp r8, #0 + 8ac: 0a00001a beq 91c + c = fmt[i] & 0xff; + if(state == 0){ + 8b0: e35a0000 cmp sl, #0 + 8b4: 0afffff4 beq 88c + if(c == '%'){ + state = '%'; + } else { + putc(fd, c); + } + } else if(state == '%'){ + 8b8: e35a0025 cmp sl, #37 ; 0x25 + 8bc: 1afffff8 bne 8a4 + if(c == 'd'){ + 8c0: e3580064 cmp r8, #100 ; 0x64 + 8c4: 0a00002c beq 97c + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + 8c8: e3580078 cmp r8, #120 ; 0x78 + 8cc: 13580070 cmpne r8, #112 ; 0x70 + 8d0: 13a09000 movne r9, #0 + 8d4: 03a09001 moveq r9, #1 + 8d8: 0a000013 beq 92c + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + 8dc: e3580073 cmp r8, #115 ; 0x73 + 8e0: 0a000018 beq 948 + s = "(null)"; + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + 8e4: e3580063 cmp r8, #99 ; 0x63 + 8e8: 0a00002a beq 998 + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 8ec: e3580025 cmp r8, #37 ; 0x25 + putc(fd, c); + 8f0: e1a0100a mov r1, sl + 8f4: e1a00005 mov r0, r5 + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 8f8: 0a000002 beq 908 + putc(fd, c); + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + 8fc: ebffff87 bl 720 + putc(fd, c); + 900: e1a00005 mov r0, r5 + 904: e1a01008 mov r1, r8 + 908: ebffff84 bl 720 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 90c: e5f48001 ldrb r8, [r4, #1]! + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 910: e1a0a009 mov sl, r9 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 914: e3580000 cmp r8, #0 + 918: 1affffe4 bne 8b0 + putc(fd, c); + } + state = 0; + } + } +} + 91c: e24bd020 sub sp, fp, #32 + 920: e8bd4ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 924: e28dd00c add sp, sp, #12 + 928: e12fff1e bx lr + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + 92c: e1a00005 mov r0, r5 + 930: e4961004 ldr r1, [r6], #4 + 934: e3a02010 mov r2, #16 + 938: e3a03000 mov r3, #0 + 93c: ebffff81 bl 748 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 940: e3a0a000 mov sl, #0 + 944: eaffffd6 b 8a4 + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + s = (char*)*ap; + 948: e4968004 ldr r8, [r6], #4 + ap++; + if(s == 0) + s = "(null)"; + 94c: e3580000 cmp r8, #0 + 950: 01a08007 moveq r8, r7 + while(*s != 0){ + 954: e5d81000 ldrb r1, [r8] + 958: e3510000 cmp r1, #0 + 95c: 0a000004 beq 974 + putc(fd, *s); + 960: e1a00005 mov r0, r5 + 964: ebffff6d bl 720 + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + while(*s != 0){ + 968: e5f81001 ldrb r1, [r8, #1]! + 96c: e3510000 cmp r1, #0 + 970: 1afffffa bne 960 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 974: e1a0a001 mov sl, r1 + 978: eaffffc9 b 8a4 + } else { + putc(fd, c); + } + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + 97c: e1a00005 mov r0, r5 + 980: e4961004 ldr r1, [r6], #4 + 984: e3a0200a mov r2, #10 + 988: e3a03001 mov r3, #1 + 98c: ebffff6d bl 748 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 990: e3a0a000 mov sl, #0 + 994: eaffffc2 b 8a4 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 998: e4961004 ldr r1, [r6], #4 + 99c: e1a00005 mov r0, r5 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 9a0: e1a0a009 mov sl, r9 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 9a4: e6ef1071 uxtb r1, r1 + 9a8: ebffff5c bl 720 + 9ac: eaffffbc b 8a4 + 9b0: 00000b88 .word 0x00000b88 + +000009b4 : +free(void *ap) +{ + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 9b4: e59f3098 ldr r3, [pc, #152] ; a54 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 9b8: e92d0830 push {r4, r5, fp} + Header *bp, *p; + + bp = (Header*)ap - 1; + 9bc: e240c008 sub ip, r0, #8 + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 9c0: e5932000 ldr r2, [r3] +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 9c4: e28db008 add fp, sp, #8 + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 9c8: e152000c cmp r2, ip + 9cc: e5921000 ldr r1, [r2] + 9d0: 2a000001 bcs 9dc + 9d4: e15c0001 cmp ip, r1 + 9d8: 3a000007 bcc 9fc + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + 9dc: e1520001 cmp r2, r1 + 9e0: 3a000003 bcc 9f4 + 9e4: e152000c cmp r2, ip + 9e8: 3a000003 bcc 9fc + 9ec: e15c0001 cmp ip, r1 + 9f0: 3a000001 bcc 9fc +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 9f4: e1a02001 mov r2, r1 + 9f8: eafffff2 b 9c8 + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + 9fc: e5104004 ldr r4, [r0, #-4] + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + freep = p; + a00: e5832000 str r2, [r3] + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + a04: e08c5184 add r5, ip, r4, lsl #3 + a08: e1550001 cmp r5, r1 + bp->s.size += p->s.ptr->s.size; + a0c: 05911004 ldreq r1, [r1, #4] + a10: 00814004 addeq r4, r1, r4 + a14: 05004004 streq r4, [r0, #-4] + bp->s.ptr = p->s.ptr->s.ptr; + a18: 05921000 ldreq r1, [r2] + a1c: 05911000 ldreq r1, [r1] + } else + bp->s.ptr = p->s.ptr; + a20: e5001008 str r1, [r0, #-8] + if(p + p->s.size == bp){ + a24: e5921004 ldr r1, [r2, #4] + a28: e0824181 add r4, r2, r1, lsl #3 + a2c: e15c0004 cmp ip, r4 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + a30: 1582c000 strne ip, [r2] + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + } else + bp->s.ptr = p->s.ptr; + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + a34: 0510c004 ldreq ip, [r0, #-4] + a38: 008c1001 addeq r1, ip, r1 + a3c: 05821004 streq r1, [r2, #4] + p->s.ptr = bp->s.ptr; + a40: 05101008 ldreq r1, [r0, #-8] + a44: 05821000 streq r1, [r2] + } else + p->s.ptr = bp; + freep = p; +} + a48: e24bd008 sub sp, fp, #8 + a4c: e8bd0830 pop {r4, r5, fp} + a50: e12fff1e bx lr + a54: 00000b90 .word 0x00000b90 + +00000a58 : + return freep; +} + +void* +malloc(uint nbytes) +{ + a58: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + a5c: e2804007 add r4, r0, #7 + if((prevp = freep) == 0){ + a60: e59f50d4 ldr r5, [pc, #212] ; b3c +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + a64: e1a041a4 lsr r4, r4, #3 + return freep; +} + +void* +malloc(uint nbytes) +{ + a68: e28db01c add fp, sp, #28 + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + a6c: e5953000 ldr r3, [r5] +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + a70: e2844001 add r4, r4, #1 + if((prevp = freep) == 0){ + a74: e3530000 cmp r3, #0 + a78: 0a00002b beq b2c + a7c: e5930000 ldr r0, [r3] + a80: e5902004 ldr r2, [r0, #4] + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + a84: e1520004 cmp r2, r4 + a88: 2a00001b bcs afc +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + a8c: e59f80ac ldr r8, [pc, #172] ; b40 + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + a90: e1a07184 lsl r7, r4, #3 + a94: ea000003 b aa8 + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + a98: e5930000 ldr r0, [r3] + if(p->s.size >= nunits){ + a9c: e5902004 ldr r2, [r0, #4] + aa0: e1540002 cmp r4, r2 + aa4: 9a000014 bls afc + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + aa8: e5952000 ldr r2, [r5] + aac: e1a03000 mov r3, r0 + ab0: e1500002 cmp r0, r2 + ab4: 1afffff7 bne a98 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + ab8: e1540008 cmp r4, r8 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + abc: 81a00007 movhi r0, r7 + ac0: 93a00902 movls r0, #32768 ; 0x8000 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + ac4: 81a06004 movhi r6, r4 + ac8: 93a06a01 movls r6, #4096 ; 0x1000 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + acc: ebfffeec bl 684 + ad0: e1a03000 mov r3, r0 + if(p == (char*)-1) + ad4: e3730001 cmn r3, #1 + return 0; + hp = (Header*)p; + hp->s.size = nu; + free((void*)(hp + 1)); + ad8: e2800008 add r0, r0, #8 + Header *hp; + + if(nu < 4096) + nu = 4096; + p = sbrk(nu * sizeof(Header)); + if(p == (char*)-1) + adc: 0a000010 beq b24 + return 0; + hp = (Header*)p; + hp->s.size = nu; + ae0: e5836004 str r6, [r3, #4] + free((void*)(hp + 1)); + ae4: ebffffb2 bl 9b4 + return freep; + ae8: e5953000 ldr r3, [r5] + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + if((p = morecore(nunits)) == 0) + aec: e3530000 cmp r3, #0 + af0: 1affffe8 bne a98 + return 0; + af4: e1a00003 mov r0, r3 + } +} + af8: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + afc: e1540002 cmp r4, r2 + prevp->s.ptr = p->s.ptr; + else { + p->s.size -= nunits; + b00: 10642002 rsbne r2, r4, r2 + b04: 15802004 strne r2, [r0, #4] + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + b08: 05902000 ldreq r2, [r0] + else { + p->s.size -= nunits; + p += p->s.size; + b0c: 10800182 addne r0, r0, r2, lsl #3 + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + b10: 05832000 streq r2, [r3] + else { + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + b14: 15804004 strne r4, [r0, #4] + } + freep = prevp; + b18: e5853000 str r3, [r5] + return (void*)(p + 1); + b1c: e2800008 add r0, r0, #8 + b20: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + } + if(p == freep) + if((p = morecore(nunits)) == 0) + return 0; + b24: e3a00000 mov r0, #0 + b28: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + b2c: e2850004 add r0, r5, #4 + b30: e5850000 str r0, [r5] + base.s.size = 0; + b34: e9850009 stmib r5, {r0, r3} + b38: eaffffd3 b a8c + b3c: 00000b90 .word 0x00000b90 + b40: 00000fff .word 0x00000fff diff -r 000000000000 -r c450faca55f4 uprogs/rm.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/rm.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,23 @@ +#include "types.h" +#include "stat.h" +#include "user.h" + +int +main(int argc, char *argv[]) +{ + int i; + + if(argc < 2){ + printf(2, "Usage: rm files...\n"); + exit(); + } + + for(i = 1; i < argc; i++){ + if(unlink(argv[i]) < 0){ + printf(2, "rm: %s failed to delete\n", argv[i]); + break; + } + } + + exit(); +} diff -r 000000000000 -r c450faca55f4 uprogs/rm.sym --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/rm.sym Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,64 @@ +00000000 .text +00000b44 .rodata +00000b90 .bss +00000000 .comment +00000000 .ARM.attributes +00000000 .debug_aranges +00000000 .debug_info +00000000 .debug_abbrev +00000000 .debug_line +00000000 .debug_frame +00000000 .debug_str +00000000 .debug_loc +00000000 .debug_ranges +00000000 rm.c +00000000 ulib.c +00000000 printf.c +00000720 putc +00000748 printint +00000b74 digits.993 +00000000 umalloc.c +00000b90 freep +00000b94 base +00000070 strcpy +0000085c printf +000002a8 memmove +000004e4 mknod +00000b9c _bss_end__ +000001a0 gets +00000650 getpid +00000a58 malloc +000006b8 sleep +00000b90 __bss_start__ +00000378 pipe +000003e0 write +0000054c fstat +00000448 kill +000005e8 chdir +0000047c exec +00000b9c __bss_end__ +00000344 wait +000003ac read +00000518 unlink +000002dc fork +00000684 sbrk +000006ec uptime +00000b90 __bss_start +00000124 memset +00000000 main +00000b9c __end__ +00000098 strcmp +0000061c dup +00000218 stat +00000b90 _edata +00000b9c _end +00000580 link +00000310 exit +00000254 atoi +000000e4 strlen +000004b0 open +00000814 div +0000015c strchr +000005b4 mkdir +00000414 close +000009b4 free diff -r 000000000000 -r c450faca55f4 uprogs/sh.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/sh.asm Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,3428 @@ + +_sh: file format elf32-littlearm + + +Disassembly of section .text: + +00000000
: + return 0; +} + +int +main(void) +{ + 0: e92d4830 push {r4, r5, fp, lr} + 4: e28db00c add fp, sp, #12 + static char buf[100]; + int fd; + + // Assumes three file descriptors open. + while((fd = open("console", O_RDWR)) >= 0){ + 8: ea000001 b 14 + if(fd >= 3){ + c: e3530002 cmp r3, #2 + 10: ca000027 bgt b4 +{ + static char buf[100]; + int fd; + + // Assumes three file descriptors open. + while((fd = open("console", O_RDWR)) >= 0){ + 14: e59f00ac ldr r0, [pc, #172] ; c8 + 18: e3a01002 mov r1, #2 + 1c: eb0003c1 bl f28 + 20: e2503000 subs r3, r0, #0 + 24: aafffff8 bge c + break; + } + } + + // Read and run input commands. + while(getcmd(buf, sizeof(buf)) >= 0){ + 28: e59f409c ldr r4, [pc, #156] ; cc + if(buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' '){ + // Clumsy but will have to do for now. + // Chdir has no effect on the parent if run in the child. + buf[strlen(buf)-1] = 0; // chop \n + 2c: e3a05000 mov r5, #0 + 30: ea000003 b 44 + if(chdir(buf+3) < 0) + printf(2, "cannot cd %s\n", buf+3); + continue; + } + if(fork1() == 0) + 34: eb000043 bl 148 + 38: e3500000 cmp r0, #0 + 3c: 0a00001e beq bc + runcmd(parsecmd(buf)); + wait(); + 40: eb00035d bl dbc + break; + } + } + + // Read and run input commands. + while(getcmd(buf, sizeof(buf)) >= 0){ + 44: e59f0080 ldr r0, [pc, #128] ; cc + 48: e3a01064 mov r1, #100 ; 0x64 + 4c: eb000021 bl d8 + 50: e3500000 cmp r0, #0 + 54: ba000015 blt b0 + if(buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' '){ + 58: e5d43000 ldrb r3, [r4] + 5c: e3530063 cmp r3, #99 ; 0x63 + 60: 1afffff3 bne 34 + 64: e5d43001 ldrb r3, [r4, #1] + 68: e3530064 cmp r3, #100 ; 0x64 + 6c: 1afffff0 bne 34 + 70: e5d43002 ldrb r3, [r4, #2] + 74: e3530020 cmp r3, #32 + 78: 1affffed bne 34 + // Clumsy but will have to do for now. + // Chdir has no effect on the parent if run in the child. + buf[strlen(buf)-1] = 0; // chop \n + 7c: e59f0048 ldr r0, [pc, #72] ; cc + 80: eb0002b5 bl b5c + 84: e0843000 add r3, r4, r0 + if(chdir(buf+3) < 0) + 88: e59f0040 ldr r0, [pc, #64] ; d0 + // Read and run input commands. + while(getcmd(buf, sizeof(buf)) >= 0){ + if(buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' '){ + // Clumsy but will have to do for now. + // Chdir has no effect on the parent if run in the child. + buf[strlen(buf)-1] = 0; // chop \n + 8c: e5435001 strb r5, [r3, #-1] + if(chdir(buf+3) < 0) + 90: eb0003f2 bl 1060 + 94: e3500000 cmp r0, #0 + 98: aaffffe9 bge 44 + printf(2, "cannot cd %s\n", buf+3); + 9c: e3a00002 mov r0, #2 + a0: e59f102c ldr r1, [pc, #44] ; d4 + a4: e59f2024 ldr r2, [pc, #36] ; d0 + a8: eb000489 bl 12d4 + ac: eaffffe4 b 44 + } + if(fork1() == 0) + runcmd(parsecmd(buf)); + wait(); + } + exit(); + b0: eb000334 bl d88 + int fd; + + // Assumes three file descriptors open. + while((fd = open("console", O_RDWR)) >= 0){ + if(fd >= 3){ + close(fd); + b4: eb000374 bl e8c + break; + b8: eaffffda b 28 + if(chdir(buf+3) < 0) + printf(2, "cannot cd %s\n", buf+3); + continue; + } + if(fork1() == 0) + runcmd(parsecmd(buf)); + bc: e59f0008 ldr r0, [pc, #8] ; cc + c0: eb000268 bl a68 + c4: eb000027 bl 168 + c8: 00001684 .word 0x00001684 + cc: 000016c8 .word 0x000016c8 + d0: 000016cb .word 0x000016cb + d4: 0000168c .word 0x0000168c + +000000d8 : + exit(); +} + +int +getcmd(char *buf, int nbuf) +{ + d8: e92d4830 push {r4, r5, fp, lr} + dc: e1a04000 mov r4, r0 + e0: e28db00c add fp, sp, #12 + e4: e1a05001 mov r5, r1 + printf(2, "$ "); + e8: e3a00002 mov r0, #2 + ec: e59f1030 ldr r1, [pc, #48] ; 124 + f0: eb000477 bl 12d4 + memset(buf, 0, nbuf); + f4: e1a02005 mov r2, r5 + f8: e1a00004 mov r0, r4 + fc: e3a01000 mov r1, #0 + 100: eb0002a5 bl b9c + gets(buf, nbuf); + 104: e1a00004 mov r0, r4 + 108: e1a01005 mov r1, r5 + 10c: eb0002c1 bl c18 + if(buf[0] == 0) // EOF + 110: e5d43000 ldrb r3, [r4] + 114: e3530000 cmp r3, #0 + return -1; + return 0; +} + 118: 03e00000 mvneq r0, #0 + 11c: 13a00000 movne r0, #0 + 120: e8bd8830 pop {r4, r5, fp, pc} + 124: 000015bc .word 0x000015bc + +00000128 : + exit(); +} + +void +panic(char *s) +{ + 128: e92d4800 push {fp, lr} + 12c: e1a02000 mov r2, r0 + 130: e28db004 add fp, sp, #4 + printf(2, "%s\n", s); + 134: e59f1008 ldr r1, [pc, #8] ; 144 + 138: e3a00002 mov r0, #2 + 13c: eb000464 bl 12d4 + exit(); + 140: eb000310 bl d88 + 144: 000015c0 .word 0x000015c0 + +00000148 : +} + +int +fork1(void) +{ + 148: e92d4800 push {fp, lr} + 14c: e28db004 add fp, sp, #4 + int pid; + + pid = fork(); + 150: eb0002ff bl d54 + if(pid == -1) + 154: e3700001 cmn r0, #1 + 158: 18bd8800 popne {fp, pc} + panic("fork"); + 15c: e59f0000 ldr r0, [pc] ; 164 + 160: ebfffff0 bl 128 + 164: 000015c4 .word 0x000015c4 + +00000168 : +struct cmd *parsecmd(char*); + +// Execute cmd. Never returns. +void +runcmd(struct cmd *cmd) +{ + 168: e92d4810 push {r4, fp, lr} + struct execcmd *ecmd; + struct listcmd *lcmd; + struct pipecmd *pcmd; + struct redircmd *rcmd; + + if(cmd == 0) + 16c: e2504000 subs r4, r0, #0 +struct cmd *parsecmd(char*); + +// Execute cmd. Never returns. +void +runcmd(struct cmd *cmd) +{ + 170: e28db008 add fp, sp, #8 + 174: e24dd00c sub sp, sp, #12 + struct execcmd *ecmd; + struct listcmd *lcmd; + struct pipecmd *pcmd; + struct redircmd *rcmd; + + if(cmd == 0) + 178: 0a000019 beq 1e4 + exit(); + + switch(cmd->type){ + 17c: e5943000 ldr r3, [r4] + 180: e2433001 sub r3, r3, #1 + 184: e3530004 cmp r3, #4 + 188: 979ff103 ldrls pc, [pc, r3, lsl #2] + 18c: ea000019 b 1f8 + 190: 00000200 .word 0x00000200 + 194: 00000228 .word 0x00000228 + 198: 000001a4 .word 0x000001a4 + 19c: 0000024c .word 0x0000024c + 1a0: 000001e8 .word 0x000001e8 + runcmd(lcmd->right); + break; + + case PIPE: + pcmd = (struct pipecmd*)cmd; + if(pipe(p) < 0) + 1a4: e24b0014 sub r0, fp, #20 + 1a8: eb000310 bl df0 + 1ac: e3500000 cmp r0, #0 + 1b0: ba000030 blt 278 + panic("pipe"); + if(fork1() == 0){ + 1b4: ebffffe3 bl 148 + 1b8: e3500000 cmp r0, #0 + 1bc: 0a000038 beq 2a4 + dup(p[1]); + close(p[0]); + close(p[1]); + runcmd(pcmd->left); + } + if(fork1() == 0){ + 1c0: ebffffe0 bl 148 + 1c4: e3500000 cmp r0, #0 + 1c8: 0a00002c beq 280 + dup(p[0]); + close(p[0]); + close(p[1]); + runcmd(pcmd->right); + } + close(p[0]); + 1cc: e51b0014 ldr r0, [fp, #-20] + 1d0: eb00032d bl e8c + close(p[1]); + 1d4: e51b0010 ldr r0, [fp, #-16] + 1d8: eb00032b bl e8c + wait(); + 1dc: eb0002f6 bl dbc + wait(); + 1e0: eb0002f5 bl dbc + bcmd = (struct backcmd*)cmd; + if(fork1() == 0) + runcmd(bcmd->cmd); + break; + } + exit(); + 1e4: eb0002e7 bl d88 + wait(); + break; + + case BACK: + bcmd = (struct backcmd*)cmd; + if(fork1() == 0) + 1e8: ebffffd6 bl 148 + 1ec: e3500000 cmp r0, #0 + 1f0: 0a000013 beq 244 + runcmd(bcmd->cmd); + break; + } + exit(); + 1f4: eb0002e3 bl d88 + if(cmd == 0) + exit(); + + switch(cmd->type){ + default: + panic("runcmd"); + 1f8: e59f00cc ldr r0, [pc, #204] ; 2cc + 1fc: ebffffc9 bl 128 + + case EXEC: + ecmd = (struct execcmd*)cmd; + if(ecmd->argv[0] == 0) + 200: e5940004 ldr r0, [r4, #4] + 204: e3500000 cmp r0, #0 + 208: 0afffff5 beq 1e4 + exit(); + exec(ecmd->argv[0], ecmd->argv); + 20c: e2841004 add r1, r4, #4 + 210: eb000337 bl ef4 + printf(2, "exec %s failed\n", ecmd->argv[0]); + 214: e3a00002 mov r0, #2 + 218: e59f10b0 ldr r1, [pc, #176] ; 2d0 + 21c: e5942004 ldr r2, [r4, #4] + 220: eb00042b bl 12d4 + bcmd = (struct backcmd*)cmd; + if(fork1() == 0) + runcmd(bcmd->cmd); + break; + } + exit(); + 224: eb0002d7 bl d88 + printf(2, "exec %s failed\n", ecmd->argv[0]); + break; + + case REDIR: + rcmd = (struct redircmd*)cmd; + close(rcmd->fd); + 228: e5940014 ldr r0, [r4, #20] + 22c: eb000316 bl e8c + if(open(rcmd->file, rcmd->mode) < 0){ + 230: e5940008 ldr r0, [r4, #8] + 234: e5941010 ldr r1, [r4, #16] + 238: eb00033a bl f28 + 23c: e3500000 cmp r0, #0 + 240: ba000007 blt 264 + break; + + case BACK: + bcmd = (struct backcmd*)cmd; + if(fork1() == 0) + runcmd(bcmd->cmd); + 244: e5940004 ldr r0, [r4, #4] + 248: ebffffc6 bl 168 + runcmd(rcmd->cmd); + break; + + case LIST: + lcmd = (struct listcmd*)cmd; + if(fork1() == 0) + 24c: ebffffbd bl 148 + 250: e3500000 cmp r0, #0 + 254: 0afffffa beq 244 + runcmd(lcmd->left); + wait(); + 258: eb0002d7 bl dbc + runcmd(lcmd->right); + 25c: e5940008 ldr r0, [r4, #8] + 260: ebffffc0 bl 168 + + case REDIR: + rcmd = (struct redircmd*)cmd; + close(rcmd->fd); + if(open(rcmd->file, rcmd->mode) < 0){ + printf(2, "open %s failed\n", rcmd->file); + 264: e3a00002 mov r0, #2 + 268: e59f1064 ldr r1, [pc, #100] ; 2d4 + 26c: e5942008 ldr r2, [r4, #8] + 270: eb000417 bl 12d4 + exit(); + 274: eb0002c3 bl d88 + break; + + case PIPE: + pcmd = (struct pipecmd*)cmd; + if(pipe(p) < 0) + panic("pipe"); + 278: e59f0058 ldr r0, [pc, #88] ; 2d8 + 27c: ebffffa9 bl 128 + close(p[0]); + close(p[1]); + runcmd(pcmd->left); + } + if(fork1() == 0){ + close(0); + 280: eb000301 bl e8c + dup(p[0]); + 284: e51b0014 ldr r0, [fp, #-20] + 288: eb000381 bl 1094 + close(p[0]); + 28c: e51b0014 ldr r0, [fp, #-20] + 290: eb0002fd bl e8c + close(p[1]); + 294: e51b0010 ldr r0, [fp, #-16] + 298: eb0002fb bl e8c + runcmd(pcmd->right); + 29c: e5940008 ldr r0, [r4, #8] + 2a0: ebffffb0 bl 168 + case PIPE: + pcmd = (struct pipecmd*)cmd; + if(pipe(p) < 0) + panic("pipe"); + if(fork1() == 0){ + close(1); + 2a4: e3a00001 mov r0, #1 + 2a8: eb0002f7 bl e8c + dup(p[1]); + 2ac: e51b0010 ldr r0, [fp, #-16] + 2b0: eb000377 bl 1094 + close(p[0]); + 2b4: e51b0014 ldr r0, [fp, #-20] + 2b8: eb0002f3 bl e8c + close(p[1]); + 2bc: e51b0010 ldr r0, [fp, #-16] + 2c0: eb0002f1 bl e8c + runcmd(pcmd->left); + 2c4: e5940004 ldr r0, [r4, #4] + 2c8: ebffffa6 bl 168 + 2cc: 000015cc .word 0x000015cc + 2d0: 000015d4 .word 0x000015d4 + 2d4: 000015e4 .word 0x000015e4 + 2d8: 000015f4 .word 0x000015f4 + +000002dc : +//PAGEBREAK! +// Constructors + +struct cmd* +execcmd(void) +{ + 2dc: e92d4818 push {r3, r4, fp, lr} + struct execcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 2e0: e3a00054 mov r0, #84 ; 0x54 +//PAGEBREAK! +// Constructors + +struct cmd* +execcmd(void) +{ + 2e4: e28db00c add fp, sp, #12 + struct execcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 2e8: eb000478 bl 14d0 + memset(cmd, 0, sizeof(*cmd)); + 2ec: e3a01000 mov r1, #0 + 2f0: e3a02054 mov r2, #84 ; 0x54 +struct cmd* +execcmd(void) +{ + struct execcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 2f4: e1a04000 mov r4, r0 + memset(cmd, 0, sizeof(*cmd)); + 2f8: eb000227 bl b9c + cmd->type = EXEC; + 2fc: e3a03001 mov r3, #1 + 300: e5843000 str r3, [r4] + return (struct cmd*)cmd; +} + 304: e1a00004 mov r0, r4 + 308: e8bd8818 pop {r3, r4, fp, pc} + +0000030c : + +struct cmd* +redircmd(struct cmd *subcmd, char *file, char *efile, int mode, int fd) +{ + 30c: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + 310: e1a06000 mov r6, r0 + 314: e28db01c add fp, sp, #28 + struct redircmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 318: e3a00018 mov r0, #24 + return (struct cmd*)cmd; +} + +struct cmd* +redircmd(struct cmd *subcmd, char *file, char *efile, int mode, int fd) +{ + 31c: e1a08003 mov r8, r3 + 320: e1a05001 mov r5, r1 + 324: e1a04002 mov r4, r2 + struct redircmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 328: eb000468 bl 14d0 + memset(cmd, 0, sizeof(*cmd)); + 32c: e3a01000 mov r1, #0 + 330: e3a02018 mov r2, #24 +struct cmd* +redircmd(struct cmd *subcmd, char *file, char *efile, int mode, int fd) +{ + struct redircmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 334: e1a07000 mov r7, r0 + memset(cmd, 0, sizeof(*cmd)); + 338: eb000217 bl b9c + cmd->type = REDIR; + 33c: e3a03002 mov r3, #2 + cmd->cmd = subcmd; + cmd->file = file; + 340: e5875008 str r5, [r7, #8] + struct redircmd *cmd; + + cmd = malloc(sizeof(*cmd)); + memset(cmd, 0, sizeof(*cmd)); + cmd->type = REDIR; + cmd->cmd = subcmd; + 344: e8870048 stm r7, {r3, r6} + cmd->file = file; + cmd->efile = efile; + cmd->mode = mode; + cmd->fd = fd; + 348: e59b3004 ldr r3, [fp, #4] + cmd = malloc(sizeof(*cmd)); + memset(cmd, 0, sizeof(*cmd)); + cmd->type = REDIR; + cmd->cmd = subcmd; + cmd->file = file; + cmd->efile = efile; + 34c: e587400c str r4, [r7, #12] + cmd->mode = mode; + 350: e5878010 str r8, [r7, #16] + cmd->fd = fd; + 354: e5873014 str r3, [r7, #20] + return (struct cmd*)cmd; +} + 358: e1a00007 mov r0, r7 + 35c: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + +00000360 : + +struct cmd* +pipecmd(struct cmd *left, struct cmd *right) +{ + 360: e92d4878 push {r3, r4, r5, r6, fp, lr} + 364: e1a06000 mov r6, r0 + 368: e28db014 add fp, sp, #20 + struct pipecmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 36c: e3a0000c mov r0, #12 + return (struct cmd*)cmd; +} + +struct cmd* +pipecmd(struct cmd *left, struct cmd *right) +{ + 370: e1a05001 mov r5, r1 + struct pipecmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 374: eb000455 bl 14d0 + memset(cmd, 0, sizeof(*cmd)); + 378: e3a01000 mov r1, #0 + 37c: e3a0200c mov r2, #12 +struct cmd* +pipecmd(struct cmd *left, struct cmd *right) +{ + struct pipecmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 380: e1a04000 mov r4, r0 + memset(cmd, 0, sizeof(*cmd)); + 384: eb000204 bl b9c + cmd->type = PIPE; + 388: e3a03003 mov r3, #3 + cmd->left = left; + cmd->right = right; + 38c: e5845008 str r5, [r4, #8] + struct pipecmd *cmd; + + cmd = malloc(sizeof(*cmd)); + memset(cmd, 0, sizeof(*cmd)); + cmd->type = PIPE; + cmd->left = left; + 390: e8840048 stm r4, {r3, r6} + cmd->right = right; + return (struct cmd*)cmd; +} + 394: e1a00004 mov r0, r4 + 398: e8bd8878 pop {r3, r4, r5, r6, fp, pc} + +0000039c : + +struct cmd* +listcmd(struct cmd *left, struct cmd *right) +{ + 39c: e92d4878 push {r3, r4, r5, r6, fp, lr} + 3a0: e1a06000 mov r6, r0 + 3a4: e28db014 add fp, sp, #20 + struct listcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 3a8: e3a0000c mov r0, #12 + return (struct cmd*)cmd; +} + +struct cmd* +listcmd(struct cmd *left, struct cmd *right) +{ + 3ac: e1a05001 mov r5, r1 + struct listcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 3b0: eb000446 bl 14d0 + memset(cmd, 0, sizeof(*cmd)); + 3b4: e3a01000 mov r1, #0 + 3b8: e3a0200c mov r2, #12 +struct cmd* +listcmd(struct cmd *left, struct cmd *right) +{ + struct listcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 3bc: e1a04000 mov r4, r0 + memset(cmd, 0, sizeof(*cmd)); + 3c0: eb0001f5 bl b9c + cmd->type = LIST; + 3c4: e3a03004 mov r3, #4 + cmd->left = left; + cmd->right = right; + 3c8: e5845008 str r5, [r4, #8] + struct listcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + memset(cmd, 0, sizeof(*cmd)); + cmd->type = LIST; + cmd->left = left; + 3cc: e8840048 stm r4, {r3, r6} + cmd->right = right; + return (struct cmd*)cmd; +} + 3d0: e1a00004 mov r0, r4 + 3d4: e8bd8878 pop {r3, r4, r5, r6, fp, pc} + +000003d8 : + +struct cmd* +backcmd(struct cmd *subcmd) +{ + 3d8: e92d4830 push {r4, r5, fp, lr} + 3dc: e1a05000 mov r5, r0 + 3e0: e28db00c add fp, sp, #12 + struct backcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 3e4: e3a00008 mov r0, #8 + 3e8: eb000438 bl 14d0 + memset(cmd, 0, sizeof(*cmd)); + 3ec: e3a01000 mov r1, #0 + 3f0: e3a02008 mov r2, #8 +struct cmd* +backcmd(struct cmd *subcmd) +{ + struct backcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + 3f4: e1a04000 mov r4, r0 + memset(cmd, 0, sizeof(*cmd)); + 3f8: eb0001e7 bl b9c + cmd->type = BACK; + 3fc: e3a03005 mov r3, #5 + cmd->cmd = subcmd; + return (struct cmd*)cmd; +} + 400: e1a00004 mov r0, r4 + struct backcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + memset(cmd, 0, sizeof(*cmd)); + cmd->type = BACK; + cmd->cmd = subcmd; + 404: e8840028 stm r4, {r3, r5} + return (struct cmd*)cmd; +} + 408: e8bd8830 pop {r4, r5, fp, pc} + +0000040c : +char whitespace[] = " \t\r\n\v"; +char symbols[] = "<|>&;()"; + +int +gettoken(char **ps, char *es, char **q, char **eq) +{ + 40c: e92d4df0 push {r4, r5, r6, r7, r8, sl, fp, lr} + 410: e1a06000 mov r6, r0 + char *s; + int ret; + + s = *ps; + 414: e5904000 ldr r4, [r0] +char whitespace[] = " \t\r\n\v"; +char symbols[] = "<|>&;()"; + +int +gettoken(char **ps, char *es, char **q, char **eq) +{ + 418: e28db01c add fp, sp, #28 + char *s; + int ret; + + s = *ps; + while(s < es && strchr(whitespace, *s)) + 41c: e1540001 cmp r4, r1 +char whitespace[] = " \t\r\n\v"; +char symbols[] = "<|>&;()"; + +int +gettoken(char **ps, char *es, char **q, char **eq) +{ + 420: e1a05001 mov r5, r1 + 424: e1a07002 mov r7, r2 + 428: e1a0a003 mov sl, r3 + char *s; + int ret; + + s = *ps; + while(s < es && strchr(whitespace, *s)) + 42c: 31a08004 movcc r8, r4 + 430: 3a000003 bcc 444 + 434: ea000009 b 460 + 438: e1580005 cmp r8, r5 + s++; + 43c: e1a04008 mov r4, r8 +{ + char *s; + int ret; + + s = *ps; + while(s < es && strchr(whitespace, *s)) + 440: 0a000006 beq 460 + 444: e5d81000 ldrb r1, [r8] + 448: e59f0124 ldr r0, [pc, #292] ; 574 + 44c: eb0001e0 bl bd4 + 450: e1a04008 mov r4, r8 + 454: e2888001 add r8, r8, #1 + 458: e3500000 cmp r0, #0 + 45c: 1afffff5 bne 438 + s++; + if(q) + 460: e3570000 cmp r7, #0 + *q = s; + 464: 15874000 strne r4, [r7] + ret = *s; + 468: e5d48000 ldrb r8, [r4] + switch(*s){ + 46c: e358003c cmp r8, #60 ; 0x3c + s = *ps; + while(s < es && strchr(whitespace, *s)) + s++; + if(q) + *q = s; + ret = *s; + 470: e1a01008 mov r1, r8 + switch(*s){ + 474: 8a000015 bhi 4d0 + 478: e358003b cmp r8, #59 ; 0x3b + 47c: 3a00002d bcc 538 + case '&': + case '<': + s++; + break; + case '>': + s++; + 480: e2844001 add r4, r4, #1 + ret = 'a'; + while(s < es && !strchr(whitespace, *s) && !strchr(symbols, *s)) + s++; + break; + } + if(eq) + 484: e35a0000 cmp sl, #0 + *eq = s; + 488: 158a4000 strne r4, [sl] + + while(s < es && strchr(whitespace, *s)) + 48c: e1540005 cmp r4, r5 + 490: 31a07004 movcc r7, r4 + 494: 3a000003 bcc 4a8 + 498: ea000009 b 4c4 + 49c: e1570005 cmp r7, r5 + s++; + 4a0: e1a04007 mov r4, r7 + break; + } + if(eq) + *eq = s; + + while(s < es && strchr(whitespace, *s)) + 4a4: 0a000006 beq 4c4 + 4a8: e5d71000 ldrb r1, [r7] + 4ac: e59f00c0 ldr r0, [pc, #192] ; 574 + 4b0: eb0001c7 bl bd4 + 4b4: e1a04007 mov r4, r7 + 4b8: e2877001 add r7, r7, #1 + 4bc: e3500000 cmp r0, #0 + 4c0: 1afffff5 bne 49c + s++; + *ps = s; + 4c4: e5864000 str r4, [r6] + return ret; +} + 4c8: e1a00008 mov r0, r8 + 4cc: e8bd8df0 pop {r4, r5, r6, r7, r8, sl, fp, pc} + while(s < es && strchr(whitespace, *s)) + s++; + if(q) + *q = s; + ret = *s; + switch(*s){ + 4d0: e358003e cmp r8, #62 ; 0x3e + 4d4: 0a000020 beq 55c + 4d8: e358007c cmp r8, #124 ; 0x7c + 4dc: 0affffe7 beq 480 + s++; + } + break; + default: + ret = 'a'; + while(s < es && !strchr(whitespace, *s) && !strchr(symbols, *s)) + 4e0: e1550004 cmp r5, r4 + 4e4: 81a08004 movhi r8, r4 + 4e8: 81a07008 movhi r7, r8 + 4ec: 8a000008 bhi 514 + 4f0: ea00000e b 530 + 4f4: e5d41000 ldrb r1, [r4] + 4f8: eb0001b5 bl bd4 + 4fc: e3500000 cmp r0, #0 + 500: 1a00000a bne 530 + 504: e1570005 cmp r7, r5 + s++; + 508: e1a04007 mov r4, r7 + s++; + } + break; + default: + ret = 'a'; + while(s < es && !strchr(whitespace, *s) && !strchr(symbols, *s)) + 50c: 0a000007 beq 530 + 510: e5f81001 ldrb r1, [r8, #1]! + 514: e59f0058 ldr r0, [pc, #88] ; 574 + 518: eb0001ad bl bd4 + 51c: e1a04007 mov r4, r7 + 520: e2877001 add r7, r7, #1 + 524: e3500000 cmp r0, #0 + 528: e59f0048 ldr r0, [pc, #72] ; 578 + 52c: 0afffff0 beq 4f4 + ret = '+'; + s++; + } + break; + default: + ret = 'a'; + 530: e3a08061 mov r8, #97 ; 0x61 + 534: eaffffd2 b 484 + while(s < es && strchr(whitespace, *s)) + s++; + if(q) + *q = s; + ret = *s; + switch(*s){ + 538: e3580029 cmp r8, #41 ; 0x29 + 53c: 8affffe7 bhi 4e0 + 540: e3580028 cmp r8, #40 ; 0x28 + 544: 2affffcd bcs 480 + 548: e3580000 cmp r8, #0 + 54c: 0affffcc beq 484 + 550: e3580026 cmp r8, #38 ; 0x26 + 554: 1affffe1 bne 4e0 + 558: eaffffc8 b 480 + case '<': + s++; + break; + case '>': + s++; + if(*s == '>'){ + 55c: e5d43001 ldrb r3, [r4, #1] + 560: e353003e cmp r3, #62 ; 0x3e + ret = '+'; + s++; + 564: 02844002 addeq r4, r4, #2 + s++; + break; + case '>': + s++; + if(*s == '>'){ + ret = '+'; + 568: 03a0802b moveq r8, #43 ; 0x2b + case '<': + s++; + break; + case '>': + s++; + if(*s == '>'){ + 56c: 1affffc3 bne 480 + 570: eaffffc3 b 484 + 574: 000016b8 .word 0x000016b8 + 578: 000016c0 .word 0x000016c0 + +0000057c : + return ret; +} + +int +peek(char **ps, char *es, char *toks) +{ + 57c: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + 580: e1a06000 mov r6, r0 + char *s; + + s = *ps; + 584: e5904000 ldr r4, [r0] + return ret; +} + +int +peek(char **ps, char *es, char *toks) +{ + 588: e28db01c add fp, sp, #28 + char *s; + + s = *ps; + while(s < es && strchr(whitespace, *s)) + 58c: e1540001 cmp r4, r1 + return ret; +} + +int +peek(char **ps, char *es, char *toks) +{ + 590: e1a05001 mov r5, r1 + 594: e1a08002 mov r8, r2 + char *s; + + s = *ps; + while(s < es && strchr(whitespace, *s)) + 598: 31a07004 movcc r7, r4 + 59c: 3a000003 bcc 5b0 + 5a0: ea000009 b 5cc + 5a4: e1570005 cmp r7, r5 + s++; + 5a8: e1a04007 mov r4, r7 +peek(char **ps, char *es, char *toks) +{ + char *s; + + s = *ps; + while(s < es && strchr(whitespace, *s)) + 5ac: 0a000006 beq 5cc + 5b0: e5d71000 ldrb r1, [r7] + 5b4: e59f003c ldr r0, [pc, #60] ; 5f8 + 5b8: eb000185 bl bd4 + 5bc: e1a04007 mov r4, r7 + 5c0: e2877001 add r7, r7, #1 + 5c4: e3500000 cmp r0, #0 + 5c8: 1afffff5 bne 5a4 + s++; + *ps = s; + 5cc: e5864000 str r4, [r6] + return *s && strchr(toks, *s); + 5d0: e5d41000 ldrb r1, [r4] + 5d4: e3510000 cmp r1, #0 + 5d8: 1a000001 bne 5e4 + 5dc: e1a00001 mov r0, r1 +} + 5e0: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + + s = *ps; + while(s < es && strchr(whitespace, *s)) + s++; + *ps = s; + return *s && strchr(toks, *s); + 5e4: e1a00008 mov r0, r8 + 5e8: eb000179 bl bd4 + *ps = s; + return ret; +} + +int +peek(char **ps, char *es, char *toks) + 5ec: e2900000 adds r0, r0, #0 + 5f0: 13a00001 movne r0, #1 + 5f4: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + 5f8: 000016b8 .word 0x000016b8 + +000005fc : + return cmd; +} + +struct cmd* +parseredirs(struct cmd *cmd, char **ps, char *es) +{ + 5fc: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + 600: e28db018 add fp, sp, #24 + 604: e24dd014 sub sp, sp, #20 + 608: e1a07000 mov r7, r0 + 60c: e1a06001 mov r6, r1 + 610: e1a05002 mov r5, r2 + switch(tok){ + case '<': + cmd = redircmd(cmd, q, eq, O_RDONLY, 0); + break; + case '>': + cmd = redircmd(cmd, q, eq, O_WRONLY|O_CREATE, 1); + 614: e3a08001 mov r8, #1 +parseredirs(struct cmd *cmd, char **ps, char *es) +{ + int tok; + char *q, *eq; + + while(peek(ps, es, "<>")){ + 618: e1a00006 mov r0, r6 + 61c: e1a01005 mov r1, r5 + 620: e59f20c0 ldr r2, [pc, #192] ; 6e8 + 624: ebffffd4 bl 57c + 628: e3500000 cmp r0, #0 + 62c: 0a00001f beq 6b0 + tok = gettoken(ps, es, 0, 0); + 630: e3a02000 mov r2, #0 + 634: e1a03002 mov r3, r2 + 638: e1a01005 mov r1, r5 + 63c: e1a00006 mov r0, r6 + 640: ebffff71 bl 40c + if(gettoken(ps, es, &q, &eq) != 'a') + 644: e1a01005 mov r1, r5 + 648: e24b2024 sub r2, fp, #36 ; 0x24 + 64c: e24b3020 sub r3, fp, #32 +{ + int tok; + char *q, *eq; + + while(peek(ps, es, "<>")){ + tok = gettoken(ps, es, 0, 0); + 650: e1a04000 mov r4, r0 + if(gettoken(ps, es, &q, &eq) != 'a') + 654: e1a00006 mov r0, r6 + 658: ebffff6b bl 40c + 65c: e3500061 cmp r0, #97 ; 0x61 + 660: 1a00001e bne 6e0 + panic("missing file for redirection"); + switch(tok){ + 664: e354003c cmp r4, #60 ; 0x3c + 668: 0a000013 beq 6bc + 66c: e354003e cmp r4, #62 ; 0x3e + 670: 0a000001 beq 67c + 674: e354002b cmp r4, #43 ; 0x2b + 678: 1affffe6 bne 618 + break; + case '>': + cmd = redircmd(cmd, q, eq, O_WRONLY|O_CREATE, 1); + break; + case '+': // >> + cmd = redircmd(cmd, q, eq, O_WRONLY|O_CREATE, 1); + 67c: e1a00007 mov r0, r7 + 680: e51b1024 ldr r1, [fp, #-36] ; 0x24 + 684: e51b2020 ldr r2, [fp, #-32] + 688: e59f305c ldr r3, [pc, #92] ; 6ec + 68c: e58d8000 str r8, [sp] + 690: ebffff1d bl 30c +parseredirs(struct cmd *cmd, char **ps, char *es) +{ + int tok; + char *q, *eq; + + while(peek(ps, es, "<>")){ + 694: e1a01005 mov r1, r5 + 698: e59f2048 ldr r2, [pc, #72] ; 6e8 + break; + case '>': + cmd = redircmd(cmd, q, eq, O_WRONLY|O_CREATE, 1); + break; + case '+': // >> + cmd = redircmd(cmd, q, eq, O_WRONLY|O_CREATE, 1); + 69c: e1a07000 mov r7, r0 +parseredirs(struct cmd *cmd, char **ps, char *es) +{ + int tok; + char *q, *eq; + + while(peek(ps, es, "<>")){ + 6a0: e1a00006 mov r0, r6 + 6a4: ebffffb4 bl 57c + 6a8: e3500000 cmp r0, #0 + 6ac: 1affffdf bne 630 + cmd = redircmd(cmd, q, eq, O_WRONLY|O_CREATE, 1); + break; + } + } + return cmd; +} + 6b0: e1a00007 mov r0, r7 + 6b4: e24bd018 sub sp, fp, #24 + 6b8: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} + tok = gettoken(ps, es, 0, 0); + if(gettoken(ps, es, &q, &eq) != 'a') + panic("missing file for redirection"); + switch(tok){ + case '<': + cmd = redircmd(cmd, q, eq, O_RDONLY, 0); + 6bc: e3a0c000 mov ip, #0 + 6c0: e1a00007 mov r0, r7 + 6c4: e51b1024 ldr r1, [fp, #-36] ; 0x24 + 6c8: e51b2020 ldr r2, [fp, #-32] + 6cc: e1a0300c mov r3, ip + 6d0: e58dc000 str ip, [sp] + 6d4: ebffff0c bl 30c + 6d8: e1a07000 mov r7, r0 + break; + 6dc: eaffffcd b 618 + char *q, *eq; + + while(peek(ps, es, "<>")){ + tok = gettoken(ps, es, 0, 0); + if(gettoken(ps, es, &q, &eq) != 'a') + panic("missing file for redirection"); + 6e0: e59f0008 ldr r0, [pc, #8] ; 6f0 + 6e4: ebfffe8f bl 128 + 6e8: 0000161c .word 0x0000161c + 6ec: 00000201 .word 0x00000201 + 6f0: 000015fc .word 0x000015fc + +000006f4 : + return cmd; +} + +struct cmd* +parseexec(char **ps, char *es) +{ + 6f4: e92d4df0 push {r4, r5, r6, r7, r8, sl, fp, lr} + 6f8: e28db01c add fp, sp, #28 + 6fc: e24dd008 sub sp, sp, #8 + char *q, *eq; + int tok, argc; + struct execcmd *cmd; + struct cmd *ret; + + if(peek(ps, es, "(")) + 700: e59f20e8 ldr r2, [pc, #232] ; 7f0 + return cmd; +} + +struct cmd* +parseexec(char **ps, char *es) +{ + 704: e1a06000 mov r6, r0 + 708: e1a05001 mov r5, r1 + char *q, *eq; + int tok, argc; + struct execcmd *cmd; + struct cmd *ret; + + if(peek(ps, es, "(")) + 70c: ebffff9a bl 57c + 710: e2507000 subs r7, r0, #0 + 714: 1a000025 bne 7b0 + return parseblock(ps, es); + + ret = execcmd(); + 718: ebfffeef bl 2dc + cmd = (struct execcmd*)ret; + + argc = 0; + ret = parseredirs(ret, ps, es); + 71c: e1a01006 mov r1, r6 + 720: e1a02005 mov r2, r5 + struct cmd *ret; + + if(peek(ps, es, "(")) + return parseblock(ps, es); + + ret = execcmd(); + 724: e1a0a000 mov sl, r0 + cmd = (struct execcmd*)ret; + + argc = 0; + ret = parseredirs(ret, ps, es); + 728: ebffffb3 bl 5fc + 72c: e1a0400a mov r4, sl + 730: e1a08000 mov r8, r0 + while(!peek(ps, es, "|)&;")){ + 734: ea000004 b 74c + cmd->argv[argc] = q; + cmd->eargv[argc] = eq; + argc++; + if(argc >= MAXARGS) + panic("too many args"); + ret = parseredirs(ret, ps, es); + 738: e1a00008 mov r0, r8 + 73c: e1a01006 mov r1, r6 + 740: e1a02005 mov r2, r5 + 744: ebffffac bl 5fc + 748: e1a08000 mov r8, r0 + ret = execcmd(); + cmd = (struct execcmd*)ret; + + argc = 0; + ret = parseredirs(ret, ps, es); + while(!peek(ps, es, "|)&;")){ + 74c: e1a00006 mov r0, r6 + 750: e1a01005 mov r1, r5 + 754: e59f2098 ldr r2, [pc, #152] ; 7f4 + 758: ebffff87 bl 57c + 75c: e3500000 cmp r0, #0 + 760: 1a000019 bne 7cc + if((tok=gettoken(ps, es, &q, &eq)) == 0) + 764: e1a00006 mov r0, r6 + 768: e1a01005 mov r1, r5 + 76c: e24b2024 sub r2, fp, #36 ; 0x24 + 770: e24b3020 sub r3, fp, #32 + 774: ebffff24 bl 40c + 778: e3500000 cmp r0, #0 + 77c: 0a000012 beq 7cc + break; + if(tok != 'a') + 780: e3500061 cmp r0, #97 ; 0x61 + 784: 1a000017 bne 7e8 + panic("syntax"); + cmd->argv[argc] = q; + 788: e51b3024 ldr r3, [fp, #-36] ; 0x24 + cmd->eargv[argc] = eq; + argc++; + 78c: e2877001 add r7, r7, #1 + while(!peek(ps, es, "|)&;")){ + if((tok=gettoken(ps, es, &q, &eq)) == 0) + break; + if(tok != 'a') + panic("syntax"); + cmd->argv[argc] = q; + 790: e5843004 str r3, [r4, #4] + cmd->eargv[argc] = eq; + 794: e51b3020 ldr r3, [fp, #-32] + argc++; + if(argc >= MAXARGS) + 798: e357000a cmp r7, #10 + if((tok=gettoken(ps, es, &q, &eq)) == 0) + break; + if(tok != 'a') + panic("syntax"); + cmd->argv[argc] = q; + cmd->eargv[argc] = eq; + 79c: e584302c str r3, [r4, #44] ; 0x2c + argc++; + 7a0: e2844004 add r4, r4, #4 + if(argc >= MAXARGS) + 7a4: 1affffe3 bne 738 + panic("too many args"); + 7a8: e59f0048 ldr r0, [pc, #72] ; 7f8 + 7ac: ebfffe5d bl 128 + int tok, argc; + struct execcmd *cmd; + struct cmd *ret; + + if(peek(ps, es, "(")) + return parseblock(ps, es); + 7b0: e1a00006 mov r0, r6 + 7b4: e1a01005 mov r1, r5 + 7b8: eb000054 bl 910 + 7bc: e1a08000 mov r8, r0 + ret = parseredirs(ret, ps, es); + } + cmd->argv[argc] = 0; + cmd->eargv[argc] = 0; + return ret; +} + 7c0: e1a00008 mov r0, r8 + 7c4: e24bd01c sub sp, fp, #28 + 7c8: e8bd8df0 pop {r4, r5, r6, r7, r8, sl, fp, pc} + if(argc >= MAXARGS) + panic("too many args"); + ret = parseredirs(ret, ps, es); + } + cmd->argv[argc] = 0; + cmd->eargv[argc] = 0; + 7cc: e287300a add r3, r7, #10 + argc++; + if(argc >= MAXARGS) + panic("too many args"); + ret = parseredirs(ret, ps, es); + } + cmd->argv[argc] = 0; + 7d0: e08a7107 add r7, sl, r7, lsl #2 + cmd->eargv[argc] = 0; + 7d4: e08aa103 add sl, sl, r3, lsl #2 + argc++; + if(argc >= MAXARGS) + panic("too many args"); + ret = parseredirs(ret, ps, es); + } + cmd->argv[argc] = 0; + 7d8: e3a03000 mov r3, #0 + 7dc: e5873004 str r3, [r7, #4] + cmd->eargv[argc] = 0; + 7e0: e58a3004 str r3, [sl, #4] + return ret; + 7e4: eafffff5 b 7c0 + ret = parseredirs(ret, ps, es); + while(!peek(ps, es, "|)&;")){ + if((tok=gettoken(ps, es, &q, &eq)) == 0) + break; + if(tok != 'a') + panic("syntax"); + 7e8: e59f000c ldr r0, [pc, #12] ; 7fc + 7ec: ebfffe4d bl 128 + 7f0: 00001620 .word 0x00001620 + 7f4: 0000163c .word 0x0000163c + 7f8: 0000162c .word 0x0000162c + 7fc: 00001624 .word 0x00001624 + +00000800 : + return cmd; +} + +struct cmd* +parsepipe(char **ps, char *es) +{ + 800: e92d4878 push {r3, r4, r5, r6, fp, lr} + 804: e28db014 add fp, sp, #20 + 808: e1a05000 mov r5, r0 + 80c: e1a04001 mov r4, r1 + struct cmd *cmd; + + cmd = parseexec(ps, es); + 810: ebffffb7 bl 6f4 + if(peek(ps, es, "|")){ + 814: e1a01004 mov r1, r4 + 818: e59f2048 ldr r2, [pc, #72] ; 868 +struct cmd* +parsepipe(char **ps, char *es) +{ + struct cmd *cmd; + + cmd = parseexec(ps, es); + 81c: e1a06000 mov r6, r0 + if(peek(ps, es, "|")){ + 820: e1a00005 mov r0, r5 + 824: ebffff54 bl 57c + 828: e3500000 cmp r0, #0 + 82c: 1a000001 bne 838 + gettoken(ps, es, 0, 0); + cmd = pipecmd(cmd, parsepipe(ps, es)); + } + return cmd; +} + 830: e1a00006 mov r0, r6 + 834: e8bd8878 pop {r3, r4, r5, r6, fp, pc} +{ + struct cmd *cmd; + + cmd = parseexec(ps, es); + if(peek(ps, es, "|")){ + gettoken(ps, es, 0, 0); + 838: e3a02000 mov r2, #0 + 83c: e1a03002 mov r3, r2 + 840: e1a01004 mov r1, r4 + 844: e1a00005 mov r0, r5 + 848: ebfffeef bl 40c + cmd = pipecmd(cmd, parsepipe(ps, es)); + 84c: e1a01004 mov r1, r4 + 850: e1a00005 mov r0, r5 + 854: ebffffe9 bl 800 + 858: e1a01000 mov r1, r0 + 85c: e1a00006 mov r0, r6 + } + return cmd; +} + 860: e8bd4878 pop {r3, r4, r5, r6, fp, lr} + struct cmd *cmd; + + cmd = parseexec(ps, es); + if(peek(ps, es, "|")){ + gettoken(ps, es, 0, 0); + cmd = pipecmd(cmd, parsepipe(ps, es)); + 864: eafffebd b 360 + 868: 00001644 .word 0x00001644 + +0000086c : + return cmd; +} + +struct cmd* +parseline(char **ps, char *es) +{ + 86c: e92d48f0 push {r4, r5, r6, r7, fp, lr} + 870: e28db014 add fp, sp, #20 + 874: e1a05000 mov r5, r0 + 878: e1a04001 mov r4, r1 + struct cmd *cmd; + + cmd = parsepipe(ps, es); + 87c: ebffffdf bl 800 + 880: e1a06000 mov r6, r0 + while(peek(ps, es, "&")){ + 884: ea000003 b 898 + gettoken(ps, es, 0, 0); + 888: ebfffedf bl 40c + cmd = backcmd(cmd); + 88c: e1a00006 mov r0, r6 + 890: ebfffed0 bl 3d8 + 894: e1a06000 mov r6, r0 +parseline(char **ps, char *es) +{ + struct cmd *cmd; + + cmd = parsepipe(ps, es); + while(peek(ps, es, "&")){ + 898: e1a01004 mov r1, r4 + 89c: e59f2064 ldr r2, [pc, #100] ; 908 + 8a0: e1a00005 mov r0, r5 + 8a4: ebffff34 bl 57c + gettoken(ps, es, 0, 0); + 8a8: e3a02000 mov r2, #0 + 8ac: e1a01004 mov r1, r4 + 8b0: e1a03002 mov r3, r2 +parseline(char **ps, char *es) +{ + struct cmd *cmd; + + cmd = parsepipe(ps, es); + while(peek(ps, es, "&")){ + 8b4: e2507000 subs r7, r0, #0 + gettoken(ps, es, 0, 0); + 8b8: e1a00005 mov r0, r5 +parseline(char **ps, char *es) +{ + struct cmd *cmd; + + cmd = parsepipe(ps, es); + while(peek(ps, es, "&")){ + 8bc: 1afffff1 bne 888 + gettoken(ps, es, 0, 0); + cmd = backcmd(cmd); + } + if(peek(ps, es, ";")){ + 8c0: e59f2044 ldr r2, [pc, #68] ; 90c + 8c4: ebffff2c bl 57c + 8c8: e3500000 cmp r0, #0 + 8cc: 1a000001 bne 8d8 + gettoken(ps, es, 0, 0); + cmd = listcmd(cmd, parseline(ps, es)); + } + return cmd; +} + 8d0: e1a00006 mov r0, r6 + 8d4: e8bd88f0 pop {r4, r5, r6, r7, fp, pc} + while(peek(ps, es, "&")){ + gettoken(ps, es, 0, 0); + cmd = backcmd(cmd); + } + if(peek(ps, es, ";")){ + gettoken(ps, es, 0, 0); + 8d8: e1a02007 mov r2, r7 + 8dc: e1a03007 mov r3, r7 + 8e0: e1a01004 mov r1, r4 + 8e4: e1a00005 mov r0, r5 + 8e8: ebfffec7 bl 40c + cmd = listcmd(cmd, parseline(ps, es)); + 8ec: e1a01004 mov r1, r4 + 8f0: e1a00005 mov r0, r5 + 8f4: ebffffdc bl 86c + 8f8: e1a01000 mov r1, r0 + 8fc: e1a00006 mov r0, r6 + } + return cmd; +} + 900: e8bd48f0 pop {r4, r5, r6, r7, fp, lr} + gettoken(ps, es, 0, 0); + cmd = backcmd(cmd); + } + if(peek(ps, es, ";")){ + gettoken(ps, es, 0, 0); + cmd = listcmd(cmd, parseline(ps, es)); + 904: eafffea4 b 39c + 908: 00001648 .word 0x00001648 + 90c: 0000164c .word 0x0000164c + +00000910 : + return cmd; +} + +struct cmd* +parseblock(char **ps, char *es) +{ + 910: e92d4878 push {r3, r4, r5, r6, fp, lr} + 914: e28db014 add fp, sp, #20 + struct cmd *cmd; + + if(!peek(ps, es, "(")) + 918: e59f2084 ldr r2, [pc, #132] ; 9a4 + return cmd; +} + +struct cmd* +parseblock(char **ps, char *es) +{ + 91c: e1a05000 mov r5, r0 + 920: e1a04001 mov r4, r1 + struct cmd *cmd; + + if(!peek(ps, es, "(")) + 924: ebffff14 bl 57c + 928: e3500000 cmp r0, #0 + 92c: 0a000018 beq 994 + panic("parseblock"); + gettoken(ps, es, 0, 0); + 930: e3a02000 mov r2, #0 + 934: e1a03002 mov r3, r2 + 938: e1a01004 mov r1, r4 + 93c: e1a00005 mov r0, r5 + 940: ebfffeb1 bl 40c + cmd = parseline(ps, es); + 944: e1a01004 mov r1, r4 + 948: e1a00005 mov r0, r5 + 94c: ebffffc6 bl 86c + if(!peek(ps, es, ")")) + 950: e1a01004 mov r1, r4 + 954: e59f204c ldr r2, [pc, #76] ; 9a8 + struct cmd *cmd; + + if(!peek(ps, es, "(")) + panic("parseblock"); + gettoken(ps, es, 0, 0); + cmd = parseline(ps, es); + 958: e1a06000 mov r6, r0 + if(!peek(ps, es, ")")) + 95c: e1a00005 mov r0, r5 + 960: ebffff05 bl 57c + 964: e3500000 cmp r0, #0 + 968: 0a00000b beq 99c + panic("syntax - missing )"); + gettoken(ps, es, 0, 0); + 96c: e3a02000 mov r2, #0 + 970: e1a01004 mov r1, r4 + 974: e1a03002 mov r3, r2 + 978: e1a00005 mov r0, r5 + 97c: ebfffea2 bl 40c + cmd = parseredirs(cmd, ps, es); + 980: e1a00006 mov r0, r6 + 984: e1a01005 mov r1, r5 + 988: e1a02004 mov r2, r4 + return cmd; +} + 98c: e8bd4878 pop {r3, r4, r5, r6, fp, lr} + gettoken(ps, es, 0, 0); + cmd = parseline(ps, es); + if(!peek(ps, es, ")")) + panic("syntax - missing )"); + gettoken(ps, es, 0, 0); + cmd = parseredirs(cmd, ps, es); + 990: eaffff19 b 5fc +parseblock(char **ps, char *es) +{ + struct cmd *cmd; + + if(!peek(ps, es, "(")) + panic("parseblock"); + 994: e59f0010 ldr r0, [pc, #16] ; 9ac + 998: ebfffde2 bl 128 + gettoken(ps, es, 0, 0); + cmd = parseline(ps, es); + if(!peek(ps, es, ")")) + panic("syntax - missing )"); + 99c: e59f000c ldr r0, [pc, #12] ; 9b0 + 9a0: ebfffde0 bl 128 + 9a4: 00001620 .word 0x00001620 + 9a8: 0000165c .word 0x0000165c + 9ac: 00001650 .word 0x00001650 + 9b0: 00001660 .word 0x00001660 + +000009b4 : +} + +// NUL-terminate all the counted strings. +struct cmd* +nulterminate(struct cmd *cmd) +{ + 9b4: e92d4818 push {r3, r4, fp, lr} + struct execcmd *ecmd; + struct listcmd *lcmd; + struct pipecmd *pcmd; + struct redircmd *rcmd; + + if(cmd == 0) + 9b8: e2504000 subs r4, r0, #0 +} + +// NUL-terminate all the counted strings. +struct cmd* +nulterminate(struct cmd *cmd) +{ + 9bc: e28db00c add fp, sp, #12 + struct execcmd *ecmd; + struct listcmd *lcmd; + struct pipecmd *pcmd; + struct redircmd *rcmd; + + if(cmd == 0) + 9c0: 0a00000b beq 9f4 + return 0; + + switch(cmd->type){ + 9c4: e5943000 ldr r3, [r4] + 9c8: e2433001 sub r3, r3, #1 + 9cc: e3530004 cmp r3, #4 + 9d0: 979ff103 ldrls pc, [pc, r3, lsl #2] + 9d4: ea000006 b 9f4 + 9d8: 00000a14 .word 0x00000a14 + 9dc: 00000a4c .word 0x00000a4c + 9e0: 000009fc .word 0x000009fc + 9e4: 000009fc .word 0x000009fc + 9e8: 000009ec .word 0x000009ec + nulterminate(lcmd->right); + break; + + case BACK: + bcmd = (struct backcmd*)cmd; + nulterminate(bcmd->cmd); + 9ec: e5940004 ldr r0, [r4, #4] + 9f0: ebffffef bl 9b4 + break; + } + return cmd; +} + 9f4: e1a00004 mov r0, r4 + 9f8: e8bd8818 pop {r3, r4, fp, pc} + nulterminate(pcmd->right); + break; + + case LIST: + lcmd = (struct listcmd*)cmd; + nulterminate(lcmd->left); + 9fc: e5940004 ldr r0, [r4, #4] + a00: ebffffeb bl 9b4 + nulterminate(lcmd->right); + a04: e5940008 ldr r0, [r4, #8] + a08: ebffffe9 bl 9b4 + bcmd = (struct backcmd*)cmd; + nulterminate(bcmd->cmd); + break; + } + return cmd; +} + a0c: e1a00004 mov r0, r4 + a10: e8bd8818 pop {r3, r4, fp, pc} + return 0; + + switch(cmd->type){ + case EXEC: + ecmd = (struct execcmd*)cmd; + for(i=0; ecmd->argv[i]; i++) + a14: e5943004 ldr r3, [r4, #4] + a18: e3530000 cmp r3, #0 + a1c: 0afffff4 beq 9f4 + a20: e1a03004 mov r3, r4 + *ecmd->eargv[i] = 0; + a24: e3a00000 mov r0, #0 + a28: e593102c ldr r1, [r3, #44] ; 0x2c + return ret; +} + +// NUL-terminate all the counted strings. +struct cmd* +nulterminate(struct cmd *cmd) + a2c: e1a02003 mov r2, r3 + + switch(cmd->type){ + case EXEC: + ecmd = (struct execcmd*)cmd; + for(i=0; ecmd->argv[i]; i++) + *ecmd->eargv[i] = 0; + a30: e2833004 add r3, r3, #4 + a34: e5c10000 strb r0, [r1] + return 0; + + switch(cmd->type){ + case EXEC: + ecmd = (struct execcmd*)cmd; + for(i=0; ecmd->argv[i]; i++) + a38: e5922008 ldr r2, [r2, #8] + a3c: e3520000 cmp r2, #0 + a40: 1afffff8 bne a28 + bcmd = (struct backcmd*)cmd; + nulterminate(bcmd->cmd); + break; + } + return cmd; +} + a44: e1a00004 mov r0, r4 + a48: e8bd8818 pop {r3, r4, fp, pc} + *ecmd->eargv[i] = 0; + break; + + case REDIR: + rcmd = (struct redircmd*)cmd; + nulterminate(rcmd->cmd); + a4c: e5940004 ldr r0, [r4, #4] + a50: ebffffd7 bl 9b4 + *rcmd->efile = 0; + a54: e594300c ldr r3, [r4, #12] + a58: e3a02000 mov r2, #0 + bcmd = (struct backcmd*)cmd; + nulterminate(bcmd->cmd); + break; + } + return cmd; +} + a5c: e1a00004 mov r0, r4 + break; + + case REDIR: + rcmd = (struct redircmd*)cmd; + nulterminate(rcmd->cmd); + *rcmd->efile = 0; + a60: e5c32000 strb r2, [r3] + bcmd = (struct backcmd*)cmd; + nulterminate(bcmd->cmd); + break; + } + return cmd; +} + a64: e8bd8818 pop {r3, r4, fp, pc} + +00000a68 : +struct cmd *parseexec(char**, char*); +struct cmd *nulterminate(struct cmd*); + +struct cmd* +parsecmd(char *s) +{ + a68: e92d4870 push {r4, r5, r6, fp, lr} + a6c: e28db010 add fp, sp, #16 + a70: e24b6014 sub r6, fp, #20 + a74: e24dd00c sub sp, sp, #12 + a78: e5260004 str r0, [r6, #-4]! + char *es; + struct cmd *cmd; + + es = s + strlen(s); + a7c: e1a04000 mov r4, r0 + a80: eb000035 bl b5c + a84: e0844000 add r4, r4, r0 + cmd = parseline(&s, es); + a88: e1a01004 mov r1, r4 + a8c: e1a00006 mov r0, r6 + a90: ebffff75 bl 86c + peek(&s, es, ""); + a94: e59f2040 ldr r2, [pc, #64] ; adc + a98: e1a01004 mov r1, r4 +{ + char *es; + struct cmd *cmd; + + es = s + strlen(s); + cmd = parseline(&s, es); + a9c: e1a05000 mov r5, r0 + peek(&s, es, ""); + aa0: e1a00006 mov r0, r6 + aa4: ebfffeb4 bl 57c + if(s != es){ + aa8: e51b2018 ldr r2, [fp, #-24] + aac: e1520004 cmp r2, r4 + ab0: 1a000004 bne ac8 + printf(2, "leftovers: %s\n", s); + panic("syntax"); + } + nulterminate(cmd); + ab4: e1a00005 mov r0, r5 + ab8: ebffffbd bl 9b4 + return cmd; +} + abc: e1a00005 mov r0, r5 + ac0: e24bd010 sub sp, fp, #16 + ac4: e8bd8870 pop {r4, r5, r6, fp, pc} + + es = s + strlen(s); + cmd = parseline(&s, es); + peek(&s, es, ""); + if(s != es){ + printf(2, "leftovers: %s\n", s); + ac8: e3a00002 mov r0, #2 + acc: e59f100c ldr r1, [pc, #12] ; ae0 + ad0: eb0001ff bl 12d4 + panic("syntax"); + ad4: e59f0008 ldr r0, [pc, #8] ; ae4 + ad8: ebfffd92 bl 128 + adc: 00001640 .word 0x00001640 + ae0: 00001674 .word 0x00001674 + ae4: 00001624 .word 0x00001624 + +00000ae8 : +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + ae8: e52db004 push {fp} ; (str fp, [sp, #-4]!) + char *os; + + os = s; + while((*s++ = *t++) != 0) + aec: e1a02000 mov r2, r0 +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + af0: e28db000 add fp, sp, #0 + char *os; + + os = s; + while((*s++ = *t++) != 0) + af4: e4d13001 ldrb r3, [r1], #1 + af8: e3530000 cmp r3, #0 + afc: e4c23001 strb r3, [r2], #1 + b00: 1afffffb bne af4 + ; + return os; +} + b04: e28bd000 add sp, fp, #0 + b08: e8bd0800 pop {fp} + b0c: e12fff1e bx lr + +00000b10 : + +int +strcmp(const char *p, const char *q) +{ + b10: e52db004 push {fp} ; (str fp, [sp, #-4]!) + b14: e28db000 add fp, sp, #0 + while(*p && *p == *q) + b18: e5d03000 ldrb r3, [r0] + b1c: e5d12000 ldrb r2, [r1] + b20: e3530000 cmp r3, #0 + b24: 1a000004 bne b3c + b28: ea000005 b b44 + b2c: e5f03001 ldrb r3, [r0, #1]! + b30: e3530000 cmp r3, #0 + b34: 0a000006 beq b54 + b38: e5f12001 ldrb r2, [r1, #1]! + b3c: e1530002 cmp r3, r2 + b40: 0afffff9 beq b2c + p++, q++; + return (uchar)*p - (uchar)*q; +} + b44: e0620003 rsb r0, r2, r3 + b48: e28bd000 add sp, fp, #0 + b4c: e8bd0800 pop {fp} + b50: e12fff1e bx lr +} + +int +strcmp(const char *p, const char *q) +{ + while(*p && *p == *q) + b54: e5d12001 ldrb r2, [r1, #1] + b58: eafffff9 b b44 + +00000b5c : + return (uchar)*p - (uchar)*q; +} + +uint +strlen(char *s) +{ + b5c: e52db004 push {fp} ; (str fp, [sp, #-4]!) + b60: e28db000 add fp, sp, #0 + int n; + + for(n = 0; s[n]; n++) + b64: e5d03000 ldrb r3, [r0] + b68: e3530000 cmp r3, #0 + b6c: 01a00003 moveq r0, r3 + b70: 0a000006 beq b90 + b74: e1a02000 mov r2, r0 + b78: e3a03000 mov r3, #0 + b7c: e5f21001 ldrb r1, [r2, #1]! + b80: e2833001 add r3, r3, #1 + b84: e1a00003 mov r0, r3 + b88: e3510000 cmp r1, #0 + b8c: 1afffffa bne b7c + ; + return n; +} + b90: e28bd000 add sp, fp, #0 + b94: e8bd0800 pop {fp} + b98: e12fff1e bx lr + +00000b9c : +memset(void *dst, int c, uint n) +{ + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + b9c: e3520000 cmp r2, #0 + return n; +} + +void* +memset(void *dst, int c, uint n) +{ + ba0: e52db004 push {fp} ; (str fp, [sp, #-4]!) + ba4: e28db000 add fp, sp, #0 + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + ba8: 0a000006 beq bc8 + bac: e6ef1071 uxtb r1, r1 + bb0: e1a03002 mov r3, r2 +} + +void* +memset(void *dst, int c, uint n) +{ + char *p=dst; + bb4: e1a0c000 mov ip, r0 + u32 rc=n; + + while (rc-- > 0) *p++ = c; + bb8: e2533001 subs r3, r3, #1 + bbc: e4cc1001 strb r1, [ip], #1 + bc0: 1afffffc bne bb8 + bc4: e0800002 add r0, r0, r2 + return (void *)p; +} + bc8: e28bd000 add sp, fp, #0 + bcc: e8bd0800 pop {fp} + bd0: e12fff1e bx lr + +00000bd4 : + +char* +strchr(const char *s, char c) +{ + bd4: e52db004 push {fp} ; (str fp, [sp, #-4]!) + bd8: e28db000 add fp, sp, #0 + for(; *s; s++) + bdc: e5d03000 ldrb r3, [r0] + be0: e3530000 cmp r3, #0 + be4: 1a000004 bne bfc + be8: ea000008 b c10 + bec: e5d03001 ldrb r3, [r0, #1] + bf0: e2800001 add r0, r0, #1 + bf4: e3530000 cmp r3, #0 + bf8: 0a000004 beq c10 + if(*s == c) + bfc: e1530001 cmp r3, r1 + c00: 1afffff9 bne bec + return (char*)s; + return 0; +} + c04: e28bd000 add sp, fp, #0 + c08: e8bd0800 pop {fp} + c0c: e12fff1e bx lr +strchr(const char *s, char c) +{ + for(; *s; s++) + if(*s == c) + return (char*)s; + return 0; + c10: e1a00003 mov r0, r3 + c14: eafffffa b c04 + +00000c18 : +} + +char* +gets(char *buf, int max) +{ + c18: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + c1c: e28db018 add fp, sp, #24 + c20: e24dd00c sub sp, sp, #12 + c24: e1a08000 mov r8, r0 + c28: e1a07001 mov r7, r1 + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + c2c: e1a06000 mov r6, r0 + c30: e3a05000 mov r5, #0 + c34: ea000008 b c5c + cc = read(0, &c, 1); + c38: eb000079 bl e24 + if(cc < 1) + c3c: e3500000 cmp r0, #0 + c40: da00000b ble c74 + break; + buf[i++] = c; + c44: e55b301d ldrb r3, [fp, #-29] + if(c == '\n' || c == '\r') + c48: e1a05004 mov r5, r4 + c4c: e353000a cmp r3, #10 + c50: 1353000d cmpne r3, #13 + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + if(cc < 1) + break; + buf[i++] = c; + c54: e4c63001 strb r3, [r6], #1 + if(c == '\n' || c == '\r') + c58: 0a00000a beq c88 +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + c5c: e3a02001 mov r2, #1 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + c60: e0854002 add r4, r5, r2 + c64: e1540007 cmp r4, r7 + cc = read(0, &c, 1); + c68: e3a00000 mov r0, #0 + c6c: e24b101d sub r1, fp, #29 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + c70: bafffff0 blt c38 + break; + buf[i++] = c; + if(c == '\n' || c == '\r') + break; + } + buf[i] = '\0'; + c74: e3a03000 mov r3, #0 + c78: e7c83005 strb r3, [r8, r5] + return buf; +} + c7c: e1a00008 mov r0, r8 + c80: e24bd018 sub sp, fp, #24 + c84: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + c88: e1a05004 mov r5, r4 + c8c: eafffff8 b c74 + +00000c90 : + return buf; +} + +int +stat(char *n, struct stat *st) +{ + c90: e92d4830 push {r4, r5, fp, lr} + c94: e1a05001 mov r5, r1 + c98: e28db00c add fp, sp, #12 + int fd; + int r; + + fd = open(n, O_RDONLY); + c9c: e3a01000 mov r1, #0 + ca0: eb0000a0 bl f28 + if(fd < 0) + ca4: e2504000 subs r4, r0, #0 + return -1; + ca8: b3e05000 mvnlt r5, #0 +{ + int fd; + int r; + + fd = open(n, O_RDONLY); + if(fd < 0) + cac: ba000004 blt cc4 + return -1; + r = fstat(fd, st); + cb0: e1a01005 mov r1, r5 + cb4: eb0000c2 bl fc4 + cb8: e1a05000 mov r5, r0 + close(fd); + cbc: e1a00004 mov r0, r4 + cc0: eb000071 bl e8c + return r; +} + cc4: e1a00005 mov r0, r5 + cc8: e8bd8830 pop {r4, r5, fp, pc} + +00000ccc : + +int +atoi(const char *s) +{ + ccc: e52db004 push {fp} ; (str fp, [sp, #-4]!) + cd0: e28db000 add fp, sp, #0 + int n; + + n = 0; + while('0' <= *s && *s <= '9') + cd4: e5d03000 ldrb r3, [r0] + cd8: e2432030 sub r2, r3, #48 ; 0x30 + cdc: e6ef2072 uxtb r2, r2 + ce0: e3520009 cmp r2, #9 +int +atoi(const char *s) +{ + int n; + + n = 0; + ce4: 83a00000 movhi r0, #0 + while('0' <= *s && *s <= '9') + ce8: 8a000009 bhi d14 + cec: e1a02000 mov r2, r0 +int +atoi(const char *s) +{ + int n; + + n = 0; + cf0: e3a00000 mov r0, #0 + while('0' <= *s && *s <= '9') + n = n*10 + *s++ - '0'; + cf4: e0800100 add r0, r0, r0, lsl #2 + cf8: e0830080 add r0, r3, r0, lsl #1 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + cfc: e5f23001 ldrb r3, [r2, #1]! + n = n*10 + *s++ - '0'; + d00: e2400030 sub r0, r0, #48 ; 0x30 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + d04: e2431030 sub r1, r3, #48 ; 0x30 + d08: e6ef1071 uxtb r1, r1 + d0c: e3510009 cmp r1, #9 + d10: 9afffff7 bls cf4 + n = n*10 + *s++ - '0'; + return n; +} + d14: e28bd000 add sp, fp, #0 + d18: e8bd0800 pop {fp} + d1c: e12fff1e bx lr + +00000d20 : +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + d20: e3520000 cmp r2, #0 + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) +{ + d24: e52db004 push {fp} ; (str fp, [sp, #-4]!) + d28: e28db000 add fp, sp, #0 + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + d2c: da000005 ble d48 + n = n*10 + *s++ - '0'; + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) + d30: e0802002 add r2, r0, r2 +{ + char *dst, *src; + + dst = vdst; + d34: e1a03000 mov r3, r0 + src = vsrc; + while(n-- > 0) + *dst++ = *src++; + d38: e4d1c001 ldrb ip, [r1], #1 + d3c: e4c3c001 strb ip, [r3], #1 +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + d40: e1530002 cmp r3, r2 + d44: 1afffffb bne d38 + *dst++ = *src++; + return vdst; +} + d48: e28bd000 add sp, fp, #0 + d4c: e8bd0800 pop {fp} + d50: e12fff1e bx lr + +00000d54 : + d54: e92d4000 push {lr} + d58: e92d0008 push {r3} + d5c: e92d0004 push {r2} + d60: e92d0002 push {r1} + d64: e92d0001 push {r0} + d68: e3a00001 mov r0, #1 + d6c: ef000040 svc 0x00000040 + d70: e8bd0002 pop {r1} + d74: e8bd0002 pop {r1} + d78: e8bd0004 pop {r2} + d7c: e8bd0008 pop {r3} + d80: e8bd4000 pop {lr} + d84: e12fff1e bx lr + +00000d88 : + d88: e92d4000 push {lr} + d8c: e92d0008 push {r3} + d90: e92d0004 push {r2} + d94: e92d0002 push {r1} + d98: e92d0001 push {r0} + d9c: e3a00002 mov r0, #2 + da0: ef000040 svc 0x00000040 + da4: e8bd0002 pop {r1} + da8: e8bd0002 pop {r1} + dac: e8bd0004 pop {r2} + db0: e8bd0008 pop {r3} + db4: e8bd4000 pop {lr} + db8: e12fff1e bx lr + +00000dbc : + dbc: e92d4000 push {lr} + dc0: e92d0008 push {r3} + dc4: e92d0004 push {r2} + dc8: e92d0002 push {r1} + dcc: e92d0001 push {r0} + dd0: e3a00003 mov r0, #3 + dd4: ef000040 svc 0x00000040 + dd8: e8bd0002 pop {r1} + ddc: e8bd0002 pop {r1} + de0: e8bd0004 pop {r2} + de4: e8bd0008 pop {r3} + de8: e8bd4000 pop {lr} + dec: e12fff1e bx lr + +00000df0 : + df0: e92d4000 push {lr} + df4: e92d0008 push {r3} + df8: e92d0004 push {r2} + dfc: e92d0002 push {r1} + e00: e92d0001 push {r0} + e04: e3a00004 mov r0, #4 + e08: ef000040 svc 0x00000040 + e0c: e8bd0002 pop {r1} + e10: e8bd0002 pop {r1} + e14: e8bd0004 pop {r2} + e18: e8bd0008 pop {r3} + e1c: e8bd4000 pop {lr} + e20: e12fff1e bx lr + +00000e24 : + e24: e92d4000 push {lr} + e28: e92d0008 push {r3} + e2c: e92d0004 push {r2} + e30: e92d0002 push {r1} + e34: e92d0001 push {r0} + e38: e3a00005 mov r0, #5 + e3c: ef000040 svc 0x00000040 + e40: e8bd0002 pop {r1} + e44: e8bd0002 pop {r1} + e48: e8bd0004 pop {r2} + e4c: e8bd0008 pop {r3} + e50: e8bd4000 pop {lr} + e54: e12fff1e bx lr + +00000e58 : + e58: e92d4000 push {lr} + e5c: e92d0008 push {r3} + e60: e92d0004 push {r2} + e64: e92d0002 push {r1} + e68: e92d0001 push {r0} + e6c: e3a00010 mov r0, #16 + e70: ef000040 svc 0x00000040 + e74: e8bd0002 pop {r1} + e78: e8bd0002 pop {r1} + e7c: e8bd0004 pop {r2} + e80: e8bd0008 pop {r3} + e84: e8bd4000 pop {lr} + e88: e12fff1e bx lr + +00000e8c : + e8c: e92d4000 push {lr} + e90: e92d0008 push {r3} + e94: e92d0004 push {r2} + e98: e92d0002 push {r1} + e9c: e92d0001 push {r0} + ea0: e3a00015 mov r0, #21 + ea4: ef000040 svc 0x00000040 + ea8: e8bd0002 pop {r1} + eac: e8bd0002 pop {r1} + eb0: e8bd0004 pop {r2} + eb4: e8bd0008 pop {r3} + eb8: e8bd4000 pop {lr} + ebc: e12fff1e bx lr + +00000ec0 : + ec0: e92d4000 push {lr} + ec4: e92d0008 push {r3} + ec8: e92d0004 push {r2} + ecc: e92d0002 push {r1} + ed0: e92d0001 push {r0} + ed4: e3a00006 mov r0, #6 + ed8: ef000040 svc 0x00000040 + edc: e8bd0002 pop {r1} + ee0: e8bd0002 pop {r1} + ee4: e8bd0004 pop {r2} + ee8: e8bd0008 pop {r3} + eec: e8bd4000 pop {lr} + ef0: e12fff1e bx lr + +00000ef4 : + ef4: e92d4000 push {lr} + ef8: e92d0008 push {r3} + efc: e92d0004 push {r2} + f00: e92d0002 push {r1} + f04: e92d0001 push {r0} + f08: e3a00007 mov r0, #7 + f0c: ef000040 svc 0x00000040 + f10: e8bd0002 pop {r1} + f14: e8bd0002 pop {r1} + f18: e8bd0004 pop {r2} + f1c: e8bd0008 pop {r3} + f20: e8bd4000 pop {lr} + f24: e12fff1e bx lr + +00000f28 : + f28: e92d4000 push {lr} + f2c: e92d0008 push {r3} + f30: e92d0004 push {r2} + f34: e92d0002 push {r1} + f38: e92d0001 push {r0} + f3c: e3a0000f mov r0, #15 + f40: ef000040 svc 0x00000040 + f44: e8bd0002 pop {r1} + f48: e8bd0002 pop {r1} + f4c: e8bd0004 pop {r2} + f50: e8bd0008 pop {r3} + f54: e8bd4000 pop {lr} + f58: e12fff1e bx lr + +00000f5c : + f5c: e92d4000 push {lr} + f60: e92d0008 push {r3} + f64: e92d0004 push {r2} + f68: e92d0002 push {r1} + f6c: e92d0001 push {r0} + f70: e3a00011 mov r0, #17 + f74: ef000040 svc 0x00000040 + f78: e8bd0002 pop {r1} + f7c: e8bd0002 pop {r1} + f80: e8bd0004 pop {r2} + f84: e8bd0008 pop {r3} + f88: e8bd4000 pop {lr} + f8c: e12fff1e bx lr + +00000f90 : + f90: e92d4000 push {lr} + f94: e92d0008 push {r3} + f98: e92d0004 push {r2} + f9c: e92d0002 push {r1} + fa0: e92d0001 push {r0} + fa4: e3a00012 mov r0, #18 + fa8: ef000040 svc 0x00000040 + fac: e8bd0002 pop {r1} + fb0: e8bd0002 pop {r1} + fb4: e8bd0004 pop {r2} + fb8: e8bd0008 pop {r3} + fbc: e8bd4000 pop {lr} + fc0: e12fff1e bx lr + +00000fc4 : + fc4: e92d4000 push {lr} + fc8: e92d0008 push {r3} + fcc: e92d0004 push {r2} + fd0: e92d0002 push {r1} + fd4: e92d0001 push {r0} + fd8: e3a00008 mov r0, #8 + fdc: ef000040 svc 0x00000040 + fe0: e8bd0002 pop {r1} + fe4: e8bd0002 pop {r1} + fe8: e8bd0004 pop {r2} + fec: e8bd0008 pop {r3} + ff0: e8bd4000 pop {lr} + ff4: e12fff1e bx lr + +00000ff8 : + ff8: e92d4000 push {lr} + ffc: e92d0008 push {r3} + 1000: e92d0004 push {r2} + 1004: e92d0002 push {r1} + 1008: e92d0001 push {r0} + 100c: e3a00013 mov r0, #19 + 1010: ef000040 svc 0x00000040 + 1014: e8bd0002 pop {r1} + 1018: e8bd0002 pop {r1} + 101c: e8bd0004 pop {r2} + 1020: e8bd0008 pop {r3} + 1024: e8bd4000 pop {lr} + 1028: e12fff1e bx lr + +0000102c : + 102c: e92d4000 push {lr} + 1030: e92d0008 push {r3} + 1034: e92d0004 push {r2} + 1038: e92d0002 push {r1} + 103c: e92d0001 push {r0} + 1040: e3a00014 mov r0, #20 + 1044: ef000040 svc 0x00000040 + 1048: e8bd0002 pop {r1} + 104c: e8bd0002 pop {r1} + 1050: e8bd0004 pop {r2} + 1054: e8bd0008 pop {r3} + 1058: e8bd4000 pop {lr} + 105c: e12fff1e bx lr + +00001060 : + 1060: e92d4000 push {lr} + 1064: e92d0008 push {r3} + 1068: e92d0004 push {r2} + 106c: e92d0002 push {r1} + 1070: e92d0001 push {r0} + 1074: e3a00009 mov r0, #9 + 1078: ef000040 svc 0x00000040 + 107c: e8bd0002 pop {r1} + 1080: e8bd0002 pop {r1} + 1084: e8bd0004 pop {r2} + 1088: e8bd0008 pop {r3} + 108c: e8bd4000 pop {lr} + 1090: e12fff1e bx lr + +00001094 : + 1094: e92d4000 push {lr} + 1098: e92d0008 push {r3} + 109c: e92d0004 push {r2} + 10a0: e92d0002 push {r1} + 10a4: e92d0001 push {r0} + 10a8: e3a0000a mov r0, #10 + 10ac: ef000040 svc 0x00000040 + 10b0: e8bd0002 pop {r1} + 10b4: e8bd0002 pop {r1} + 10b8: e8bd0004 pop {r2} + 10bc: e8bd0008 pop {r3} + 10c0: e8bd4000 pop {lr} + 10c4: e12fff1e bx lr + +000010c8 : + 10c8: e92d4000 push {lr} + 10cc: e92d0008 push {r3} + 10d0: e92d0004 push {r2} + 10d4: e92d0002 push {r1} + 10d8: e92d0001 push {r0} + 10dc: e3a0000b mov r0, #11 + 10e0: ef000040 svc 0x00000040 + 10e4: e8bd0002 pop {r1} + 10e8: e8bd0002 pop {r1} + 10ec: e8bd0004 pop {r2} + 10f0: e8bd0008 pop {r3} + 10f4: e8bd4000 pop {lr} + 10f8: e12fff1e bx lr + +000010fc : + 10fc: e92d4000 push {lr} + 1100: e92d0008 push {r3} + 1104: e92d0004 push {r2} + 1108: e92d0002 push {r1} + 110c: e92d0001 push {r0} + 1110: e3a0000c mov r0, #12 + 1114: ef000040 svc 0x00000040 + 1118: e8bd0002 pop {r1} + 111c: e8bd0002 pop {r1} + 1120: e8bd0004 pop {r2} + 1124: e8bd0008 pop {r3} + 1128: e8bd4000 pop {lr} + 112c: e12fff1e bx lr + +00001130 : + 1130: e92d4000 push {lr} + 1134: e92d0008 push {r3} + 1138: e92d0004 push {r2} + 113c: e92d0002 push {r1} + 1140: e92d0001 push {r0} + 1144: e3a0000d mov r0, #13 + 1148: ef000040 svc 0x00000040 + 114c: e8bd0002 pop {r1} + 1150: e8bd0002 pop {r1} + 1154: e8bd0004 pop {r2} + 1158: e8bd0008 pop {r3} + 115c: e8bd4000 pop {lr} + 1160: e12fff1e bx lr + +00001164 : + 1164: e92d4000 push {lr} + 1168: e92d0008 push {r3} + 116c: e92d0004 push {r2} + 1170: e92d0002 push {r1} + 1174: e92d0001 push {r0} + 1178: e3a0000e mov r0, #14 + 117c: ef000040 svc 0x00000040 + 1180: e8bd0002 pop {r1} + 1184: e8bd0002 pop {r1} + 1188: e8bd0004 pop {r2} + 118c: e8bd0008 pop {r3} + 1190: e8bd4000 pop {lr} + 1194: e12fff1e bx lr + +00001198 : +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 1198: e92d4800 push {fp, lr} + 119c: e28db004 add fp, sp, #4 + 11a0: e24b3004 sub r3, fp, #4 + 11a4: e24dd008 sub sp, sp, #8 + write(fd, &c, 1); + 11a8: e3a02001 mov r2, #1 +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 11ac: e5631001 strb r1, [r3, #-1]! + write(fd, &c, 1); + 11b0: e1a01003 mov r1, r3 + 11b4: ebffff27 bl e58 +} + 11b8: e24bd004 sub sp, fp, #4 + 11bc: e8bd8800 pop {fp, pc} + +000011c0 : + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 11c0: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 11c4: e1a04000 mov r4, r0 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 11c8: e1a00fa1 lsr r0, r1, #31 + 11cc: e3530000 cmp r3, #0 + 11d0: 03a03000 moveq r3, #0 + 11d4: 12003001 andne r3, r0, #1 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 11d8: e28db020 add fp, sp, #32 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 11dc: e3530000 cmp r3, #0 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 11e0: e24dd014 sub sp, sp, #20 + 11e4: e59f909c ldr r9, [pc, #156] ; 1288 + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + x = -xx; + 11e8: 12611000 rsbne r1, r1, #0 + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + 11ec: 13a03001 movne r3, #1 + } else { + x = xx; + } + + b = base; + i = 0; + 11f0: e3a0a000 mov sl, #0 + 11f4: e24b6034 sub r6, fp, #52 ; 0x34 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 11f8: e3a08001 mov r8, #1 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 11fc: e3a07000 mov r7, #0 + int i; + + for(i=31;i>=0;i--){ + 1200: e3a0001f mov r0, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 1204: e1a0c007 mov ip, r7 + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 1208: e1a0e031 lsr lr, r1, r0 + 120c: e20ee001 and lr, lr, #1 + 1210: e18ec08c orr ip, lr, ip, lsl #1 + if(r >= d) { + 1214: e152000c cmp r2, ip + r = r - d; + q = q | (1 << i); + 1218: 91877018 orrls r7, r7, r8, lsl r0 + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 121c: 9062c00c rsbls ip, r2, ip +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 1220: e2500001 subs r0, r0, #1 + 1224: 2afffff7 bcs 1208 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 1228: e0000792 mul r0, r2, r7 + }while((x = y) != 0); + 122c: e3570000 cmp r7, #0 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 1230: e0601001 rsb r1, r0, r1 + 1234: e28a5001 add r5, sl, #1 + 1238: e7d91001 ldrb r1, [r9, r1] + 123c: e7c6100a strb r1, [r6, sl] + }while((x = y) != 0); + 1240: 11a01007 movne r1, r7 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 1244: 11a0a005 movne sl, r5 + 1248: 1affffeb bne 11fc + }while((x = y) != 0); + if(neg) + 124c: e3530000 cmp r3, #0 + buf[i++] = '-'; + 1250: 124b2024 subne r2, fp, #36 ; 0x24 + 1254: 10823005 addne r3, r2, r5 + 1258: 128a5002 addne r5, sl, #2 + + while(--i >= 0) + 125c: e2455001 sub r5, r5, #1 + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + 1260: 13a0202d movne r2, #45 ; 0x2d + 1264: 15432010 strbne r2, [r3, #-16] + + while(--i >= 0) + putc(fd, buf[i]); + 1268: e7d61005 ldrb r1, [r6, r5] + 126c: e1a00004 mov r0, r4 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 1270: e2455001 sub r5, r5, #1 + putc(fd, buf[i]); + 1274: ebffffc7 bl 1198 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 1278: e3750001 cmn r5, #1 + 127c: 1afffff9 bne 1268 + putc(fd, buf[i]); +} + 1280: e24bd020 sub sp, fp, #32 + 1284: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} + 1288: 0000169c .word 0x0000169c + +0000128c
: + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 128c: e3a03000 mov r3, #0 +{ + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + 1290: e92d0830 push {r4, r5, fp} + 1294: e1a02000 mov r2, r0 + 1298: e28db008 add fp, sp, #8 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 129c: e3a0c01f mov ip, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 12a0: e1a00003 mov r0, r3 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 12a4: e3a05001 mov r5, #1 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 12a8: e1a04c32 lsr r4, r2, ip + 12ac: e2044001 and r4, r4, #1 + 12b0: e1843083 orr r3, r4, r3, lsl #1 + if(r >= d) { + 12b4: e1530001 cmp r3, r1 + r = r - d; + q = q | (1 << i); + 12b8: 21800c15 orrcs r0, r0, r5, lsl ip + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 12bc: 20613003 rsbcs r3, r1, r3 +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 12c0: e25cc001 subs ip, ip, #1 + 12c4: 2afffff7 bcs 12a8 + r = r - d; + q = q | (1 << i); + } + } + return q; +} + 12c8: e24bd008 sub sp, fp, #8 + 12cc: e8bd0830 pop {r4, r5, fp} + 12d0: e12fff1e bx lr + +000012d4 : +} + +// Print to the given fd. Only understands %d, %x, %p, %s. +void +printf(int fd, char *fmt, ...) +{ + 12d4: e92d000e push {r1, r2, r3} + 12d8: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 12dc: e28db020 add fp, sp, #32 + 12e0: e1a05000 mov r5, r0 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 12e4: e59b4004 ldr r4, [fp, #4] + 12e8: e5d48000 ldrb r8, [r4] + 12ec: e3580000 cmp r8, #0 + 12f0: 0a000027 beq 1394 + ap++; + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + 12f4: e59f712c ldr r7, [pc, #300] ; 1428 + char *s; + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + 12f8: e28b6008 add r6, fp, #8 +{ + char *s; + int c, i, state; + uint *ap; + + state = 0; + 12fc: e3a0a000 mov sl, #0 + 1300: ea000008 b 1328 + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 1304: e3580025 cmp r8, #37 ; 0x25 + state = '%'; + 1308: 01a0a008 moveq sl, r8 + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 130c: 0a000002 beq 131c + state = '%'; + } else { + putc(fd, c); + 1310: e1a00005 mov r0, r5 + 1314: e1a01008 mov r1, r8 + 1318: ebffff9e bl 1198 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 131c: e5f48001 ldrb r8, [r4, #1]! + 1320: e3580000 cmp r8, #0 + 1324: 0a00001a beq 1394 + c = fmt[i] & 0xff; + if(state == 0){ + 1328: e35a0000 cmp sl, #0 + 132c: 0afffff4 beq 1304 + if(c == '%'){ + state = '%'; + } else { + putc(fd, c); + } + } else if(state == '%'){ + 1330: e35a0025 cmp sl, #37 ; 0x25 + 1334: 1afffff8 bne 131c + if(c == 'd'){ + 1338: e3580064 cmp r8, #100 ; 0x64 + 133c: 0a00002c beq 13f4 + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + 1340: e3580078 cmp r8, #120 ; 0x78 + 1344: 13580070 cmpne r8, #112 ; 0x70 + 1348: 13a09000 movne r9, #0 + 134c: 03a09001 moveq r9, #1 + 1350: 0a000013 beq 13a4 + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + 1354: e3580073 cmp r8, #115 ; 0x73 + 1358: 0a000018 beq 13c0 + s = "(null)"; + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + 135c: e3580063 cmp r8, #99 ; 0x63 + 1360: 0a00002a beq 1410 + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 1364: e3580025 cmp r8, #37 ; 0x25 + putc(fd, c); + 1368: e1a0100a mov r1, sl + 136c: e1a00005 mov r0, r5 + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 1370: 0a000002 beq 1380 + putc(fd, c); + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + 1374: ebffff87 bl 1198 + putc(fd, c); + 1378: e1a00005 mov r0, r5 + 137c: e1a01008 mov r1, r8 + 1380: ebffff84 bl 1198 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 1384: e5f48001 ldrb r8, [r4, #1]! + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 1388: e1a0a009 mov sl, r9 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 138c: e3580000 cmp r8, #0 + 1390: 1affffe4 bne 1328 + putc(fd, c); + } + state = 0; + } + } +} + 1394: e24bd020 sub sp, fp, #32 + 1398: e8bd4ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 139c: e28dd00c add sp, sp, #12 + 13a0: e12fff1e bx lr + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + 13a4: e1a00005 mov r0, r5 + 13a8: e4961004 ldr r1, [r6], #4 + 13ac: e3a02010 mov r2, #16 + 13b0: e3a03000 mov r3, #0 + 13b4: ebffff81 bl 11c0 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 13b8: e3a0a000 mov sl, #0 + 13bc: eaffffd6 b 131c + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + s = (char*)*ap; + 13c0: e4968004 ldr r8, [r6], #4 + ap++; + if(s == 0) + s = "(null)"; + 13c4: e3580000 cmp r8, #0 + 13c8: 01a08007 moveq r8, r7 + while(*s != 0){ + 13cc: e5d81000 ldrb r1, [r8] + 13d0: e3510000 cmp r1, #0 + 13d4: 0a000004 beq 13ec + putc(fd, *s); + 13d8: e1a00005 mov r0, r5 + 13dc: ebffff6d bl 1198 + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + while(*s != 0){ + 13e0: e5f81001 ldrb r1, [r8, #1]! + 13e4: e3510000 cmp r1, #0 + 13e8: 1afffffa bne 13d8 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 13ec: e1a0a001 mov sl, r1 + 13f0: eaffffc9 b 131c + } else { + putc(fd, c); + } + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + 13f4: e1a00005 mov r0, r5 + 13f8: e4961004 ldr r1, [r6], #4 + 13fc: e3a0200a mov r2, #10 + 1400: e3a03001 mov r3, #1 + 1404: ebffff6d bl 11c0 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 1408: e3a0a000 mov sl, #0 + 140c: eaffffc2 b 131c + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 1410: e4961004 ldr r1, [r6], #4 + 1414: e1a00005 mov r0, r5 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 1418: e1a0a009 mov sl, r9 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 141c: e6ef1071 uxtb r1, r1 + 1420: ebffff5c bl 1198 + 1424: eaffffbc b 131c + 1428: 000016b0 .word 0x000016b0 + +0000142c : +free(void *ap) +{ + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 142c: e59f3098 ldr r3, [pc, #152] ; 14cc +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 1430: e92d0830 push {r4, r5, fp} + Header *bp, *p; + + bp = (Header*)ap - 1; + 1434: e240c008 sub ip, r0, #8 + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 1438: e5932000 ldr r2, [r3] +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 143c: e28db008 add fp, sp, #8 + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 1440: e152000c cmp r2, ip + 1444: e5921000 ldr r1, [r2] + 1448: 2a000001 bcs 1454 + 144c: e15c0001 cmp ip, r1 + 1450: 3a000007 bcc 1474 + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + 1454: e1520001 cmp r2, r1 + 1458: 3a000003 bcc 146c + 145c: e152000c cmp r2, ip + 1460: 3a000003 bcc 1474 + 1464: e15c0001 cmp ip, r1 + 1468: 3a000001 bcc 1474 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 146c: e1a02001 mov r2, r1 + 1470: eafffff2 b 1440 + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + 1474: e5104004 ldr r4, [r0, #-4] + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + freep = p; + 1478: e5832000 str r2, [r3] + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + 147c: e08c5184 add r5, ip, r4, lsl #3 + 1480: e1550001 cmp r5, r1 + bp->s.size += p->s.ptr->s.size; + 1484: 05911004 ldreq r1, [r1, #4] + 1488: 00814004 addeq r4, r1, r4 + 148c: 05004004 streq r4, [r0, #-4] + bp->s.ptr = p->s.ptr->s.ptr; + 1490: 05921000 ldreq r1, [r2] + 1494: 05911000 ldreq r1, [r1] + } else + bp->s.ptr = p->s.ptr; + 1498: e5001008 str r1, [r0, #-8] + if(p + p->s.size == bp){ + 149c: e5921004 ldr r1, [r2, #4] + 14a0: e0824181 add r4, r2, r1, lsl #3 + 14a4: e15c0004 cmp ip, r4 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + 14a8: 1582c000 strne ip, [r2] + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + } else + bp->s.ptr = p->s.ptr; + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + 14ac: 0510c004 ldreq ip, [r0, #-4] + 14b0: 008c1001 addeq r1, ip, r1 + 14b4: 05821004 streq r1, [r2, #4] + p->s.ptr = bp->s.ptr; + 14b8: 05101008 ldreq r1, [r0, #-8] + 14bc: 05821000 streq r1, [r2] + } else + p->s.ptr = bp; + freep = p; +} + 14c0: e24bd008 sub sp, fp, #8 + 14c4: e8bd0830 pop {r4, r5, fp} + 14c8: e12fff1e bx lr + 14cc: 0000172c .word 0x0000172c + +000014d0 : + return freep; +} + +void* +malloc(uint nbytes) +{ + 14d0: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + 14d4: e2804007 add r4, r0, #7 + if((prevp = freep) == 0){ + 14d8: e59f50d4 ldr r5, [pc, #212] ; 15b4 +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + 14dc: e1a041a4 lsr r4, r4, #3 + return freep; +} + +void* +malloc(uint nbytes) +{ + 14e0: e28db01c add fp, sp, #28 + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + 14e4: e5953000 ldr r3, [r5] +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + 14e8: e2844001 add r4, r4, #1 + if((prevp = freep) == 0){ + 14ec: e3530000 cmp r3, #0 + 14f0: 0a00002b beq 15a4 + 14f4: e5930000 ldr r0, [r3] + 14f8: e5902004 ldr r2, [r0, #4] + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + 14fc: e1520004 cmp r2, r4 + 1500: 2a00001b bcs 1574 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + 1504: e59f80ac ldr r8, [pc, #172] ; 15b8 + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + 1508: e1a07184 lsl r7, r4, #3 + 150c: ea000003 b 1520 + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + 1510: e5930000 ldr r0, [r3] + if(p->s.size >= nunits){ + 1514: e5902004 ldr r2, [r0, #4] + 1518: e1540002 cmp r4, r2 + 151c: 9a000014 bls 1574 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + 1520: e5952000 ldr r2, [r5] + 1524: e1a03000 mov r3, r0 + 1528: e1500002 cmp r0, r2 + 152c: 1afffff7 bne 1510 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + 1530: e1540008 cmp r4, r8 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + 1534: 81a00007 movhi r0, r7 + 1538: 93a00902 movls r0, #32768 ; 0x8000 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + 153c: 81a06004 movhi r6, r4 + 1540: 93a06a01 movls r6, #4096 ; 0x1000 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + 1544: ebfffeec bl 10fc + 1548: e1a03000 mov r3, r0 + if(p == (char*)-1) + 154c: e3730001 cmn r3, #1 + return 0; + hp = (Header*)p; + hp->s.size = nu; + free((void*)(hp + 1)); + 1550: e2800008 add r0, r0, #8 + Header *hp; + + if(nu < 4096) + nu = 4096; + p = sbrk(nu * sizeof(Header)); + if(p == (char*)-1) + 1554: 0a000010 beq 159c + return 0; + hp = (Header*)p; + hp->s.size = nu; + 1558: e5836004 str r6, [r3, #4] + free((void*)(hp + 1)); + 155c: ebffffb2 bl 142c + return freep; + 1560: e5953000 ldr r3, [r5] + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + if((p = morecore(nunits)) == 0) + 1564: e3530000 cmp r3, #0 + 1568: 1affffe8 bne 1510 + return 0; + 156c: e1a00003 mov r0, r3 + } +} + 1570: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + 1574: e1540002 cmp r4, r2 + prevp->s.ptr = p->s.ptr; + else { + p->s.size -= nunits; + 1578: 10642002 rsbne r2, r4, r2 + 157c: 15802004 strne r2, [r0, #4] + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + 1580: 05902000 ldreq r2, [r0] + else { + p->s.size -= nunits; + p += p->s.size; + 1584: 10800182 addne r0, r0, r2, lsl #3 + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + 1588: 05832000 streq r2, [r3] + else { + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + 158c: 15804004 strne r4, [r0, #4] + } + freep = prevp; + 1590: e5853000 str r3, [r5] + return (void*)(p + 1); + 1594: e2800008 add r0, r0, #8 + 1598: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + } + if(p == freep) + if((p = morecore(nunits)) == 0) + return 0; + 159c: e3a00000 mov r0, #0 + 15a0: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + 15a4: e2850004 add r0, r5, #4 + 15a8: e5850000 str r0, [r5] + base.s.size = 0; + 15ac: e9850009 stmib r5, {r0, r3} + 15b0: eaffffd3 b 1504 + 15b4: 0000172c .word 0x0000172c + 15b8: 00000fff .word 0x00000fff diff -r 000000000000 -r c450faca55f4 uprogs/sh.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/sh.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,494 @@ +// Shell. + +#include "types.h" +#include "user.h" +#include "fcntl.h" + +// Parsed command representation +#define EXEC 1 +#define REDIR 2 +#define PIPE 3 +#define LIST 4 +#define BACK 5 + +#define MAXARGS 10 + +struct cmd { + int type; +}; + +struct execcmd { + int type; + char *argv[MAXARGS]; + char *eargv[MAXARGS]; +}; + +struct redircmd { + int type; + struct cmd *cmd; + char *file; + char *efile; + int mode; + int fd; +}; + +struct pipecmd { + int type; + struct cmd *left; + struct cmd *right; +}; + +struct listcmd { + int type; + struct cmd *left; + struct cmd *right; +}; + +struct backcmd { + int type; + struct cmd *cmd; +}; + +int fork1(void); // Fork but panics on failure. +void panic(char*); +struct cmd *parsecmd(char*); + +// Execute cmd. Never returns. +void +runcmd(struct cmd *cmd) +{ + int p[2]; + struct backcmd *bcmd; + struct execcmd *ecmd; + struct listcmd *lcmd; + struct pipecmd *pcmd; + struct redircmd *rcmd; + + if(cmd == 0) + exit(); + + switch(cmd->type){ + default: + panic("runcmd"); + + case EXEC: + ecmd = (struct execcmd*)cmd; + if(ecmd->argv[0] == 0) + exit(); + exec(ecmd->argv[0], ecmd->argv); + printf(2, "exec %s failed\n", ecmd->argv[0]); + break; + + case REDIR: + rcmd = (struct redircmd*)cmd; + close(rcmd->fd); + if(open(rcmd->file, rcmd->mode) < 0){ + printf(2, "open %s failed\n", rcmd->file); + exit(); + } + runcmd(rcmd->cmd); + break; + + case LIST: + lcmd = (struct listcmd*)cmd; + if(fork1() == 0) + runcmd(lcmd->left); + wait(); + runcmd(lcmd->right); + break; + + case PIPE: + pcmd = (struct pipecmd*)cmd; + if(pipe(p) < 0) + panic("pipe"); + if(fork1() == 0){ + close(1); + dup(p[1]); + close(p[0]); + close(p[1]); + runcmd(pcmd->left); + } + if(fork1() == 0){ + close(0); + dup(p[0]); + close(p[0]); + close(p[1]); + runcmd(pcmd->right); + } + close(p[0]); + close(p[1]); + wait(); + wait(); + break; + + case BACK: + bcmd = (struct backcmd*)cmd; + if(fork1() == 0) + runcmd(bcmd->cmd); + break; + } + exit(); +} + +int +getcmd(char *buf, int nbuf) +{ + printf(2, "$ "); + memset(buf, 0, nbuf); + gets(buf, nbuf); + if(buf[0] == 0) // EOF + return -1; + return 0; +} + +int +main(void) +{ + static char buf[100]; + int fd; + + // Assumes three file descriptors open. + while((fd = open("console", O_RDWR)) >= 0){ + if(fd >= 3){ + close(fd); + break; + } + } + + // Read and run input commands. + while(getcmd(buf, sizeof(buf)) >= 0){ + if(buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' '){ + // Clumsy but will have to do for now. + // Chdir has no effect on the parent if run in the child. + buf[strlen(buf)-1] = 0; // chop \n + if(chdir(buf+3) < 0) + printf(2, "cannot cd %s\n", buf+3); + continue; + } + if(fork1() == 0) + runcmd(parsecmd(buf)); + wait(); + } + exit(); +} + +void +panic(char *s) +{ + printf(2, "%s\n", s); + exit(); +} + +int +fork1(void) +{ + int pid; + + pid = fork(); + if(pid == -1) + panic("fork"); + return pid; +} + +//PAGEBREAK! +// Constructors + +struct cmd* +execcmd(void) +{ + struct execcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + memset(cmd, 0, sizeof(*cmd)); + cmd->type = EXEC; + return (struct cmd*)cmd; +} + +struct cmd* +redircmd(struct cmd *subcmd, char *file, char *efile, int mode, int fd) +{ + struct redircmd *cmd; + + cmd = malloc(sizeof(*cmd)); + memset(cmd, 0, sizeof(*cmd)); + cmd->type = REDIR; + cmd->cmd = subcmd; + cmd->file = file; + cmd->efile = efile; + cmd->mode = mode; + cmd->fd = fd; + return (struct cmd*)cmd; +} + +struct cmd* +pipecmd(struct cmd *left, struct cmd *right) +{ + struct pipecmd *cmd; + + cmd = malloc(sizeof(*cmd)); + memset(cmd, 0, sizeof(*cmd)); + cmd->type = PIPE; + cmd->left = left; + cmd->right = right; + return (struct cmd*)cmd; +} + +struct cmd* +listcmd(struct cmd *left, struct cmd *right) +{ + struct listcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + memset(cmd, 0, sizeof(*cmd)); + cmd->type = LIST; + cmd->left = left; + cmd->right = right; + return (struct cmd*)cmd; +} + +struct cmd* +backcmd(struct cmd *subcmd) +{ + struct backcmd *cmd; + + cmd = malloc(sizeof(*cmd)); + memset(cmd, 0, sizeof(*cmd)); + cmd->type = BACK; + cmd->cmd = subcmd; + return (struct cmd*)cmd; +} +//PAGEBREAK! +// Parsing + +char whitespace[] = " \t\r\n\v"; +char symbols[] = "<|>&;()"; + +int +gettoken(char **ps, char *es, char **q, char **eq) +{ + char *s; + int ret; + + s = *ps; + while(s < es && strchr(whitespace, *s)) + s++; + if(q) + *q = s; + ret = *s; + switch(*s){ + case 0: + break; + case '|': + case '(': + case ')': + case ';': + case '&': + case '<': + s++; + break; + case '>': + s++; + if(*s == '>'){ + ret = '+'; + s++; + } + break; + default: + ret = 'a'; + while(s < es && !strchr(whitespace, *s) && !strchr(symbols, *s)) + s++; + break; + } + if(eq) + *eq = s; + + while(s < es && strchr(whitespace, *s)) + s++; + *ps = s; + return ret; +} + +int +peek(char **ps, char *es, char *toks) +{ + char *s; + + s = *ps; + while(s < es && strchr(whitespace, *s)) + s++; + *ps = s; + return *s && strchr(toks, *s); +} + +struct cmd *parseline(char**, char*); +struct cmd *parsepipe(char**, char*); +struct cmd *parseexec(char**, char*); +struct cmd *nulterminate(struct cmd*); + +struct cmd* +parsecmd(char *s) +{ + char *es; + struct cmd *cmd; + + es = s + strlen(s); + cmd = parseline(&s, es); + peek(&s, es, ""); + if(s != es){ + printf(2, "leftovers: %s\n", s); + panic("syntax"); + } + nulterminate(cmd); + return cmd; +} + +struct cmd* +parseline(char **ps, char *es) +{ + struct cmd *cmd; + + cmd = parsepipe(ps, es); + while(peek(ps, es, "&")){ + gettoken(ps, es, 0, 0); + cmd = backcmd(cmd); + } + if(peek(ps, es, ";")){ + gettoken(ps, es, 0, 0); + cmd = listcmd(cmd, parseline(ps, es)); + } + return cmd; +} + +struct cmd* +parsepipe(char **ps, char *es) +{ + struct cmd *cmd; + + cmd = parseexec(ps, es); + if(peek(ps, es, "|")){ + gettoken(ps, es, 0, 0); + cmd = pipecmd(cmd, parsepipe(ps, es)); + } + return cmd; +} + +struct cmd* +parseredirs(struct cmd *cmd, char **ps, char *es) +{ + int tok; + char *q, *eq; + + while(peek(ps, es, "<>")){ + tok = gettoken(ps, es, 0, 0); + if(gettoken(ps, es, &q, &eq) != 'a') + panic("missing file for redirection"); + switch(tok){ + case '<': + cmd = redircmd(cmd, q, eq, O_RDONLY, 0); + break; + case '>': + cmd = redircmd(cmd, q, eq, O_WRONLY|O_CREATE, 1); + break; + case '+': // >> + cmd = redircmd(cmd, q, eq, O_WRONLY|O_CREATE, 1); + break; + } + } + return cmd; +} + +struct cmd* +parseblock(char **ps, char *es) +{ + struct cmd *cmd; + + if(!peek(ps, es, "(")) + panic("parseblock"); + gettoken(ps, es, 0, 0); + cmd = parseline(ps, es); + if(!peek(ps, es, ")")) + panic("syntax - missing )"); + gettoken(ps, es, 0, 0); + cmd = parseredirs(cmd, ps, es); + return cmd; +} + +struct cmd* +parseexec(char **ps, char *es) +{ + char *q, *eq; + int tok, argc; + struct execcmd *cmd; + struct cmd *ret; + + if(peek(ps, es, "(")) + return parseblock(ps, es); + + ret = execcmd(); + cmd = (struct execcmd*)ret; + + argc = 0; + ret = parseredirs(ret, ps, es); + while(!peek(ps, es, "|)&;")){ + if((tok=gettoken(ps, es, &q, &eq)) == 0) + break; + if(tok != 'a') + panic("syntax"); + cmd->argv[argc] = q; + cmd->eargv[argc] = eq; + argc++; + if(argc >= MAXARGS) + panic("too many args"); + ret = parseredirs(ret, ps, es); + } + cmd->argv[argc] = 0; + cmd->eargv[argc] = 0; + return ret; +} + +// NUL-terminate all the counted strings. +struct cmd* +nulterminate(struct cmd *cmd) +{ + int i; + struct backcmd *bcmd; + struct execcmd *ecmd; + struct listcmd *lcmd; + struct pipecmd *pcmd; + struct redircmd *rcmd; + + if(cmd == 0) + return 0; + + switch(cmd->type){ + case EXEC: + ecmd = (struct execcmd*)cmd; + for(i=0; ecmd->argv[i]; i++) + *ecmd->eargv[i] = 0; + break; + + case REDIR: + rcmd = (struct redircmd*)cmd; + nulterminate(rcmd->cmd); + *rcmd->efile = 0; + break; + + case PIPE: + pcmd = (struct pipecmd*)cmd; + nulterminate(pcmd->left); + nulterminate(pcmd->right); + break; + + case LIST: + lcmd = (struct listcmd*)cmd; + nulterminate(lcmd->left); + nulterminate(lcmd->right); + break; + + case BACK: + bcmd = (struct backcmd*)cmd; + nulterminate(bcmd->cmd); + break; + } + return cmd; +} diff -r 000000000000 -r c450faca55f4 uprogs/sh.sym --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/sh.sym Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,86 @@ +00000000 .text +000015bc .rodata +000016b8 .data +000016c8 .bss +00000000 .comment +00000000 .ARM.attributes +00000000 .debug_aranges +00000000 .debug_info +00000000 .debug_abbrev +00000000 .debug_line +00000000 .debug_frame +00000000 .debug_str +00000000 .debug_loc +00000000 .debug_ranges +00000000 sh.c +000016c8 buf.1021 +00000000 ulib.c +00000000 printf.c +00001198 putc +000011c0 printint +0000169c digits.993 +00000000 umalloc.c +0000172c freep +00001730 base +00000ae8 strcpy +000012d4 printf +00000d20 memmove +00000f5c mknod +000002dc execcmd +00001738 _bss_end__ +00000c18 gets +000010c8 getpid +00000800 parsepipe +00000a68 parsecmd +000003d8 backcmd +0000057c peek +000005fc parseredirs +0000040c gettoken +000014d0 malloc +00001130 sleep +000016b8 whitespace +000016c8 __bss_start__ +00000148 fork1 +000009b4 nulterminate +00000df0 pipe +000000d8 getcmd +00000e58 write +00000fc4 fstat +00000ec0 kill +00001060 chdir +0000086c parseline +00000168 runcmd +00000910 parseblock +00000ef4 exec +00001738 __bss_end__ +00000dbc wait +000016c0 symbols +00000e24 read +000006f4 parseexec +00000f90 unlink +00000128 panic +00000d54 fork +000010fc sbrk +00001164 uptime +000016c8 __bss_start +00000b9c memset +00000000 main +00001738 __end__ +00000b10 strcmp +00001094 dup +00000360 pipecmd +0000030c redircmd +00000c90 stat +000016c8 _edata +00001738 _end +00000ff8 link +00000d88 exit +00000ccc atoi +00000b5c strlen +00000f28 open +0000128c div +00000bd4 strchr +0000102c mkdir +00000e8c close +0000039c listcmd +0000142c free diff -r 000000000000 -r c450faca55f4 uprogs/spinlock.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/spinlock.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,11 @@ +// Mutual exclusion lock. +struct spinlock { + uint locked; // Is the lock held? + + // For debugging: + char *name; // Name of lock. + struct cpu *cpu; // The cpu holding the lock. + uint pcs[10]; // The call stack (an array of program counters) + // that locked the lock. +}; + diff -r 000000000000 -r c450faca55f4 uprogs/stat.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/stat.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,11 @@ +#define T_DIR 1 // Directory +#define T_FILE 2 // File +#define T_DEV 3 // Device + +struct stat { + short type; // Type of file + int dev; // File system's disk device + uint ino; // Inode number + short nlink; // Number of links to file + uint size; // Size of file in bytes +}; diff -r 000000000000 -r c450faca55f4 uprogs/stressfs.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/stressfs.asm Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,1789 @@ + +_stressfs: file format elf32-littlearm + + +Disassembly of section .text: + +00000000
: +#include "fs.h" +#include "fcntl.h" + +int +main(int argc, char *argv[]) +{ + 0: e92d4830 push {r4, r5, fp, lr} + 4: e28db00c add fp, sp, #12 + int fd, i; + char path[] = "stressfs0"; + 8: e59f20ec ldr r2, [pc, #236] ; fc +#include "fs.h" +#include "fcntl.h" + +int +main(int argc, char *argv[]) +{ + c: e24dde21 sub sp, sp, #528 ; 0x210 + int fd, i; + char path[] = "stressfs0"; + 10: e24b3018 sub r3, fp, #24 + 14: e8920007 ldm r2, {r0, r1, r2} + char data[512]; + + printf(1, "stressfs starting\n"); + memset(data, 'a', sizeof(data)); + + for(i = 0; i < 4; i++) + 18: e3a04000 mov r4, #0 + +int +main(int argc, char *argv[]) +{ + int fd, i; + char path[] = "stressfs0"; + 1c: e8a30003 stmia r3!, {r0, r1} + char data[512]; + + printf(1, "stressfs starting\n"); + 20: e3a00001 mov r0, #1 + 24: e59f10d4 ldr r1, [pc, #212] ; 100 + +int +main(int argc, char *argv[]) +{ + int fd, i; + char path[] = "stressfs0"; + 28: e1c320b0 strh r2, [r3] + char data[512]; + + printf(1, "stressfs starting\n"); + 2c: eb000232 bl 8fc + memset(data, 'a', sizeof(data)); + 30: e24b0f86 sub r0, fp, #536 ; 0x218 + 34: e3a01061 mov r1, #97 ; 0x61 + 38: e3a02c02 mov r2, #512 ; 0x200 + 3c: eb000060 bl 1c4 + + for(i = 0; i < 4; i++) + if(fork() > 0) + 40: eb0000cd bl 37c + 44: e3500000 cmp r0, #0 + 48: ca000029 bgt f4 + char data[512]; + + printf(1, "stressfs starting\n"); + memset(data, 'a', sizeof(data)); + + for(i = 0; i < 4; i++) + 4c: e2844001 add r4, r4, #1 + 50: e3540004 cmp r4, #4 + 54: 1afffff9 bne 40 + 58: e1a05004 mov r5, r4 + if(fork() > 0) + break; + + printf(1, "write %d\n", i); + 5c: e1a02004 mov r2, r4 + 60: e3a00001 mov r0, #1 + 64: e59f1098 ldr r1, [pc, #152] ; 104 + 68: eb000223 bl 8fc + + path[8] += i; + 6c: e55b3010 ldrb r3, [fp, #-16] + fd = open(path, O_CREATE | O_RDWR); + 70: e24b0018 sub r0, fp, #24 + 74: e59f108c ldr r1, [pc, #140] ; 108 + if(fork() > 0) + break; + + printf(1, "write %d\n", i); + + path[8] += i; + 78: e0855003 add r5, r5, r3 + 7c: e54b5010 strb r5, [fp, #-16] + fd = open(path, O_CREATE | O_RDWR); + 80: eb000132 bl 550 + 84: e3a04014 mov r4, #20 + 88: e1a05000 mov r5, r0 + for(i = 0; i < 20; i++) +// printf(fd, "%d\n", i); + write(fd, data, sizeof(data)); + 8c: e1a00005 mov r0, r5 + 90: e24b1f86 sub r1, fp, #536 ; 0x218 + 94: e3a02c02 mov r2, #512 ; 0x200 + 98: eb0000f8 bl 480 + + printf(1, "write %d\n", i); + + path[8] += i; + fd = open(path, O_CREATE | O_RDWR); + for(i = 0; i < 20; i++) + 9c: e2544001 subs r4, r4, #1 + a0: 1afffff9 bne 8c +// printf(fd, "%d\n", i); + write(fd, data, sizeof(data)); + close(fd); + a4: e1a00005 mov r0, r5 + a8: eb000101 bl 4b4 + + printf(1, "read\n"); + ac: e3a00001 mov r0, #1 + b0: e59f1054 ldr r1, [pc, #84] ; 10c + b4: eb000210 bl 8fc + + fd = open(path, O_RDONLY); + b8: e1a01004 mov r1, r4 + bc: e24b0018 sub r0, fp, #24 + c0: eb000122 bl 550 + c4: e3a04014 mov r4, #20 + c8: e1a05000 mov r5, r0 + for (i = 0; i < 20; i++) + read(fd, data, sizeof(data)); + cc: e1a00005 mov r0, r5 + d0: e24b1f86 sub r1, fp, #536 ; 0x218 + d4: e3a02c02 mov r2, #512 ; 0x200 + d8: eb0000db bl 44c + close(fd); + + printf(1, "read\n"); + + fd = open(path, O_RDONLY); + for (i = 0; i < 20; i++) + dc: e2544001 subs r4, r4, #1 + e0: 1afffff9 bne cc + read(fd, data, sizeof(data)); + close(fd); + e4: e1a00005 mov r0, r5 + e8: eb0000f1 bl 4b4 + + wait(); + ec: eb0000bc bl 3e4 + + exit(); + f0: eb0000ae bl 3b0 + + printf(1, "stressfs starting\n"); + memset(data, 'a', sizeof(data)); + + for(i = 0; i < 4; i++) + if(fork() > 0) + f4: e6ef5074 uxtb r5, r4 + f8: eaffffd7 b 5c + fc: 00000c0c .word 0x00000c0c + 100: 00000be4 .word 0x00000be4 + 104: 00000bf8 .word 0x00000bf8 + 108: 00000202 .word 0x00000202 + 10c: 00000c04 .word 0x00000c04 + +00000110 : +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 110: e52db004 push {fp} ; (str fp, [sp, #-4]!) + char *os; + + os = s; + while((*s++ = *t++) != 0) + 114: e1a02000 mov r2, r0 +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 118: e28db000 add fp, sp, #0 + char *os; + + os = s; + while((*s++ = *t++) != 0) + 11c: e4d13001 ldrb r3, [r1], #1 + 120: e3530000 cmp r3, #0 + 124: e4c23001 strb r3, [r2], #1 + 128: 1afffffb bne 11c + ; + return os; +} + 12c: e28bd000 add sp, fp, #0 + 130: e8bd0800 pop {fp} + 134: e12fff1e bx lr + +00000138 : + +int +strcmp(const char *p, const char *q) +{ + 138: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 13c: e28db000 add fp, sp, #0 + while(*p && *p == *q) + 140: e5d03000 ldrb r3, [r0] + 144: e5d12000 ldrb r2, [r1] + 148: e3530000 cmp r3, #0 + 14c: 1a000004 bne 164 + 150: ea000005 b 16c + 154: e5f03001 ldrb r3, [r0, #1]! + 158: e3530000 cmp r3, #0 + 15c: 0a000006 beq 17c + 160: e5f12001 ldrb r2, [r1, #1]! + 164: e1530002 cmp r3, r2 + 168: 0afffff9 beq 154 + p++, q++; + return (uchar)*p - (uchar)*q; +} + 16c: e0620003 rsb r0, r2, r3 + 170: e28bd000 add sp, fp, #0 + 174: e8bd0800 pop {fp} + 178: e12fff1e bx lr +} + +int +strcmp(const char *p, const char *q) +{ + while(*p && *p == *q) + 17c: e5d12001 ldrb r2, [r1, #1] + 180: eafffff9 b 16c + +00000184 : + return (uchar)*p - (uchar)*q; +} + +uint +strlen(char *s) +{ + 184: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 188: e28db000 add fp, sp, #0 + int n; + + for(n = 0; s[n]; n++) + 18c: e5d03000 ldrb r3, [r0] + 190: e3530000 cmp r3, #0 + 194: 01a00003 moveq r0, r3 + 198: 0a000006 beq 1b8 + 19c: e1a02000 mov r2, r0 + 1a0: e3a03000 mov r3, #0 + 1a4: e5f21001 ldrb r1, [r2, #1]! + 1a8: e2833001 add r3, r3, #1 + 1ac: e1a00003 mov r0, r3 + 1b0: e3510000 cmp r1, #0 + 1b4: 1afffffa bne 1a4 + ; + return n; +} + 1b8: e28bd000 add sp, fp, #0 + 1bc: e8bd0800 pop {fp} + 1c0: e12fff1e bx lr + +000001c4 : +memset(void *dst, int c, uint n) +{ + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 1c4: e3520000 cmp r2, #0 + return n; +} + +void* +memset(void *dst, int c, uint n) +{ + 1c8: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 1cc: e28db000 add fp, sp, #0 + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 1d0: 0a000006 beq 1f0 + 1d4: e6ef1071 uxtb r1, r1 + 1d8: e1a03002 mov r3, r2 +} + +void* +memset(void *dst, int c, uint n) +{ + char *p=dst; + 1dc: e1a0c000 mov ip, r0 + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 1e0: e2533001 subs r3, r3, #1 + 1e4: e4cc1001 strb r1, [ip], #1 + 1e8: 1afffffc bne 1e0 + 1ec: e0800002 add r0, r0, r2 + return (void *)p; +} + 1f0: e28bd000 add sp, fp, #0 + 1f4: e8bd0800 pop {fp} + 1f8: e12fff1e bx lr + +000001fc : + +char* +strchr(const char *s, char c) +{ + 1fc: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 200: e28db000 add fp, sp, #0 + for(; *s; s++) + 204: e5d03000 ldrb r3, [r0] + 208: e3530000 cmp r3, #0 + 20c: 1a000004 bne 224 + 210: ea000008 b 238 + 214: e5d03001 ldrb r3, [r0, #1] + 218: e2800001 add r0, r0, #1 + 21c: e3530000 cmp r3, #0 + 220: 0a000004 beq 238 + if(*s == c) + 224: e1530001 cmp r3, r1 + 228: 1afffff9 bne 214 + return (char*)s; + return 0; +} + 22c: e28bd000 add sp, fp, #0 + 230: e8bd0800 pop {fp} + 234: e12fff1e bx lr +strchr(const char *s, char c) +{ + for(; *s; s++) + if(*s == c) + return (char*)s; + return 0; + 238: e1a00003 mov r0, r3 + 23c: eafffffa b 22c + +00000240 : +} + +char* +gets(char *buf, int max) +{ + 240: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + 244: e28db018 add fp, sp, #24 + 248: e24dd00c sub sp, sp, #12 + 24c: e1a08000 mov r8, r0 + 250: e1a07001 mov r7, r1 + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 254: e1a06000 mov r6, r0 + 258: e3a05000 mov r5, #0 + 25c: ea000008 b 284 + cc = read(0, &c, 1); + 260: eb000079 bl 44c + if(cc < 1) + 264: e3500000 cmp r0, #0 + 268: da00000b ble 29c + break; + buf[i++] = c; + 26c: e55b301d ldrb r3, [fp, #-29] + if(c == '\n' || c == '\r') + 270: e1a05004 mov r5, r4 + 274: e353000a cmp r3, #10 + 278: 1353000d cmpne r3, #13 + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + if(cc < 1) + break; + buf[i++] = c; + 27c: e4c63001 strb r3, [r6], #1 + if(c == '\n' || c == '\r') + 280: 0a00000a beq 2b0 +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + 284: e3a02001 mov r2, #1 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 288: e0854002 add r4, r5, r2 + 28c: e1540007 cmp r4, r7 + cc = read(0, &c, 1); + 290: e3a00000 mov r0, #0 + 294: e24b101d sub r1, fp, #29 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 298: bafffff0 blt 260 + break; + buf[i++] = c; + if(c == '\n' || c == '\r') + break; + } + buf[i] = '\0'; + 29c: e3a03000 mov r3, #0 + 2a0: e7c83005 strb r3, [r8, r5] + return buf; +} + 2a4: e1a00008 mov r0, r8 + 2a8: e24bd018 sub sp, fp, #24 + 2ac: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 2b0: e1a05004 mov r5, r4 + 2b4: eafffff8 b 29c + +000002b8 : + return buf; +} + +int +stat(char *n, struct stat *st) +{ + 2b8: e92d4830 push {r4, r5, fp, lr} + 2bc: e1a05001 mov r5, r1 + 2c0: e28db00c add fp, sp, #12 + int fd; + int r; + + fd = open(n, O_RDONLY); + 2c4: e3a01000 mov r1, #0 + 2c8: eb0000a0 bl 550 + if(fd < 0) + 2cc: e2504000 subs r4, r0, #0 + return -1; + 2d0: b3e05000 mvnlt r5, #0 +{ + int fd; + int r; + + fd = open(n, O_RDONLY); + if(fd < 0) + 2d4: ba000004 blt 2ec + return -1; + r = fstat(fd, st); + 2d8: e1a01005 mov r1, r5 + 2dc: eb0000c2 bl 5ec + 2e0: e1a05000 mov r5, r0 + close(fd); + 2e4: e1a00004 mov r0, r4 + 2e8: eb000071 bl 4b4 + return r; +} + 2ec: e1a00005 mov r0, r5 + 2f0: e8bd8830 pop {r4, r5, fp, pc} + +000002f4 : + +int +atoi(const char *s) +{ + 2f4: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 2f8: e28db000 add fp, sp, #0 + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 2fc: e5d03000 ldrb r3, [r0] + 300: e2432030 sub r2, r3, #48 ; 0x30 + 304: e6ef2072 uxtb r2, r2 + 308: e3520009 cmp r2, #9 +int +atoi(const char *s) +{ + int n; + + n = 0; + 30c: 83a00000 movhi r0, #0 + while('0' <= *s && *s <= '9') + 310: 8a000009 bhi 33c + 314: e1a02000 mov r2, r0 +int +atoi(const char *s) +{ + int n; + + n = 0; + 318: e3a00000 mov r0, #0 + while('0' <= *s && *s <= '9') + n = n*10 + *s++ - '0'; + 31c: e0800100 add r0, r0, r0, lsl #2 + 320: e0830080 add r0, r3, r0, lsl #1 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 324: e5f23001 ldrb r3, [r2, #1]! + n = n*10 + *s++ - '0'; + 328: e2400030 sub r0, r0, #48 ; 0x30 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 32c: e2431030 sub r1, r3, #48 ; 0x30 + 330: e6ef1071 uxtb r1, r1 + 334: e3510009 cmp r1, #9 + 338: 9afffff7 bls 31c + n = n*10 + *s++ - '0'; + return n; +} + 33c: e28bd000 add sp, fp, #0 + 340: e8bd0800 pop {fp} + 344: e12fff1e bx lr + +00000348 : +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 348: e3520000 cmp r2, #0 + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) +{ + 34c: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 350: e28db000 add fp, sp, #0 + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 354: da000005 ble 370 + n = n*10 + *s++ - '0'; + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) + 358: e0802002 add r2, r0, r2 +{ + char *dst, *src; + + dst = vdst; + 35c: e1a03000 mov r3, r0 + src = vsrc; + while(n-- > 0) + *dst++ = *src++; + 360: e4d1c001 ldrb ip, [r1], #1 + 364: e4c3c001 strb ip, [r3], #1 +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 368: e1530002 cmp r3, r2 + 36c: 1afffffb bne 360 + *dst++ = *src++; + return vdst; +} + 370: e28bd000 add sp, fp, #0 + 374: e8bd0800 pop {fp} + 378: e12fff1e bx lr + +0000037c : + 37c: e92d4000 push {lr} + 380: e92d0008 push {r3} + 384: e92d0004 push {r2} + 388: e92d0002 push {r1} + 38c: e92d0001 push {r0} + 390: e3a00001 mov r0, #1 + 394: ef000040 svc 0x00000040 + 398: e8bd0002 pop {r1} + 39c: e8bd0002 pop {r1} + 3a0: e8bd0004 pop {r2} + 3a4: e8bd0008 pop {r3} + 3a8: e8bd4000 pop {lr} + 3ac: e12fff1e bx lr + +000003b0 : + 3b0: e92d4000 push {lr} + 3b4: e92d0008 push {r3} + 3b8: e92d0004 push {r2} + 3bc: e92d0002 push {r1} + 3c0: e92d0001 push {r0} + 3c4: e3a00002 mov r0, #2 + 3c8: ef000040 svc 0x00000040 + 3cc: e8bd0002 pop {r1} + 3d0: e8bd0002 pop {r1} + 3d4: e8bd0004 pop {r2} + 3d8: e8bd0008 pop {r3} + 3dc: e8bd4000 pop {lr} + 3e0: e12fff1e bx lr + +000003e4 : + 3e4: e92d4000 push {lr} + 3e8: e92d0008 push {r3} + 3ec: e92d0004 push {r2} + 3f0: e92d0002 push {r1} + 3f4: e92d0001 push {r0} + 3f8: e3a00003 mov r0, #3 + 3fc: ef000040 svc 0x00000040 + 400: e8bd0002 pop {r1} + 404: e8bd0002 pop {r1} + 408: e8bd0004 pop {r2} + 40c: e8bd0008 pop {r3} + 410: e8bd4000 pop {lr} + 414: e12fff1e bx lr + +00000418 : + 418: e92d4000 push {lr} + 41c: e92d0008 push {r3} + 420: e92d0004 push {r2} + 424: e92d0002 push {r1} + 428: e92d0001 push {r0} + 42c: e3a00004 mov r0, #4 + 430: ef000040 svc 0x00000040 + 434: e8bd0002 pop {r1} + 438: e8bd0002 pop {r1} + 43c: e8bd0004 pop {r2} + 440: e8bd0008 pop {r3} + 444: e8bd4000 pop {lr} + 448: e12fff1e bx lr + +0000044c : + 44c: e92d4000 push {lr} + 450: e92d0008 push {r3} + 454: e92d0004 push {r2} + 458: e92d0002 push {r1} + 45c: e92d0001 push {r0} + 460: e3a00005 mov r0, #5 + 464: ef000040 svc 0x00000040 + 468: e8bd0002 pop {r1} + 46c: e8bd0002 pop {r1} + 470: e8bd0004 pop {r2} + 474: e8bd0008 pop {r3} + 478: e8bd4000 pop {lr} + 47c: e12fff1e bx lr + +00000480 : + 480: e92d4000 push {lr} + 484: e92d0008 push {r3} + 488: e92d0004 push {r2} + 48c: e92d0002 push {r1} + 490: e92d0001 push {r0} + 494: e3a00010 mov r0, #16 + 498: ef000040 svc 0x00000040 + 49c: e8bd0002 pop {r1} + 4a0: e8bd0002 pop {r1} + 4a4: e8bd0004 pop {r2} + 4a8: e8bd0008 pop {r3} + 4ac: e8bd4000 pop {lr} + 4b0: e12fff1e bx lr + +000004b4 : + 4b4: e92d4000 push {lr} + 4b8: e92d0008 push {r3} + 4bc: e92d0004 push {r2} + 4c0: e92d0002 push {r1} + 4c4: e92d0001 push {r0} + 4c8: e3a00015 mov r0, #21 + 4cc: ef000040 svc 0x00000040 + 4d0: e8bd0002 pop {r1} + 4d4: e8bd0002 pop {r1} + 4d8: e8bd0004 pop {r2} + 4dc: e8bd0008 pop {r3} + 4e0: e8bd4000 pop {lr} + 4e4: e12fff1e bx lr + +000004e8 : + 4e8: e92d4000 push {lr} + 4ec: e92d0008 push {r3} + 4f0: e92d0004 push {r2} + 4f4: e92d0002 push {r1} + 4f8: e92d0001 push {r0} + 4fc: e3a00006 mov r0, #6 + 500: ef000040 svc 0x00000040 + 504: e8bd0002 pop {r1} + 508: e8bd0002 pop {r1} + 50c: e8bd0004 pop {r2} + 510: e8bd0008 pop {r3} + 514: e8bd4000 pop {lr} + 518: e12fff1e bx lr + +0000051c : + 51c: e92d4000 push {lr} + 520: e92d0008 push {r3} + 524: e92d0004 push {r2} + 528: e92d0002 push {r1} + 52c: e92d0001 push {r0} + 530: e3a00007 mov r0, #7 + 534: ef000040 svc 0x00000040 + 538: e8bd0002 pop {r1} + 53c: e8bd0002 pop {r1} + 540: e8bd0004 pop {r2} + 544: e8bd0008 pop {r3} + 548: e8bd4000 pop {lr} + 54c: e12fff1e bx lr + +00000550 : + 550: e92d4000 push {lr} + 554: e92d0008 push {r3} + 558: e92d0004 push {r2} + 55c: e92d0002 push {r1} + 560: e92d0001 push {r0} + 564: e3a0000f mov r0, #15 + 568: ef000040 svc 0x00000040 + 56c: e8bd0002 pop {r1} + 570: e8bd0002 pop {r1} + 574: e8bd0004 pop {r2} + 578: e8bd0008 pop {r3} + 57c: e8bd4000 pop {lr} + 580: e12fff1e bx lr + +00000584 : + 584: e92d4000 push {lr} + 588: e92d0008 push {r3} + 58c: e92d0004 push {r2} + 590: e92d0002 push {r1} + 594: e92d0001 push {r0} + 598: e3a00011 mov r0, #17 + 59c: ef000040 svc 0x00000040 + 5a0: e8bd0002 pop {r1} + 5a4: e8bd0002 pop {r1} + 5a8: e8bd0004 pop {r2} + 5ac: e8bd0008 pop {r3} + 5b0: e8bd4000 pop {lr} + 5b4: e12fff1e bx lr + +000005b8 : + 5b8: e92d4000 push {lr} + 5bc: e92d0008 push {r3} + 5c0: e92d0004 push {r2} + 5c4: e92d0002 push {r1} + 5c8: e92d0001 push {r0} + 5cc: e3a00012 mov r0, #18 + 5d0: ef000040 svc 0x00000040 + 5d4: e8bd0002 pop {r1} + 5d8: e8bd0002 pop {r1} + 5dc: e8bd0004 pop {r2} + 5e0: e8bd0008 pop {r3} + 5e4: e8bd4000 pop {lr} + 5e8: e12fff1e bx lr + +000005ec : + 5ec: e92d4000 push {lr} + 5f0: e92d0008 push {r3} + 5f4: e92d0004 push {r2} + 5f8: e92d0002 push {r1} + 5fc: e92d0001 push {r0} + 600: e3a00008 mov r0, #8 + 604: ef000040 svc 0x00000040 + 608: e8bd0002 pop {r1} + 60c: e8bd0002 pop {r1} + 610: e8bd0004 pop {r2} + 614: e8bd0008 pop {r3} + 618: e8bd4000 pop {lr} + 61c: e12fff1e bx lr + +00000620 : + 620: e92d4000 push {lr} + 624: e92d0008 push {r3} + 628: e92d0004 push {r2} + 62c: e92d0002 push {r1} + 630: e92d0001 push {r0} + 634: e3a00013 mov r0, #19 + 638: ef000040 svc 0x00000040 + 63c: e8bd0002 pop {r1} + 640: e8bd0002 pop {r1} + 644: e8bd0004 pop {r2} + 648: e8bd0008 pop {r3} + 64c: e8bd4000 pop {lr} + 650: e12fff1e bx lr + +00000654 : + 654: e92d4000 push {lr} + 658: e92d0008 push {r3} + 65c: e92d0004 push {r2} + 660: e92d0002 push {r1} + 664: e92d0001 push {r0} + 668: e3a00014 mov r0, #20 + 66c: ef000040 svc 0x00000040 + 670: e8bd0002 pop {r1} + 674: e8bd0002 pop {r1} + 678: e8bd0004 pop {r2} + 67c: e8bd0008 pop {r3} + 680: e8bd4000 pop {lr} + 684: e12fff1e bx lr + +00000688 : + 688: e92d4000 push {lr} + 68c: e92d0008 push {r3} + 690: e92d0004 push {r2} + 694: e92d0002 push {r1} + 698: e92d0001 push {r0} + 69c: e3a00009 mov r0, #9 + 6a0: ef000040 svc 0x00000040 + 6a4: e8bd0002 pop {r1} + 6a8: e8bd0002 pop {r1} + 6ac: e8bd0004 pop {r2} + 6b0: e8bd0008 pop {r3} + 6b4: e8bd4000 pop {lr} + 6b8: e12fff1e bx lr + +000006bc : + 6bc: e92d4000 push {lr} + 6c0: e92d0008 push {r3} + 6c4: e92d0004 push {r2} + 6c8: e92d0002 push {r1} + 6cc: e92d0001 push {r0} + 6d0: e3a0000a mov r0, #10 + 6d4: ef000040 svc 0x00000040 + 6d8: e8bd0002 pop {r1} + 6dc: e8bd0002 pop {r1} + 6e0: e8bd0004 pop {r2} + 6e4: e8bd0008 pop {r3} + 6e8: e8bd4000 pop {lr} + 6ec: e12fff1e bx lr + +000006f0 : + 6f0: e92d4000 push {lr} + 6f4: e92d0008 push {r3} + 6f8: e92d0004 push {r2} + 6fc: e92d0002 push {r1} + 700: e92d0001 push {r0} + 704: e3a0000b mov r0, #11 + 708: ef000040 svc 0x00000040 + 70c: e8bd0002 pop {r1} + 710: e8bd0002 pop {r1} + 714: e8bd0004 pop {r2} + 718: e8bd0008 pop {r3} + 71c: e8bd4000 pop {lr} + 720: e12fff1e bx lr + +00000724 : + 724: e92d4000 push {lr} + 728: e92d0008 push {r3} + 72c: e92d0004 push {r2} + 730: e92d0002 push {r1} + 734: e92d0001 push {r0} + 738: e3a0000c mov r0, #12 + 73c: ef000040 svc 0x00000040 + 740: e8bd0002 pop {r1} + 744: e8bd0002 pop {r1} + 748: e8bd0004 pop {r2} + 74c: e8bd0008 pop {r3} + 750: e8bd4000 pop {lr} + 754: e12fff1e bx lr + +00000758 : + 758: e92d4000 push {lr} + 75c: e92d0008 push {r3} + 760: e92d0004 push {r2} + 764: e92d0002 push {r1} + 768: e92d0001 push {r0} + 76c: e3a0000d mov r0, #13 + 770: ef000040 svc 0x00000040 + 774: e8bd0002 pop {r1} + 778: e8bd0002 pop {r1} + 77c: e8bd0004 pop {r2} + 780: e8bd0008 pop {r3} + 784: e8bd4000 pop {lr} + 788: e12fff1e bx lr + +0000078c : + 78c: e92d4000 push {lr} + 790: e92d0008 push {r3} + 794: e92d0004 push {r2} + 798: e92d0002 push {r1} + 79c: e92d0001 push {r0} + 7a0: e3a0000e mov r0, #14 + 7a4: ef000040 svc 0x00000040 + 7a8: e8bd0002 pop {r1} + 7ac: e8bd0002 pop {r1} + 7b0: e8bd0004 pop {r2} + 7b4: e8bd0008 pop {r3} + 7b8: e8bd4000 pop {lr} + 7bc: e12fff1e bx lr + +000007c0 : +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 7c0: e92d4800 push {fp, lr} + 7c4: e28db004 add fp, sp, #4 + 7c8: e24b3004 sub r3, fp, #4 + 7cc: e24dd008 sub sp, sp, #8 + write(fd, &c, 1); + 7d0: e3a02001 mov r2, #1 +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 7d4: e5631001 strb r1, [r3, #-1]! + write(fd, &c, 1); + 7d8: e1a01003 mov r1, r3 + 7dc: ebffff27 bl 480 +} + 7e0: e24bd004 sub sp, fp, #4 + 7e4: e8bd8800 pop {fp, pc} + +000007e8 : + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 7e8: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 7ec: e1a04000 mov r4, r0 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 7f0: e1a00fa1 lsr r0, r1, #31 + 7f4: e3530000 cmp r3, #0 + 7f8: 03a03000 moveq r3, #0 + 7fc: 12003001 andne r3, r0, #1 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 800: e28db020 add fp, sp, #32 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 804: e3530000 cmp r3, #0 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 808: e24dd014 sub sp, sp, #20 + 80c: e59f909c ldr r9, [pc, #156] ; 8b0 + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + x = -xx; + 810: 12611000 rsbne r1, r1, #0 + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + 814: 13a03001 movne r3, #1 + } else { + x = xx; + } + + b = base; + i = 0; + 818: e3a0a000 mov sl, #0 + 81c: e24b6034 sub r6, fp, #52 ; 0x34 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 820: e3a08001 mov r8, #1 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 824: e3a07000 mov r7, #0 + int i; + + for(i=31;i>=0;i--){ + 828: e3a0001f mov r0, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 82c: e1a0c007 mov ip, r7 + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 830: e1a0e031 lsr lr, r1, r0 + 834: e20ee001 and lr, lr, #1 + 838: e18ec08c orr ip, lr, ip, lsl #1 + if(r >= d) { + 83c: e152000c cmp r2, ip + r = r - d; + q = q | (1 << i); + 840: 91877018 orrls r7, r7, r8, lsl r0 + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 844: 9062c00c rsbls ip, r2, ip +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 848: e2500001 subs r0, r0, #1 + 84c: 2afffff7 bcs 830 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 850: e0000792 mul r0, r2, r7 + }while((x = y) != 0); + 854: e3570000 cmp r7, #0 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 858: e0601001 rsb r1, r0, r1 + 85c: e28a5001 add r5, sl, #1 + 860: e7d91001 ldrb r1, [r9, r1] + 864: e7c6100a strb r1, [r6, sl] + }while((x = y) != 0); + 868: 11a01007 movne r1, r7 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 86c: 11a0a005 movne sl, r5 + 870: 1affffeb bne 824 + }while((x = y) != 0); + if(neg) + 874: e3530000 cmp r3, #0 + buf[i++] = '-'; + 878: 124b2024 subne r2, fp, #36 ; 0x24 + 87c: 10823005 addne r3, r2, r5 + 880: 128a5002 addne r5, sl, #2 + + while(--i >= 0) + 884: e2455001 sub r5, r5, #1 + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + 888: 13a0202d movne r2, #45 ; 0x2d + 88c: 15432010 strbne r2, [r3, #-16] + + while(--i >= 0) + putc(fd, buf[i]); + 890: e7d61005 ldrb r1, [r6, r5] + 894: e1a00004 mov r0, r4 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 898: e2455001 sub r5, r5, #1 + putc(fd, buf[i]); + 89c: ebffffc7 bl 7c0 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 8a0: e3750001 cmn r5, #1 + 8a4: 1afffff9 bne 890 + putc(fd, buf[i]); +} + 8a8: e24bd020 sub sp, fp, #32 + 8ac: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} + 8b0: 00000c18 .word 0x00000c18 + +000008b4
: + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 8b4: e3a03000 mov r3, #0 +{ + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + 8b8: e92d0830 push {r4, r5, fp} + 8bc: e1a02000 mov r2, r0 + 8c0: e28db008 add fp, sp, #8 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 8c4: e3a0c01f mov ip, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 8c8: e1a00003 mov r0, r3 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 8cc: e3a05001 mov r5, #1 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 8d0: e1a04c32 lsr r4, r2, ip + 8d4: e2044001 and r4, r4, #1 + 8d8: e1843083 orr r3, r4, r3, lsl #1 + if(r >= d) { + 8dc: e1530001 cmp r3, r1 + r = r - d; + q = q | (1 << i); + 8e0: 21800c15 orrcs r0, r0, r5, lsl ip + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 8e4: 20613003 rsbcs r3, r1, r3 +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 8e8: e25cc001 subs ip, ip, #1 + 8ec: 2afffff7 bcs 8d0 + r = r - d; + q = q | (1 << i); + } + } + return q; +} + 8f0: e24bd008 sub sp, fp, #8 + 8f4: e8bd0830 pop {r4, r5, fp} + 8f8: e12fff1e bx lr + +000008fc : +} + +// Print to the given fd. Only understands %d, %x, %p, %s. +void +printf(int fd, char *fmt, ...) +{ + 8fc: e92d000e push {r1, r2, r3} + 900: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 904: e28db020 add fp, sp, #32 + 908: e1a05000 mov r5, r0 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 90c: e59b4004 ldr r4, [fp, #4] + 910: e5d48000 ldrb r8, [r4] + 914: e3580000 cmp r8, #0 + 918: 0a000027 beq 9bc + ap++; + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + 91c: e59f712c ldr r7, [pc, #300] ; a50 + char *s; + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + 920: e28b6008 add r6, fp, #8 +{ + char *s; + int c, i, state; + uint *ap; + + state = 0; + 924: e3a0a000 mov sl, #0 + 928: ea000008 b 950 + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 92c: e3580025 cmp r8, #37 ; 0x25 + state = '%'; + 930: 01a0a008 moveq sl, r8 + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 934: 0a000002 beq 944 + state = '%'; + } else { + putc(fd, c); + 938: e1a00005 mov r0, r5 + 93c: e1a01008 mov r1, r8 + 940: ebffff9e bl 7c0 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 944: e5f48001 ldrb r8, [r4, #1]! + 948: e3580000 cmp r8, #0 + 94c: 0a00001a beq 9bc + c = fmt[i] & 0xff; + if(state == 0){ + 950: e35a0000 cmp sl, #0 + 954: 0afffff4 beq 92c + if(c == '%'){ + state = '%'; + } else { + putc(fd, c); + } + } else if(state == '%'){ + 958: e35a0025 cmp sl, #37 ; 0x25 + 95c: 1afffff8 bne 944 + if(c == 'd'){ + 960: e3580064 cmp r8, #100 ; 0x64 + 964: 0a00002c beq a1c + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + 968: e3580078 cmp r8, #120 ; 0x78 + 96c: 13580070 cmpne r8, #112 ; 0x70 + 970: 13a09000 movne r9, #0 + 974: 03a09001 moveq r9, #1 + 978: 0a000013 beq 9cc + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + 97c: e3580073 cmp r8, #115 ; 0x73 + 980: 0a000018 beq 9e8 + s = "(null)"; + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + 984: e3580063 cmp r8, #99 ; 0x63 + 988: 0a00002a beq a38 + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 98c: e3580025 cmp r8, #37 ; 0x25 + putc(fd, c); + 990: e1a0100a mov r1, sl + 994: e1a00005 mov r0, r5 + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 998: 0a000002 beq 9a8 + putc(fd, c); + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + 99c: ebffff87 bl 7c0 + putc(fd, c); + 9a0: e1a00005 mov r0, r5 + 9a4: e1a01008 mov r1, r8 + 9a8: ebffff84 bl 7c0 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 9ac: e5f48001 ldrb r8, [r4, #1]! + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 9b0: e1a0a009 mov sl, r9 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 9b4: e3580000 cmp r8, #0 + 9b8: 1affffe4 bne 950 + putc(fd, c); + } + state = 0; + } + } +} + 9bc: e24bd020 sub sp, fp, #32 + 9c0: e8bd4ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 9c4: e28dd00c add sp, sp, #12 + 9c8: e12fff1e bx lr + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + 9cc: e1a00005 mov r0, r5 + 9d0: e4961004 ldr r1, [r6], #4 + 9d4: e3a02010 mov r2, #16 + 9d8: e3a03000 mov r3, #0 + 9dc: ebffff81 bl 7e8 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 9e0: e3a0a000 mov sl, #0 + 9e4: eaffffd6 b 944 + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + s = (char*)*ap; + 9e8: e4968004 ldr r8, [r6], #4 + ap++; + if(s == 0) + s = "(null)"; + 9ec: e3580000 cmp r8, #0 + 9f0: 01a08007 moveq r8, r7 + while(*s != 0){ + 9f4: e5d81000 ldrb r1, [r8] + 9f8: e3510000 cmp r1, #0 + 9fc: 0a000004 beq a14 + putc(fd, *s); + a00: e1a00005 mov r0, r5 + a04: ebffff6d bl 7c0 + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + while(*s != 0){ + a08: e5f81001 ldrb r1, [r8, #1]! + a0c: e3510000 cmp r1, #0 + a10: 1afffffa bne a00 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + a14: e1a0a001 mov sl, r1 + a18: eaffffc9 b 944 + } else { + putc(fd, c); + } + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + a1c: e1a00005 mov r0, r5 + a20: e4961004 ldr r1, [r6], #4 + a24: e3a0200a mov r2, #10 + a28: e3a03001 mov r3, #1 + a2c: ebffff6d bl 7e8 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + a30: e3a0a000 mov sl, #0 + a34: eaffffc2 b 944 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + a38: e4961004 ldr r1, [r6], #4 + a3c: e1a00005 mov r0, r5 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + a40: e1a0a009 mov sl, r9 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + a44: e6ef1071 uxtb r1, r1 + a48: ebffff5c bl 7c0 + a4c: eaffffbc b 944 + a50: 00000c2c .word 0x00000c2c + +00000a54 : +free(void *ap) +{ + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + a54: e59f3098 ldr r3, [pc, #152] ; af4 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + a58: e92d0830 push {r4, r5, fp} + Header *bp, *p; + + bp = (Header*)ap - 1; + a5c: e240c008 sub ip, r0, #8 + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + a60: e5932000 ldr r2, [r3] +static Header base; +static Header *freep; + +void +free(void *ap) +{ + a64: e28db008 add fp, sp, #8 + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + a68: e152000c cmp r2, ip + a6c: e5921000 ldr r1, [r2] + a70: 2a000001 bcs a7c + a74: e15c0001 cmp ip, r1 + a78: 3a000007 bcc a9c + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + a7c: e1520001 cmp r2, r1 + a80: 3a000003 bcc a94 + a84: e152000c cmp r2, ip + a88: 3a000003 bcc a9c + a8c: e15c0001 cmp ip, r1 + a90: 3a000001 bcc a9c +static Header base; +static Header *freep; + +void +free(void *ap) +{ + a94: e1a02001 mov r2, r1 + a98: eafffff2 b a68 + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + a9c: e5104004 ldr r4, [r0, #-4] + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + freep = p; + aa0: e5832000 str r2, [r3] + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + aa4: e08c5184 add r5, ip, r4, lsl #3 + aa8: e1550001 cmp r5, r1 + bp->s.size += p->s.ptr->s.size; + aac: 05911004 ldreq r1, [r1, #4] + ab0: 00814004 addeq r4, r1, r4 + ab4: 05004004 streq r4, [r0, #-4] + bp->s.ptr = p->s.ptr->s.ptr; + ab8: 05921000 ldreq r1, [r2] + abc: 05911000 ldreq r1, [r1] + } else + bp->s.ptr = p->s.ptr; + ac0: e5001008 str r1, [r0, #-8] + if(p + p->s.size == bp){ + ac4: e5921004 ldr r1, [r2, #4] + ac8: e0824181 add r4, r2, r1, lsl #3 + acc: e15c0004 cmp ip, r4 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + ad0: 1582c000 strne ip, [r2] + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + } else + bp->s.ptr = p->s.ptr; + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + ad4: 0510c004 ldreq ip, [r0, #-4] + ad8: 008c1001 addeq r1, ip, r1 + adc: 05821004 streq r1, [r2, #4] + p->s.ptr = bp->s.ptr; + ae0: 05101008 ldreq r1, [r0, #-8] + ae4: 05821000 streq r1, [r2] + } else + p->s.ptr = bp; + freep = p; +} + ae8: e24bd008 sub sp, fp, #8 + aec: e8bd0830 pop {r4, r5, fp} + af0: e12fff1e bx lr + af4: 00000c34 .word 0x00000c34 + +00000af8 : + return freep; +} + +void* +malloc(uint nbytes) +{ + af8: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + afc: e2804007 add r4, r0, #7 + if((prevp = freep) == 0){ + b00: e59f50d4 ldr r5, [pc, #212] ; bdc +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + b04: e1a041a4 lsr r4, r4, #3 + return freep; +} + +void* +malloc(uint nbytes) +{ + b08: e28db01c add fp, sp, #28 + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + b0c: e5953000 ldr r3, [r5] +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + b10: e2844001 add r4, r4, #1 + if((prevp = freep) == 0){ + b14: e3530000 cmp r3, #0 + b18: 0a00002b beq bcc + b1c: e5930000 ldr r0, [r3] + b20: e5902004 ldr r2, [r0, #4] + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + b24: e1520004 cmp r2, r4 + b28: 2a00001b bcs b9c +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + b2c: e59f80ac ldr r8, [pc, #172] ; be0 + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + b30: e1a07184 lsl r7, r4, #3 + b34: ea000003 b b48 + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + b38: e5930000 ldr r0, [r3] + if(p->s.size >= nunits){ + b3c: e5902004 ldr r2, [r0, #4] + b40: e1540002 cmp r4, r2 + b44: 9a000014 bls b9c + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + b48: e5952000 ldr r2, [r5] + b4c: e1a03000 mov r3, r0 + b50: e1500002 cmp r0, r2 + b54: 1afffff7 bne b38 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + b58: e1540008 cmp r4, r8 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + b5c: 81a00007 movhi r0, r7 + b60: 93a00902 movls r0, #32768 ; 0x8000 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + b64: 81a06004 movhi r6, r4 + b68: 93a06a01 movls r6, #4096 ; 0x1000 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + b6c: ebfffeec bl 724 + b70: e1a03000 mov r3, r0 + if(p == (char*)-1) + b74: e3730001 cmn r3, #1 + return 0; + hp = (Header*)p; + hp->s.size = nu; + free((void*)(hp + 1)); + b78: e2800008 add r0, r0, #8 + Header *hp; + + if(nu < 4096) + nu = 4096; + p = sbrk(nu * sizeof(Header)); + if(p == (char*)-1) + b7c: 0a000010 beq bc4 + return 0; + hp = (Header*)p; + hp->s.size = nu; + b80: e5836004 str r6, [r3, #4] + free((void*)(hp + 1)); + b84: ebffffb2 bl a54 + return freep; + b88: e5953000 ldr r3, [r5] + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + if((p = morecore(nunits)) == 0) + b8c: e3530000 cmp r3, #0 + b90: 1affffe8 bne b38 + return 0; + b94: e1a00003 mov r0, r3 + } +} + b98: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + b9c: e1540002 cmp r4, r2 + prevp->s.ptr = p->s.ptr; + else { + p->s.size -= nunits; + ba0: 10642002 rsbne r2, r4, r2 + ba4: 15802004 strne r2, [r0, #4] + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + ba8: 05902000 ldreq r2, [r0] + else { + p->s.size -= nunits; + p += p->s.size; + bac: 10800182 addne r0, r0, r2, lsl #3 + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + bb0: 05832000 streq r2, [r3] + else { + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + bb4: 15804004 strne r4, [r0, #4] + } + freep = prevp; + bb8: e5853000 str r3, [r5] + return (void*)(p + 1); + bbc: e2800008 add r0, r0, #8 + bc0: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + } + if(p == freep) + if((p = morecore(nunits)) == 0) + return 0; + bc4: e3a00000 mov r0, #0 + bc8: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + bcc: e2850004 add r0, r5, #4 + bd0: e5850000 str r0, [r5] + base.s.size = 0; + bd4: e9850009 stmib r5, {r0, r3} + bd8: eaffffd3 b b2c + bdc: 00000c34 .word 0x00000c34 + be0: 00000fff .word 0x00000fff diff -r 000000000000 -r c450faca55f4 uprogs/stressfs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/stressfs.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,49 @@ +// Demonstrate that moving the "acquire" in iderw after the loop that +// appends to the idequeue results in a race. + +// For this to work, you should also add a spin within iderw's +// idequeue traversal loop. Adding the following demonstrated a panic +// after about 5 runs of stressfs in QEMU on a 2.1GHz CPU: +// for (i = 0; i < 40000; i++) +// asm volatile(""); + +#include "types.h" +#include "stat.h" +#include "user.h" +#include "fs.h" +#include "fcntl.h" + +int +main(int argc, char *argv[]) +{ + int fd, i; + char path[] = "stressfs0"; + char data[512]; + + printf(1, "stressfs starting\n"); + memset(data, 'a', sizeof(data)); + + for(i = 0; i < 4; i++) + if(fork() > 0) + break; + + printf(1, "write %d\n", i); + + path[8] += i; + fd = open(path, O_CREATE | O_RDWR); + for(i = 0; i < 20; i++) +// printf(fd, "%d\n", i); + write(fd, data, sizeof(data)); + close(fd); + + printf(1, "read\n"); + + fd = open(path, O_RDONLY); + for (i = 0; i < 20; i++) + read(fd, data, sizeof(data)); + close(fd); + + wait(); + + exit(); +} diff -r 000000000000 -r c450faca55f4 uprogs/stressfs.sym --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/stressfs.sym Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,64 @@ +00000000 .text +00000be4 .rodata +00000c34 .bss +00000000 .comment +00000000 .ARM.attributes +00000000 .debug_aranges +00000000 .debug_info +00000000 .debug_abbrev +00000000 .debug_line +00000000 .debug_frame +00000000 .debug_str +00000000 .debug_loc +00000000 .debug_ranges +00000000 stressfs.c +00000000 ulib.c +00000000 printf.c +000007c0 putc +000007e8 printint +00000c18 digits.993 +00000000 umalloc.c +00000c34 freep +00000c38 base +00000110 strcpy +000008fc printf +00000348 memmove +00000584 mknod +00000c40 _bss_end__ +00000240 gets +000006f0 getpid +00000af8 malloc +00000758 sleep +00000c34 __bss_start__ +00000418 pipe +00000480 write +000005ec fstat +000004e8 kill +00000688 chdir +0000051c exec +00000c40 __bss_end__ +000003e4 wait +0000044c read +000005b8 unlink +0000037c fork +00000724 sbrk +0000078c uptime +00000c34 __bss_start +000001c4 memset +00000000 main +00000c40 __end__ +00000138 strcmp +000006bc dup +000002b8 stat +00000c34 _edata +00000c40 _end +00000620 link +000003b0 exit +000002f4 atoi +00000184 strlen +00000550 open +000008b4 div +000001fc strchr +00000654 mkdir +000004b4 close +00000a54 free diff -r 000000000000 -r c450faca55f4 uprogs/syscall.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/syscall.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,22 @@ +// System call numbers +#define SYS_fork 1 +#define SYS_exit 2 +#define SYS_wait 3 +#define SYS_pipe 4 +#define SYS_read 5 +#define SYS_kill 6 +#define SYS_exec 7 +#define SYS_fstat 8 +#define SYS_chdir 9 +#define SYS_dup 10 +#define SYS_getpid 11 +#define SYS_sbrk 12 +#define SYS_sleep 13 +#define SYS_uptime 14 +#define SYS_open 15 +#define SYS_write 16 +#define SYS_mknod 17 +#define SYS_unlink 18 +#define SYS_link 19 +#define SYS_mkdir 20 +#define SYS_close 21 diff -r 000000000000 -r c450faca55f4 uprogs/traps.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/traps.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,15 @@ +// These are arbitrarily chosen, but with care not to overlap +// processor defined exceptions or interrupt vectors. +#define T_SYSCALL 64 // system call +#define T_DEFAULT 500 // catchall + +#define T_IRQ0 32 // IRQ 0 corresponds to int T_IRQ + +#define IRQ_TIMER 0 +#define IRQ_KBD 1 +#define IRQ_COM1 4 +#define IRQ_IDE 14 +#define IRQ_ERROR 19 +#define IRQ_SPURIOUS 31 + + diff -r 000000000000 -r c450faca55f4 uprogs/types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/types.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,86 @@ +typedef unsigned int u32; +typedef unsigned short u16; +typedef unsigned char u8; +typedef unsigned long long u64; + +typedef unsigned int uint; +typedef unsigned short ushort; +typedef unsigned char uchar; +typedef uint pde_t; +typedef uint pte_t; + + +/* trap vectors layout at virtual +address HVECTORS (and KZERO(0x80000000), doubled mapped).*/ +typedef struct Vpage0 { + void (*vectors[8])(void); + u32 vtable[8]; +} Vpage0; + + +/* interrupt control registers */ +typedef struct Intregs { + u32 ARMpending; + u32 GPUpending[2]; + u32 FIQctl; + u32 GPUenable[2]; + u32 ARMenable; + u32 GPUdisable[2]; + u32 ARMdisable; +} Intregs; + + +typedef struct Mach +{ + int machno; /* physical id of processor */ + + int flushmmu; /* flush current proc mmu state */ + + /* stats */ + int tlbfault; + int tlbpurge; + int pfault; + int cs; + int syscall; + int load; + int intr; + int lastintr; + int ilockdepth; + + + int cpumhz; + /* vfp2 or vfp3 fpu */ + int havefp; + int havefpvalid; + int fpon; + int fpconfiged; + int fpnregs; + int fppid; /* pid of last fault */ + int fpcnt; /* how many consecutive at that addr */ + + /* save areas for exceptions, hold R0-R4 */ + u32 sfiq[5]; + u32 sirq[5]; + u32 sund[5]; + u32 sabt[5]; + u32 smon[5]; /* probably not needed */ + u32 ssys[5]; + + int stack[1]; +} Mach; + + +struct framebufferdescription { + u32 width; //width + u32 height; // height + u32 v_width; // virtual width + u32 v_height; // virtual height + u32 pitch; // GPU pitch + u32 depth; // bit depth + u32 x; + u32 y; + u32 fbp; //GPU framebuffer pointer + u32 fbs; // GPU framebuffer size +}; + +typedef struct framebufferdescription FBI; diff -r 000000000000 -r c450faca55f4 uprogs/ulib.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/ulib.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,108 @@ +#include "types.h" +#include "stat.h" +#include "fcntl.h" +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + char *os; + + os = s; + while((*s++ = *t++) != 0) + ; + return os; +} + +int +strcmp(const char *p, const char *q) +{ + while(*p && *p == *q) + p++, q++; + return (uchar)*p - (uchar)*q; +} + +uint +strlen(char *s) +{ + int n; + + for(n = 0; s[n]; n++) + ; + return n; +} + +void* +memset(void *dst, int c, uint n) +{ + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + return (void *)p; +} + +char* +strchr(const char *s, char c) +{ + for(; *s; s++) + if(*s == c) + return (char*)s; + return 0; +} + +char* +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + if(cc < 1) + break; + buf[i++] = c; + if(c == '\n' || c == '\r') + break; + } + buf[i] = '\0'; + return buf; +} + +int +stat(char *n, struct stat *st) +{ + int fd; + int r; + + fd = open(n, O_RDONLY); + if(fd < 0) + return -1; + r = fstat(fd, st); + close(fd); + return r; +} + +int +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + n = n*10 + *s++ - '0'; + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + *dst++ = *src++; + return vdst; +} diff -r 000000000000 -r c450faca55f4 uprogs/umalloc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/umalloc.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,90 @@ +#include "types.h" +#include "stat.h" +#include "user.h" +#include "param.h" + +// Memory allocator by Kernighan and Ritchie, +// The C programming Language, 2nd ed. Section 8.7. + +typedef long Align; + +union header { + struct { + union header *ptr; + uint size; + } s; + Align x; +}; + +typedef union header Header; + +static Header base; +static Header *freep; + +void +free(void *ap) +{ + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + } else + bp->s.ptr = p->s.ptr; + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + freep = p; +} + +static Header* +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + nu = 4096; + p = sbrk(nu * sizeof(Header)); + if(p == (char*)-1) + return 0; + hp = (Header*)p; + hp->s.size = nu; + free((void*)(hp + 1)); + return freep; +} + +void* +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + else { + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + if((p = morecore(nunits)) == 0) + return 0; + } +} diff -r 000000000000 -r c450faca55f4 uprogs/user.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/user.h Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,38 @@ +struct stat; + +// system calls +int fork(void); +int exit(void) __attribute__((noreturn)); +int wait(void); +int pipe(int*); +int write(int, void*, int); +int read(int, void*, int); +int close(int); +int kill(int); +int exec(char*, char**); +int open(char*, int); +int mknod(char*, short, short); +int unlink(char*); +int fstat(int fd, struct stat*); +int link(char*, char*); +int mkdir(char*); +int chdir(char*); +int dup(int); +int getpid(void); +char* sbrk(int); +int sleep(int); +int uptime(void); + +// ulib.c +int stat(char*, struct stat*); +char* strcpy(char*, char*); +void *memmove(void*, void*, int); +char* strchr(const char*, char c); +int strcmp(const char*, const char*); +void printf(int, char*, ...); +char* gets(char*, int max); +uint strlen(char*); +void* memset(void*, int, uint); +void* malloc(uint); +void free(void*); +int atoi(const char*); diff -r 000000000000 -r c450faca55f4 uprogs/usertests.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/usertests.asm Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,9126 @@ + +_usertests: file format elf32-littlearm + + +Disassembly of section .text: + +00000000
: + return randstate; +} + +int +main(int argc, char *argv[]) +{ + 0: e92d4800 push {fp, lr} + printf(1, "usertests starting\n"); + 4: e3a00001 mov r0, #1 + return randstate; +} + +int +main(int argc, char *argv[]) +{ + 8: e28db004 add fp, sp, #4 + printf(1, "usertests starting\n"); + c: e59f10b0 ldr r1, [pc, #176] ; c4 + 10: eb000dcb bl 3744 + + if(open("usertests.ran", 0) >= 0){ + 14: e59f00ac ldr r0, [pc, #172] ; c8 + 18: e3a01000 mov r1, #0 + 1c: eb000cdd bl 3398 + 20: e3500000 cmp r0, #0 + 24: ba000003 blt 38 + printf(1, "already ran user tests -- rebuild fs.img\n"); + 28: e3a00001 mov r0, #1 + 2c: e59f1098 ldr r1, [pc, #152] ; cc + 30: eb000dc3 bl 3744 + exit(); + 34: eb000c6f bl 31f8 + } + close(open("usertests.ran", O_CREATE)); + 38: e3a01c02 mov r1, #512 ; 0x200 + 3c: e59f0084 ldr r0, [pc, #132] ; c8 + 40: eb000cd4 bl 3398 + 44: eb000cac bl 32fc + + bigargtest(); + 48: eb000af2 bl 2c18 + bigwrite(); + 4c: eb000798 bl 1eb4 + bigargtest(); + 50: eb000af0 bl 2c18 + bsstest(); + 54: eb000ad1 bl 2ba0 + sbrktest(); + 58: eb0009b2 bl 2728 + validatetest(); + 5c: eb000aa6 bl 2afc + + opentest(); + 60: eb00001a bl d0 + writetest(); + 64: eb00003c bl 15c + writetest1(); + 68: eb0000a5 bl 304 + createtest(); + 6c: eb000108 bl 494 + + mem(); + 70: eb000246 bl 990 + pipe1(); + 74: eb000175 bl 650 + preempt(); + 78: eb0001db bl 7ec + exitwait(); + 7c: eb000226 bl 91c + + rmdot(); + 80: eb000878 bl 2268 + fourteen(); + 84: eb00082d bl 2140 + bigfile(); + 88: eb0007c2 bl 1f98 + subdir(); + 8c: eb000604 bl 18a4 + concreate(); + 90: eb0004b2 bl 1360 + linkunlink(); + 94: eb00057a bl 1684 + linktest(); + 98: eb00043a bl 1188 + unlinkread(); + 9c: eb0003db bl 1010 + createdelete(); + a0: eb000347 bl dc4 + twofiles(); + a4: eb0002cf bl be8 + sharedfd(); + a8: eb000267 bl a4c + dirfile(); + ac: eb0008c5 bl 23c8 + iref(); + b0: eb000936 bl 2590 + forktest(); + b4: eb00096f bl 2678 + bigdir(); // slow + b8: eb0005ad bl 1774 + + exectest(); + bc: eb000150 bl 604 + + exit(); + c0: eb000c4c bl 31f8 + c4: 000051c4 .word 0x000051c4 + c8: 000051d8 .word 0x000051d8 + cc: 000051e8 .word 0x000051e8 + +000000d0 : + +// simple file system tests + +void +opentest(void) +{ + d0: e92d4818 push {r3, r4, fp, lr} + d4: e28db00c add fp, sp, #12 + int fd; + + printf(stdout, "open test\n"); + d8: e59f4060 ldr r4, [pc, #96] ; 140 + dc: e59f1060 ldr r1, [pc, #96] ; 144 + e0: e5940000 ldr r0, [r4] + e4: eb000d96 bl 3744 + fd = open("echo", 0); + e8: e59f0058 ldr r0, [pc, #88] ; 148 + ec: e3a01000 mov r1, #0 + f0: eb000ca8 bl 3398 + if(fd < 0){ + f4: e3500000 cmp r0, #0 + f8: ba000009 blt 124 + printf(stdout, "open echo failed!\n"); + exit(); + } + close(fd); + fc: eb000c7e bl 32fc + fd = open("doesnotexist", 0); + 100: e59f0044 ldr r0, [pc, #68] ; 14c + 104: e3a01000 mov r1, #0 + 108: eb000ca2 bl 3398 + if(fd >= 0){ + 10c: e3500000 cmp r0, #0 + printf(stdout, "open doesnotexist succeeded!\n"); + 110: e5940000 ldr r0, [r4] + printf(stdout, "open echo failed!\n"); + exit(); + } + close(fd); + fd = open("doesnotexist", 0); + if(fd >= 0){ + 114: aa000006 bge 134 + printf(stdout, "open doesnotexist succeeded!\n"); + exit(); + } + printf(stdout, "open test ok\n"); + 118: e59f1030 ldr r1, [pc, #48] ; 150 +} + 11c: e8bd4818 pop {r3, r4, fp, lr} + fd = open("doesnotexist", 0); + if(fd >= 0){ + printf(stdout, "open doesnotexist succeeded!\n"); + exit(); + } + printf(stdout, "open test ok\n"); + 120: ea000d87 b 3744 + int fd; + + printf(stdout, "open test\n"); + fd = open("echo", 0); + if(fd < 0){ + printf(stdout, "open echo failed!\n"); + 124: e5940000 ldr r0, [r4] + 128: e59f1024 ldr r1, [pc, #36] ; 154 + 12c: eb000d84 bl 3744 + exit(); + 130: eb000c30 bl 31f8 + } + close(fd); + fd = open("doesnotexist", 0); + if(fd >= 0){ + printf(stdout, "open doesnotexist succeeded!\n"); + 134: e59f101c ldr r1, [pc, #28] ; 158 + 138: eb000d81 bl 3744 + exit(); + 13c: eb000c2d bl 31f8 + 140: 00005244 .word 0x00005244 + 144: 00003a2c .word 0x00003a2c + 148: 00003a38 .word 0x00003a38 + 14c: 00003a54 .word 0x00003a54 + 150: 00003a84 .word 0x00003a84 + 154: 00003a40 .word 0x00003a40 + 158: 00003a64 .word 0x00003a64 + +0000015c : + printf(stdout, "open test ok\n"); +} + +void +writetest(void) +{ + 15c: e92d4878 push {r3, r4, r5, r6, fp, lr} + 160: e28db014 add fp, sp, #20 + int fd; + int i; + + printf(stdout, "small file test\n"); + 164: e59f6150 ldr r6, [pc, #336] ; 2bc + 168: e59f1150 ldr r1, [pc, #336] ; 2c0 + 16c: e5960000 ldr r0, [r6] + 170: eb000d73 bl 3744 + fd = open("small", O_CREATE|O_RDWR); + 174: e59f0148 ldr r0, [pc, #328] ; 2c4 + 178: e59f1148 ldr r1, [pc, #328] ; 2c8 + 17c: eb000c85 bl 3398 + if(fd >= 0){ + 180: e2505000 subs r5, r0, #0 + printf(stdout, "creat small succeeded; ok\n"); + 184: e5960000 ldr r0, [r6] + int fd; + int i; + + printf(stdout, "small file test\n"); + fd = open("small", O_CREATE|O_RDWR); + if(fd >= 0){ + 188: ba000048 blt 2b0 + printf(stdout, "creat small succeeded; ok\n"); + 18c: e59f1138 ldr r1, [pc, #312] ; 2cc + 190: eb000d6b bl 3744 + } else { + printf(stdout, "error: creat small failed!\n"); + exit(); + } + for(i = 0; i < 100; i++){ + 194: e3a04000 mov r4, #0 + if(write(fd, "aaaaaaaaaa", 10) != 10){ + 198: e3a0200a mov r2, #10 + 19c: e1a00005 mov r0, r5 + 1a0: e59f1128 ldr r1, [pc, #296] ; 2d0 + 1a4: eb000c47 bl 32c8 + 1a8: e350000a cmp r0, #10 + 1ac: e1a02000 mov r2, r0 + 1b0: 1a000028 bne 258 + printf(stdout, "error: write aa %d new file failed\n", i); + exit(); + } + if(write(fd, "bbbbbbbbbb", 10) != 10){ + 1b4: e1a00005 mov r0, r5 + 1b8: e59f1114 ldr r1, [pc, #276] ; 2d4 + 1bc: eb000c41 bl 32c8 + 1c0: e350000a cmp r0, #10 + 1c4: 1a000028 bne 26c + printf(stdout, "creat small succeeded; ok\n"); + } else { + printf(stdout, "error: creat small failed!\n"); + exit(); + } + for(i = 0; i < 100; i++){ + 1c8: e2844001 add r4, r4, #1 + 1cc: e3540064 cmp r4, #100 ; 0x64 + 1d0: 1afffff0 bne 198 + if(write(fd, "bbbbbbbbbb", 10) != 10){ + printf(stdout, "error: write bb %d new file failed\n", i); + exit(); + } + } + printf(stdout, "writes ok\n"); + 1d4: e59f10fc ldr r1, [pc, #252] ; 2d8 + 1d8: e5960000 ldr r0, [r6] + 1dc: eb000d58 bl 3744 + close(fd); + 1e0: e1a00005 mov r0, r5 + 1e4: eb000c44 bl 32fc + fd = open("small", O_RDONLY); + 1e8: e59f00d4 ldr r0, [pc, #212] ; 2c4 + 1ec: e3a01000 mov r1, #0 + 1f0: eb000c68 bl 3398 + if(write(fd, "bbbbbbbbbb", 10) != 10){ + printf(stdout, "error: write bb %d new file failed\n", i); + exit(); + } + } + printf(stdout, "writes ok\n"); + 1f4: e59f40c0 ldr r4, [pc, #192] ; 2bc + close(fd); + fd = open("small", O_RDONLY); + if(fd >= 0){ + 1f8: e2505000 subs r5, r0, #0 + 1fc: ba00001f blt 280 + printf(stdout, "open small succeeded ok\n"); + 200: e59f10d4 ldr r1, [pc, #212] ; 2dc + 204: e5940000 ldr r0, [r4] + 208: eb000d4d bl 3744 + } else { + printf(stdout, "error: open small failed!\n"); + exit(); + } + i = read(fd, buf, 2000); + 20c: e1a00005 mov r0, r5 + 210: e59f10c8 ldr r1, [pc, #200] ; 2e0 + 214: e3a02e7d mov r2, #2000 ; 0x7d0 + 218: eb000c1d bl 3294 + if(i == 2000){ + 21c: e3500e7d cmp r0, #2000 ; 0x7d0 + 220: 1a00001a bne 290 + printf(stdout, "read succeeded ok\n"); + 224: e59f10b8 ldr r1, [pc, #184] ; 2e4 + 228: e5940000 ldr r0, [r4] + 22c: eb000d44 bl 3744 + } else { + printf(stdout, "read failed\n"); + exit(); + } + close(fd); + 230: e1a00005 mov r0, r5 + 234: eb000c30 bl 32fc + + if(unlink("small") < 0){ + 238: e59f0084 ldr r0, [pc, #132] ; 2c4 + 23c: eb000c6f bl 3400 + 240: e3500000 cmp r0, #0 + 244: ba000015 blt 2a0 + printf(stdout, "unlink small failed\n"); + exit(); + } + printf(stdout, "small file test ok\n"); + 248: e5940000 ldr r0, [r4] + 24c: e59f1094 ldr r1, [pc, #148] ; 2e8 +} + 250: e8bd4878 pop {r3, r4, r5, r6, fp, lr} + + if(unlink("small") < 0){ + printf(stdout, "unlink small failed\n"); + exit(); + } + printf(stdout, "small file test ok\n"); + 254: ea000d3a b 3744 + printf(stdout, "error: creat small failed!\n"); + exit(); + } + for(i = 0; i < 100; i++){ + if(write(fd, "aaaaaaaaaa", 10) != 10){ + printf(stdout, "error: write aa %d new file failed\n", i); + 258: e5960000 ldr r0, [r6] + 25c: e59f1088 ldr r1, [pc, #136] ; 2ec + 260: e1a02004 mov r2, r4 + 264: eb000d36 bl 3744 + exit(); + 268: eb000be2 bl 31f8 + } + if(write(fd, "bbbbbbbbbb", 10) != 10){ + printf(stdout, "error: write bb %d new file failed\n", i); + 26c: e5960000 ldr r0, [r6] + 270: e59f1078 ldr r1, [pc, #120] ; 2f0 + 274: e1a02004 mov r2, r4 + 278: eb000d31 bl 3744 + exit(); + 27c: eb000bdd bl 31f8 + close(fd); + fd = open("small", O_RDONLY); + if(fd >= 0){ + printf(stdout, "open small succeeded ok\n"); + } else { + printf(stdout, "error: open small failed!\n"); + 280: e5940000 ldr r0, [r4] + 284: e59f1068 ldr r1, [pc, #104] ; 2f4 + 288: eb000d2d bl 3744 + exit(); + 28c: eb000bd9 bl 31f8 + } + i = read(fd, buf, 2000); + if(i == 2000){ + printf(stdout, "read succeeded ok\n"); + } else { + printf(stdout, "read failed\n"); + 290: e5940000 ldr r0, [r4] + 294: e59f105c ldr r1, [pc, #92] ; 2f8 + 298: eb000d29 bl 3744 + exit(); + 29c: eb000bd5 bl 31f8 + } + close(fd); + + if(unlink("small") < 0){ + printf(stdout, "unlink small failed\n"); + 2a0: e5940000 ldr r0, [r4] + 2a4: e59f1050 ldr r1, [pc, #80] ; 2fc + 2a8: eb000d25 bl 3744 + exit(); + 2ac: eb000bd1 bl 31f8 + printf(stdout, "small file test\n"); + fd = open("small", O_CREATE|O_RDWR); + if(fd >= 0){ + printf(stdout, "creat small succeeded; ok\n"); + } else { + printf(stdout, "error: creat small failed!\n"); + 2b0: e59f1048 ldr r1, [pc, #72] ; 300 + 2b4: eb000d22 bl 3744 + exit(); + 2b8: eb000bce bl 31f8 + 2bc: 00005244 .word 0x00005244 + 2c0: 00003a94 .word 0x00003a94 + 2c4: 00003aa8 .word 0x00003aa8 + 2c8: 00000202 .word 0x00000202 + 2cc: 00003ab0 .word 0x00003ab0 + 2d0: 00003ae8 .word 0x00003ae8 + 2d4: 00003b18 .word 0x00003b18 + 2d8: 00003b48 .word 0x00003b48 + 2dc: 00003b54 .word 0x00003b54 + 2e0: 000079fc .word 0x000079fc + 2e4: 00003b8c .word 0x00003b8c + 2e8: 00003bc8 .word 0x00003bc8 + 2ec: 00003af4 .word 0x00003af4 + 2f0: 00003b24 .word 0x00003b24 + 2f4: 00003b70 .word 0x00003b70 + 2f8: 00003ba0 .word 0x00003ba0 + 2fc: 00003bb0 .word 0x00003bb0 + 300: 00003acc .word 0x00003acc + +00000304 : + printf(stdout, "small file test ok\n"); +} + +void +writetest1(void) +{ + 304: e92d48f0 push {r4, r5, r6, r7, fp, lr} + 308: e28db014 add fp, sp, #20 + int i, fd, n; + + printf(stdout, "big files test\n"); + 30c: e59f714c ldr r7, [pc, #332] ; 460 + 310: e59f114c ldr r1, [pc, #332] ; 464 + 314: e5970000 ldr r0, [r7] + 318: eb000d09 bl 3744 + + fd = open("big", O_CREATE|O_RDWR); + 31c: e59f0144 ldr r0, [pc, #324] ; 468 + 320: e59f1144 ldr r1, [pc, #324] ; 46c + 324: eb000c1b bl 3398 + if(fd < 0){ + 328: e2505000 subs r5, r0, #0 + 32c: ba000044 blt 444 + 330: e59f6138 ldr r6, [pc, #312] ; 470 + 334: e3a04000 mov r4, #0 + exit(); + } + + for(i = 0; i < MAXFILE; i++){ + ((int*)buf)[0] = i; + if(write(fd, buf, 512) != 512){ + 338: e1a00005 mov r0, r5 + 33c: e59f112c ldr r1, [pc, #300] ; 470 + 340: e3a02c02 mov r2, #512 ; 0x200 + printf(stdout, "error: creat big failed!\n"); + exit(); + } + + for(i = 0; i < MAXFILE; i++){ + ((int*)buf)[0] = i; + 344: e5864000 str r4, [r6] + if(write(fd, buf, 512) != 512){ + 348: eb000bde bl 32c8 + 34c: e3500c02 cmp r0, #512 ; 0x200 + 350: 1a000024 bne 3e8 + if(fd < 0){ + printf(stdout, "error: creat big failed!\n"); + exit(); + } + + for(i = 0; i < MAXFILE; i++){ + 354: e2844001 add r4, r4, #1 + 358: e354008c cmp r4, #140 ; 0x8c + 35c: 1afffff5 bne 338 + printf(stdout, "error: write big file failed\n", i); + exit(); + } + } + + close(fd); + 360: e1a00005 mov r0, r5 + 364: eb000be4 bl 32fc + + fd = open("big", O_RDONLY); + 368: e59f00f8 ldr r0, [pc, #248] ; 468 + 36c: e3a01000 mov r1, #0 + 370: eb000c08 bl 3398 + if(fd < 0){ + 374: e2505000 subs r5, r0, #0 + 378: ba00002d blt 434 + exit(); + } + + n = 0; + for(;;){ + i = read(fd, buf, 512); + 37c: e59f60ec ldr r6, [pc, #236] ; 470 + } + + close(fd); + + fd = open("big", O_RDONLY); + if(fd < 0){ + 380: e3a04000 mov r4, #0 + 384: ea000005 b 3a0 + if(n == MAXFILE - 1){ + printf(stdout, "read only %d blocks from big", n); + exit(); + } + break; + } else if(i != 512){ + 388: e3520c02 cmp r2, #512 ; 0x200 + 38c: 1a00001f bne 410 + printf(stdout, "read failed %d\n", i); + exit(); + } + if(((int*)buf)[0] != n){ + 390: e5963000 ldr r3, [r6] + 394: e1530004 cmp r3, r4 + 398: 1a000017 bne 3fc + printf(stdout, "read content of block %d is %d\n", + n, ((int*)buf)[0]); + exit(); + } + n++; + 39c: e2844001 add r4, r4, #1 + exit(); + } + + n = 0; + for(;;){ + i = read(fd, buf, 512); + 3a0: e3a02c02 mov r2, #512 ; 0x200 + 3a4: e1a00005 mov r0, r5 + 3a8: e59f10c0 ldr r1, [pc, #192] ; 470 + 3ac: eb000bb8 bl 3294 + if(i == 0){ + 3b0: e2502000 subs r2, r0, #0 + 3b4: 1afffff3 bne 388 + if(n == MAXFILE - 1){ + 3b8: e354008b cmp r4, #139 ; 0x8b + 3bc: 0a000017 beq 420 + n, ((int*)buf)[0]); + exit(); + } + n++; + } + close(fd); + 3c0: e1a00005 mov r0, r5 + 3c4: eb000bcc bl 32fc + if(unlink("big") < 0){ + 3c8: e59f0098 ldr r0, [pc, #152] ; 468 + 3cc: eb000c0b bl 3400 + 3d0: e3500000 cmp r0, #0 + printf(stdout, "unlink big failed\n"); + 3d4: e5970000 ldr r0, [r7] + exit(); + } + n++; + } + close(fd); + if(unlink("big") < 0){ + 3d8: ba00001d blt 454 + printf(stdout, "unlink big failed\n"); + exit(); + } + printf(stdout, "big files ok\n"); + 3dc: e59f1090 ldr r1, [pc, #144] ; 474 +} + 3e0: e8bd48f0 pop {r4, r5, r6, r7, fp, lr} + close(fd); + if(unlink("big") < 0){ + printf(stdout, "unlink big failed\n"); + exit(); + } + printf(stdout, "big files ok\n"); + 3e4: ea000cd6 b 3744 + } + + for(i = 0; i < MAXFILE; i++){ + ((int*)buf)[0] = i; + if(write(fd, buf, 512) != 512){ + printf(stdout, "error: write big file failed\n", i); + 3e8: e5970000 ldr r0, [r7] + 3ec: e59f1084 ldr r1, [pc, #132] ; 478 + 3f0: e1a02004 mov r2, r4 + 3f4: eb000cd2 bl 3744 + exit(); + 3f8: eb000b7e bl 31f8 + } else if(i != 512){ + printf(stdout, "read failed %d\n", i); + exit(); + } + if(((int*)buf)[0] != n){ + printf(stdout, "read content of block %d is %d\n", + 3fc: e5970000 ldr r0, [r7] + 400: e59f1074 ldr r1, [pc, #116] ; 47c + 404: e1a02004 mov r2, r4 + 408: eb000ccd bl 3744 + n, ((int*)buf)[0]); + exit(); + 40c: eb000b79 bl 31f8 + printf(stdout, "read only %d blocks from big", n); + exit(); + } + break; + } else if(i != 512){ + printf(stdout, "read failed %d\n", i); + 410: e5970000 ldr r0, [r7] + 414: e59f1064 ldr r1, [pc, #100] ; 480 + 418: eb000cc9 bl 3744 + exit(); + 41c: eb000b75 bl 31f8 + n = 0; + for(;;){ + i = read(fd, buf, 512); + if(i == 0){ + if(n == MAXFILE - 1){ + printf(stdout, "read only %d blocks from big", n); + 420: e5970000 ldr r0, [r7] + 424: e59f1058 ldr r1, [pc, #88] ; 484 + 428: e1a02004 mov r2, r4 + 42c: eb000cc4 bl 3744 + exit(); + 430: eb000b70 bl 31f8 + + close(fd); + + fd = open("big", O_RDONLY); + if(fd < 0){ + printf(stdout, "error: open big failed!\n"); + 434: e5970000 ldr r0, [r7] + 438: e59f1048 ldr r1, [pc, #72] ; 488 + 43c: eb000cc0 bl 3744 + exit(); + 440: eb000b6c bl 31f8 + + printf(stdout, "big files test\n"); + + fd = open("big", O_CREATE|O_RDWR); + if(fd < 0){ + printf(stdout, "error: creat big failed!\n"); + 444: e5970000 ldr r0, [r7] + 448: e59f103c ldr r1, [pc, #60] ; 48c + 44c: eb000cbc bl 3744 + exit(); + 450: eb000b68 bl 31f8 + } + n++; + } + close(fd); + if(unlink("big") < 0){ + printf(stdout, "unlink big failed\n"); + 454: e59f1034 ldr r1, [pc, #52] ; 490 + 458: eb000cb9 bl 3744 + exit(); + 45c: eb000b65 bl 31f8 + 460: 00005244 .word 0x00005244 + 464: 00003bdc .word 0x00003bdc + 468: 00003bec .word 0x00003bec + 46c: 00000202 .word 0x00000202 + 470: 000079fc .word 0x000079fc + 474: 00003cac .word 0x00003cac + 478: 00003c0c .word 0x00003c0c + 47c: 00003c78 .word 0x00003c78 + 480: 00003c68 .word 0x00003c68 + 484: 00003c48 .word 0x00003c48 + 488: 00003c2c .word 0x00003c2c + 48c: 00003bf0 .word 0x00003bf0 + 490: 00003c98 .word 0x00003c98 + +00000494 : + printf(stdout, "big files ok\n"); +} + +void +createtest(void) +{ + 494: e92d48f0 push {r4, r5, r6, r7, fp, lr} + 498: e28db014 add fp, sp, #20 + int i, fd; + + printf(stdout, "many creates, followed by unlink test\n"); + 49c: e59f7088 ldr r7, [pc, #136] ; 52c + + name[0] = 'a'; + 4a0: e59f5088 ldr r5, [pc, #136] ; 530 +void +createtest(void) +{ + int i, fd; + + printf(stdout, "many creates, followed by unlink test\n"); + 4a4: e59f1088 ldr r1, [pc, #136] ; 534 + 4a8: e5970000 ldr r0, [r7] + 4ac: eb000ca4 bl 3744 + + name[0] = 'a'; + name[2] = '\0'; + 4b0: e3a04030 mov r4, #48 ; 0x30 +{ + int i, fd; + + printf(stdout, "many creates, followed by unlink test\n"); + + name[0] = 'a'; + 4b4: e3a03061 mov r3, #97 ; 0x61 + 4b8: e5c53000 strb r3, [r5] + name[2] = '\0'; + 4bc: e3a03000 mov r3, #0 + 4c0: e5c53002 strb r3, [r5, #2] + for(i = 0; i < 52; i++){ + name[1] = '0' + i; + 4c4: e59f6064 ldr r6, [pc, #100] ; 530 + 4c8: e5c54001 strb r4, [r5, #1] + fd = open(name, O_CREATE|O_RDWR); + close(fd); + 4cc: e2844001 add r4, r4, #1 + + name[0] = 'a'; + name[2] = '\0'; + for(i = 0; i < 52; i++){ + name[1] = '0' + i; + fd = open(name, O_CREATE|O_RDWR); + 4d0: e59f1060 ldr r1, [pc, #96] ; 538 + 4d4: e1a00006 mov r0, r6 + 4d8: eb000bae bl 3398 + close(fd); + 4dc: e6ef4074 uxtb r4, r4 + 4e0: eb000b85 bl 32fc + + printf(stdout, "many creates, followed by unlink test\n"); + + name[0] = 'a'; + name[2] = '\0'; + for(i = 0; i < 52; i++){ + 4e4: e3540064 cmp r4, #100 ; 0x64 + 4e8: 1afffff5 bne 4c4 + name[1] = '0' + i; + fd = open(name, O_CREATE|O_RDWR); + close(fd); + } + name[0] = 'a'; + 4ec: e3a03061 mov r3, #97 ; 0x61 + name[2] = '\0'; + 4f0: e3a04030 mov r4, #48 ; 0x30 + for(i = 0; i < 52; i++){ + name[1] = '0' + i; + fd = open(name, O_CREATE|O_RDWR); + close(fd); + } + name[0] = 'a'; + 4f4: e5c63000 strb r3, [r6] + name[2] = '\0'; + 4f8: e3a03000 mov r3, #0 + 4fc: e5c63002 strb r3, [r6, #2] + for(i = 0; i < 52; i++){ + name[1] = '0' + i; + 500: e5c54001 strb r4, [r5, #1] + unlink(name); + 504: e2844001 add r4, r4, #1 + 508: e59f0020 ldr r0, [pc, #32] ; 530 + 50c: e6ef4074 uxtb r4, r4 + 510: eb000bba bl 3400 + fd = open(name, O_CREATE|O_RDWR); + close(fd); + } + name[0] = 'a'; + name[2] = '\0'; + for(i = 0; i < 52; i++){ + 514: e3540064 cmp r4, #100 ; 0x64 + 518: 1afffff8 bne 500 + name[1] = '0' + i; + unlink(name); + } + printf(stdout, "many creates, followed by unlink; ok\n"); + 51c: e5970000 ldr r0, [r7] + 520: e59f1014 ldr r1, [pc, #20] ; 53c +} + 524: e8bd48f0 pop {r4, r5, r6, r7, fp, lr} + name[2] = '\0'; + for(i = 0; i < 52; i++){ + name[1] = '0' + i; + unlink(name); + } + printf(stdout, "many creates, followed by unlink; ok\n"); + 528: ea000c85 b 3744 + 52c: 00005244 .word 0x00005244 + 530: 000099fc .word 0x000099fc + 534: 00003cbc .word 0x00003cbc + 538: 00000202 .word 0x00000202 + 53c: 00003ce4 .word 0x00003ce4 + +00000540 : +} + +void dirtest(void) +{ + 540: e92d4818 push {r3, r4, fp, lr} + 544: e28db00c add fp, sp, #12 + printf(stdout, "mkdir test\n"); + 548: e59f4094 ldr r4, [pc, #148] ; 5e4 + 54c: e59f1094 ldr r1, [pc, #148] ; 5e8 + 550: e5940000 ldr r0, [r4] + 554: eb000c7a bl 3744 + + if(mkdir("dir0") < 0){ + 558: e59f008c ldr r0, [pc, #140] ; 5ec + 55c: eb000bce bl 349c + 560: e3500000 cmp r0, #0 + 564: ba00000f blt 5a8 + printf(stdout, "mkdir failed\n"); + exit(); + } + + if(chdir("dir0") < 0){ + 568: e59f007c ldr r0, [pc, #124] ; 5ec + 56c: eb000bd7 bl 34d0 + 570: e3500000 cmp r0, #0 + 574: ba000016 blt 5d4 + printf(stdout, "chdir dir0 failed\n"); + exit(); + } + + if(chdir("..") < 0){ + 578: e59f0070 ldr r0, [pc, #112] ; 5f0 + 57c: eb000bd3 bl 34d0 + 580: e3500000 cmp r0, #0 + 584: ba00000e blt 5c4 + printf(stdout, "chdir .. failed\n"); + exit(); + } + + if(unlink("dir0") < 0){ + 588: e59f005c ldr r0, [pc, #92] ; 5ec + 58c: eb000b9b bl 3400 + 590: e3500000 cmp r0, #0 + printf(stdout, "unlink dir0 failed\n"); + 594: e5940000 ldr r0, [r4] + if(chdir("..") < 0){ + printf(stdout, "chdir .. failed\n"); + exit(); + } + + if(unlink("dir0") < 0){ + 598: ba000006 blt 5b8 + printf(stdout, "unlink dir0 failed\n"); + exit(); + } + printf(stdout, "mkdir test\n"); + 59c: e59f1044 ldr r1, [pc, #68] ; 5e8 +} + 5a0: e8bd4818 pop {r3, r4, fp, lr} + + if(unlink("dir0") < 0){ + printf(stdout, "unlink dir0 failed\n"); + exit(); + } + printf(stdout, "mkdir test\n"); + 5a4: ea000c66 b 3744 +void dirtest(void) +{ + printf(stdout, "mkdir test\n"); + + if(mkdir("dir0") < 0){ + printf(stdout, "mkdir failed\n"); + 5a8: e5940000 ldr r0, [r4] + 5ac: e59f1040 ldr r1, [pc, #64] ; 5f4 + 5b0: eb000c63 bl 3744 + exit(); + 5b4: eb000b0f bl 31f8 + printf(stdout, "chdir .. failed\n"); + exit(); + } + + if(unlink("dir0") < 0){ + printf(stdout, "unlink dir0 failed\n"); + 5b8: e59f1038 ldr r1, [pc, #56] ; 5f8 + 5bc: eb000c60 bl 3744 + exit(); + 5c0: eb000b0c bl 31f8 + printf(stdout, "chdir dir0 failed\n"); + exit(); + } + + if(chdir("..") < 0){ + printf(stdout, "chdir .. failed\n"); + 5c4: e5940000 ldr r0, [r4] + 5c8: e59f102c ldr r1, [pc, #44] ; 5fc + 5cc: eb000c5c bl 3744 + exit(); + 5d0: eb000b08 bl 31f8 + printf(stdout, "mkdir failed\n"); + exit(); + } + + if(chdir("dir0") < 0){ + printf(stdout, "chdir dir0 failed\n"); + 5d4: e5940000 ldr r0, [r4] + 5d8: e59f1020 ldr r1, [pc, #32] ; 600 + 5dc: eb000c58 bl 3744 + exit(); + 5e0: eb000b04 bl 31f8 + 5e4: 00005244 .word 0x00005244 + 5e8: 00003d0c .word 0x00003d0c + 5ec: 00003d18 .word 0x00003d18 + 5f0: 00003d44 .word 0x00003d44 + 5f4: 00003d20 .word 0x00003d20 + 5f8: 00003d5c .word 0x00003d5c + 5fc: 00003d48 .word 0x00003d48 + 600: 00003d30 .word 0x00003d30 + +00000604 : + printf(stdout, "mkdir test\n"); +} + +void +exectest(void) +{ + 604: e92d4818 push {r3, r4, fp, lr} + 608: e28db00c add fp, sp, #12 + printf(stdout, "exec test\n"); + 60c: e59f402c ldr r4, [pc, #44] ; 640 + 610: e59f102c ldr r1, [pc, #44] ; 644 + 614: e5940000 ldr r0, [r4] + 618: eb000c49 bl 3744 + if(exec("echo", echoargv) < 0){ + 61c: e59f0024 ldr r0, [pc, #36] ; 648 + 620: e2841004 add r1, r4, #4 + 624: eb000b4e bl 3364 + 628: e3500000 cmp r0, #0 + 62c: a8bd8818 popge {r3, r4, fp, pc} + printf(stdout, "exec echo failed\n"); + 630: e5940000 ldr r0, [r4] + 634: e59f1010 ldr r1, [pc, #16] ; 64c + 638: eb000c41 bl 3744 + exit(); + 63c: eb000aed bl 31f8 + 640: 00005244 .word 0x00005244 + 644: 00003d70 .word 0x00003d70 + 648: 00003a38 .word 0x00003a38 + 64c: 00003d7c .word 0x00003d7c + +00000650 : + +// simple fork and pipe read/write + +void +pipe1(void) +{ + 650: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + 654: e28db018 add fp, sp, #24 + 658: e24dd00c sub sp, sp, #12 + int fds[2], pid; + int seq, i, n, cc, total; + + if(pipe(fds) != 0){ + 65c: e24b0024 sub r0, fp, #36 ; 0x24 + 660: eb000afe bl 3260 + 664: e2506000 subs r6, r0, #0 + 668: 1a000049 bne 794 + printf(1, "pipe() failed\n"); + exit(); + } + pid = fork(); + 66c: eb000ad4 bl 31c4 + seq = 0; + if(pid == 0){ + 670: e2504000 subs r4, r0, #0 + 674: 0a00001f beq 6f8 + printf(1, "pipe1 oops 1\n"); + exit(); + } + } + exit(); + } else if(pid > 0){ + 678: da000049 ble 7a4 + close(fds[1]); + 67c: e51b0020 ldr r0, [fp, #-32] + 680: eb000b1d bl 32fc + total = 0; + cc = 1; + while((n = read(fds[0], buf, cc)) > 0){ + 684: e59f7138 ldr r7, [pc, #312] ; 7c4 + } + } + total += n; + cc = cc * 2; + if(cc > sizeof(buf)) + cc = sizeof(buf); + 688: e59f8138 ldr r8, [pc, #312] ; 7c8 + } + exit(); + } else if(pid > 0){ + close(fds[1]); + total = 0; + cc = 1; + 68c: e3a05001 mov r5, #1 + if(pipe(fds) != 0){ + printf(1, "pipe() failed\n"); + exit(); + } + pid = fork(); + seq = 0; + 690: e1a04006 mov r4, r6 + exit(); + } else if(pid > 0){ + close(fds[1]); + total = 0; + cc = 1; + while((n = read(fds[0], buf, cc)) > 0){ + 694: e51b0024 ldr r0, [fp, #-36] ; 0x24 + 698: e59f1124 ldr r1, [pc, #292] ; 7c4 + 69c: e1a02005 mov r2, r5 + 6a0: eb000afb bl 3294 + 6a4: e3500000 cmp r0, #0 + 6a8: da00002a ble 758 +} + +// simple fork and pipe read/write + +void +pipe1(void) + 6ac: e084c000 add ip, r4, r0 + 6b0: e0641007 rsb r1, r4, r7 + close(fds[1]); + total = 0; + cc = 1; + while((n = read(fds[0], buf, cc)) > 0){ + for(i = 0; i < n; i++){ + if((buf[i] & 0xff) != (seq++ & 0xff)){ + 6b4: e7d12004 ldrb r2, [r1, r4] + 6b8: e6ef3074 uxtb r3, r4 + 6bc: e1520003 cmp r2, r3 + 6c0: 1a000007 bne 6e4 + 6c4: e2844001 add r4, r4, #1 + } else if(pid > 0){ + close(fds[1]); + total = 0; + cc = 1; + while((n = read(fds[0], buf, cc)) > 0){ + for(i = 0; i < n; i++){ + 6c8: e154000c cmp r4, ip + 6cc: 1afffff8 bne 6b4 + printf(1, "pipe1 oops 2\n"); + return; + } + } + total += n; + cc = cc * 2; + 6d0: e1a05085 lsl r5, r5, #1 + if(cc > sizeof(buf)) + cc = sizeof(buf); + 6d4: e1550008 cmp r5, r8 + if((buf[i] & 0xff) != (seq++ & 0xff)){ + printf(1, "pipe1 oops 2\n"); + return; + } + } + total += n; + 6d8: e0866000 add r6, r6, r0 + cc = cc * 2; + if(cc > sizeof(buf)) + cc = sizeof(buf); + 6dc: 23a05a02 movcs r5, #8192 ; 0x2000 + 6e0: eaffffeb b 694 + total = 0; + cc = 1; + while((n = read(fds[0], buf, cc)) > 0){ + for(i = 0; i < n; i++){ + if((buf[i] & 0xff) != (seq++ & 0xff)){ + printf(1, "pipe1 oops 2\n"); + 6e4: e3a00001 mov r0, #1 + 6e8: e59f10dc ldr r1, [pc, #220] ; 7cc + 6ec: eb000c14 bl 3744 + } else { + printf(1, "fork() failed\n"); + exit(); + } + printf(1, "pipe1 ok\n"); +} + 6f0: e24bd018 sub sp, fp, #24 + 6f4: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} + exit(); + } + pid = fork(); + seq = 0; + if(pid == 0){ + close(fds[0]); + 6f8: e51b0024 ldr r0, [fp, #-36] ; 0x24 + 6fc: e59f70c0 ldr r7, [pc, #192] ; 7c4 + for(n = 0; n < 5; n++){ + for(i = 0; i < 1033; i++) + buf[i] = seq++; + if(write(fds[1], buf, 1033) != 1033){ + 700: e59f60c8 ldr r6, [pc, #200] ; 7d0 + } + pid = fork(); + seq = 0; + if(pid == 0){ + close(fds[0]); + for(n = 0; n < 5; n++){ + 704: e59f50c8 ldr r5, [pc, #200] ; 7d4 + exit(); + } + pid = fork(); + seq = 0; + if(pid == 0){ + close(fds[0]); + 708: eb000afb bl 32fc + if(pipe(fds) != 0){ + printf(1, "pipe() failed\n"); + exit(); + } + pid = fork(); + seq = 0; + 70c: e1a03004 mov r3, r4 +} + +// simple fork and pipe read/write + +void +pipe1(void) + 710: e2832b01 add r2, r3, #1024 ; 0x400 + 714: e1a04003 mov r4, r3 + 718: e2822009 add r2, r2, #9 + 71c: e0633007 rsb r3, r3, r7 + seq = 0; + if(pid == 0){ + close(fds[0]); + for(n = 0; n < 5; n++){ + for(i = 0; i < 1033; i++) + buf[i] = seq++; + 720: e7c34004 strb r4, [r3, r4] + 724: e2844001 add r4, r4, #1 + pid = fork(); + seq = 0; + if(pid == 0){ + close(fds[0]); + for(n = 0; n < 5; n++){ + for(i = 0; i < 1033; i++) + 728: e1540002 cmp r4, r2 + 72c: 1afffffb bne 720 + buf[i] = seq++; + if(write(fds[1], buf, 1033) != 1033){ + 730: e51b0020 ldr r0, [fp, #-32] + 734: e59f1088 ldr r1, [pc, #136] ; 7c4 + 738: e59f2090 ldr r2, [pc, #144] ; 7d0 + 73c: eb000ae1 bl 32c8 + pid = fork(); + seq = 0; + if(pid == 0){ + close(fds[0]); + for(n = 0; n < 5; n++){ + for(i = 0; i < 1033; i++) + 740: e1a03004 mov r3, r4 + buf[i] = seq++; + if(write(fds[1], buf, 1033) != 1033){ + 744: e1500006 cmp r0, r6 + 748: 1a000019 bne 7b4 + } + pid = fork(); + seq = 0; + if(pid == 0){ + close(fds[0]); + for(n = 0; n < 5; n++){ + 74c: e1540005 cmp r4, r5 + 750: 1affffee bne 710 + if(cc > sizeof(buf)) + cc = sizeof(buf); + } + if(total != 5 * 1033){ + printf(1, "pipe1 oops 3 total %d\n", total); + exit(); + 754: eb000aa7 bl 31f8 + total += n; + cc = cc * 2; + if(cc > sizeof(buf)) + cc = sizeof(buf); + } + if(total != 5 * 1033){ + 758: e59f3074 ldr r3, [pc, #116] ; 7d4 + 75c: e1560003 cmp r6, r3 + 760: 1a000006 bne 780 + printf(1, "pipe1 oops 3 total %d\n", total); + exit(); + } + close(fds[0]); + 764: e51b0024 ldr r0, [fp, #-36] ; 0x24 + 768: eb000ae3 bl 32fc + wait(); + 76c: eb000aae bl 322c + } else { + printf(1, "fork() failed\n"); + exit(); + } + printf(1, "pipe1 ok\n"); + 770: e3a00001 mov r0, #1 + 774: e59f105c ldr r1, [pc, #92] ; 7d8 + 778: eb000bf1 bl 3744 + 77c: eaffffdb b 6f0 + cc = cc * 2; + if(cc > sizeof(buf)) + cc = sizeof(buf); + } + if(total != 5 * 1033){ + printf(1, "pipe1 oops 3 total %d\n", total); + 780: e3a00001 mov r0, #1 + 784: e59f1050 ldr r1, [pc, #80] ; 7dc + 788: e1a02006 mov r2, r6 + 78c: eb000bec bl 3744 + exit(); + 790: eb000a98 bl 31f8 +{ + int fds[2], pid; + int seq, i, n, cc, total; + + if(pipe(fds) != 0){ + printf(1, "pipe() failed\n"); + 794: e3a00001 mov r0, #1 + 798: e59f1040 ldr r1, [pc, #64] ; 7e0 + 79c: eb000be8 bl 3744 + exit(); + 7a0: eb000a94 bl 31f8 + exit(); + } + close(fds[0]); + wait(); + } else { + printf(1, "fork() failed\n"); + 7a4: e3a00001 mov r0, #1 + 7a8: e59f1034 ldr r1, [pc, #52] ; 7e4 + 7ac: eb000be4 bl 3744 + exit(); + 7b0: eb000a90 bl 31f8 + close(fds[0]); + for(n = 0; n < 5; n++){ + for(i = 0; i < 1033; i++) + buf[i] = seq++; + if(write(fds[1], buf, 1033) != 1033){ + printf(1, "pipe1 oops 1\n"); + 7b4: e3a00001 mov r0, #1 + 7b8: e59f1028 ldr r1, [pc, #40] ; 7e8 + 7bc: eb000be0 bl 3744 + exit(); + 7c0: eb000a8c bl 31f8 + 7c4: 000079fc .word 0x000079fc + 7c8: 00002001 .word 0x00002001 + 7cc: 00003db0 .word 0x00003db0 + 7d0: 00000409 .word 0x00000409 + 7d4: 0000142d .word 0x0000142d + 7d8: 00003dd8 .word 0x00003dd8 + 7dc: 00003dc0 .word 0x00003dc0 + 7e0: 00003d90 .word 0x00003d90 + 7e4: 00003de4 .word 0x00003de4 + 7e8: 00003da0 .word 0x00003da0 + +000007ec : +} + +// meant to be run w/ at most two CPUs +void +preempt(void) +{ + 7ec: e92d48f0 push {r4, r5, r6, r7, fp, lr} + 7f0: e28db014 add fp, sp, #20 + 7f4: e24dd008 sub sp, sp, #8 + int pid1, pid2, pid3; + int pfds[2]; + + printf(1, "preempt: "); + 7f8: e3a00001 mov r0, #1 + 7fc: e59f10f8 ldr r1, [pc, #248] ; 8fc + 800: eb000bcf bl 3744 + pid1 = fork(); + 804: eb000a6e bl 31c4 + if(pid1 == 0) + 808: e2506000 subs r6, r0, #0 + 80c: 1a000000 bne 814 + 810: eafffffe b 810 + for(;;) + ; + + pid2 = fork(); + 814: eb000a6a bl 31c4 + if(pid2 == 0) + 818: e2505000 subs r5, r0, #0 + 81c: 1a000000 bne 824 + 820: eafffffe b 820 + for(;;) + ; + + pipe(pfds); + 824: e24b001c sub r0, fp, #28 + 828: eb000a8c bl 3260 + pid3 = fork(); + 82c: eb000a64 bl 31c4 + if(pid3 == 0){ + 830: e2504000 subs r4, r0, #0 + 834: 1a00000d bne 870 + close(pfds[0]); + 838: e51b001c ldr r0, [fp, #-28] + 83c: eb000aae bl 32fc + if(write(pfds[1], "x", 1) != 1) + 840: e51b0018 ldr r0, [fp, #-24] + 844: e59f10b4 ldr r1, [pc, #180] ; 900 + 848: e3a02001 mov r2, #1 + 84c: eb000a9d bl 32c8 + 850: e3500001 cmp r0, #1 + 854: 0a000002 beq 864 + printf(1, "preempt write error"); + 858: e3a00001 mov r0, #1 + 85c: e59f10a0 ldr r1, [pc, #160] ; 904 + 860: eb000bb7 bl 3744 + close(pfds[1]); + 864: e51b0018 ldr r0, [fp, #-24] + 868: eb000aa3 bl 32fc + 86c: eafffffe b 86c + for(;;) + ; + } + + close(pfds[1]); + 870: e51b0018 ldr r0, [fp, #-24] + 874: eb000aa0 bl 32fc + if(read(pfds[0], buf, sizeof(buf)) != 1){ + 878: e51b001c ldr r0, [fp, #-28] + 87c: e59f1084 ldr r1, [pc, #132] ; 908 + 880: e3a02a02 mov r2, #8192 ; 0x2000 + 884: eb000a82 bl 3294 + 888: e3500001 cmp r0, #1 + 88c: e1a07000 mov r7, r0 + 890: 0a000004 beq 8a8 + printf(1, "preempt read error"); + 894: e3a00001 mov r0, #1 + 898: e59f106c ldr r1, [pc, #108] ; 90c + 89c: eb000ba8 bl 3744 + printf(1, "wait... "); + wait(); + wait(); + wait(); + printf(1, "preempt ok\n"); +} + 8a0: e24bd014 sub sp, fp, #20 + 8a4: e8bd88f0 pop {r4, r5, r6, r7, fp, pc} + close(pfds[1]); + if(read(pfds[0], buf, sizeof(buf)) != 1){ + printf(1, "preempt read error"); + return; + } + close(pfds[0]); + 8a8: e51b001c ldr r0, [fp, #-28] + 8ac: eb000a92 bl 32fc + printf(1, "kill... "); + 8b0: e59f1058 ldr r1, [pc, #88] ; 910 + 8b4: e1a00007 mov r0, r7 + 8b8: eb000ba1 bl 3744 + kill(pid1); + 8bc: e1a00006 mov r0, r6 + 8c0: eb000a9a bl 3330 + kill(pid2); + 8c4: e1a00005 mov r0, r5 + 8c8: eb000a98 bl 3330 + kill(pid3); + 8cc: e1a00004 mov r0, r4 + 8d0: eb000a96 bl 3330 + printf(1, "wait... "); + 8d4: e59f1038 ldr r1, [pc, #56] ; 914 + 8d8: e1a00007 mov r0, r7 + 8dc: eb000b98 bl 3744 + wait(); + 8e0: eb000a51 bl 322c + wait(); + 8e4: eb000a50 bl 322c + wait(); + 8e8: eb000a4f bl 322c + printf(1, "preempt ok\n"); + 8ec: e1a00007 mov r0, r7 + 8f0: e59f1020 ldr r1, [pc, #32] ; 918 + 8f4: eb000b92 bl 3744 + 8f8: eaffffe8 b 8a0 + 8fc: 00003df4 .word 0x00003df4 + 900: 00004760 .word 0x00004760 + 904: 00003e00 .word 0x00003e00 + 908: 000079fc .word 0x000079fc + 90c: 00003e14 .word 0x00003e14 + 910: 00003e28 .word 0x00003e28 + 914: 00003e34 .word 0x00003e34 + 918: 00003e40 .word 0x00003e40 + +0000091c : +} + +// try to find any races between exit and wait +void +exitwait(void) +{ + 91c: e92d4830 push {r4, r5, fp, lr} + 920: e3a04064 mov r4, #100 ; 0x64 + 924: e28db00c add fp, sp, #12 + 928: ea000005 b 944 + pid = fork(); + if(pid < 0){ + printf(1, "fork failed\n"); + return; + } + if(pid){ + 92c: 0a000013 beq 980 + if(wait() != pid){ + 930: eb000a3d bl 322c + 934: e1500005 cmp r0, r5 + 938: 1a000008 bne 960 +void +exitwait(void) +{ + int i, pid; + + for(i = 0; i < 100; i++){ + 93c: e2544001 subs r4, r4, #1 + 940: 0a00000a beq 970 + pid = fork(); + 944: eb000a1e bl 31c4 + if(pid < 0){ + 948: e2505000 subs r5, r0, #0 + 94c: aafffff6 bge 92c + printf(1, "fork failed\n"); + 950: e3a00001 mov r0, #1 + 954: e59f1028 ldr r1, [pc, #40] ; 984 + } else { + exit(); + } + } + printf(1, "exitwait ok\n"); +} + 958: e8bd4830 pop {r4, r5, fp, lr} + int i, pid; + + for(i = 0; i < 100; i++){ + pid = fork(); + if(pid < 0){ + printf(1, "fork failed\n"); + 95c: ea000b78 b 3744 + return; + } + if(pid){ + if(wait() != pid){ + printf(1, "wait wrong pid\n"); + 960: e3a00001 mov r0, #1 + 964: e59f101c ldr r1, [pc, #28] ; 988 + } else { + exit(); + } + } + printf(1, "exitwait ok\n"); +} + 968: e8bd4830 pop {r4, r5, fp, lr} + printf(1, "fork failed\n"); + return; + } + if(pid){ + if(wait() != pid){ + printf(1, "wait wrong pid\n"); + 96c: ea000b74 b 3744 + } + } else { + exit(); + } + } + printf(1, "exitwait ok\n"); + 970: e3a00001 mov r0, #1 + 974: e59f1010 ldr r1, [pc, #16] ; 98c +} + 978: e8bd4830 pop {r4, r5, fp, lr} + } + } else { + exit(); + } + } + printf(1, "exitwait ok\n"); + 97c: ea000b70 b 3744 + if(wait() != pid){ + printf(1, "wait wrong pid\n"); + return; + } + } else { + exit(); + 980: eb000a1c bl 31f8 + 984: 00005148 .word 0x00005148 + 988: 00003e4c .word 0x00003e4c + 98c: 00003e5c .word 0x00003e5c + +00000990 : + printf(1, "exitwait ok\n"); +} + +void +mem(void) +{ + 990: e92d4878 push {r3, r4, r5, r6, fp, lr} + void *m1, *m2; + int pid, ppid; + + printf(1, "mem test\n"); + 994: e3a00001 mov r0, #1 + printf(1, "exitwait ok\n"); +} + +void +mem(void) +{ + 998: e28db014 add fp, sp, #20 + void *m1, *m2; + int pid, ppid; + + printf(1, "mem test\n"); + 99c: e59f1098 ldr r1, [pc, #152] ; a3c + 9a0: eb000b67 bl 3744 + ppid = getpid(); + 9a4: eb000ae3 bl 3538 + 9a8: e1a04000 mov r4, r0 + if((pid = fork()) == 0){ + 9ac: eb000a04 bl 31c4 + 9b0: e2505000 subs r5, r0, #0 + 9b4: 0a000002 beq 9c4 + 9b8: ea000017 b a1c + m1 = 0; + while((m2 = malloc(10001)) != 0){ + *(char**)m2 = m1; + 9bc: e5805000 str r5, [r0] + 9c0: e1a05000 mov r5, r0 + + printf(1, "mem test\n"); + ppid = getpid(); + if((pid = fork()) == 0){ + m1 = 0; + while((m2 = malloc(10001)) != 0){ + 9c4: e59f0074 ldr r0, [pc, #116] ; a40 + 9c8: eb000bdc bl 3940 + 9cc: e3500000 cmp r0, #0 + 9d0: 1afffff9 bne 9bc + *(char**)m2 = m1; + m1 = m2; + } + while(m1){ + 9d4: e3550000 cmp r5, #0 + 9d8: 1a000001 bne 9e4 + 9dc: ea000005 b 9f8 + m2 = *(char**)m1; + free(m1); + m1 = m2; + 9e0: e1a05006 mov r5, r6 + while((m2 = malloc(10001)) != 0){ + *(char**)m2 = m1; + m1 = m2; + } + while(m1){ + m2 = *(char**)m1; + 9e4: e5956000 ldr r6, [r5] + free(m1); + 9e8: e1a00005 mov r0, r5 + 9ec: eb000baa bl 389c + m1 = 0; + while((m2 = malloc(10001)) != 0){ + *(char**)m2 = m1; + m1 = m2; + } + while(m1){ + 9f0: e3560000 cmp r6, #0 + 9f4: 1afffff9 bne 9e0 + m2 = *(char**)m1; + free(m1); + m1 = m2; + } + m1 = malloc(1024*20); + 9f8: e3a00a05 mov r0, #20480 ; 0x5000 + 9fc: eb000bcf bl 3940 + if(m1 == 0){ + a00: e3500000 cmp r0, #0 + a04: 0a000006 beq a24 + printf(1, "couldn't allocate mem?!!\n"); + kill(ppid); + exit(); + } + free(m1); + a08: eb000ba3 bl 389c + printf(1, "mem ok\n"); + a0c: e3a00001 mov r0, #1 + a10: e59f102c ldr r1, [pc, #44] ; a44 + a14: eb000b4a bl 3744 + exit(); + a18: eb0009f6 bl 31f8 + } else { + wait(); + } +} + a1c: e8bd4878 pop {r3, r4, r5, r6, fp, lr} + } + free(m1); + printf(1, "mem ok\n"); + exit(); + } else { + wait(); + a20: ea000a01 b 322c + free(m1); + m1 = m2; + } + m1 = malloc(1024*20); + if(m1 == 0){ + printf(1, "couldn't allocate mem?!!\n"); + a24: e59f101c ldr r1, [pc, #28] ; a48 + a28: e3a00001 mov r0, #1 + a2c: eb000b44 bl 3744 + kill(ppid); + a30: e1a00004 mov r0, r4 + a34: eb000a3d bl 3330 + exit(); + a38: eb0009ee bl 31f8 + a3c: 00003e6c .word 0x00003e6c + a40: 00002711 .word 0x00002711 + a44: 00003e94 .word 0x00003e94 + a48: 00003e78 .word 0x00003e78 + +00000a4c : + +// two processes write to the same file descriptor +// is the offset shared? does inode locking work? +void +sharedfd(void) +{ + a4c: e92d48f0 push {r4, r5, r6, r7, fp, lr} + a50: e28db014 add fp, sp, #20 + a54: e24dd010 sub sp, sp, #16 + int fd, pid, i, n, nc, np; + char buf[10]; + + printf(1, "sharedfd test\n"); + a58: e59f1164 ldr r1, [pc, #356] ; bc4 + a5c: e3a00001 mov r0, #1 + a60: eb000b37 bl 3744 + + unlink("sharedfd"); + a64: e59f015c ldr r0, [pc, #348] ; bc8 + a68: eb000a64 bl 3400 + fd = open("sharedfd", O_CREATE|O_RDWR); + a6c: e59f0154 ldr r0, [pc, #340] ; bc8 + a70: e59f1154 ldr r1, [pc, #340] ; bcc + a74: eb000a47 bl 3398 + if(fd < 0){ + a78: e2505000 subs r5, r0, #0 + a7c: ba000043 blt b90 + printf(1, "fstests: cannot open sharedfd for writing"); + return; + } + pid = fork(); + a80: eb0009cf bl 31c4 + memset(buf, pid==0?'c':'p', sizeof(buf)); + a84: e3a0200a mov r2, #10 + a88: e3a04ffa mov r4, #1000 ; 0x3e8 + a8c: e3500000 cmp r0, #0 + a90: e1a06000 mov r6, r0 + a94: 13a01070 movne r1, #112 ; 0x70 + a98: 03a01063 moveq r1, #99 ; 0x63 + a9c: e24b0020 sub r0, fp, #32 + aa0: eb000959 bl 300c + aa4: ea000001 b ab0 + for(i = 0; i < 1000; i++){ + aa8: e2544001 subs r4, r4, #1 + aac: 0a000008 beq ad4 + if(write(fd, buf, sizeof(buf)) != sizeof(buf)){ + ab0: e1a00005 mov r0, r5 + ab4: e24b1020 sub r1, fp, #32 + ab8: e3a0200a mov r2, #10 + abc: eb000a01 bl 32c8 + ac0: e350000a cmp r0, #10 + ac4: 0afffff7 beq aa8 + printf(1, "fstests: write sharedfd failed\n"); + ac8: e3a00001 mov r0, #1 + acc: e59f10fc ldr r1, [pc, #252] ; bd0 + ad0: eb000b1b bl 3744 + break; + } + } + if(pid == 0) + ad4: e3560000 cmp r6, #0 + ad8: 0a000038 beq bc0 + exit(); + else + wait(); + adc: eb0009d2 bl 322c + close(fd); + ae0: e1a00005 mov r0, r5 + ae4: eb000a04 bl 32fc + fd = open("sharedfd", 0); + ae8: e59f00d8 ldr r0, [pc, #216] ; bc8 + aec: e3a01000 mov r1, #0 + af0: eb000a28 bl 3398 + if(fd < 0){ + af4: e2507000 subs r7, r0, #0 + af8: a3a05000 movge r5, #0 + afc: a1a06005 movge r6, r5 +// More file system tests + +// two processes write to the same file descriptor +// is the offset shared? does inode locking work? +void +sharedfd(void) + b00: a24b4017 subge r4, fp, #23 + exit(); + else + wait(); + close(fd); + fd = open("sharedfd", 0); + if(fd < 0){ + b04: ba000025 blt ba0 + printf(1, "fstests: cannot open sharedfd for reading\n"); + return; + } + nc = np = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + b08: e1a00007 mov r0, r7 + b0c: e24b1020 sub r1, fp, #32 + b10: e3a0200a mov r2, #10 + b14: eb0009de bl 3294 + b18: e3500000 cmp r0, #0 + b1c: da00000e ble b5c + b20: e24b3021 sub r3, fp, #33 ; 0x21 + for(i = 0; i < sizeof(buf); i++){ + if(buf[i] == 'c') + b24: e5f32001 ldrb r2, [r3, #1]! + b28: e3520063 cmp r2, #99 ; 0x63 + nc++; + b2c: 02866001 addeq r6, r6, #1 + return; + } + nc = np = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + for(i = 0; i < sizeof(buf); i++){ + if(buf[i] == 'c') + b30: 0a000001 beq b3c + nc++; + if(buf[i] == 'p') + b34: e3520070 cmp r2, #112 ; 0x70 + np++; + b38: 02855001 addeq r5, r5, #1 + printf(1, "fstests: cannot open sharedfd for reading\n"); + return; + } + nc = np = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + for(i = 0; i < sizeof(buf); i++){ + b3c: e1530004 cmp r3, r4 + b40: 1afffff7 bne b24 + if(fd < 0){ + printf(1, "fstests: cannot open sharedfd for reading\n"); + return; + } + nc = np = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + b44: e1a00007 mov r0, r7 + b48: e24b1020 sub r1, fp, #32 + b4c: e3a0200a mov r2, #10 + b50: eb0009cf bl 3294 + b54: e3500000 cmp r0, #0 + b58: cafffff0 bgt b20 + nc++; + if(buf[i] == 'p') + np++; + } + } + close(fd); + b5c: e1a00007 mov r0, r7 + b60: eb0009e5 bl 32fc + unlink("sharedfd"); + b64: e59f005c ldr r0, [pc, #92] ; bc8 + b68: eb000a24 bl 3400 + if(nc == 10000 && np == 10000){ + b6c: e59f3060 ldr r3, [pc, #96] ; bd4 + printf(1, "sharedfd ok\n"); + b70: e3a00001 mov r0, #1 + np++; + } + } + close(fd); + unlink("sharedfd"); + if(nc == 10000 && np == 10000){ + b74: e1550003 cmp r5, r3 + b78: 01560003 cmpeq r6, r3 + b7c: 1a00000b bne bb0 + printf(1, "sharedfd ok\n"); + b80: e59f1050 ldr r1, [pc, #80] ; bd8 + b84: eb000aee bl 3744 + } else { + printf(1, "sharedfd oops %d %d\n", nc, np); + exit(); + } +} + b88: e24bd014 sub sp, fp, #20 + b8c: e8bd88f0 pop {r4, r5, r6, r7, fp, pc} + printf(1, "sharedfd test\n"); + + unlink("sharedfd"); + fd = open("sharedfd", O_CREATE|O_RDWR); + if(fd < 0){ + printf(1, "fstests: cannot open sharedfd for writing"); + b90: e3a00001 mov r0, #1 + b94: e59f1040 ldr r1, [pc, #64] ; bdc + b98: eb000ae9 bl 3744 + return; + b9c: eafffff9 b b88 + else + wait(); + close(fd); + fd = open("sharedfd", 0); + if(fd < 0){ + printf(1, "fstests: cannot open sharedfd for reading\n"); + ba0: e3a00001 mov r0, #1 + ba4: e59f1034 ldr r1, [pc, #52] ; be0 + ba8: eb000ae5 bl 3744 + return; + bac: eafffff5 b b88 + close(fd); + unlink("sharedfd"); + if(nc == 10000 && np == 10000){ + printf(1, "sharedfd ok\n"); + } else { + printf(1, "sharedfd oops %d %d\n", nc, np); + bb0: e59f102c ldr r1, [pc, #44] ; be4 + bb4: e1a02006 mov r2, r6 + bb8: e1a03005 mov r3, r5 + bbc: eb000ae0 bl 3744 + exit(); + bc0: eb00098c bl 31f8 + bc4: 00003e9c .word 0x00003e9c + bc8: 00003eac .word 0x00003eac + bcc: 00000202 .word 0x00000202 + bd0: 00003ee4 .word 0x00003ee4 + bd4: 00002710 .word 0x00002710 + bd8: 00003f30 .word 0x00003f30 + bdc: 00003eb8 .word 0x00003eb8 + be0: 00003f04 .word 0x00003f04 + be4: 00003f40 .word 0x00003f40 + +00000be8 : + +// two processes write two different files at the same +// time, to test block allocation. +void +twofiles(void) +{ + be8: e92d48f0 push {r4, r5, r6, r7, fp, lr} + int fd, pid, i, j, n, total; + char *fname; + + printf(1, "twofiles test\n"); + bec: e3a00001 mov r0, #1 + +// two processes write two different files at the same +// time, to test block allocation. +void +twofiles(void) +{ + bf0: e28db014 add fp, sp, #20 + int fd, pid, i, j, n, total; + char *fname; + + printf(1, "twofiles test\n"); + bf4: e59f1194 ldr r1, [pc, #404] ; d90 + bf8: eb000ad1 bl 3744 + + unlink("f1"); + bfc: e59f0190 ldr r0, [pc, #400] ; d94 + c00: eb0009fe bl 3400 + unlink("f2"); + c04: e59f018c ldr r0, [pc, #396] ; d98 + c08: eb0009fc bl 3400 + + pid = fork(); + c0c: eb00096c bl 31c4 + if(pid < 0){ + c10: e2506000 subs r6, r0, #0 + c14: ba000050 blt d5c + printf(1, "fork failed\n"); + exit(); + } + + fname = pid ? "f1" : "f2"; + c18: 159f0174 ldrne r0, [pc, #372] ; d94 + c1c: 059f0174 ldreq r0, [pc, #372] ; d98 + fd = open(fname, O_CREATE | O_RDWR); + c20: e59f1174 ldr r1, [pc, #372] ; d9c + c24: eb0009db bl 3398 + if(fd < 0){ + c28: e2505000 subs r5, r0, #0 + c2c: ba00004e blt d6c + printf(1, "create failed\n"); + exit(); + } + + memset(buf, pid?'p':'c', 512); + c30: e3560000 cmp r6, #0 + c34: e59f0164 ldr r0, [pc, #356] ; da0 + c38: 03a01063 moveq r1, #99 ; 0x63 + c3c: 13a01070 movne r1, #112 ; 0x70 + c40: e3a02c02 mov r2, #512 ; 0x200 + c44: eb0008f0 bl 300c + c48: e3a0400c mov r4, #12 + for(i = 0; i < 12; i++){ + if((n = write(fd, buf, 500)) != 500){ + c4c: e3a02f7d mov r2, #500 ; 0x1f4 + c50: e1a00005 mov r0, r5 + c54: e59f1144 ldr r1, [pc, #324] ; da0 + c58: eb00099a bl 32c8 + c5c: e3500f7d cmp r0, #500 ; 0x1f4 + c60: e1a02000 mov r2, r0 + c64: 1a000038 bne d4c + printf(1, "create failed\n"); + exit(); + } + + memset(buf, pid?'p':'c', 512); + for(i = 0; i < 12; i++){ + c68: e2544001 subs r4, r4, #1 + c6c: 1afffff6 bne c4c + if((n = write(fd, buf, 500)) != 500){ + printf(1, "write failed %d\n", n); + exit(); + } + } + close(fd); + c70: e1a00005 mov r0, r5 + c74: eb0009a0 bl 32fc + if(pid) + c78: e3560000 cmp r6, #0 + c7c: 0a000031 beq d48 + wait(); + c80: eb000969 bl 322c + exit(); + + for(i = 0; i < 2; i++){ + fd = open(i?"f1":"f2", 0); + total = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + c84: e59f7118 ldr r7, [pc, #280] ; da4 + wait(); + else + exit(); + + for(i = 0; i < 2; i++){ + fd = open(i?"f1":"f2", 0); + c88: e59f0108 ldr r0, [pc, #264] ; d98 + c8c: e3a01000 mov r1, #0 + c90: eb0009c0 bl 3398 + total = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + c94: e59f1104 ldr r1, [pc, #260] ; da0 + c98: e3a02a02 mov r2, #8192 ; 0x2000 + else + exit(); + + for(i = 0; i < 2; i++){ + fd = open(i?"f1":"f2", 0); + total = 0; + c9c: e3a05000 mov r5, #0 + wait(); + else + exit(); + + for(i = 0; i < 2; i++){ + fd = open(i?"f1":"f2", 0); + ca0: e1a06000 mov r6, r0 + total = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + ca4: e1a00006 mov r0, r6 + ca8: eb000979 bl 3294 + cac: e3500000 cmp r0, #0 + cb0: da000010 ble cf8 + cb4: e59f30e8 ldr r3, [pc, #232] ; da4 +} + +// two processes write two different files at the same +// time, to test block allocation. +void +twofiles(void) + cb8: e087c000 add ip, r7, r0 + for(i = 0; i < 2; i++){ + fd = open(i?"f1":"f2", 0); + total = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + for(j = 0; j < n; j++){ + if(buf[j] != (i?'p':'c')){ + cbc: e5f31001 ldrb r1, [r3, #1]! + cc0: e3540000 cmp r4, #0 + cc4: 03a02063 moveq r2, #99 ; 0x63 + cc8: 13a02070 movne r2, #112 ; 0x70 + ccc: e1510002 cmp r1, r2 + cd0: 1a000019 bne d3c + + for(i = 0; i < 2; i++){ + fd = open(i?"f1":"f2", 0); + total = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + for(j = 0; j < n; j++){ + cd4: e153000c cmp r3, ip + cd8: 1afffff7 bne cbc + if(buf[j] != (i?'p':'c')){ + printf(1, "wrong char\n"); + exit(); + } + } + total += n; + cdc: e0855000 add r5, r5, r0 + exit(); + + for(i = 0; i < 2; i++){ + fd = open(i?"f1":"f2", 0); + total = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + ce0: e59f10b8 ldr r1, [pc, #184] ; da0 + ce4: e1a00006 mov r0, r6 + ce8: e3a02a02 mov r2, #8192 ; 0x2000 + cec: eb000968 bl 3294 + cf0: e3500000 cmp r0, #0 + cf4: caffffee bgt cb4 + exit(); + } + } + total += n; + } + close(fd); + cf8: e1a00006 mov r0, r6 + cfc: eb00097e bl 32fc + if(total != 12*500){ + d00: e59f30a0 ldr r3, [pc, #160] ; da8 + d04: e1550003 cmp r5, r3 + d08: 1a00001b bne d7c + if(pid) + wait(); + else + exit(); + + for(i = 0; i < 2; i++){ + d0c: e3540001 cmp r4, #1 + d10: e59f007c ldr r0, [pc, #124] ; d94 + d14: 1a000006 bne d34 + printf(1, "wrong length %d\n", total); + exit(); + } + } + + unlink("f1"); + d18: eb0009b8 bl 3400 + unlink("f2"); + d1c: e59f0074 ldr r0, [pc, #116] ; d98 + d20: eb0009b6 bl 3400 + + printf(1, "twofiles ok\n"); + d24: e1a00004 mov r0, r4 + d28: e59f107c ldr r1, [pc, #124] ; dac +} + d2c: e8bd48f0 pop {r4, r5, r6, r7, fp, lr} + } + + unlink("f1"); + unlink("f2"); + + printf(1, "twofiles ok\n"); + d30: ea000a83 b 3744 + if(pid) + wait(); + else + exit(); + + for(i = 0; i < 2; i++){ + d34: e3a04001 mov r4, #1 + d38: eaffffd3 b c8c + fd = open(i?"f1":"f2", 0); + total = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + for(j = 0; j < n; j++){ + if(buf[j] != (i?'p':'c')){ + printf(1, "wrong char\n"); + d3c: e3a00001 mov r0, #1 + d40: e59f1068 ldr r1, [pc, #104] ; db0 + d44: eb000a7e bl 3744 + exit(); + d48: eb00092a bl 31f8 + } + + memset(buf, pid?'p':'c', 512); + for(i = 0; i < 12; i++){ + if((n = write(fd, buf, 500)) != 500){ + printf(1, "write failed %d\n", n); + d4c: e3a00001 mov r0, #1 + d50: e59f105c ldr r1, [pc, #92] ; db4 + d54: eb000a7a bl 3744 + exit(); + d58: eb000926 bl 31f8 + unlink("f1"); + unlink("f2"); + + pid = fork(); + if(pid < 0){ + printf(1, "fork failed\n"); + d5c: e3a00001 mov r0, #1 + d60: e59f1050 ldr r1, [pc, #80] ; db8 + d64: eb000a76 bl 3744 + exit(); + d68: eb000922 bl 31f8 + } + + fname = pid ? "f1" : "f2"; + fd = open(fname, O_CREATE | O_RDWR); + if(fd < 0){ + printf(1, "create failed\n"); + d6c: e3a00001 mov r0, #1 + d70: e59f1044 ldr r1, [pc, #68] ; dbc + d74: eb000a72 bl 3744 + exit(); + d78: eb00091e bl 31f8 + } + total += n; + } + close(fd); + if(total != 12*500){ + printf(1, "wrong length %d\n", total); + d7c: e3a00001 mov r0, #1 + d80: e59f1038 ldr r1, [pc, #56] ; dc0 + d84: e1a02005 mov r2, r5 + d88: eb000a6d bl 3744 + exit(); + d8c: eb000919 bl 31f8 + d90: 00003f60 .word 0x00003f60 + d94: 00003f58 .word 0x00003f58 + d98: 00003f5c .word 0x00003f5c + d9c: 00000202 .word 0x00000202 + da0: 000079fc .word 0x000079fc + da4: 000079fb .word 0x000079fb + da8: 00001770 .word 0x00001770 + dac: 00003fb4 .word 0x00003fb4 + db0: 00003f94 .word 0x00003f94 + db4: 00003f80 .word 0x00003f80 + db8: 00005148 .word 0x00005148 + dbc: 00003f70 .word 0x00003f70 + dc0: 00003fa0 .word 0x00003fa0 + +00000dc4 : +} + +// two processes create and delete different files in same directory +void +createdelete(void) +{ + dc4: e92d4df0 push {r4, r5, r6, r7, r8, sl, fp, lr} + dc8: e28db01c add fp, sp, #28 + dcc: e24dd020 sub sp, sp, #32 + enum { N = 20 }; + int pid, i, fd; + char name[32]; + + printf(1, "createdelete test\n"); + dd0: e3a00001 mov r0, #1 + dd4: e59f1214 ldr r1, [pc, #532] ; ff0 + dd8: eb000a59 bl 3744 + pid = fork(); + ddc: eb0008f8 bl 31c4 + if(pid < 0){ + de0: e2507000 subs r7, r0, #0 + de4: ba00007d blt fe0 + printf(1, "fork failed\n"); + exit(); + } + + name[0] = pid ? 'p' : 'c'; + de8: 13a03070 movne r3, #112 ; 0x70 + dec: 03a03063 moveq r3, #99 ; 0x63 + name[2] = '\0'; + df0: e3a04000 mov r4, #0 + if(pid < 0){ + printf(1, "fork failed\n"); + exit(); + } + + name[0] = pid ? 'p' : 'c'; + df4: e54b303c strb r3, [fp, #-60] ; 0x3c + name[2] = '\0'; + df8: e54b403a strb r4, [fp, #-58] ; 0x3a + dfc: e3a06001 mov r6, #1 + e00: e3a05030 mov r5, #48 ; 0x30 + e04: ea000005 b e20 + for(i = 0; i < N; i++){ + e08: e3560014 cmp r6, #20 + e0c: 0a000019 beq e78 + printf(1, "fork failed\n"); + exit(); + } + + name[0] = pid ? 'p' : 'c'; + name[2] = '\0'; + e10: e2855001 add r5, r5, #1 + e14: e2844001 add r4, r4, #1 + e18: e6ef5075 uxtb r5, r5 + e1c: e2866001 add r6, r6, #1 + for(i = 0; i < N; i++){ + name[1] = '0' + i; + fd = open(name, O_CREATE | O_RDWR); + e20: e24b003c sub r0, fp, #60 ; 0x3c + e24: e59f11c8 ldr r1, [pc, #456] ; ff4 + } + + name[0] = pid ? 'p' : 'c'; + name[2] = '\0'; + for(i = 0; i < N; i++){ + name[1] = '0' + i; + e28: e54b503b strb r5, [fp, #-59] ; 0x3b + fd = open(name, O_CREATE | O_RDWR); + e2c: eb000959 bl 3398 + if(fd < 0){ + e30: e3500000 cmp r0, #0 + e34: ba00005b blt fa8 + printf(1, "create failed\n"); + exit(); + } + close(fd); + e38: eb00092f bl 32fc + if(i > 0 && (i % 2 ) == 0){ + e3c: e3540000 cmp r4, #0 + e40: 0afffff2 beq e10 + e44: e3140001 tst r4, #1 + e48: 1affffee bne e08 + name[1] = '0' + (i / 2); + e4c: e1a030c4 asr r3, r4, #1 + e50: e2833030 add r3, r3, #48 ; 0x30 + if(unlink(name) < 0){ + e54: e24b003c sub r0, fp, #60 ; 0x3c + printf(1, "create failed\n"); + exit(); + } + close(fd); + if(i > 0 && (i % 2 ) == 0){ + name[1] = '0' + (i / 2); + e58: e54b303b strb r3, [fp, #-59] ; 0x3b + if(unlink(name) < 0){ + e5c: eb000967 bl 3400 + e60: e3500000 cmp r0, #0 + e64: aaffffe7 bge e08 + printf(1, "unlink failed\n"); + e68: e3a00001 mov r0, #1 + e6c: e59f1184 ldr r1, [pc, #388] ; ff8 + e70: eb000a33 bl 3744 + exit(); + e74: eb0008df bl 31f8 + } + } + } + + if(pid==0) + e78: e3570000 cmp r7, #0 + e7c: 0a000056 beq fdc + exit(); + else + wait(); + e80: eb0008e9 bl 322c + e84: e3a05030 mov r5, #48 ; 0x30 + + for(i = 0; i < N; i++){ + e88: e3a04000 mov r4, #0 + name[0] = 'p'; + e8c: e3a0a070 mov sl, #112 ; 0x70 + exit(); + } + if(fd >= 0) + close(fd); + + name[0] = 'c'; + e90: e3a08063 mov r8, #99 ; 0x63 + wait(); + + for(i = 0; i < N; i++){ + name[0] = 'p'; + name[1] = '0' + i; + fd = open(name, 0); + e94: e24b003c sub r0, fp, #60 ; 0x3c + e98: e3a01000 mov r1, #0 + exit(); + else + wait(); + + for(i = 0; i < N; i++){ + name[0] = 'p'; + e9c: e54ba03c strb sl, [fp, #-60] ; 0x3c + name[1] = '0' + i; + ea0: e54b503b strb r5, [fp, #-59] ; 0x3b + fd = open(name, 0); + ea4: eb00093b bl 3398 + if((i == 0 || i >= N/2) && fd < 0){ + ea8: e2747001 rsbs r7, r4, #1 + eac: 33a07000 movcc r7, #0 + eb0: e3540009 cmp r4, #9 + eb4: c3877001 orrgt r7, r7, #1 + eb8: e3570000 cmp r7, #0 + ebc: 0a000001 beq ec8 + ec0: e3500000 cmp r0, #0 + ec4: ba000040 blt fcc + printf(1, "oops createdelete %s didn't exist\n", name); + exit(); + } else if((i >= 1 && i < N/2) && fd >= 0){ + ec8: e2446001 sub r6, r4, #1 + ecc: e1e03000 mvn r3, r0 + ed0: e3560008 cmp r6, #8 + ed4: 83a06000 movhi r6, #0 + ed8: 93a06001 movls r6, #1 + edc: e1a03fa3 lsr r3, r3, #31 + ee0: e1160003 tst r6, r3 + ee4: 1a00002a bne f94 + printf(1, "oops createdelete %s did exist\n", name); + exit(); + } + if(fd >= 0) + ee8: e3530000 cmp r3, #0 + eec: 0a000000 beq ef4 + close(fd); + ef0: eb000901 bl 32fc + + name[0] = 'c'; + name[1] = '0' + i; + fd = open(name, 0); + ef4: e24b003c sub r0, fp, #60 ; 0x3c + ef8: e3a01000 mov r1, #0 + exit(); + } + if(fd >= 0) + close(fd); + + name[0] = 'c'; + efc: e54b803c strb r8, [fp, #-60] ; 0x3c + name[1] = '0' + i; + f00: e54b503b strb r5, [fp, #-59] ; 0x3b + fd = open(name, 0); + f04: eb000923 bl 3398 + if((i == 0 || i >= N/2) && fd < 0){ + f08: e3570000 cmp r7, #0 + f0c: 0a000001 beq f18 + f10: e3500000 cmp r0, #0 + f14: ba000027 blt fb8 + printf(1, "oops createdelete %s didn't exist\n", name); + exit(); + } else if((i >= 1 && i < N/2) && fd >= 0){ + f18: e1e03000 mvn r3, r0 + f1c: e1a03fa3 lsr r3, r3, #31 + f20: e1130006 tst r3, r6 + f24: 1a00001a bne f94 + printf(1, "oops createdelete %s did exist\n", name); + exit(); + } + if(fd >= 0) + f28: e3530000 cmp r3, #0 + f2c: 0a000000 beq f34 + close(fd); + f30: eb0008f1 bl 32fc + if(pid==0) + exit(); + else + wait(); + + for(i = 0; i < N; i++){ + f34: e2844001 add r4, r4, #1 + f38: e2855001 add r5, r5, #1 + f3c: e3540014 cmp r4, #20 + f40: e6ef5075 uxtb r5, r5 + f44: 1affffd2 bne e94 + f48: e3a04030 mov r4, #48 ; 0x30 + if(fd >= 0) + close(fd); + } + + for(i = 0; i < N; i++){ + name[0] = 'p'; + f4c: e3a06070 mov r6, #112 ; 0x70 + name[1] = '0' + i; + unlink(name); + name[0] = 'c'; + f50: e3a05063 mov r5, #99 ; 0x63 + close(fd); + } + + for(i = 0; i < N; i++){ + name[0] = 'p'; + name[1] = '0' + i; + f54: e54b403b strb r4, [fp, #-59] ; 0x3b + unlink(name); + name[0] = 'c'; + unlink(name); + f58: e2844001 add r4, r4, #1 + } + + for(i = 0; i < N; i++){ + name[0] = 'p'; + name[1] = '0' + i; + unlink(name); + f5c: e24b003c sub r0, fp, #60 ; 0x3c + if(fd >= 0) + close(fd); + } + + for(i = 0; i < N; i++){ + name[0] = 'p'; + f60: e54b603c strb r6, [fp, #-60] ; 0x3c + name[1] = '0' + i; + unlink(name); + name[0] = 'c'; + unlink(name); + f64: e6ef4074 uxtb r4, r4 + } + + for(i = 0; i < N; i++){ + name[0] = 'p'; + name[1] = '0' + i; + unlink(name); + f68: eb000924 bl 3400 + name[0] = 'c'; + unlink(name); + f6c: e24b003c sub r0, fp, #60 ; 0x3c + + for(i = 0; i < N; i++){ + name[0] = 'p'; + name[1] = '0' + i; + unlink(name); + name[0] = 'c'; + f70: e54b503c strb r5, [fp, #-60] ; 0x3c + unlink(name); + f74: eb000921 bl 3400 + } + if(fd >= 0) + close(fd); + } + + for(i = 0; i < N; i++){ + f78: e3540044 cmp r4, #68 ; 0x44 + f7c: 1afffff4 bne f54 + unlink(name); + name[0] = 'c'; + unlink(name); + } + + printf(1, "createdelete ok\n"); + f80: e3a00001 mov r0, #1 + f84: e59f1070 ldr r1, [pc, #112] ; ffc + f88: eb0009ed bl 3744 +} + f8c: e24bd01c sub sp, fp, #28 + f90: e8bd8df0 pop {r4, r5, r6, r7, r8, sl, fp, pc} + fd = open(name, 0); + if((i == 0 || i >= N/2) && fd < 0){ + printf(1, "oops createdelete %s didn't exist\n", name); + exit(); + } else if((i >= 1 && i < N/2) && fd >= 0){ + printf(1, "oops createdelete %s did exist\n", name); + f94: e3a00001 mov r0, #1 + f98: e59f1060 ldr r1, [pc, #96] ; 1000 + f9c: e24b203c sub r2, fp, #60 ; 0x3c + fa0: eb0009e7 bl 3744 + exit(); + fa4: eb000893 bl 31f8 + name[2] = '\0'; + for(i = 0; i < N; i++){ + name[1] = '0' + i; + fd = open(name, O_CREATE | O_RDWR); + if(fd < 0){ + printf(1, "create failed\n"); + fa8: e3a00001 mov r0, #1 + fac: e59f1050 ldr r1, [pc, #80] ; 1004 + fb0: eb0009e3 bl 3744 + exit(); + fb4: eb00088f bl 31f8 + + name[0] = 'c'; + name[1] = '0' + i; + fd = open(name, 0); + if((i == 0 || i >= N/2) && fd < 0){ + printf(1, "oops createdelete %s didn't exist\n", name); + fb8: e3a00001 mov r0, #1 + fbc: e59f1044 ldr r1, [pc, #68] ; 1008 + fc0: e24b203c sub r2, fp, #60 ; 0x3c + fc4: eb0009de bl 3744 + exit(); + fc8: eb00088a bl 31f8 + for(i = 0; i < N; i++){ + name[0] = 'p'; + name[1] = '0' + i; + fd = open(name, 0); + if((i == 0 || i >= N/2) && fd < 0){ + printf(1, "oops createdelete %s didn't exist\n", name); + fcc: e3a00001 mov r0, #1 + fd0: e59f1030 ldr r1, [pc, #48] ; 1008 + fd4: e24b203c sub r2, fp, #60 ; 0x3c + fd8: eb0009d9 bl 3744 + exit(); + fdc: eb000885 bl 31f8 + char name[32]; + + printf(1, "createdelete test\n"); + pid = fork(); + if(pid < 0){ + printf(1, "fork failed\n"); + fe0: e3a00001 mov r0, #1 + fe4: e59f1020 ldr r1, [pc, #32] ; 100c + fe8: eb0009d5 bl 3744 + exit(); + fec: eb000881 bl 31f8 + ff0: 00003fc4 .word 0x00003fc4 + ff4: 00000202 .word 0x00000202 + ff8: 00003fd8 .word 0x00003fd8 + ffc: 0000402c .word 0x0000402c + 1000: 0000400c .word 0x0000400c + 1004: 00003f70 .word 0x00003f70 + 1008: 00003fe8 .word 0x00003fe8 + 100c: 00005148 .word 0x00005148 + +00001010 : +} + +// can I unlink a file and still read it? +void +unlinkread(void) +{ + 1010: e92d4878 push {r3, r4, r5, r6, fp, lr} + int fd, fd1; + + printf(1, "unlinkread test\n"); + 1014: e3a00001 mov r0, #1 +} + +// can I unlink a file and still read it? +void +unlinkread(void) +{ + 1018: e28db014 add fp, sp, #20 + int fd, fd1; + + printf(1, "unlinkread test\n"); + 101c: e59f1130 ldr r1, [pc, #304] ; 1154 + 1020: eb0009c7 bl 3744 + fd = open("unlinkread", O_CREATE | O_RDWR); + 1024: e59f012c ldr r0, [pc, #300] ; 1158 + 1028: e59f112c ldr r1, [pc, #300] ; 115c + 102c: eb0008d9 bl 3398 + if(fd < 0){ + 1030: e2504000 subs r4, r0, #0 + 1034: ba00002e blt 10f4 + printf(1, "create unlinkread failed\n"); + exit(); + } + write(fd, "hello", 5); + 1038: e59f1120 ldr r1, [pc, #288] ; 1160 + 103c: e3a02005 mov r2, #5 + 1040: eb0008a0 bl 32c8 + close(fd); + 1044: e1a00004 mov r0, r4 + 1048: eb0008ab bl 32fc + + fd = open("unlinkread", O_RDWR); + 104c: e59f0104 ldr r0, [pc, #260] ; 1158 + 1050: e3a01002 mov r1, #2 + 1054: eb0008cf bl 3398 + if(fd < 0){ + 1058: e2504000 subs r4, r0, #0 + 105c: ba000038 blt 1144 + printf(1, "open unlinkread failed\n"); + exit(); + } + if(unlink("unlinkread") != 0){ + 1060: e59f00f0 ldr r0, [pc, #240] ; 1158 + 1064: eb0008e5 bl 3400 + 1068: e3500000 cmp r0, #0 + 106c: 1a000030 bne 1134 + printf(1, "unlink unlinkread failed\n"); + exit(); + } + + fd1 = open("unlinkread", O_CREATE | O_RDWR); + 1070: e59f10e4 ldr r1, [pc, #228] ; 115c + 1074: e59f00dc ldr r0, [pc, #220] ; 1158 + 1078: eb0008c6 bl 3398 + write(fd1, "yyy", 3); + close(fd1); + + if(read(fd, buf, sizeof(buf)) != 5){ + 107c: e59f50e0 ldr r5, [pc, #224] ; 1164 + printf(1, "unlink unlinkread failed\n"); + exit(); + } + + fd1 = open("unlinkread", O_CREATE | O_RDWR); + write(fd1, "yyy", 3); + 1080: e59f10e0 ldr r1, [pc, #224] ; 1168 + 1084: e3a02003 mov r2, #3 + if(unlink("unlinkread") != 0){ + printf(1, "unlink unlinkread failed\n"); + exit(); + } + + fd1 = open("unlinkread", O_CREATE | O_RDWR); + 1088: e1a06000 mov r6, r0 + write(fd1, "yyy", 3); + 108c: eb00088d bl 32c8 + close(fd1); + 1090: e1a00006 mov r0, r6 + 1094: eb000898 bl 32fc + + if(read(fd, buf, sizeof(buf)) != 5){ + 1098: e1a00004 mov r0, r4 + 109c: e1a01005 mov r1, r5 + 10a0: e3a02a02 mov r2, #8192 ; 0x2000 + 10a4: eb00087a bl 3294 + 10a8: e3500005 cmp r0, #5 + 10ac: 1a00001c bne 1124 + printf(1, "unlinkread read failed"); + exit(); + } + if(buf[0] != 'h'){ + 10b0: e5d53000 ldrb r3, [r5] + 10b4: e3530068 cmp r3, #104 ; 0x68 + 10b8: 1a000015 bne 1114 + printf(1, "unlinkread wrong data\n"); + exit(); + } + if(write(fd, buf, 10) != 10){ + 10bc: e1a00004 mov r0, r4 + 10c0: e1a01005 mov r1, r5 + 10c4: e3a0200a mov r2, #10 + 10c8: eb00087e bl 32c8 + 10cc: e350000a cmp r0, #10 + 10d0: 1a00000b bne 1104 + printf(1, "unlinkread write failed\n"); + exit(); + } + close(fd); + 10d4: e1a00004 mov r0, r4 + 10d8: eb000887 bl 32fc + unlink("unlinkread"); + 10dc: e59f0074 ldr r0, [pc, #116] ; 1158 + 10e0: eb0008c6 bl 3400 + printf(1, "unlinkread ok\n"); + 10e4: e3a00001 mov r0, #1 + 10e8: e59f107c ldr r1, [pc, #124] ; 116c +} + 10ec: e8bd4878 pop {r3, r4, r5, r6, fp, lr} + printf(1, "unlinkread write failed\n"); + exit(); + } + close(fd); + unlink("unlinkread"); + printf(1, "unlinkread ok\n"); + 10f0: ea000993 b 3744 + int fd, fd1; + + printf(1, "unlinkread test\n"); + fd = open("unlinkread", O_CREATE | O_RDWR); + if(fd < 0){ + printf(1, "create unlinkread failed\n"); + 10f4: e3a00001 mov r0, #1 + 10f8: e59f1070 ldr r1, [pc, #112] ; 1170 + 10fc: eb000990 bl 3744 + exit(); + 1100: eb00083c bl 31f8 + if(buf[0] != 'h'){ + printf(1, "unlinkread wrong data\n"); + exit(); + } + if(write(fd, buf, 10) != 10){ + printf(1, "unlinkread write failed\n"); + 1104: e3a00001 mov r0, #1 + 1108: e59f1064 ldr r1, [pc, #100] ; 1174 + 110c: eb00098c bl 3744 + exit(); + 1110: eb000838 bl 31f8 + if(read(fd, buf, sizeof(buf)) != 5){ + printf(1, "unlinkread read failed"); + exit(); + } + if(buf[0] != 'h'){ + printf(1, "unlinkread wrong data\n"); + 1114: e3a00001 mov r0, #1 + 1118: e59f1058 ldr r1, [pc, #88] ; 1178 + 111c: eb000988 bl 3744 + exit(); + 1120: eb000834 bl 31f8 + fd1 = open("unlinkread", O_CREATE | O_RDWR); + write(fd1, "yyy", 3); + close(fd1); + + if(read(fd, buf, sizeof(buf)) != 5){ + printf(1, "unlinkread read failed"); + 1124: e3a00001 mov r0, #1 + 1128: e59f104c ldr r1, [pc, #76] ; 117c + 112c: eb000984 bl 3744 + exit(); + 1130: eb000830 bl 31f8 + if(fd < 0){ + printf(1, "open unlinkread failed\n"); + exit(); + } + if(unlink("unlinkread") != 0){ + printf(1, "unlink unlinkread failed\n"); + 1134: e3a00001 mov r0, #1 + 1138: e59f1040 ldr r1, [pc, #64] ; 1180 + 113c: eb000980 bl 3744 + exit(); + 1140: eb00082c bl 31f8 + write(fd, "hello", 5); + close(fd); + + fd = open("unlinkread", O_RDWR); + if(fd < 0){ + printf(1, "open unlinkread failed\n"); + 1144: e3a00001 mov r0, #1 + 1148: e59f1034 ldr r1, [pc, #52] ; 1184 + 114c: eb00097c bl 3744 + exit(); + 1150: eb000828 bl 31f8 + 1154: 00004040 .word 0x00004040 + 1158: 00004054 .word 0x00004054 + 115c: 00000202 .word 0x00000202 + 1160: 0000407c .word 0x0000407c + 1164: 000079fc .word 0x000079fc + 1168: 000040b8 .word 0x000040b8 + 116c: 00004108 .word 0x00004108 + 1170: 00004060 .word 0x00004060 + 1174: 000040ec .word 0x000040ec + 1178: 000040d4 .word 0x000040d4 + 117c: 000040bc .word 0x000040bc + 1180: 0000409c .word 0x0000409c + 1184: 00004084 .word 0x00004084 + +00001188 : + printf(1, "unlinkread ok\n"); +} + +void +linktest(void) +{ + 1188: e92d4818 push {r3, r4, fp, lr} + int fd; + + printf(1, "linktest\n"); + 118c: e3a00001 mov r0, #1 + printf(1, "unlinkread ok\n"); +} + +void +linktest(void) +{ + 1190: e28db00c add fp, sp, #12 + int fd; + + printf(1, "linktest\n"); + 1194: e59f1180 ldr r1, [pc, #384] ; 131c + 1198: eb000969 bl 3744 + + unlink("lf1"); + 119c: e59f017c ldr r0, [pc, #380] ; 1320 + 11a0: eb000896 bl 3400 + unlink("lf2"); + 11a4: e59f0178 ldr r0, [pc, #376] ; 1324 + 11a8: eb000894 bl 3400 + + fd = open("lf1", O_CREATE|O_RDWR); + 11ac: e59f016c ldr r0, [pc, #364] ; 1320 + 11b0: e59f1170 ldr r1, [pc, #368] ; 1328 + 11b4: eb000877 bl 3398 + if(fd < 0){ + 11b8: e2504000 subs r4, r0, #0 + 11bc: ba000033 blt 1290 + printf(1, "create lf1 failed\n"); + exit(); + } + if(write(fd, "hello", 5) != 5){ + 11c0: e59f1164 ldr r1, [pc, #356] ; 132c + 11c4: e3a02005 mov r2, #5 + 11c8: eb00083e bl 32c8 + 11cc: e3500005 cmp r0, #5 + 11d0: 1a00004d bne 130c + printf(1, "write lf1 failed\n"); + exit(); + } + close(fd); + 11d4: e1a00004 mov r0, r4 + 11d8: eb000847 bl 32fc + + if(link("lf1", "lf2") < 0){ + 11dc: e59f013c ldr r0, [pc, #316] ; 1320 + 11e0: e59f113c ldr r1, [pc, #316] ; 1324 + 11e4: eb00089f bl 3468 + 11e8: e3500000 cmp r0, #0 + 11ec: ba000042 blt 12fc + printf(1, "link lf1 lf2 failed\n"); + exit(); + } + unlink("lf1"); + 11f0: e59f0128 ldr r0, [pc, #296] ; 1320 + 11f4: eb000881 bl 3400 + + if(open("lf1", 0) >= 0){ + 11f8: e59f0120 ldr r0, [pc, #288] ; 1320 + 11fc: e3a01000 mov r1, #0 + 1200: eb000864 bl 3398 + 1204: e3500000 cmp r0, #0 + 1208: aa000037 bge 12ec + printf(1, "unlinked lf1 but it is still there!\n"); + exit(); + } + + fd = open("lf2", 0); + 120c: e59f0110 ldr r0, [pc, #272] ; 1324 + 1210: e3a01000 mov r1, #0 + 1214: eb00085f bl 3398 + if(fd < 0){ + 1218: e2504000 subs r4, r0, #0 + 121c: ba00002e blt 12dc + printf(1, "open lf2 failed\n"); + exit(); + } + if(read(fd, buf, sizeof(buf)) != 5){ + 1220: e59f1108 ldr r1, [pc, #264] ; 1330 + 1224: e3a02a02 mov r2, #8192 ; 0x2000 + 1228: eb000819 bl 3294 + 122c: e3500005 cmp r0, #5 + 1230: 1a000025 bne 12cc + printf(1, "read lf2 failed\n"); + exit(); + } + close(fd); + 1234: e1a00004 mov r0, r4 + 1238: eb00082f bl 32fc + + if(link("lf2", "lf2") >= 0){ + 123c: e59f00e0 ldr r0, [pc, #224] ; 1324 + 1240: e1a01000 mov r1, r0 + 1244: eb000887 bl 3468 + 1248: e3500000 cmp r0, #0 + 124c: aa00001a bge 12bc + printf(1, "link lf2 lf2 succeeded! oops\n"); + exit(); + } + + unlink("lf2"); + 1250: e59f00cc ldr r0, [pc, #204] ; 1324 + 1254: eb000869 bl 3400 + if(link("lf2", "lf1") >= 0){ + 1258: e59f00c4 ldr r0, [pc, #196] ; 1324 + 125c: e59f10bc ldr r1, [pc, #188] ; 1320 + 1260: eb000880 bl 3468 + 1264: e3500000 cmp r0, #0 + 1268: aa00000f bge 12ac + printf(1, "link non-existant succeeded! oops\n"); + exit(); + } + + if(link(".", "lf1") >= 0){ + 126c: e59f00c0 ldr r0, [pc, #192] ; 1334 + 1270: e59f10a8 ldr r1, [pc, #168] ; 1320 + 1274: eb00087b bl 3468 + 1278: e3500000 cmp r0, #0 + printf(1, "link . lf1 succeeded! oops\n"); + 127c: e3a00001 mov r0, #1 + if(link("lf2", "lf1") >= 0){ + printf(1, "link non-existant succeeded! oops\n"); + exit(); + } + + if(link(".", "lf1") >= 0){ + 1280: aa000006 bge 12a0 + printf(1, "link . lf1 succeeded! oops\n"); + exit(); + } + + printf(1, "linktest ok\n"); + 1284: e59f10ac ldr r1, [pc, #172] ; 1338 +} + 1288: e8bd4818 pop {r3, r4, fp, lr} + if(link(".", "lf1") >= 0){ + printf(1, "link . lf1 succeeded! oops\n"); + exit(); + } + + printf(1, "linktest ok\n"); + 128c: ea00092c b 3744 + unlink("lf1"); + unlink("lf2"); + + fd = open("lf1", O_CREATE|O_RDWR); + if(fd < 0){ + printf(1, "create lf1 failed\n"); + 1290: e3a00001 mov r0, #1 + 1294: e59f10a0 ldr r1, [pc, #160] ; 133c + 1298: eb000929 bl 3744 + exit(); + 129c: eb0007d5 bl 31f8 + printf(1, "link non-existant succeeded! oops\n"); + exit(); + } + + if(link(".", "lf1") >= 0){ + printf(1, "link . lf1 succeeded! oops\n"); + 12a0: e59f1098 ldr r1, [pc, #152] ; 1340 + 12a4: eb000926 bl 3744 + exit(); + 12a8: eb0007d2 bl 31f8 + exit(); + } + + unlink("lf2"); + if(link("lf2", "lf1") >= 0){ + printf(1, "link non-existant succeeded! oops\n"); + 12ac: e3a00001 mov r0, #1 + 12b0: e59f108c ldr r1, [pc, #140] ; 1344 + 12b4: eb000922 bl 3744 + exit(); + 12b8: eb0007ce bl 31f8 + exit(); + } + close(fd); + + if(link("lf2", "lf2") >= 0){ + printf(1, "link lf2 lf2 succeeded! oops\n"); + 12bc: e3a00001 mov r0, #1 + 12c0: e59f1080 ldr r1, [pc, #128] ; 1348 + 12c4: eb00091e bl 3744 + exit(); + 12c8: eb0007ca bl 31f8 + if(fd < 0){ + printf(1, "open lf2 failed\n"); + exit(); + } + if(read(fd, buf, sizeof(buf)) != 5){ + printf(1, "read lf2 failed\n"); + 12cc: e3a00001 mov r0, #1 + 12d0: e59f1074 ldr r1, [pc, #116] ; 134c + 12d4: eb00091a bl 3744 + exit(); + 12d8: eb0007c6 bl 31f8 + exit(); + } + + fd = open("lf2", 0); + if(fd < 0){ + printf(1, "open lf2 failed\n"); + 12dc: e3a00001 mov r0, #1 + 12e0: e59f1068 ldr r1, [pc, #104] ; 1350 + 12e4: eb000916 bl 3744 + exit(); + 12e8: eb0007c2 bl 31f8 + exit(); + } + unlink("lf1"); + + if(open("lf1", 0) >= 0){ + printf(1, "unlinked lf1 but it is still there!\n"); + 12ec: e3a00001 mov r0, #1 + 12f0: e59f105c ldr r1, [pc, #92] ; 1354 + 12f4: eb000912 bl 3744 + exit(); + 12f8: eb0007be bl 31f8 + exit(); + } + close(fd); + + if(link("lf1", "lf2") < 0){ + printf(1, "link lf1 lf2 failed\n"); + 12fc: e3a00001 mov r0, #1 + 1300: e59f1050 ldr r1, [pc, #80] ; 1358 + 1304: eb00090e bl 3744 + exit(); + 1308: eb0007ba bl 31f8 + if(fd < 0){ + printf(1, "create lf1 failed\n"); + exit(); + } + if(write(fd, "hello", 5) != 5){ + printf(1, "write lf1 failed\n"); + 130c: e3a00001 mov r0, #1 + 1310: e59f1044 ldr r1, [pc, #68] ; 135c + 1314: eb00090a bl 3744 + exit(); + 1318: eb0007b6 bl 31f8 + 131c: 00004118 .word 0x00004118 + 1320: 00004124 .word 0x00004124 + 1324: 00004128 .word 0x00004128 + 1328: 00000202 .word 0x00000202 + 132c: 0000407c .word 0x0000407c + 1330: 000079fc .word 0x000079fc + 1334: 00004200 .word 0x00004200 + 1338: 00004220 .word 0x00004220 + 133c: 0000412c .word 0x0000412c + 1340: 00004204 .word 0x00004204 + 1344: 000041dc .word 0x000041dc + 1348: 000041bc .word 0x000041bc + 134c: 000041a8 .word 0x000041a8 + 1350: 00004194 .word 0x00004194 + 1354: 0000416c .word 0x0000416c + 1358: 00004154 .word 0x00004154 + 135c: 00004140 .word 0x00004140 + +00001360 : +} + +// test concurrent create/link/unlink of the same file +void +concreate(void) +{ + 1360: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + 1364: e28db018 add fp, sp, #24 + 1368: e24dd044 sub sp, sp, #68 ; 0x44 + struct { + ushort inum; + char name[14]; + } de; + + printf(1, "concreate test\n"); + 136c: e3a00001 mov r0, #1 + 1370: e59f12dc ldr r1, [pc, #732] ; 1654 + 1374: eb0008f2 bl 3744 + file[0] = 'C'; + file[2] = '\0'; + 1378: e3a03000 mov r3, #0 + ushort inum; + char name[14]; + } de; + + printf(1, "concreate test\n"); + file[0] = 'C'; + 137c: e3a02043 mov r2, #67 ; 0x43 + file[1] = '0' + i; + unlink(file); + pid = fork(); + if(pid && (i % 3) == 1){ + link("C0", file); + } else if(pid == 0 && (i % 5) == 1){ + 1380: e59f72d0 ldr r7, [pc, #720] ; 1658 + file[2] = '\0'; + for(i = 0; i < 40; i++){ + file[1] = '0' + i; + unlink(file); + pid = fork(); + if(pid && (i % 3) == 1){ + 1384: e59f82d0 ldr r8, [pc, #720] ; 165c + char name[14]; + } de; + + printf(1, "concreate test\n"); + file[0] = 'C'; + file[2] = '\0'; + 1388: e3a05030 mov r5, #48 ; 0x30 + for(i = 0; i < 40; i++){ + 138c: e1a04003 mov r4, r3 + ushort inum; + char name[14]; + } de; + + printf(1, "concreate test\n"); + file[0] = 'C'; + 1390: e54b2020 strb r2, [fp, #-32] + file[2] = '\0'; + 1394: e54b301e strb r3, [fp, #-30] + 1398: ea000013 b 13ec + for(i = 0; i < 40; i++){ + file[1] = '0' + i; + unlink(file); + pid = fork(); + if(pid && (i % 3) == 1){ + 139c: e0c32498 smull r2, r3, r8, r4 + 13a0: e0433fc4 sub r3, r3, r4, asr #31 + 13a4: e0833083 add r3, r3, r3, lsl #1 + 13a8: e0633004 rsb r3, r3, r4 + 13ac: e3530001 cmp r3, #1 + 13b0: 0a00001e beq 1430 + link("C0", file); + } else if(pid == 0 && (i % 5) == 1){ + link("C0", file); + } else { + fd = open(file, O_CREATE | O_RDWR); + 13b4: e24b0020 sub r0, fp, #32 + 13b8: e59f12a0 ldr r1, [pc, #672] ; 1660 + 13bc: eb0007f5 bl 3398 + if(fd < 0){ + 13c0: e3500000 cmp r0, #0 + 13c4: ba00008f blt 1608 + printf(1, "concreate create %s failed\n", file); + exit(); + } + close(fd); + 13c8: eb0007cb bl 32fc + } + if(pid == 0) + 13cc: e3560000 cmp r6, #0 + 13d0: 0a000015 beq 142c + } de; + + printf(1, "concreate test\n"); + file[0] = 'C'; + file[2] = '\0'; + for(i = 0; i < 40; i++){ + 13d4: e2844001 add r4, r4, #1 + 13d8: e2855001 add r5, r5, #1 + close(fd); + } + if(pid == 0) + exit(); + else + wait(); + 13dc: eb000792 bl 322c + } de; + + printf(1, "concreate test\n"); + file[0] = 'C'; + file[2] = '\0'; + for(i = 0; i < 40; i++){ + 13e0: e3540028 cmp r4, #40 ; 0x28 + 13e4: e6ef5075 uxtb r5, r5 + 13e8: 0a000019 beq 1454 + file[1] = '0' + i; + unlink(file); + 13ec: e24b0020 sub r0, fp, #32 + + printf(1, "concreate test\n"); + file[0] = 'C'; + file[2] = '\0'; + for(i = 0; i < 40; i++){ + file[1] = '0' + i; + 13f0: e54b501f strb r5, [fp, #-31] + unlink(file); + 13f4: eb000801 bl 3400 + pid = fork(); + 13f8: eb000771 bl 31c4 + if(pid && (i % 3) == 1){ + 13fc: e2506000 subs r6, r0, #0 + 1400: 1affffe5 bne 139c + link("C0", file); + } else if(pid == 0 && (i % 5) == 1){ + 1404: e0c23497 smull r3, r2, r7, r4 + 1408: e1a03fc4 asr r3, r4, #31 + 140c: e06330c2 rsb r3, r3, r2, asr #1 + 1410: e0833103 add r3, r3, r3, lsl #2 + 1414: e0633004 rsb r3, r3, r4 + 1418: e3530001 cmp r3, #1 + 141c: 1affffe4 bne 13b4 + link("C0", file); + 1420: e24b1020 sub r1, fp, #32 + 1424: e59f0238 ldr r0, [pc, #568] ; 1664 + 1428: eb00080e bl 3468 + continue; + if(de.name[0] == 'C' && de.name[2] == '\0'){ + i = de.name[1] - '0'; + if(i < 0 || i >= sizeof(fa)){ + printf(1, "concreate weird file %s\n", de.name); + exit(); + 142c: eb000771 bl 31f8 + for(i = 0; i < 40; i++){ + file[1] = '0' + i; + unlink(file); + pid = fork(); + if(pid && (i % 3) == 1){ + link("C0", file); + 1430: e24b1020 sub r1, fp, #32 + 1434: e59f0228 ldr r0, [pc, #552] ; 1664 + } de; + + printf(1, "concreate test\n"); + file[0] = 'C'; + file[2] = '\0'; + for(i = 0; i < 40; i++){ + 1438: e2844001 add r4, r4, #1 + 143c: e2855001 add r5, r5, #1 + file[1] = '0' + i; + unlink(file); + pid = fork(); + if(pid && (i % 3) == 1){ + link("C0", file); + 1440: eb000808 bl 3468 + close(fd); + } + if(pid == 0) + exit(); + else + wait(); + 1444: eb000778 bl 322c + } de; + + printf(1, "concreate test\n"); + file[0] = 'C'; + file[2] = '\0'; + for(i = 0; i < 40; i++){ + 1448: e3540028 cmp r4, #40 ; 0x28 + 144c: e6ef5075 uxtb r5, r5 + 1450: 1affffe5 bne 13ec + exit(); + else + wait(); + } + + memset(fa, 0, sizeof(fa)); + 1454: e1a02004 mov r2, r4 + 1458: e3a01000 mov r1, #0 + 145c: e24b0058 sub r0, fp, #88 ; 0x58 + 1460: eb0006e9 bl 300c + fd = open(".", 0); + 1464: e59f01fc ldr r0, [pc, #508] ; 1668 + 1468: e3a01000 mov r1, #0 + 146c: eb0007c9 bl 3398 + n = 0; + 1470: e3a05000 mov r5, #0 + } + if(fa[i]){ + printf(1, "concreate duplicate file %s\n", de.name); + exit(); + } + fa[i] = 1; + 1474: e3a06001 mov r6, #1 + else + wait(); + } + + memset(fa, 0, sizeof(fa)); + fd = open(".", 0); + 1478: e1a04000 mov r4, r0 + n = 0; + while(read(fd, &de, sizeof(de)) > 0){ + 147c: e1a00004 mov r0, r4 + 1480: e24b1030 sub r1, fp, #48 ; 0x30 + 1484: e3a02010 mov r2, #16 + 1488: eb000781 bl 3294 + 148c: e3500000 cmp r0, #0 + 1490: da000019 ble 14fc + if(de.inum == 0) + 1494: e15b33b0 ldrh r3, [fp, #-48] ; 0xffffffd0 + 1498: e3530000 cmp r3, #0 + 149c: 0afffff6 beq 147c + continue; + if(de.name[0] == 'C' && de.name[2] == '\0'){ + 14a0: e55b302e ldrb r3, [fp, #-46] ; 0x2e + 14a4: e3530043 cmp r3, #67 ; 0x43 + 14a8: 1afffff3 bne 147c + 14ac: e55b302c ldrb r3, [fp, #-44] ; 0x2c + 14b0: e3530000 cmp r3, #0 + 14b4: 1afffff0 bne 147c + i = de.name[1] - '0'; + 14b8: e55b302d ldrb r3, [fp, #-45] ; 0x2d + 14bc: e2433030 sub r3, r3, #48 ; 0x30 + if(i < 0 || i >= sizeof(fa)){ + 14c0: e3530027 cmp r3, #39 ; 0x27 + 14c4: 8a00005d bhi 1640 + printf(1, "concreate weird file %s\n", de.name); + exit(); + } + if(fa[i]){ + 14c8: e24b201c sub r2, fp, #28 + 14cc: e0823003 add r3, r2, r3 + 14d0: e553203c ldrb r2, [r3, #-60] ; 0x3c + 14d4: e3520000 cmp r2, #0 + 14d8: 1a000053 bne 162c + printf(1, "concreate duplicate file %s\n", de.name); + exit(); + } + fa[i] = 1; + 14dc: e543603c strb r6, [r3, #-60] ; 0x3c + } + + memset(fa, 0, sizeof(fa)); + fd = open(".", 0); + n = 0; + while(read(fd, &de, sizeof(de)) > 0){ + 14e0: e1a00004 mov r0, r4 + 14e4: e24b1030 sub r1, fp, #48 ; 0x30 + 14e8: e3a02010 mov r2, #16 + 14ec: eb000768 bl 3294 + if(fa[i]){ + printf(1, "concreate duplicate file %s\n", de.name); + exit(); + } + fa[i] = 1; + n++; + 14f0: e2855001 add r5, r5, #1 + } + + memset(fa, 0, sizeof(fa)); + fd = open(".", 0); + n = 0; + while(read(fd, &de, sizeof(de)) > 0){ + 14f4: e3500000 cmp r0, #0 + 14f8: caffffe5 bgt 1494 + } + fa[i] = 1; + n++; + } + } + close(fd); + 14fc: e1a00004 mov r0, r4 + 1500: eb00077d bl 32fc + + if(n != 40){ + 1504: e3550028 cmp r5, #40 ; 0x28 + 1508: 1a000043 bne 161c + pid = fork(); + if(pid < 0){ + printf(1, "fork failed\n"); + exit(); + } + if(((i % 3) == 0 && pid == 0) || + 150c: e59f7148 ldr r7, [pc, #328] ; 165c + n++; + } + } + close(fd); + + if(n != 40){ + 1510: e3a06030 mov r6, #48 ; 0x30 + 1514: e3a04000 mov r4, #0 + 1518: ea000017 b 157c + printf(1, "fork failed\n"); + exit(); + } + if(((i % 3) == 0 && pid == 0) || + ((i % 3) == 1 && pid != 0)){ + close(open(file, 0)); + 151c: e3a01000 mov r1, #0 + 1520: e24b0020 sub r0, fp, #32 + 1524: eb00079b bl 3398 + 1528: eb000773 bl 32fc + close(open(file, 0)); + 152c: e3a01000 mov r1, #0 + 1530: e24b0020 sub r0, fp, #32 + 1534: eb000797 bl 3398 + 1538: eb00076f bl 32fc + close(open(file, 0)); + 153c: e3a01000 mov r1, #0 + 1540: e24b0020 sub r0, fp, #32 + 1544: eb000793 bl 3398 + 1548: eb00076b bl 32fc + close(open(file, 0)); + 154c: e3a01000 mov r1, #0 + 1550: e24b0020 sub r0, fp, #32 + 1554: eb00078f bl 3398 + 1558: eb000767 bl 32fc + unlink(file); + unlink(file); + unlink(file); + unlink(file); + } + if(pid == 0) + 155c: e3550000 cmp r5, #0 + 1560: 0affffb1 beq 142c + if(n != 40){ + printf(1, "concreate not enough files in directory listing\n"); + exit(); + } + + for(i = 0; i < 40; i++){ + 1564: e2844001 add r4, r4, #1 + 1568: e2866001 add r6, r6, #1 + unlink(file); + } + if(pid == 0) + exit(); + else + wait(); + 156c: eb00072e bl 322c + if(n != 40){ + printf(1, "concreate not enough files in directory listing\n"); + exit(); + } + + for(i = 0; i < 40; i++){ + 1570: e3540028 cmp r4, #40 ; 0x28 + 1574: e6ef6076 uxtb r6, r6 + 1578: 0a000019 beq 15e4 + file[1] = '0' + i; + 157c: e54b601f strb r6, [fp, #-31] + pid = fork(); + 1580: eb00070f bl 31c4 + if(pid < 0){ + 1584: e2505000 subs r5, r0, #0 + 1588: ba00001a blt 15f8 + printf(1, "fork failed\n"); + exit(); + } + if(((i % 3) == 0 && pid == 0) || + 158c: e0c32497 smull r2, r3, r7, r4 + 1590: e0433fc4 sub r3, r3, r4, asr #31 + 1594: e0833083 add r3, r3, r3, lsl #1 + 1598: e0633004 rsb r3, r3, r4 + 159c: e1932005 orrs r2, r3, r5 + 15a0: 0affffdd beq 151c + 15a4: e2432001 sub r2, r3, #1 + 15a8: e2723000 rsbs r3, r2, #0 + 15ac: e0a33002 adc r3, r3, r2 + 15b0: e3550000 cmp r5, #0 + 15b4: 03a03000 moveq r3, #0 + 15b8: e3530000 cmp r3, #0 + 15bc: 1affffd6 bne 151c + close(open(file, 0)); + close(open(file, 0)); + close(open(file, 0)); + close(open(file, 0)); + } else { + unlink(file); + 15c0: e24b0020 sub r0, fp, #32 + 15c4: eb00078d bl 3400 + unlink(file); + 15c8: e24b0020 sub r0, fp, #32 + 15cc: eb00078b bl 3400 + unlink(file); + 15d0: e24b0020 sub r0, fp, #32 + 15d4: eb000789 bl 3400 + unlink(file); + 15d8: e24b0020 sub r0, fp, #32 + 15dc: eb000787 bl 3400 + 15e0: eaffffdd b 155c + exit(); + else + wait(); + } + + printf(1, "concreate ok\n"); + 15e4: e3a00001 mov r0, #1 + 15e8: e59f107c ldr r1, [pc, #124] ; 166c + 15ec: eb000854 bl 3744 +} + 15f0: e24bd018 sub sp, fp, #24 + 15f4: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} + + for(i = 0; i < 40; i++){ + file[1] = '0' + i; + pid = fork(); + if(pid < 0){ + printf(1, "fork failed\n"); + 15f8: e3a00001 mov r0, #1 + 15fc: e59f106c ldr r1, [pc, #108] ; 1670 + 1600: eb00084f bl 3744 + exit(); + 1604: eb0006fb bl 31f8 + } else if(pid == 0 && (i % 5) == 1){ + link("C0", file); + } else { + fd = open(file, O_CREATE | O_RDWR); + if(fd < 0){ + printf(1, "concreate create %s failed\n", file); + 1608: e3a00001 mov r0, #1 + 160c: e59f1060 ldr r1, [pc, #96] ; 1674 + 1610: e24b2020 sub r2, fp, #32 + 1614: eb00084a bl 3744 + exit(); + 1618: eb0006f6 bl 31f8 + } + } + close(fd); + + if(n != 40){ + printf(1, "concreate not enough files in directory listing\n"); + 161c: e3a00001 mov r0, #1 + 1620: e59f1050 ldr r1, [pc, #80] ; 1678 + 1624: eb000846 bl 3744 + exit(); + 1628: eb0006f2 bl 31f8 + if(i < 0 || i >= sizeof(fa)){ + printf(1, "concreate weird file %s\n", de.name); + exit(); + } + if(fa[i]){ + printf(1, "concreate duplicate file %s\n", de.name); + 162c: e3a00001 mov r0, #1 + 1630: e59f1044 ldr r1, [pc, #68] ; 167c + 1634: e24b202e sub r2, fp, #46 ; 0x2e + 1638: eb000841 bl 3744 + exit(); + 163c: eb0006ed bl 31f8 + if(de.inum == 0) + continue; + if(de.name[0] == 'C' && de.name[2] == '\0'){ + i = de.name[1] - '0'; + if(i < 0 || i >= sizeof(fa)){ + printf(1, "concreate weird file %s\n", de.name); + 1640: e3a00001 mov r0, #1 + 1644: e59f1034 ldr r1, [pc, #52] ; 1680 + 1648: e24b202e sub r2, fp, #46 ; 0x2e + 164c: eb00083c bl 3744 + exit(); + 1650: eb0006e8 bl 31f8 + 1654: 00004230 .word 0x00004230 + 1658: 66666667 .word 0x66666667 + 165c: 55555556 .word 0x55555556 + 1660: 00000202 .word 0x00000202 + 1664: 00004240 .word 0x00004240 + 1668: 00004200 .word 0x00004200 + 166c: 000042d0 .word 0x000042d0 + 1670: 00005148 .word 0x00005148 + 1674: 00004244 .word 0x00004244 + 1678: 0000429c .word 0x0000429c + 167c: 0000427c .word 0x0000427c + 1680: 00004260 .word 0x00004260 + +00001684 : + +// another concurrent link/unlink/create test, +// to look for deadlocks. +void +linkunlink() +{ + 1684: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + int pid, i; + + printf(1, "linkunlink test\n"); + 1688: e3a00001 mov r0, #1 + +// another concurrent link/unlink/create test, +// to look for deadlocks. +void +linkunlink() +{ + 168c: e28db01c add fp, sp, #28 + int pid, i; + + printf(1, "linkunlink test\n"); + 1690: e59f10bc ldr r1, [pc, #188] ; 1754 + 1694: eb00082a bl 3744 + + unlink("x"); + 1698: e59f00b8 ldr r0, [pc, #184] ; 1758 + 169c: eb000757 bl 3400 + pid = fork(); + 16a0: eb0006c7 bl 31c4 + if(pid < 0){ + 16a4: e2508000 subs r8, r0, #0 + 16a8: ba000024 blt 1740 + printf(1, "fork failed\n"); + exit(); + } + + unsigned int x = (pid ? 1 : 97); + 16ac: 13a04001 movne r4, #1 + 16b0: 03a04061 moveq r4, #97 ; 0x61 + for(i = 0; i < 100; i++){ + x = x * 1103515245 + 12345; + 16b4: e59f70a0 ldr r7, [pc, #160] ; 175c + if((x % 3) == 0){ + 16b8: e59f60a0 ldr r6, [pc, #160] ; 1760 + if(pid < 0){ + printf(1, "fork failed\n"); + exit(); + } + + unsigned int x = (pid ? 1 : 97); + 16bc: e3a05064 mov r5, #100 ; 0x64 + 16c0: ea000005 b 16dc + for(i = 0; i < 100; i++){ + x = x * 1103515245 + 12345; + if((x % 3) == 0){ + close(open("x", O_RDWR | O_CREATE)); + } else if((x % 3) == 1){ + 16c4: e3530001 cmp r3, #1 + 16c8: 0a000018 beq 1730 + link("cat", "x"); + } else { + unlink("x"); + 16cc: e59f0084 ldr r0, [pc, #132] ; 1758 + 16d0: eb00074a bl 3400 + printf(1, "fork failed\n"); + exit(); + } + + unsigned int x = (pid ? 1 : 97); + for(i = 0; i < 100; i++){ + 16d4: e2555001 subs r5, r5, #1 + 16d8: 0a00000d beq 1714 + x = x * 1103515245 + 12345; + 16dc: e0040497 mul r4, r7, r4 + 16e0: e2844a03 add r4, r4, #12288 ; 0x3000 + 16e4: e2844039 add r4, r4, #57 ; 0x39 + if((x % 3) == 0){ + 16e8: e0832496 umull r2, r3, r6, r4 + 16ec: e1a030a3 lsr r3, r3, #1 + 16f0: e0833083 add r3, r3, r3, lsl #1 + 16f4: e0543003 subs r3, r4, r3 + 16f8: 1afffff1 bne 16c4 + close(open("x", O_RDWR | O_CREATE)); + 16fc: e59f1060 ldr r1, [pc, #96] ; 1764 + 1700: e59f0050 ldr r0, [pc, #80] ; 1758 + 1704: eb000723 bl 3398 + 1708: eb0006fb bl 32fc + printf(1, "fork failed\n"); + exit(); + } + + unsigned int x = (pid ? 1 : 97); + for(i = 0; i < 100; i++){ + 170c: e2555001 subs r5, r5, #1 + 1710: 1afffff1 bne 16dc + } else { + unlink("x"); + } + } + + if(pid) + 1714: e3580000 cmp r8, #0 + 1718: 0a00000c beq 1750 + wait(); + 171c: eb0006c2 bl 322c + else + exit(); + + printf(1, "linkunlink ok\n"); + 1720: e3a00001 mov r0, #1 + 1724: e59f103c ldr r1, [pc, #60] ; 1768 +} + 1728: e8bd49f8 pop {r3, r4, r5, r6, r7, r8, fp, lr} + if(pid) + wait(); + else + exit(); + + printf(1, "linkunlink ok\n"); + 172c: ea000804 b 3744 + for(i = 0; i < 100; i++){ + x = x * 1103515245 + 12345; + if((x % 3) == 0){ + close(open("x", O_RDWR | O_CREATE)); + } else if((x % 3) == 1){ + link("cat", "x"); + 1730: e59f1020 ldr r1, [pc, #32] ; 1758 + 1734: e59f0030 ldr r0, [pc, #48] ; 176c + 1738: eb00074a bl 3468 + 173c: eaffffe4 b 16d4 + printf(1, "linkunlink test\n"); + + unlink("x"); + pid = fork(); + if(pid < 0){ + printf(1, "fork failed\n"); + 1740: e3a00001 mov r0, #1 + 1744: e59f1024 ldr r1, [pc, #36] ; 1770 + 1748: eb0007fd bl 3744 + exit(); + 174c: eb0006a9 bl 31f8 + } + + if(pid) + wait(); + else + exit(); + 1750: eb0006a8 bl 31f8 + 1754: 000042e0 .word 0x000042e0 + 1758: 00004760 .word 0x00004760 + 175c: 41c64e6d .word 0x41c64e6d + 1760: aaaaaaab .word 0xaaaaaaab + 1764: 00000202 .word 0x00000202 + 1768: 000042f8 .word 0x000042f8 + 176c: 000042f4 .word 0x000042f4 + 1770: 00005148 .word 0x00005148 + +00001774 : +} + +// directory that uses indirect blocks +void +bigdir(void) +{ + 1774: e92d48f0 push {r4, r5, r6, r7, fp, lr} + 1778: e28db014 add fp, sp, #20 + 177c: e24dd010 sub sp, sp, #16 + int i, fd; + char name[10]; + + printf(1, "bigdir test\n"); + 1780: e59f1104 ldr r1, [pc, #260] ; 188c + 1784: e3a00001 mov r0, #1 + 1788: eb0007ed bl 3744 + unlink("bd"); + 178c: e59f00fc ldr r0, [pc, #252] ; 1890 + 1790: eb00071a bl 3400 + + fd = open("bd", O_CREATE); + 1794: e59f00f4 ldr r0, [pc, #244] ; 1890 + 1798: e3a01c02 mov r1, #512 ; 0x200 + 179c: eb0006fd bl 3398 + if(fd < 0){ + 17a0: e3500000 cmp r0, #0 + 17a4: ba000034 blt 187c + printf(1, "bigdir create failed\n"); + exit(); + } + close(fd); + 17a8: eb0006d3 bl 32fc + + for(i = 0; i < 500; i++){ + 17ac: e3a04000 mov r4, #0 + name[0] = 'x'; + 17b0: e3a06078 mov r6, #120 ; 0x78 + name[1] = '0' + (i / 64); + name[2] = '0' + (i % 64); + name[3] = '\0'; + 17b4: e1a05004 mov r5, r4 + } + close(fd); + + for(i = 0; i < 500; i++){ + name[0] = 'x'; + name[1] = '0' + (i / 64); + 17b8: e1a02344 asr r2, r4, #6 + name[2] = '0' + (i % 64); + 17bc: e204303f and r3, r4, #63 ; 0x3f + } + close(fd); + + for(i = 0; i < 500; i++){ + name[0] = 'x'; + name[1] = '0' + (i / 64); + 17c0: e2822030 add r2, r2, #48 ; 0x30 + name[2] = '0' + (i % 64); + 17c4: e2833030 add r3, r3, #48 ; 0x30 + name[3] = '\0'; + if(link("bd", name) != 0){ + 17c8: e59f00c0 ldr r0, [pc, #192] ; 1890 + 17cc: e24b1020 sub r1, fp, #32 + exit(); + } + close(fd); + + for(i = 0; i < 500; i++){ + name[0] = 'x'; + 17d0: e54b6020 strb r6, [fp, #-32] + name[1] = '0' + (i / 64); + 17d4: e54b201f strb r2, [fp, #-31] + name[2] = '0' + (i % 64); + 17d8: e54b301e strb r3, [fp, #-30] + name[3] = '\0'; + 17dc: e54b501d strb r5, [fp, #-29] + if(link("bd", name) != 0){ + 17e0: eb000720 bl 3468 + 17e4: e2507000 subs r7, r0, #0 + 17e8: 1a00001b bne 185c + printf(1, "bigdir create failed\n"); + exit(); + } + close(fd); + + for(i = 0; i < 500; i++){ + 17ec: e2844001 add r4, r4, #1 + 17f0: e3540f7d cmp r4, #500 ; 0x1f4 + 17f4: 1affffef bne 17b8 + printf(1, "bigdir link failed\n"); + exit(); + } + } + + unlink("bd"); + 17f8: e59f0090 ldr r0, [pc, #144] ; 1890 + 17fc: eb0006ff bl 3400 + for(i = 0; i < 500; i++){ + 1800: e1a04007 mov r4, r7 + name[0] = 'x'; + 1804: e3a06078 mov r6, #120 ; 0x78 + name[1] = '0' + (i / 64); + name[2] = '0' + (i % 64); + name[3] = '\0'; + 1808: e1a05007 mov r5, r7 + } + + unlink("bd"); + for(i = 0; i < 500; i++){ + name[0] = 'x'; + name[1] = '0' + (i / 64); + 180c: e1a02344 asr r2, r4, #6 + name[2] = '0' + (i % 64); + 1810: e204303f and r3, r4, #63 ; 0x3f + } + + unlink("bd"); + for(i = 0; i < 500; i++){ + name[0] = 'x'; + name[1] = '0' + (i / 64); + 1814: e2822030 add r2, r2, #48 ; 0x30 + name[2] = '0' + (i % 64); + 1818: e2833030 add r3, r3, #48 ; 0x30 + name[3] = '\0'; + if(unlink(name) != 0){ + 181c: e24b0020 sub r0, fp, #32 + } + } + + unlink("bd"); + for(i = 0; i < 500; i++){ + name[0] = 'x'; + 1820: e54b6020 strb r6, [fp, #-32] + name[1] = '0' + (i / 64); + 1824: e54b201f strb r2, [fp, #-31] + name[2] = '0' + (i % 64); + 1828: e54b301e strb r3, [fp, #-30] + name[3] = '\0'; + 182c: e54b501d strb r5, [fp, #-29] + if(unlink(name) != 0){ + 1830: eb0006f2 bl 3400 + 1834: e3500000 cmp r0, #0 + 1838: 1a00000b bne 186c + exit(); + } + } + + unlink("bd"); + for(i = 0; i < 500; i++){ + 183c: e2844001 add r4, r4, #1 + 1840: e3540f7d cmp r4, #500 ; 0x1f4 + 1844: 1afffff0 bne 180c + printf(1, "bigdir unlink failed"); + exit(); + } + } + + printf(1, "bigdir ok\n"); + 1848: e3a00001 mov r0, #1 + 184c: e59f1040 ldr r1, [pc, #64] ; 1894 + 1850: eb0007bb bl 3744 +} + 1854: e24bd014 sub sp, fp, #20 + 1858: e8bd88f0 pop {r4, r5, r6, r7, fp, pc} + name[0] = 'x'; + name[1] = '0' + (i / 64); + name[2] = '0' + (i % 64); + name[3] = '\0'; + if(link("bd", name) != 0){ + printf(1, "bigdir link failed\n"); + 185c: e3a00001 mov r0, #1 + 1860: e59f1030 ldr r1, [pc, #48] ; 1898 + 1864: eb0007b6 bl 3744 + exit(); + 1868: eb000662 bl 31f8 + name[0] = 'x'; + name[1] = '0' + (i / 64); + name[2] = '0' + (i % 64); + name[3] = '\0'; + if(unlink(name) != 0){ + printf(1, "bigdir unlink failed"); + 186c: e3a00001 mov r0, #1 + 1870: e59f1024 ldr r1, [pc, #36] ; 189c + 1874: eb0007b2 bl 3744 + exit(); + 1878: eb00065e bl 31f8 + printf(1, "bigdir test\n"); + unlink("bd"); + + fd = open("bd", O_CREATE); + if(fd < 0){ + printf(1, "bigdir create failed\n"); + 187c: e3a00001 mov r0, #1 + 1880: e59f1018 ldr r1, [pc, #24] ; 18a0 + 1884: eb0007ae bl 3744 + exit(); + 1888: eb00065a bl 31f8 + 188c: 00004308 .word 0x00004308 + 1890: 00004318 .word 0x00004318 + 1894: 00004360 .word 0x00004360 + 1898: 00004334 .word 0x00004334 + 189c: 00004348 .word 0x00004348 + 18a0: 0000431c .word 0x0000431c + +000018a4 : + printf(1, "bigdir ok\n"); +} + +void +subdir(void) +{ + 18a4: e92d4830 push {r4, r5, fp, lr} + int fd, cc; + + printf(1, "subdir test\n"); + 18a8: e3a00001 mov r0, #1 + printf(1, "bigdir ok\n"); +} + +void +subdir(void) +{ + 18ac: e28db00c add fp, sp, #12 + int fd, cc; + + printf(1, "subdir test\n"); + 18b0: e59f1520 ldr r1, [pc, #1312] ; 1dd8 + 18b4: eb0007a2 bl 3744 + + unlink("ff"); + 18b8: e59f051c ldr r0, [pc, #1308] ; 1ddc + 18bc: eb0006cf bl 3400 + if(mkdir("dd") != 0){ + 18c0: e59f0518 ldr r0, [pc, #1304] ; 1de0 + 18c4: eb0006f4 bl 349c + 18c8: e3500000 cmp r0, #0 + 18cc: 1a00010e bne 1d0c + printf(1, "subdir mkdir dd failed\n"); + exit(); + } + + fd = open("dd/ff", O_CREATE | O_RDWR); + 18d0: e59f050c ldr r0, [pc, #1292] ; 1de4 + 18d4: e59f150c ldr r1, [pc, #1292] ; 1de8 + 18d8: eb0006ae bl 3398 + if(fd < 0){ + 18dc: e2504000 subs r4, r0, #0 + 18e0: ba000105 blt 1cfc + printf(1, "create dd/ff failed\n"); + exit(); + } + write(fd, "ff", 2); + 18e4: e59f14f0 ldr r1, [pc, #1264] ; 1ddc + 18e8: e3a02002 mov r2, #2 + 18ec: eb000675 bl 32c8 + close(fd); + 18f0: e1a00004 mov r0, r4 + 18f4: eb000680 bl 32fc + + if(unlink("dd") >= 0){ + 18f8: e59f04e0 ldr r0, [pc, #1248] ; 1de0 + 18fc: eb0006bf bl 3400 + 1900: e3500000 cmp r0, #0 + 1904: aa0000f8 bge 1cec + printf(1, "unlink dd (non-empty dir) succeeded!\n"); + exit(); + } + + if(mkdir("/dd/dd") != 0){ + 1908: e59f04dc ldr r0, [pc, #1244] ; 1dec + 190c: eb0006e2 bl 349c + 1910: e2504000 subs r4, r0, #0 + 1914: 1a0000f0 bne 1cdc + printf(1, "subdir mkdir dd/dd failed\n"); + exit(); + } + + fd = open("dd/dd/ff", O_CREATE | O_RDWR); + 1918: e59f04d0 ldr r0, [pc, #1232] ; 1df0 + 191c: e59f14c4 ldr r1, [pc, #1220] ; 1de8 + 1920: eb00069c bl 3398 + if(fd < 0){ + 1924: e2505000 subs r5, r0, #0 + 1928: ba0000bf blt 1c2c + printf(1, "create dd/dd/ff failed\n"); + exit(); + } + write(fd, "FF", 2); + 192c: e59f14c0 ldr r1, [pc, #1216] ; 1df4 + 1930: e3a02002 mov r2, #2 + 1934: eb000663 bl 32c8 + close(fd); + 1938: e1a00005 mov r0, r5 + 193c: eb00066e bl 32fc + + fd = open("dd/dd/../ff", 0); + 1940: e59f04b0 ldr r0, [pc, #1200] ; 1df8 + 1944: e1a01004 mov r1, r4 + 1948: eb000692 bl 3398 + if(fd < 0){ + 194c: e2505000 subs r5, r0, #0 + 1950: ba0000b1 blt 1c1c + printf(1, "open dd/dd/../ff failed\n"); + exit(); + } + cc = read(fd, buf, sizeof(buf)); + 1954: e59f44a0 ldr r4, [pc, #1184] ; 1dfc + 1958: e3a02a02 mov r2, #8192 ; 0x2000 + 195c: e1a01004 mov r1, r4 + 1960: eb00064b bl 3294 + if(cc != 2 || buf[0] != 'f'){ + 1964: e3500002 cmp r0, #2 + 1968: 1a00008f bne 1bac + 196c: e5d43000 ldrb r3, [r4] + 1970: e3530066 cmp r3, #102 ; 0x66 + 1974: 1a00008c bne 1bac + printf(1, "dd/dd/../ff wrong content\n"); + exit(); + } + close(fd); + 1978: e1a00005 mov r0, r5 + 197c: eb00065e bl 32fc + + if(link("dd/dd/ff", "dd/dd/ffff") != 0){ + 1980: e59f0468 ldr r0, [pc, #1128] ; 1df0 + 1984: e59f1474 ldr r1, [pc, #1140] ; 1e00 + 1988: eb0006b6 bl 3468 + 198c: e3500000 cmp r0, #0 + 1990: 1a0000ad bne 1c4c + printf(1, "link dd/dd/ff dd/dd/ffff failed\n"); + exit(); + } + + if(unlink("dd/dd/ff") != 0){ + 1994: e59f0454 ldr r0, [pc, #1108] ; 1df0 + 1998: eb000698 bl 3400 + 199c: e3500000 cmp r0, #0 + 19a0: 1a000089 bne 1bcc + printf(1, "unlink dd/dd/ff failed\n"); + exit(); + } + if(open("dd/dd/ff", O_RDONLY) >= 0){ + 19a4: e59f0444 ldr r0, [pc, #1092] ; 1df0 + 19a8: e3a01000 mov r1, #0 + 19ac: eb000679 bl 3398 + 19b0: e3500000 cmp r0, #0 + 19b4: aa0000c4 bge 1ccc + printf(1, "open (unlinked) dd/dd/ff succeeded\n"); + exit(); + } + + if(chdir("dd") != 0){ + 19b8: e59f0420 ldr r0, [pc, #1056] ; 1de0 + 19bc: eb0006c3 bl 34d0 + 19c0: e3500000 cmp r0, #0 + 19c4: 1a0000bc bne 1cbc + printf(1, "chdir dd failed\n"); + exit(); + } + if(chdir("dd/../../dd") != 0){ + 19c8: e59f0434 ldr r0, [pc, #1076] ; 1e04 + 19cc: eb0006bf bl 34d0 + 19d0: e3500000 cmp r0, #0 + 19d4: 1a000078 bne 1bbc + printf(1, "chdir dd/../../dd failed\n"); + exit(); + } + if(chdir("dd/../../../dd") != 0){ + 19d8: e59f0428 ldr r0, [pc, #1064] ; 1e08 + 19dc: eb0006bb bl 34d0 + 19e0: e3500000 cmp r0, #0 + 19e4: 1a000074 bne 1bbc + printf(1, "chdir dd/../../dd failed\n"); + exit(); + } + if(chdir("./..") != 0){ + 19e8: e59f041c ldr r0, [pc, #1052] ; 1e0c + 19ec: eb0006b7 bl 34d0 + 19f0: e2504000 subs r4, r0, #0 + 19f4: 1a000090 bne 1c3c + printf(1, "chdir ./.. failed\n"); + exit(); + } + + fd = open("dd/dd/ffff", 0); + 19f8: e59f0400 ldr r0, [pc, #1024] ; 1e00 + 19fc: e1a01004 mov r1, r4 + 1a00: eb000664 bl 3398 + if(fd < 0){ + 1a04: e2505000 subs r5, r0, #0 + 1a08: ba0000ee blt 1dc8 + printf(1, "open dd/dd/ffff failed\n"); + exit(); + } + if(read(fd, buf, sizeof(buf)) != 2){ + 1a0c: e59f13e8 ldr r1, [pc, #1000] ; 1dfc + 1a10: e3a02a02 mov r2, #8192 ; 0x2000 + 1a14: eb00061e bl 3294 + 1a18: e3500002 cmp r0, #2 + 1a1c: 1a0000e5 bne 1db8 + printf(1, "read dd/dd/ffff wrong len\n"); + exit(); + } + close(fd); + 1a20: e1a00005 mov r0, r5 + 1a24: eb000634 bl 32fc + + if(open("dd/dd/ff", O_RDONLY) >= 0){ + 1a28: e59f03c0 ldr r0, [pc, #960] ; 1df0 + 1a2c: e1a01004 mov r1, r4 + 1a30: eb000658 bl 3398 + 1a34: e3500000 cmp r0, #0 + 1a38: aa00006b bge 1bec + printf(1, "open (unlinked) dd/dd/ff succeeded!\n"); + exit(); + } + + if(open("dd/ff/ff", O_CREATE|O_RDWR) >= 0){ + 1a3c: e59f03cc ldr r0, [pc, #972] ; 1e10 + 1a40: e59f13a0 ldr r1, [pc, #928] ; 1de8 + 1a44: eb000653 bl 3398 + 1a48: e3500000 cmp r0, #0 + 1a4c: aa000062 bge 1bdc + printf(1, "create dd/ff/ff succeeded!\n"); + exit(); + } + if(open("dd/xx/ff", O_CREATE|O_RDWR) >= 0){ + 1a50: e59f03bc ldr r0, [pc, #956] ; 1e14 + 1a54: e59f138c ldr r1, [pc, #908] ; 1de8 + 1a58: eb00064e bl 3398 + 1a5c: e3500000 cmp r0, #0 + 1a60: aa000091 bge 1cac + printf(1, "create dd/xx/ff succeeded!\n"); + exit(); + } + if(open("dd", O_CREATE) >= 0){ + 1a64: e59f0374 ldr r0, [pc, #884] ; 1de0 + 1a68: e3a01c02 mov r1, #512 ; 0x200 + 1a6c: eb000649 bl 3398 + 1a70: e3500000 cmp r0, #0 + 1a74: aa000088 bge 1c9c + printf(1, "create dd succeeded!\n"); + exit(); + } + if(open("dd", O_RDWR) >= 0){ + 1a78: e59f0360 ldr r0, [pc, #864] ; 1de0 + 1a7c: e3a01002 mov r1, #2 + 1a80: eb000644 bl 3398 + 1a84: e3500000 cmp r0, #0 + 1a88: aa00007f bge 1c8c + printf(1, "open dd rdwr succeeded!\n"); + exit(); + } + if(open("dd", O_WRONLY) >= 0){ + 1a8c: e59f034c ldr r0, [pc, #844] ; 1de0 + 1a90: e3a01001 mov r1, #1 + 1a94: eb00063f bl 3398 + 1a98: e3500000 cmp r0, #0 + 1a9c: aa000076 bge 1c7c + printf(1, "open dd wronly succeeded!\n"); + exit(); + } + if(link("dd/ff/ff", "dd/dd/xx") == 0){ + 1aa0: e59f0368 ldr r0, [pc, #872] ; 1e10 + 1aa4: e59f136c ldr r1, [pc, #876] ; 1e18 + 1aa8: eb00066e bl 3468 + 1aac: e3500000 cmp r0, #0 + 1ab0: 0a00006d beq 1c6c + printf(1, "link dd/ff/ff dd/dd/xx succeeded!\n"); + exit(); + } + if(link("dd/xx/ff", "dd/dd/xx") == 0){ + 1ab4: e59f0358 ldr r0, [pc, #856] ; 1e14 + 1ab8: e59f1358 ldr r1, [pc, #856] ; 1e18 + 1abc: eb000669 bl 3468 + 1ac0: e3500000 cmp r0, #0 + 1ac4: 0a000064 beq 1c5c + printf(1, "link dd/xx/ff dd/dd/xx succeeded!\n"); + exit(); + } + if(link("dd/ff", "dd/dd/ffff") == 0){ + 1ac8: e59f0314 ldr r0, [pc, #788] ; 1de4 + 1acc: e59f132c ldr r1, [pc, #812] ; 1e00 + 1ad0: eb000664 bl 3468 + 1ad4: e3500000 cmp r0, #0 + 1ad8: 0a00004b beq 1c0c + printf(1, "link dd/ff dd/dd/ffff succeeded!\n"); + exit(); + } + if(mkdir("dd/ff/ff") == 0){ + 1adc: e59f032c ldr r0, [pc, #812] ; 1e10 + 1ae0: eb00066d bl 349c + 1ae4: e3500000 cmp r0, #0 + 1ae8: 0a000043 beq 1bfc + printf(1, "mkdir dd/ff/ff succeeded!\n"); + exit(); + } + if(mkdir("dd/xx/ff") == 0){ + 1aec: e59f0320 ldr r0, [pc, #800] ; 1e14 + 1af0: eb000669 bl 349c + 1af4: e3500000 cmp r0, #0 + 1af8: 0a0000aa beq 1da8 + printf(1, "mkdir dd/xx/ff succeeded!\n"); + exit(); + } + if(mkdir("dd/dd/ffff") == 0){ + 1afc: e59f02fc ldr r0, [pc, #764] ; 1e00 + 1b00: eb000665 bl 349c + 1b04: e3500000 cmp r0, #0 + 1b08: 0a0000a2 beq 1d98 + printf(1, "mkdir dd/dd/ffff succeeded!\n"); + exit(); + } + if(unlink("dd/xx/ff") == 0){ + 1b0c: e59f0300 ldr r0, [pc, #768] ; 1e14 + 1b10: eb00063a bl 3400 + 1b14: e3500000 cmp r0, #0 + 1b18: 0a00009a beq 1d88 + printf(1, "unlink dd/xx/ff succeeded!\n"); + exit(); + } + if(unlink("dd/ff/ff") == 0){ + 1b1c: e59f02ec ldr r0, [pc, #748] ; 1e10 + 1b20: eb000636 bl 3400 + 1b24: e3500000 cmp r0, #0 + 1b28: 0a000092 beq 1d78 + printf(1, "unlink dd/ff/ff succeeded!\n"); + exit(); + } + if(chdir("dd/ff") == 0){ + 1b2c: e59f02b0 ldr r0, [pc, #688] ; 1de4 + 1b30: eb000666 bl 34d0 + 1b34: e3500000 cmp r0, #0 + 1b38: 0a00008a beq 1d68 + printf(1, "chdir dd/ff succeeded!\n"); + exit(); + } + if(chdir("dd/xx") == 0){ + 1b3c: e59f02d8 ldr r0, [pc, #728] ; 1e1c + 1b40: eb000662 bl 34d0 + 1b44: e3500000 cmp r0, #0 + 1b48: 0a000082 beq 1d58 + printf(1, "chdir dd/xx succeeded!\n"); + exit(); + } + + if(unlink("dd/dd/ffff") != 0){ + 1b4c: e59f02ac ldr r0, [pc, #684] ; 1e00 + 1b50: eb00062a bl 3400 + 1b54: e3500000 cmp r0, #0 + 1b58: 1a00001b bne 1bcc + printf(1, "unlink dd/dd/ff failed\n"); + exit(); + } + if(unlink("dd/ff") != 0){ + 1b5c: e59f0280 ldr r0, [pc, #640] ; 1de4 + 1b60: eb000626 bl 3400 + 1b64: e3500000 cmp r0, #0 + 1b68: 1a000076 bne 1d48 + printf(1, "unlink dd/ff failed\n"); + exit(); + } + if(unlink("dd") == 0){ + 1b6c: e59f026c ldr r0, [pc, #620] ; 1de0 + 1b70: eb000622 bl 3400 + 1b74: e3500000 cmp r0, #0 + 1b78: 0a00006e beq 1d38 + printf(1, "unlink non-empty dd succeeded!\n"); + exit(); + } + if(unlink("dd/dd") < 0){ + 1b7c: e59f029c ldr r0, [pc, #668] ; 1e20 + 1b80: eb00061e bl 3400 + 1b84: e3500000 cmp r0, #0 + 1b88: ba000066 blt 1d28 + printf(1, "unlink dd/dd failed\n"); + exit(); + } + if(unlink("dd") < 0){ + 1b8c: e59f024c ldr r0, [pc, #588] ; 1de0 + 1b90: eb00061a bl 3400 + 1b94: e3500000 cmp r0, #0 + printf(1, "unlink dd failed\n"); + 1b98: e3a00001 mov r0, #1 + } + if(unlink("dd/dd") < 0){ + printf(1, "unlink dd/dd failed\n"); + exit(); + } + if(unlink("dd") < 0){ + 1b9c: ba00005e blt 1d1c + printf(1, "unlink dd failed\n"); + exit(); + } + + printf(1, "subdir ok\n"); + 1ba0: e59f127c ldr r1, [pc, #636] ; 1e24 +} + 1ba4: e8bd4830 pop {r4, r5, fp, lr} + if(unlink("dd") < 0){ + printf(1, "unlink dd failed\n"); + exit(); + } + + printf(1, "subdir ok\n"); + 1ba8: ea0006e5 b 3744 + printf(1, "open dd/dd/../ff failed\n"); + exit(); + } + cc = read(fd, buf, sizeof(buf)); + if(cc != 2 || buf[0] != 'f'){ + printf(1, "dd/dd/../ff wrong content\n"); + 1bac: e3a00001 mov r0, #1 + 1bb0: e59f1270 ldr r1, [pc, #624] ; 1e28 + 1bb4: eb0006e2 bl 3744 + exit(); + 1bb8: eb00058e bl 31f8 + if(chdir("dd/../../dd") != 0){ + printf(1, "chdir dd/../../dd failed\n"); + exit(); + } + if(chdir("dd/../../../dd") != 0){ + printf(1, "chdir dd/../../dd failed\n"); + 1bbc: e3a00001 mov r0, #1 + 1bc0: e59f1264 ldr r1, [pc, #612] ; 1e2c + 1bc4: eb0006de bl 3744 + exit(); + 1bc8: eb00058a bl 31f8 + printf(1, "chdir dd/xx succeeded!\n"); + exit(); + } + + if(unlink("dd/dd/ffff") != 0){ + printf(1, "unlink dd/dd/ff failed\n"); + 1bcc: e3a00001 mov r0, #1 + 1bd0: e59f1258 ldr r1, [pc, #600] ; 1e30 + 1bd4: eb0006da bl 3744 + exit(); + 1bd8: eb000586 bl 31f8 + printf(1, "open (unlinked) dd/dd/ff succeeded!\n"); + exit(); + } + + if(open("dd/ff/ff", O_CREATE|O_RDWR) >= 0){ + printf(1, "create dd/ff/ff succeeded!\n"); + 1bdc: e3a00001 mov r0, #1 + 1be0: e59f124c ldr r1, [pc, #588] ; 1e34 + 1be4: eb0006d6 bl 3744 + exit(); + 1be8: eb000582 bl 31f8 + exit(); + } + close(fd); + + if(open("dd/dd/ff", O_RDONLY) >= 0){ + printf(1, "open (unlinked) dd/dd/ff succeeded!\n"); + 1bec: e3a00001 mov r0, #1 + 1bf0: e59f1240 ldr r1, [pc, #576] ; 1e38 + 1bf4: eb0006d2 bl 3744 + exit(); + 1bf8: eb00057e bl 31f8 + if(link("dd/ff", "dd/dd/ffff") == 0){ + printf(1, "link dd/ff dd/dd/ffff succeeded!\n"); + exit(); + } + if(mkdir("dd/ff/ff") == 0){ + printf(1, "mkdir dd/ff/ff succeeded!\n"); + 1bfc: e3a00001 mov r0, #1 + 1c00: e59f1234 ldr r1, [pc, #564] ; 1e3c + 1c04: eb0006ce bl 3744 + exit(); + 1c08: eb00057a bl 31f8 + if(link("dd/xx/ff", "dd/dd/xx") == 0){ + printf(1, "link dd/xx/ff dd/dd/xx succeeded!\n"); + exit(); + } + if(link("dd/ff", "dd/dd/ffff") == 0){ + printf(1, "link dd/ff dd/dd/ffff succeeded!\n"); + 1c0c: e3a00001 mov r0, #1 + 1c10: e59f1228 ldr r1, [pc, #552] ; 1e40 + 1c14: eb0006ca bl 3744 + exit(); + 1c18: eb000576 bl 31f8 + write(fd, "FF", 2); + close(fd); + + fd = open("dd/dd/../ff", 0); + if(fd < 0){ + printf(1, "open dd/dd/../ff failed\n"); + 1c1c: e3a00001 mov r0, #1 + 1c20: e59f121c ldr r1, [pc, #540] ; 1e44 + 1c24: eb0006c6 bl 3744 + exit(); + 1c28: eb000572 bl 31f8 + exit(); + } + + fd = open("dd/dd/ff", O_CREATE | O_RDWR); + if(fd < 0){ + printf(1, "create dd/dd/ff failed\n"); + 1c2c: e3a00001 mov r0, #1 + 1c30: e59f1210 ldr r1, [pc, #528] ; 1e48 + 1c34: eb0006c2 bl 3744 + exit(); + 1c38: eb00056e bl 31f8 + if(chdir("dd/../../../dd") != 0){ + printf(1, "chdir dd/../../dd failed\n"); + exit(); + } + if(chdir("./..") != 0){ + printf(1, "chdir ./.. failed\n"); + 1c3c: e3a00001 mov r0, #1 + 1c40: e59f1204 ldr r1, [pc, #516] ; 1e4c + 1c44: eb0006be bl 3744 + exit(); + 1c48: eb00056a bl 31f8 + exit(); + } + close(fd); + + if(link("dd/dd/ff", "dd/dd/ffff") != 0){ + printf(1, "link dd/dd/ff dd/dd/ffff failed\n"); + 1c4c: e3a00001 mov r0, #1 + 1c50: e59f11f8 ldr r1, [pc, #504] ; 1e50 + 1c54: eb0006ba bl 3744 + exit(); + 1c58: eb000566 bl 31f8 + if(link("dd/ff/ff", "dd/dd/xx") == 0){ + printf(1, "link dd/ff/ff dd/dd/xx succeeded!\n"); + exit(); + } + if(link("dd/xx/ff", "dd/dd/xx") == 0){ + printf(1, "link dd/xx/ff dd/dd/xx succeeded!\n"); + 1c5c: e3a00001 mov r0, #1 + 1c60: e59f11ec ldr r1, [pc, #492] ; 1e54 + 1c64: eb0006b6 bl 3744 + exit(); + 1c68: eb000562 bl 31f8 + if(open("dd", O_WRONLY) >= 0){ + printf(1, "open dd wronly succeeded!\n"); + exit(); + } + if(link("dd/ff/ff", "dd/dd/xx") == 0){ + printf(1, "link dd/ff/ff dd/dd/xx succeeded!\n"); + 1c6c: e3a00001 mov r0, #1 + 1c70: e59f11e0 ldr r1, [pc, #480] ; 1e58 + 1c74: eb0006b2 bl 3744 + exit(); + 1c78: eb00055e bl 31f8 + if(open("dd", O_RDWR) >= 0){ + printf(1, "open dd rdwr succeeded!\n"); + exit(); + } + if(open("dd", O_WRONLY) >= 0){ + printf(1, "open dd wronly succeeded!\n"); + 1c7c: e3a00001 mov r0, #1 + 1c80: e59f11d4 ldr r1, [pc, #468] ; 1e5c + 1c84: eb0006ae bl 3744 + exit(); + 1c88: eb00055a bl 31f8 + if(open("dd", O_CREATE) >= 0){ + printf(1, "create dd succeeded!\n"); + exit(); + } + if(open("dd", O_RDWR) >= 0){ + printf(1, "open dd rdwr succeeded!\n"); + 1c8c: e3a00001 mov r0, #1 + 1c90: e59f11c8 ldr r1, [pc, #456] ; 1e60 + 1c94: eb0006aa bl 3744 + exit(); + 1c98: eb000556 bl 31f8 + if(open("dd/xx/ff", O_CREATE|O_RDWR) >= 0){ + printf(1, "create dd/xx/ff succeeded!\n"); + exit(); + } + if(open("dd", O_CREATE) >= 0){ + printf(1, "create dd succeeded!\n"); + 1c9c: e3a00001 mov r0, #1 + 1ca0: e59f11bc ldr r1, [pc, #444] ; 1e64 + 1ca4: eb0006a6 bl 3744 + exit(); + 1ca8: eb000552 bl 31f8 + if(open("dd/ff/ff", O_CREATE|O_RDWR) >= 0){ + printf(1, "create dd/ff/ff succeeded!\n"); + exit(); + } + if(open("dd/xx/ff", O_CREATE|O_RDWR) >= 0){ + printf(1, "create dd/xx/ff succeeded!\n"); + 1cac: e3a00001 mov r0, #1 + 1cb0: e59f11b0 ldr r1, [pc, #432] ; 1e68 + 1cb4: eb0006a2 bl 3744 + exit(); + 1cb8: eb00054e bl 31f8 + printf(1, "open (unlinked) dd/dd/ff succeeded\n"); + exit(); + } + + if(chdir("dd") != 0){ + printf(1, "chdir dd failed\n"); + 1cbc: e3a00001 mov r0, #1 + 1cc0: e59f11a4 ldr r1, [pc, #420] ; 1e6c + 1cc4: eb00069e bl 3744 + exit(); + 1cc8: eb00054a bl 31f8 + if(unlink("dd/dd/ff") != 0){ + printf(1, "unlink dd/dd/ff failed\n"); + exit(); + } + if(open("dd/dd/ff", O_RDONLY) >= 0){ + printf(1, "open (unlinked) dd/dd/ff succeeded\n"); + 1ccc: e3a00001 mov r0, #1 + 1cd0: e59f1198 ldr r1, [pc, #408] ; 1e70 + 1cd4: eb00069a bl 3744 + exit(); + 1cd8: eb000546 bl 31f8 + printf(1, "unlink dd (non-empty dir) succeeded!\n"); + exit(); + } + + if(mkdir("/dd/dd") != 0){ + printf(1, "subdir mkdir dd/dd failed\n"); + 1cdc: e3a00001 mov r0, #1 + 1ce0: e59f118c ldr r1, [pc, #396] ; 1e74 + 1ce4: eb000696 bl 3744 + exit(); + 1ce8: eb000542 bl 31f8 + } + write(fd, "ff", 2); + close(fd); + + if(unlink("dd") >= 0){ + printf(1, "unlink dd (non-empty dir) succeeded!\n"); + 1cec: e3a00001 mov r0, #1 + 1cf0: e59f1180 ldr r1, [pc, #384] ; 1e78 + 1cf4: eb000692 bl 3744 + exit(); + 1cf8: eb00053e bl 31f8 + exit(); + } + + fd = open("dd/ff", O_CREATE | O_RDWR); + if(fd < 0){ + printf(1, "create dd/ff failed\n"); + 1cfc: e3a00001 mov r0, #1 + 1d00: e59f1174 ldr r1, [pc, #372] ; 1e7c + 1d04: eb00068e bl 3744 + exit(); + 1d08: eb00053a bl 31f8 + + printf(1, "subdir test\n"); + + unlink("ff"); + if(mkdir("dd") != 0){ + printf(1, "subdir mkdir dd failed\n"); + 1d0c: e3a00001 mov r0, #1 + 1d10: e59f1168 ldr r1, [pc, #360] ; 1e80 + 1d14: eb00068a bl 3744 + exit(); + 1d18: eb000536 bl 31f8 + if(unlink("dd/dd") < 0){ + printf(1, "unlink dd/dd failed\n"); + exit(); + } + if(unlink("dd") < 0){ + printf(1, "unlink dd failed\n"); + 1d1c: e59f1160 ldr r1, [pc, #352] ; 1e84 + 1d20: eb000687 bl 3744 + exit(); + 1d24: eb000533 bl 31f8 + if(unlink("dd") == 0){ + printf(1, "unlink non-empty dd succeeded!\n"); + exit(); + } + if(unlink("dd/dd") < 0){ + printf(1, "unlink dd/dd failed\n"); + 1d28: e3a00001 mov r0, #1 + 1d2c: e59f1154 ldr r1, [pc, #340] ; 1e88 + 1d30: eb000683 bl 3744 + exit(); + 1d34: eb00052f bl 31f8 + if(unlink("dd/ff") != 0){ + printf(1, "unlink dd/ff failed\n"); + exit(); + } + if(unlink("dd") == 0){ + printf(1, "unlink non-empty dd succeeded!\n"); + 1d38: e3a00001 mov r0, #1 + 1d3c: e59f1148 ldr r1, [pc, #328] ; 1e8c + 1d40: eb00067f bl 3744 + exit(); + 1d44: eb00052b bl 31f8 + if(unlink("dd/dd/ffff") != 0){ + printf(1, "unlink dd/dd/ff failed\n"); + exit(); + } + if(unlink("dd/ff") != 0){ + printf(1, "unlink dd/ff failed\n"); + 1d48: e3a00001 mov r0, #1 + 1d4c: e59f113c ldr r1, [pc, #316] ; 1e90 + 1d50: eb00067b bl 3744 + exit(); + 1d54: eb000527 bl 31f8 + if(chdir("dd/ff") == 0){ + printf(1, "chdir dd/ff succeeded!\n"); + exit(); + } + if(chdir("dd/xx") == 0){ + printf(1, "chdir dd/xx succeeded!\n"); + 1d58: e3a00001 mov r0, #1 + 1d5c: e59f1130 ldr r1, [pc, #304] ; 1e94 + 1d60: eb000677 bl 3744 + exit(); + 1d64: eb000523 bl 31f8 + if(unlink("dd/ff/ff") == 0){ + printf(1, "unlink dd/ff/ff succeeded!\n"); + exit(); + } + if(chdir("dd/ff") == 0){ + printf(1, "chdir dd/ff succeeded!\n"); + 1d68: e3a00001 mov r0, #1 + 1d6c: e59f1124 ldr r1, [pc, #292] ; 1e98 + 1d70: eb000673 bl 3744 + exit(); + 1d74: eb00051f bl 31f8 + if(unlink("dd/xx/ff") == 0){ + printf(1, "unlink dd/xx/ff succeeded!\n"); + exit(); + } + if(unlink("dd/ff/ff") == 0){ + printf(1, "unlink dd/ff/ff succeeded!\n"); + 1d78: e3a00001 mov r0, #1 + 1d7c: e59f1118 ldr r1, [pc, #280] ; 1e9c + 1d80: eb00066f bl 3744 + exit(); + 1d84: eb00051b bl 31f8 + if(mkdir("dd/dd/ffff") == 0){ + printf(1, "mkdir dd/dd/ffff succeeded!\n"); + exit(); + } + if(unlink("dd/xx/ff") == 0){ + printf(1, "unlink dd/xx/ff succeeded!\n"); + 1d88: e3a00001 mov r0, #1 + 1d8c: e59f110c ldr r1, [pc, #268] ; 1ea0 + 1d90: eb00066b bl 3744 + exit(); + 1d94: eb000517 bl 31f8 + if(mkdir("dd/xx/ff") == 0){ + printf(1, "mkdir dd/xx/ff succeeded!\n"); + exit(); + } + if(mkdir("dd/dd/ffff") == 0){ + printf(1, "mkdir dd/dd/ffff succeeded!\n"); + 1d98: e3a00001 mov r0, #1 + 1d9c: e59f1100 ldr r1, [pc, #256] ; 1ea4 + 1da0: eb000667 bl 3744 + exit(); + 1da4: eb000513 bl 31f8 + if(mkdir("dd/ff/ff") == 0){ + printf(1, "mkdir dd/ff/ff succeeded!\n"); + exit(); + } + if(mkdir("dd/xx/ff") == 0){ + printf(1, "mkdir dd/xx/ff succeeded!\n"); + 1da8: e3a00001 mov r0, #1 + 1dac: e59f10f4 ldr r1, [pc, #244] ; 1ea8 + 1db0: eb000663 bl 3744 + exit(); + 1db4: eb00050f bl 31f8 + if(fd < 0){ + printf(1, "open dd/dd/ffff failed\n"); + exit(); + } + if(read(fd, buf, sizeof(buf)) != 2){ + printf(1, "read dd/dd/ffff wrong len\n"); + 1db8: e3a00001 mov r0, #1 + 1dbc: e59f10e8 ldr r1, [pc, #232] ; 1eac + 1dc0: eb00065f bl 3744 + exit(); + 1dc4: eb00050b bl 31f8 + exit(); + } + + fd = open("dd/dd/ffff", 0); + if(fd < 0){ + printf(1, "open dd/dd/ffff failed\n"); + 1dc8: e3a00001 mov r0, #1 + 1dcc: e59f10dc ldr r1, [pc, #220] ; 1eb0 + 1dd0: eb00065b bl 3744 + exit(); + 1dd4: eb000507 bl 31f8 + 1dd8: 0000436c .word 0x0000436c + 1ddc: 00004474 .word 0x00004474 + 1de0: 00004520 .word 0x00004520 + 1de4: 00004394 .word 0x00004394 + 1de8: 00000202 .word 0x00000202 + 1dec: 000043dc .word 0x000043dc + 1df0: 00004400 .word 0x00004400 + 1df4: 00004424 .word 0x00004424 + 1df8: 00004428 .word 0x00004428 + 1dfc: 000079fc .word 0x000079fc + 1e00: 0000446c .word 0x0000446c + 1e04: 000044ec .word 0x000044ec + 1e08: 00004514 .word 0x00004514 + 1e0c: 00004524 .word 0x00004524 + 1e10: 0000459c .word 0x0000459c + 1e14: 000045c4 .word 0x000045c4 + 1e18: 0000463c .word 0x0000463c + 1e1c: 0000475c .word 0x0000475c + 1e20: 000047b4 .word 0x000047b4 + 1e24: 000047e8 .word 0x000047e8 + 1e28: 00004450 .word 0x00004450 + 1e2c: 000044f8 .word 0x000044f8 + 1e30: 0000449c .word 0x0000449c + 1e34: 000045a8 .word 0x000045a8 + 1e38: 00004574 .word 0x00004574 + 1e3c: 000046b4 .word 0x000046b4 + 1e40: 00004690 .word 0x00004690 + 1e44: 00004434 .word 0x00004434 + 1e48: 0000440c .word 0x0000440c + 1e4c: 0000452c .word 0x0000452c + 1e50: 00004478 .word 0x00004478 + 1e54: 0000466c .word 0x0000466c + 1e58: 00004648 .word 0x00004648 + 1e5c: 00004620 .word 0x00004620 + 1e60: 00004604 .word 0x00004604 + 1e64: 000045ec .word 0x000045ec + 1e68: 000045d0 .word 0x000045d0 + 1e6c: 000044d8 .word 0x000044d8 + 1e70: 000044b4 .word 0x000044b4 + 1e74: 000043e4 .word 0x000043e4 + 1e78: 000043b4 .word 0x000043b4 + 1e7c: 0000439c .word 0x0000439c + 1e80: 0000437c .word 0x0000437c + 1e84: 000047d4 .word 0x000047d4 + 1e88: 000047bc .word 0x000047bc + 1e8c: 00004794 .word 0x00004794 + 1e90: 0000477c .word 0x0000477c + 1e94: 00004764 .word 0x00004764 + 1e98: 00004744 .word 0x00004744 + 1e9c: 00004728 .word 0x00004728 + 1ea0: 0000470c .word 0x0000470c + 1ea4: 000046ec .word 0x000046ec + 1ea8: 000046d0 .word 0x000046d0 + 1eac: 00004558 .word 0x00004558 + 1eb0: 00004540 .word 0x00004540 + +00001eb4 : +} + +// test writes that are larger than the log. +void +bigwrite(void) +{ + 1eb4: e92d4878 push {r3, r4, r5, r6, fp, lr} + int fd, sz; + + printf(1, "bigwrite test\n"); + 1eb8: e3a00001 mov r0, #1 +} + +// test writes that are larger than the log. +void +bigwrite(void) +{ + 1ebc: e28db014 add fp, sp, #20 + int fd, sz; + + printf(1, "bigwrite test\n"); + 1ec0: e59f10ac ldr r1, [pc, #172] ; 1f74 + 1ec4: eb00061e bl 3744 + + unlink("bigwrite"); + 1ec8: e59f00a8 ldr r0, [pc, #168] ; 1f78 + 1ecc: eb00054b bl 3400 + for(sz = 499; sz < 12*512; sz += 471){ + 1ed0: e59f40a4 ldr r4, [pc, #164] ; 1f7c + 1ed4: e59f60a4 ldr r6, [pc, #164] ; 1f80 + fd = open("bigwrite", O_CREATE | O_RDWR); + 1ed8: e59f0098 ldr r0, [pc, #152] ; 1f78 + 1edc: e59f10a0 ldr r1, [pc, #160] ; 1f84 + 1ee0: eb00052c bl 3398 + if(fd < 0){ + 1ee4: e2505000 subs r5, r0, #0 + 1ee8: ba00001d blt 1f64 + printf(1, "cannot create bigwrite\n"); + exit(); + } + int i; + for(i = 0; i < 2; i++){ + int cc = write(fd, buf, sz); + 1eec: e59f1094 ldr r1, [pc, #148] ; 1f88 + 1ef0: e1a02004 mov r2, r4 + 1ef4: eb0004f3 bl 32c8 + if(cc != sz){ + 1ef8: e1500004 cmp r0, r4 + printf(1, "cannot create bigwrite\n"); + exit(); + } + int i; + for(i = 0; i < 2; i++){ + int cc = write(fd, buf, sz); + 1efc: e1a03000 mov r3, r0 + if(cc != sz){ + 1f00: 1a000012 bne 1f50 + printf(1, "cannot create bigwrite\n"); + exit(); + } + int i; + for(i = 0; i < 2; i++){ + int cc = write(fd, buf, sz); + 1f04: e1a00005 mov r0, r5 + 1f08: e59f1078 ldr r1, [pc, #120] ; 1f88 + 1f0c: e1a02004 mov r2, r4 + 1f10: eb0004ec bl 32c8 + if(cc != sz){ + 1f14: e1540000 cmp r4, r0 + 1f18: 1a00000b bne 1f4c + printf(1, "write(%d) ret %d\n", sz, cc); + exit(); + } + } + close(fd); + 1f1c: e1a00005 mov r0, r5 + int fd, sz; + + printf(1, "bigwrite test\n"); + + unlink("bigwrite"); + for(sz = 499; sz < 12*512; sz += 471){ + 1f20: e2844f75 add r4, r4, #468 ; 0x1d4 + if(cc != sz){ + printf(1, "write(%d) ret %d\n", sz, cc); + exit(); + } + } + close(fd); + 1f24: eb0004f4 bl 32fc + int fd, sz; + + printf(1, "bigwrite test\n"); + + unlink("bigwrite"); + for(sz = 499; sz < 12*512; sz += 471){ + 1f28: e2844003 add r4, r4, #3 + printf(1, "write(%d) ret %d\n", sz, cc); + exit(); + } + } + close(fd); + unlink("bigwrite"); + 1f2c: e59f0044 ldr r0, [pc, #68] ; 1f78 + 1f30: eb000532 bl 3400 + int fd, sz; + + printf(1, "bigwrite test\n"); + + unlink("bigwrite"); + for(sz = 499; sz < 12*512; sz += 471){ + 1f34: e1540006 cmp r4, r6 + 1f38: 1affffe6 bne 1ed8 + } + close(fd); + unlink("bigwrite"); + } + + printf(1, "bigwrite ok\n"); + 1f3c: e3a00001 mov r0, #1 + 1f40: e59f1044 ldr r1, [pc, #68] ; 1f8c +} + 1f44: e8bd4878 pop {r3, r4, r5, r6, fp, lr} + } + close(fd); + unlink("bigwrite"); + } + + printf(1, "bigwrite ok\n"); + 1f48: ea0005fd b 3744 + printf(1, "cannot create bigwrite\n"); + exit(); + } + int i; + for(i = 0; i < 2; i++){ + int cc = write(fd, buf, sz); + 1f4c: e1a03000 mov r3, r0 + if(cc != sz){ + printf(1, "write(%d) ret %d\n", sz, cc); + 1f50: e3a00001 mov r0, #1 + 1f54: e59f1034 ldr r1, [pc, #52] ; 1f90 + 1f58: e1a02004 mov r2, r4 + 1f5c: eb0005f8 bl 3744 + exit(); + 1f60: eb0004a4 bl 31f8 + + unlink("bigwrite"); + for(sz = 499; sz < 12*512; sz += 471){ + fd = open("bigwrite", O_CREATE | O_RDWR); + if(fd < 0){ + printf(1, "cannot create bigwrite\n"); + 1f64: e3a00001 mov r0, #1 + 1f68: e59f1024 ldr r1, [pc, #36] ; 1f94 + 1f6c: eb0005f4 bl 3744 + exit(); + 1f70: eb0004a0 bl 31f8 + 1f74: 000047f4 .word 0x000047f4 + 1f78: 00004804 .word 0x00004804 + 1f7c: 000001f3 .word 0x000001f3 + 1f80: 00001807 .word 0x00001807 + 1f84: 00000202 .word 0x00000202 + 1f88: 000079fc .word 0x000079fc + 1f8c: 0000483c .word 0x0000483c + 1f90: 00004828 .word 0x00004828 + 1f94: 00004810 .word 0x00004810 + +00001f98 : + printf(1, "bigwrite ok\n"); +} + +void +bigfile(void) +{ + 1f98: e92d48f0 push {r4, r5, r6, r7, fp, lr} + int fd, i, total, cc; + + printf(1, "bigfile test\n"); + 1f9c: e3a00001 mov r0, #1 + printf(1, "bigwrite ok\n"); +} + +void +bigfile(void) +{ + 1fa0: e28db014 add fp, sp, #20 + int fd, i, total, cc; + + printf(1, "bigfile test\n"); + 1fa4: e59f1160 ldr r1, [pc, #352] ; 210c + 1fa8: eb0005e5 bl 3744 + + unlink("bigfile"); + 1fac: e59f015c ldr r0, [pc, #348] ; 2110 + 1fb0: eb000512 bl 3400 + fd = open("bigfile", O_CREATE | O_RDWR); + 1fb4: e59f0154 ldr r0, [pc, #340] ; 2110 + 1fb8: e59f1154 ldr r1, [pc, #340] ; 2114 + 1fbc: eb0004f5 bl 3398 + if(fd < 0){ + 1fc0: e2505000 subs r5, r0, #0 + 1fc4: a3a04000 movge r4, #0 + 1fc8: ba000047 blt 20ec + printf(1, "cannot create bigfile"); + exit(); + } + for(i = 0; i < 20; i++){ + memset(buf, i, 600); + 1fcc: e1a01004 mov r1, r4 + 1fd0: e3a02f96 mov r2, #600 ; 0x258 + 1fd4: e59f013c ldr r0, [pc, #316] ; 2118 + 1fd8: eb00040b bl 300c + if(write(fd, buf, 600) != 600){ + 1fdc: e1a00005 mov r0, r5 + 1fe0: e59f1130 ldr r1, [pc, #304] ; 2118 + 1fe4: e3a02f96 mov r2, #600 ; 0x258 + 1fe8: eb0004b6 bl 32c8 + 1fec: e3500f96 cmp r0, #600 ; 0x258 + 1ff0: 1a000035 bne 20cc + fd = open("bigfile", O_CREATE | O_RDWR); + if(fd < 0){ + printf(1, "cannot create bigfile"); + exit(); + } + for(i = 0; i < 20; i++){ + 1ff4: e2844001 add r4, r4, #1 + 1ff8: e3540014 cmp r4, #20 + 1ffc: 1afffff2 bne 1fcc + if(write(fd, buf, 600) != 600){ + printf(1, "write bigfile failed\n"); + exit(); + } + } + close(fd); + 2000: e1a00005 mov r0, r5 + 2004: eb0004bc bl 32fc + + fd = open("bigfile", 0); + 2008: e59f0100 ldr r0, [pc, #256] ; 2110 + 200c: e3a01000 mov r1, #0 + 2010: eb0004e0 bl 3398 + if(fd < 0){ + 2014: e2507000 subs r7, r0, #0 + 2018: ba00002f blt 20dc + 201c: e3a05000 mov r5, #0 + printf(1, "cannot open bigfile\n"); + exit(); + } + total = 0; + for(i = 0; ; i++){ + cc = read(fd, buf, 300); + 2020: e59f60f0 ldr r6, [pc, #240] ; 2118 + } + } + close(fd); + + fd = open("bigfile", 0); + if(fd < 0){ + 2024: e1a04005 mov r4, r5 + 2028: ea000009 b 2054 + printf(1, "read bigfile failed\n"); + exit(); + } + if(cc == 0) + break; + if(cc != 300){ + 202c: e3500f4b cmp r0, #300 ; 0x12c + 2030: 1a00001d bne 20ac + printf(1, "short read bigfile\n"); + exit(); + } + if(buf[0] != i/2 || buf[299] != i/2){ + 2034: e5d63000 ldrb r3, [r6] + 2038: e15300c4 cmp r3, r4, asr #1 + 203c: 1a000016 bne 209c + 2040: e5d6212b ldrb r2, [r6, #299] ; 0x12b + 2044: e1530002 cmp r3, r2 + 2048: 1a000013 bne 209c + printf(1, "read bigfile wrong data\n"); + exit(); + } + total += cc; + 204c: e2855f4b add r5, r5, #300 ; 0x12c + if(fd < 0){ + printf(1, "cannot open bigfile\n"); + exit(); + } + total = 0; + for(i = 0; ; i++){ + 2050: e2844001 add r4, r4, #1 + cc = read(fd, buf, 300); + 2054: e1a00007 mov r0, r7 + 2058: e59f10b8 ldr r1, [pc, #184] ; 2118 + 205c: e3a02f4b mov r2, #300 ; 0x12c + 2060: eb00048b bl 3294 + if(cc < 0){ + 2064: e3500000 cmp r0, #0 + 2068: ba000013 blt 20bc + printf(1, "read bigfile failed\n"); + exit(); + } + if(cc == 0) + 206c: 1affffee bne 202c + printf(1, "read bigfile wrong data\n"); + exit(); + } + total += cc; + } + close(fd); + 2070: e1a00007 mov r0, r7 + 2074: eb0004a0 bl 32fc + if(total != 20*600){ + 2078: e59f309c ldr r3, [pc, #156] ; 211c + 207c: e1550003 cmp r5, r3 + 2080: 1a00001d bne 20fc + printf(1, "read bigfile wrong total\n"); + exit(); + } + unlink("bigfile"); + 2084: e59f0084 ldr r0, [pc, #132] ; 2110 + 2088: eb0004dc bl 3400 + + printf(1, "bigfile test ok\n"); + 208c: e3a00001 mov r0, #1 + 2090: e59f1088 ldr r1, [pc, #136] ; 2120 +} + 2094: e8bd48f0 pop {r4, r5, r6, r7, fp, lr} + printf(1, "read bigfile wrong total\n"); + exit(); + } + unlink("bigfile"); + + printf(1, "bigfile test ok\n"); + 2098: ea0005a9 b 3744 + if(cc != 300){ + printf(1, "short read bigfile\n"); + exit(); + } + if(buf[0] != i/2 || buf[299] != i/2){ + printf(1, "read bigfile wrong data\n"); + 209c: e3a00001 mov r0, #1 + 20a0: e59f107c ldr r1, [pc, #124] ; 2124 + 20a4: eb0005a6 bl 3744 + exit(); + 20a8: eb000452 bl 31f8 + exit(); + } + if(cc == 0) + break; + if(cc != 300){ + printf(1, "short read bigfile\n"); + 20ac: e3a00001 mov r0, #1 + 20b0: e59f1070 ldr r1, [pc, #112] ; 2128 + 20b4: eb0005a2 bl 3744 + exit(); + 20b8: eb00044e bl 31f8 + } + total = 0; + for(i = 0; ; i++){ + cc = read(fd, buf, 300); + if(cc < 0){ + printf(1, "read bigfile failed\n"); + 20bc: e3a00001 mov r0, #1 + 20c0: e59f1064 ldr r1, [pc, #100] ; 212c + 20c4: eb00059e bl 3744 + exit(); + 20c8: eb00044a bl 31f8 + exit(); + } + for(i = 0; i < 20; i++){ + memset(buf, i, 600); + if(write(fd, buf, 600) != 600){ + printf(1, "write bigfile failed\n"); + 20cc: e3a00001 mov r0, #1 + 20d0: e59f1058 ldr r1, [pc, #88] ; 2130 + 20d4: eb00059a bl 3744 + exit(); + 20d8: eb000446 bl 31f8 + } + close(fd); + + fd = open("bigfile", 0); + if(fd < 0){ + printf(1, "cannot open bigfile\n"); + 20dc: e3a00001 mov r0, #1 + 20e0: e59f104c ldr r1, [pc, #76] ; 2134 + 20e4: eb000596 bl 3744 + exit(); + 20e8: eb000442 bl 31f8 + printf(1, "bigfile test\n"); + + unlink("bigfile"); + fd = open("bigfile", O_CREATE | O_RDWR); + if(fd < 0){ + printf(1, "cannot create bigfile"); + 20ec: e3a00001 mov r0, #1 + 20f0: e59f1040 ldr r1, [pc, #64] ; 2138 + 20f4: eb000592 bl 3744 + exit(); + 20f8: eb00043e bl 31f8 + } + total += cc; + } + close(fd); + if(total != 20*600){ + printf(1, "read bigfile wrong total\n"); + 20fc: e3a00001 mov r0, #1 + 2100: e59f1034 ldr r1, [pc, #52] ; 213c + 2104: eb00058e bl 3744 + exit(); + 2108: eb00043a bl 31f8 + 210c: 0000484c .word 0x0000484c + 2110: 0000485c .word 0x0000485c + 2114: 00000202 .word 0x00000202 + 2118: 000079fc .word 0x000079fc + 211c: 00002ee0 .word 0x00002ee0 + 2120: 00004910 .word 0x00004910 + 2124: 000048d8 .word 0x000048d8 + 2128: 000048c4 .word 0x000048c4 + 212c: 000048ac .word 0x000048ac + 2130: 0000487c .word 0x0000487c + 2134: 00004894 .word 0x00004894 + 2138: 00004864 .word 0x00004864 + 213c: 000048f4 .word 0x000048f4 + +00002140 : + printf(1, "bigfile test ok\n"); +} + +void +fourteen(void) +{ + 2140: e92d4818 push {r3, r4, fp, lr} + int fd; + + // DIRSIZ is 14. + printf(1, "fourteen test\n"); + 2144: e3a00001 mov r0, #1 + printf(1, "bigfile test ok\n"); +} + +void +fourteen(void) +{ + 2148: e28db00c add fp, sp, #12 + int fd; + + // DIRSIZ is 14. + printf(1, "fourteen test\n"); + 214c: e59f10dc ldr r1, [pc, #220] ; 2230 + 2150: eb00057b bl 3744 + + if(mkdir("12345678901234") != 0){ + 2154: e59f00d8 ldr r0, [pc, #216] ; 2234 + 2158: eb0004cf bl 349c + 215c: e3500000 cmp r0, #0 + 2160: 1a00001b bne 21d4 + printf(1, "mkdir 12345678901234 failed\n"); + exit(); + } + if(mkdir("12345678901234/123456789012345") != 0){ + 2164: e59f00cc ldr r0, [pc, #204] ; 2238 + 2168: eb0004cb bl 349c + 216c: e2504000 subs r4, r0, #0 + 2170: 1a00002a bne 2220 + printf(1, "mkdir 12345678901234/123456789012345 failed\n"); + exit(); + } + fd = open("123456789012345/123456789012345/123456789012345", O_CREATE); + 2174: e59f00c0 ldr r0, [pc, #192] ; 223c + 2178: e3a01c02 mov r1, #512 ; 0x200 + 217c: eb000485 bl 3398 + if(fd < 0){ + 2180: e3500000 cmp r0, #0 + 2184: ba000021 blt 2210 + printf(1, "create 123456789012345/123456789012345/123456789012345 failed\n"); + exit(); + } + close(fd); + 2188: eb00045b bl 32fc + fd = open("12345678901234/12345678901234/12345678901234", 0); + 218c: e59f00ac ldr r0, [pc, #172] ; 2240 + 2190: e1a01004 mov r1, r4 + 2194: eb00047f bl 3398 + if(fd < 0){ + 2198: e3500000 cmp r0, #0 + 219c: ba000017 blt 2200 + printf(1, "open 12345678901234/12345678901234/12345678901234 failed\n"); + exit(); + } + close(fd); + 21a0: eb000455 bl 32fc + + if(mkdir("12345678901234/12345678901234") == 0){ + 21a4: e59f0098 ldr r0, [pc, #152] ; 2244 + 21a8: eb0004bb bl 349c + 21ac: e3500000 cmp r0, #0 + 21b0: 0a00000e beq 21f0 + printf(1, "mkdir 12345678901234/12345678901234 succeeded!\n"); + exit(); + } + if(mkdir("123456789012345/12345678901234") == 0){ + 21b4: e59f008c ldr r0, [pc, #140] ; 2248 + 21b8: eb0004b7 bl 349c + 21bc: e3500000 cmp r0, #0 + printf(1, "mkdir 12345678901234/123456789012345 succeeded!\n"); + 21c0: e3a00001 mov r0, #1 + + if(mkdir("12345678901234/12345678901234") == 0){ + printf(1, "mkdir 12345678901234/12345678901234 succeeded!\n"); + exit(); + } + if(mkdir("123456789012345/12345678901234") == 0){ + 21c4: 0a000006 beq 21e4 + printf(1, "mkdir 12345678901234/123456789012345 succeeded!\n"); + exit(); + } + + printf(1, "fourteen ok\n"); + 21c8: e59f107c ldr r1, [pc, #124] ; 224c +} + 21cc: e8bd4818 pop {r3, r4, fp, lr} + if(mkdir("123456789012345/12345678901234") == 0){ + printf(1, "mkdir 12345678901234/123456789012345 succeeded!\n"); + exit(); + } + + printf(1, "fourteen ok\n"); + 21d0: ea00055b b 3744 + + // DIRSIZ is 14. + printf(1, "fourteen test\n"); + + if(mkdir("12345678901234") != 0){ + printf(1, "mkdir 12345678901234 failed\n"); + 21d4: e3a00001 mov r0, #1 + 21d8: e59f1070 ldr r1, [pc, #112] ; 2250 + 21dc: eb000558 bl 3744 + exit(); + 21e0: eb000404 bl 31f8 + if(mkdir("12345678901234/12345678901234") == 0){ + printf(1, "mkdir 12345678901234/12345678901234 succeeded!\n"); + exit(); + } + if(mkdir("123456789012345/12345678901234") == 0){ + printf(1, "mkdir 12345678901234/123456789012345 succeeded!\n"); + 21e4: e59f1068 ldr r1, [pc, #104] ; 2254 + 21e8: eb000555 bl 3744 + exit(); + 21ec: eb000401 bl 31f8 + exit(); + } + close(fd); + + if(mkdir("12345678901234/12345678901234") == 0){ + printf(1, "mkdir 12345678901234/12345678901234 succeeded!\n"); + 21f0: e3a00001 mov r0, #1 + 21f4: e59f105c ldr r1, [pc, #92] ; 2258 + 21f8: eb000551 bl 3744 + exit(); + 21fc: eb0003fd bl 31f8 + exit(); + } + close(fd); + fd = open("12345678901234/12345678901234/12345678901234", 0); + if(fd < 0){ + printf(1, "open 12345678901234/12345678901234/12345678901234 failed\n"); + 2200: e3a00001 mov r0, #1 + 2204: e59f1050 ldr r1, [pc, #80] ; 225c + 2208: eb00054d bl 3744 + exit(); + 220c: eb0003f9 bl 31f8 + printf(1, "mkdir 12345678901234/123456789012345 failed\n"); + exit(); + } + fd = open("123456789012345/123456789012345/123456789012345", O_CREATE); + if(fd < 0){ + printf(1, "create 123456789012345/123456789012345/123456789012345 failed\n"); + 2210: e3a00001 mov r0, #1 + 2214: e59f1044 ldr r1, [pc, #68] ; 2260 + 2218: eb000549 bl 3744 + exit(); + 221c: eb0003f5 bl 31f8 + if(mkdir("12345678901234") != 0){ + printf(1, "mkdir 12345678901234 failed\n"); + exit(); + } + if(mkdir("12345678901234/123456789012345") != 0){ + printf(1, "mkdir 12345678901234/123456789012345 failed\n"); + 2220: e3a00001 mov r0, #1 + 2224: e59f1038 ldr r1, [pc, #56] ; 2264 + 2228: eb000545 bl 3744 + exit(); + 222c: eb0003f1 bl 31f8 + 2230: 00004924 .word 0x00004924 + 2234: 00004ae0 .word 0x00004ae0 + 2238: 00004954 .word 0x00004954 + 223c: 000049a4 .word 0x000049a4 + 2240: 00004a14 .word 0x00004a14 + 2244: 00004a80 .word 0x00004a80 + 2248: 00004ad0 .word 0x00004ad0 + 224c: 00004b24 .word 0x00004b24 + 2250: 00004934 .word 0x00004934 + 2254: 00004af0 .word 0x00004af0 + 2258: 00004aa0 .word 0x00004aa0 + 225c: 00004a44 .word 0x00004a44 + 2260: 000049d4 .word 0x000049d4 + 2264: 00004974 .word 0x00004974 + +00002268 : + printf(1, "fourteen ok\n"); +} + +void +rmdot(void) +{ + 2268: e92d4800 push {fp, lr} + printf(1, "rmdot test\n"); + 226c: e3a00001 mov r0, #1 + printf(1, "fourteen ok\n"); +} + +void +rmdot(void) +{ + 2270: e28db004 add fp, sp, #4 + printf(1, "rmdot test\n"); + 2274: e59f110c ldr r1, [pc, #268] ; 2388 + 2278: eb000531 bl 3744 + if(mkdir("dots") != 0){ + 227c: e59f0108 ldr r0, [pc, #264] ; 238c + 2280: eb000485 bl 349c + 2284: e3500000 cmp r0, #0 + 2288: 1a00001f bne 230c + printf(1, "mkdir dots failed\n"); + exit(); + } + if(chdir("dots") != 0){ + 228c: e59f00f8 ldr r0, [pc, #248] ; 238c + 2290: eb00048e bl 34d0 + 2294: e3500000 cmp r0, #0 + 2298: 1a000036 bne 2378 + printf(1, "chdir dots failed\n"); + exit(); + } + if(unlink(".") == 0){ + 229c: e59f00ec ldr r0, [pc, #236] ; 2390 + 22a0: eb000456 bl 3400 + 22a4: e3500000 cmp r0, #0 + 22a8: 0a00002e beq 2368 + printf(1, "rm . worked!\n"); + exit(); + } + if(unlink("..") == 0){ + 22ac: e59f00e0 ldr r0, [pc, #224] ; 2394 + 22b0: eb000452 bl 3400 + 22b4: e3500000 cmp r0, #0 + 22b8: 0a000026 beq 2358 + printf(1, "rm .. worked!\n"); + exit(); + } + if(chdir("/") != 0){ + 22bc: e59f00d4 ldr r0, [pc, #212] ; 2398 + 22c0: eb000482 bl 34d0 + 22c4: e3500000 cmp r0, #0 + 22c8: 1a00001e bne 2348 + printf(1, "chdir / failed\n"); + exit(); + } + if(unlink("dots/.") == 0){ + 22cc: e59f00c8 ldr r0, [pc, #200] ; 239c + 22d0: eb00044a bl 3400 + 22d4: e3500000 cmp r0, #0 + 22d8: 0a000016 beq 2338 + printf(1, "unlink dots/. worked!\n"); + exit(); + } + if(unlink("dots/..") == 0){ + 22dc: e59f00bc ldr r0, [pc, #188] ; 23a0 + 22e0: eb000446 bl 3400 + 22e4: e3500000 cmp r0, #0 + 22e8: 0a00000e beq 2328 + printf(1, "unlink dots/.. worked!\n"); + exit(); + } + if(unlink("dots") != 0){ + 22ec: e59f0098 ldr r0, [pc, #152] ; 238c + 22f0: eb000442 bl 3400 + 22f4: e3500000 cmp r0, #0 + printf(1, "unlink dots failed!\n"); + 22f8: e3a00001 mov r0, #1 + } + if(unlink("dots/..") == 0){ + printf(1, "unlink dots/.. worked!\n"); + exit(); + } + if(unlink("dots") != 0){ + 22fc: 1a000006 bne 231c + printf(1, "unlink dots failed!\n"); + exit(); + } + printf(1, "rmdot ok\n"); + 2300: e59f109c ldr r1, [pc, #156] ; 23a4 +} + 2304: e8bd4800 pop {fp, lr} + } + if(unlink("dots") != 0){ + printf(1, "unlink dots failed!\n"); + exit(); + } + printf(1, "rmdot ok\n"); + 2308: ea00050d b 3744 +void +rmdot(void) +{ + printf(1, "rmdot test\n"); + if(mkdir("dots") != 0){ + printf(1, "mkdir dots failed\n"); + 230c: e3a00001 mov r0, #1 + 2310: e59f1090 ldr r1, [pc, #144] ; 23a8 + 2314: eb00050a bl 3744 + exit(); + 2318: eb0003b6 bl 31f8 + if(unlink("dots/..") == 0){ + printf(1, "unlink dots/.. worked!\n"); + exit(); + } + if(unlink("dots") != 0){ + printf(1, "unlink dots failed!\n"); + 231c: e59f1088 ldr r1, [pc, #136] ; 23ac + 2320: eb000507 bl 3744 + exit(); + 2324: eb0003b3 bl 31f8 + if(unlink("dots/.") == 0){ + printf(1, "unlink dots/. worked!\n"); + exit(); + } + if(unlink("dots/..") == 0){ + printf(1, "unlink dots/.. worked!\n"); + 2328: e3a00001 mov r0, #1 + 232c: e59f107c ldr r1, [pc, #124] ; 23b0 + 2330: eb000503 bl 3744 + exit(); + 2334: eb0003af bl 31f8 + if(chdir("/") != 0){ + printf(1, "chdir / failed\n"); + exit(); + } + if(unlink("dots/.") == 0){ + printf(1, "unlink dots/. worked!\n"); + 2338: e3a00001 mov r0, #1 + 233c: e59f1070 ldr r1, [pc, #112] ; 23b4 + 2340: eb0004ff bl 3744 + exit(); + 2344: eb0003ab bl 31f8 + if(unlink("..") == 0){ + printf(1, "rm .. worked!\n"); + exit(); + } + if(chdir("/") != 0){ + printf(1, "chdir / failed\n"); + 2348: e3a00001 mov r0, #1 + 234c: e59f1064 ldr r1, [pc, #100] ; 23b8 + 2350: eb0004fb bl 3744 + exit(); + 2354: eb0003a7 bl 31f8 + if(unlink(".") == 0){ + printf(1, "rm . worked!\n"); + exit(); + } + if(unlink("..") == 0){ + printf(1, "rm .. worked!\n"); + 2358: e3a00001 mov r0, #1 + 235c: e59f1058 ldr r1, [pc, #88] ; 23bc + 2360: eb0004f7 bl 3744 + exit(); + 2364: eb0003a3 bl 31f8 + if(chdir("dots") != 0){ + printf(1, "chdir dots failed\n"); + exit(); + } + if(unlink(".") == 0){ + printf(1, "rm . worked!\n"); + 2368: e3a00001 mov r0, #1 + 236c: e59f104c ldr r1, [pc, #76] ; 23c0 + 2370: eb0004f3 bl 3744 + exit(); + 2374: eb00039f bl 31f8 + if(mkdir("dots") != 0){ + printf(1, "mkdir dots failed\n"); + exit(); + } + if(chdir("dots") != 0){ + printf(1, "chdir dots failed\n"); + 2378: e3a00001 mov r0, #1 + 237c: e59f1040 ldr r1, [pc, #64] ; 23c4 + 2380: eb0004ef bl 3744 + exit(); + 2384: eb00039b bl 31f8 + 2388: 00004b34 .word 0x00004b34 + 238c: 00004b40 .word 0x00004b40 + 2390: 00004200 .word 0x00004200 + 2394: 00003d44 .word 0x00003d44 + 2398: 00004b90 .word 0x00004b90 + 239c: 00004ba4 .word 0x00004ba4 + 23a0: 00004bc4 .word 0x00004bc4 + 23a4: 00004bfc .word 0x00004bfc + 23a8: 00004b48 .word 0x00004b48 + 23ac: 00004be4 .word 0x00004be4 + 23b0: 00004bcc .word 0x00004bcc + 23b4: 00004bac .word 0x00004bac + 23b8: 00004b94 .word 0x00004b94 + 23bc: 00004b80 .word 0x00004b80 + 23c0: 00004b70 .word 0x00004b70 + 23c4: 00004b5c .word 0x00004b5c + +000023c8 : + printf(1, "rmdot ok\n"); +} + +void +dirfile(void) +{ + 23c8: e92d4818 push {r3, r4, fp, lr} + int fd; + + printf(1, "dir vs file\n"); + 23cc: e3a00001 mov r0, #1 + printf(1, "rmdot ok\n"); +} + +void +dirfile(void) +{ + 23d0: e28db00c add fp, sp, #12 + int fd; + + printf(1, "dir vs file\n"); + 23d4: e59f1174 ldr r1, [pc, #372] ; 2550 + 23d8: eb0004d9 bl 3744 + + fd = open("dirfile", O_CREATE); + 23dc: e59f0170 ldr r0, [pc, #368] ; 2554 + 23e0: e3a01c02 mov r1, #512 ; 0x200 + 23e4: eb0003eb bl 3398 + if(fd < 0){ + 23e8: e3500000 cmp r0, #0 + 23ec: ba00003b blt 24e0 + printf(1, "create dirfile failed\n"); + exit(); + } + close(fd); + 23f0: eb0003c1 bl 32fc + if(chdir("dirfile") == 0){ + 23f4: e59f0158 ldr r0, [pc, #344] ; 2554 + 23f8: eb000434 bl 34d0 + 23fc: e3500000 cmp r0, #0 + 2400: 0a000032 beq 24d0 + printf(1, "chdir dirfile succeeded!\n"); + exit(); + } + fd = open("dirfile/xx", 0); + 2404: e59f014c ldr r0, [pc, #332] ; 2558 + 2408: e3a01000 mov r1, #0 + 240c: eb0003e1 bl 3398 + if(fd >= 0){ + 2410: e3500000 cmp r0, #0 + 2414: aa000029 bge 24c0 + printf(1, "create dirfile/xx succeeded!\n"); + exit(); + } + fd = open("dirfile/xx", O_CREATE); + 2418: e59f0138 ldr r0, [pc, #312] ; 2558 + 241c: e3a01c02 mov r1, #512 ; 0x200 + 2420: eb0003dc bl 3398 + if(fd >= 0){ + 2424: e3500000 cmp r0, #0 + 2428: aa000024 bge 24c0 + printf(1, "create dirfile/xx succeeded!\n"); + exit(); + } + if(mkdir("dirfile/xx") == 0){ + 242c: e59f0124 ldr r0, [pc, #292] ; 2558 + 2430: eb000419 bl 349c + 2434: e3500000 cmp r0, #0 + 2438: 0a000040 beq 2540 + printf(1, "mkdir dirfile/xx succeeded!\n"); + exit(); + } + if(unlink("dirfile/xx") == 0){ + 243c: e59f0114 ldr r0, [pc, #276] ; 2558 + 2440: eb0003ee bl 3400 + 2444: e3500000 cmp r0, #0 + 2448: 0a000038 beq 2530 + printf(1, "unlink dirfile/xx succeeded!\n"); + exit(); + } + if(link("README", "dirfile/xx") == 0){ + 244c: e59f0108 ldr r0, [pc, #264] ; 255c + 2450: e59f1100 ldr r1, [pc, #256] ; 2558 + 2454: eb000403 bl 3468 + 2458: e3500000 cmp r0, #0 + 245c: 0a00002f beq 2520 + printf(1, "link to dirfile/xx succeeded!\n"); + exit(); + } + if(unlink("dirfile") != 0){ + 2460: e59f00ec ldr r0, [pc, #236] ; 2554 + 2464: eb0003e5 bl 3400 + 2468: e2504000 subs r4, r0, #0 + 246c: 1a000027 bne 2510 + printf(1, "unlink dirfile failed!\n"); + exit(); + } + + fd = open(".", O_RDWR); + 2470: e59f00e8 ldr r0, [pc, #232] ; 2560 + 2474: e3a01002 mov r1, #2 + 2478: eb0003c6 bl 3398 + if(fd >= 0){ + 247c: e3500000 cmp r0, #0 + 2480: aa00001e bge 2500 + printf(1, "open . for writing succeeded!\n"); + exit(); + } + fd = open(".", 0); + 2484: e1a01004 mov r1, r4 + 2488: e59f00d0 ldr r0, [pc, #208] ; 2560 + 248c: eb0003c1 bl 3398 + if(write(fd, "x", 1) > 0){ + 2490: e59f10cc ldr r1, [pc, #204] ; 2564 + 2494: e3a02001 mov r2, #1 + fd = open(".", O_RDWR); + if(fd >= 0){ + printf(1, "open . for writing succeeded!\n"); + exit(); + } + fd = open(".", 0); + 2498: e1a04000 mov r4, r0 + if(write(fd, "x", 1) > 0){ + 249c: eb000389 bl 32c8 + 24a0: e3500000 cmp r0, #0 + 24a4: ca000011 bgt 24f0 + printf(1, "write . succeeded!\n"); + exit(); + } + close(fd); + 24a8: e1a00004 mov r0, r4 + 24ac: eb000392 bl 32fc + + printf(1, "dir vs file OK\n"); + 24b0: e3a00001 mov r0, #1 + 24b4: e59f10ac ldr r1, [pc, #172] ; 2568 +} + 24b8: e8bd4818 pop {r3, r4, fp, lr} + printf(1, "write . succeeded!\n"); + exit(); + } + close(fd); + + printf(1, "dir vs file OK\n"); + 24bc: ea0004a0 b 3744 + printf(1, "create dirfile/xx succeeded!\n"); + exit(); + } + fd = open("dirfile/xx", O_CREATE); + if(fd >= 0){ + printf(1, "create dirfile/xx succeeded!\n"); + 24c0: e3a00001 mov r0, #1 + 24c4: e59f10a0 ldr r1, [pc, #160] ; 256c + 24c8: eb00049d bl 3744 + exit(); + 24cc: eb000349 bl 31f8 + printf(1, "create dirfile failed\n"); + exit(); + } + close(fd); + if(chdir("dirfile") == 0){ + printf(1, "chdir dirfile succeeded!\n"); + 24d0: e3a00001 mov r0, #1 + 24d4: e59f1094 ldr r1, [pc, #148] ; 2570 + 24d8: eb000499 bl 3744 + exit(); + 24dc: eb000345 bl 31f8 + + printf(1, "dir vs file\n"); + + fd = open("dirfile", O_CREATE); + if(fd < 0){ + printf(1, "create dirfile failed\n"); + 24e0: e3a00001 mov r0, #1 + 24e4: e59f1088 ldr r1, [pc, #136] ; 2574 + 24e8: eb000495 bl 3744 + exit(); + 24ec: eb000341 bl 31f8 + printf(1, "open . for writing succeeded!\n"); + exit(); + } + fd = open(".", 0); + if(write(fd, "x", 1) > 0){ + printf(1, "write . succeeded!\n"); + 24f0: e3a00001 mov r0, #1 + 24f4: e59f107c ldr r1, [pc, #124] ; 2578 + 24f8: eb000491 bl 3744 + exit(); + 24fc: eb00033d bl 31f8 + exit(); + } + + fd = open(".", O_RDWR); + if(fd >= 0){ + printf(1, "open . for writing succeeded!\n"); + 2500: e3a00001 mov r0, #1 + 2504: e59f1070 ldr r1, [pc, #112] ; 257c + 2508: eb00048d bl 3744 + exit(); + 250c: eb000339 bl 31f8 + if(link("README", "dirfile/xx") == 0){ + printf(1, "link to dirfile/xx succeeded!\n"); + exit(); + } + if(unlink("dirfile") != 0){ + printf(1, "unlink dirfile failed!\n"); + 2510: e3a00001 mov r0, #1 + 2514: e59f1064 ldr r1, [pc, #100] ; 2580 + 2518: eb000489 bl 3744 + exit(); + 251c: eb000335 bl 31f8 + if(unlink("dirfile/xx") == 0){ + printf(1, "unlink dirfile/xx succeeded!\n"); + exit(); + } + if(link("README", "dirfile/xx") == 0){ + printf(1, "link to dirfile/xx succeeded!\n"); + 2520: e3a00001 mov r0, #1 + 2524: e59f1058 ldr r1, [pc, #88] ; 2584 + 2528: eb000485 bl 3744 + exit(); + 252c: eb000331 bl 31f8 + if(mkdir("dirfile/xx") == 0){ + printf(1, "mkdir dirfile/xx succeeded!\n"); + exit(); + } + if(unlink("dirfile/xx") == 0){ + printf(1, "unlink dirfile/xx succeeded!\n"); + 2530: e3a00001 mov r0, #1 + 2534: e59f104c ldr r1, [pc, #76] ; 2588 + 2538: eb000481 bl 3744 + exit(); + 253c: eb00032d bl 31f8 + if(fd >= 0){ + printf(1, "create dirfile/xx succeeded!\n"); + exit(); + } + if(mkdir("dirfile/xx") == 0){ + printf(1, "mkdir dirfile/xx succeeded!\n"); + 2540: e3a00001 mov r0, #1 + 2544: e59f1040 ldr r1, [pc, #64] ; 258c + 2548: eb00047d bl 3744 + exit(); + 254c: eb000329 bl 31f8 + 2550: 00004c08 .word 0x00004c08 + 2554: 00004c18 .word 0x00004c18 + 2558: 00004c54 .word 0x00004c54 + 255c: 00004cc0 .word 0x00004cc0 + 2560: 00004200 .word 0x00004200 + 2564: 00004760 .word 0x00004760 + 2568: 00004d34 .word 0x00004d34 + 256c: 00004c60 .word 0x00004c60 + 2570: 00004c38 .word 0x00004c38 + 2574: 00004c20 .word 0x00004c20 + 2578: 00004d20 .word 0x00004d20 + 257c: 00004d00 .word 0x00004d00 + 2580: 00004ce8 .word 0x00004ce8 + 2584: 00004cc8 .word 0x00004cc8 + 2588: 00004ca0 .word 0x00004ca0 + 258c: 00004c80 .word 0x00004c80 + +00002590 : +} + +// test that iput() is called at the end of _namei() +void +iref(void) +{ + 2590: e92d4818 push {r3, r4, fp, lr} + int i, fd; + + printf(1, "empty file name\n"); + 2594: e3a00001 mov r0, #1 +} + +// test that iput() is called at the end of _namei() +void +iref(void) +{ + 2598: e28db00c add fp, sp, #12 + int i, fd; + + printf(1, "empty file name\n"); + 259c: e59f10b0 ldr r1, [pc, #176] ; 2654 + 25a0: eb000467 bl 3744 + 25a4: e3a04033 mov r4, #51 ; 0x33 + + // the 50 is NINODE + for(i = 0; i < 50 + 1; i++){ + if(mkdir("irefd") != 0){ + 25a8: e59f00a8 ldr r0, [pc, #168] ; 2658 + 25ac: eb0003ba bl 349c + 25b0: e3500000 cmp r0, #0 + 25b4: 1a00001e bne 2634 + printf(1, "mkdir irefd failed\n"); + exit(); + } + if(chdir("irefd") != 0){ + 25b8: e59f0098 ldr r0, [pc, #152] ; 2658 + 25bc: eb0003c3 bl 34d0 + 25c0: e3500000 cmp r0, #0 + 25c4: 1a00001e bne 2644 + printf(1, "chdir irefd failed\n"); + exit(); + } + + mkdir(""); + 25c8: e59f008c ldr r0, [pc, #140] ; 265c + 25cc: eb0003b2 bl 349c + link("README", ""); + 25d0: e59f1084 ldr r1, [pc, #132] ; 265c + 25d4: e59f0084 ldr r0, [pc, #132] ; 2660 + 25d8: eb0003a2 bl 3468 + fd = open("", O_CREATE); + 25dc: e59f0078 ldr r0, [pc, #120] ; 265c + 25e0: e3a01c02 mov r1, #512 ; 0x200 + 25e4: eb00036b bl 3398 + if(fd >= 0) + 25e8: e3500000 cmp r0, #0 + 25ec: ba000000 blt 25f4 + close(fd); + 25f0: eb000341 bl 32fc + fd = open("xx", O_CREATE); + 25f4: e59f0068 ldr r0, [pc, #104] ; 2664 + 25f8: e3a01c02 mov r1, #512 ; 0x200 + 25fc: eb000365 bl 3398 + if(fd >= 0) + 2600: e3500000 cmp r0, #0 + 2604: ba000000 blt 260c + close(fd); + 2608: eb00033b bl 32fc + unlink("xx"); + 260c: e59f0050 ldr r0, [pc, #80] ; 2664 + 2610: eb00037a bl 3400 + int i, fd; + + printf(1, "empty file name\n"); + + // the 50 is NINODE + for(i = 0; i < 50 + 1; i++){ + 2614: e2544001 subs r4, r4, #1 + 2618: 1affffe2 bne 25a8 + if(fd >= 0) + close(fd); + unlink("xx"); + } + + chdir("/"); + 261c: e59f0044 ldr r0, [pc, #68] ; 2668 + 2620: eb0003aa bl 34d0 + printf(1, "empty file name OK\n"); + 2624: e3a00001 mov r0, #1 + 2628: e59f103c ldr r1, [pc, #60] ; 266c +} + 262c: e8bd4818 pop {r3, r4, fp, lr} + close(fd); + unlink("xx"); + } + + chdir("/"); + printf(1, "empty file name OK\n"); + 2630: ea000443 b 3744 + printf(1, "empty file name\n"); + + // the 50 is NINODE + for(i = 0; i < 50 + 1; i++){ + if(mkdir("irefd") != 0){ + printf(1, "mkdir irefd failed\n"); + 2634: e3a00001 mov r0, #1 + 2638: e59f1030 ldr r1, [pc, #48] ; 2670 + 263c: eb000440 bl 3744 + exit(); + 2640: eb0002ec bl 31f8 + } + if(chdir("irefd") != 0){ + printf(1, "chdir irefd failed\n"); + 2644: e3a00001 mov r0, #1 + 2648: e59f1024 ldr r1, [pc, #36] ; 2674 + 264c: eb00043c bl 3744 + exit(); + 2650: eb0002e8 bl 31f8 + 2654: 00004d44 .word 0x00004d44 + 2658: 00004d58 .word 0x00004d58 + 265c: 00004b20 .word 0x00004b20 + 2660: 00004cc0 .word 0x00004cc0 + 2664: 00004c5c .word 0x00004c5c + 2668: 00004b90 .word 0x00004b90 + 266c: 00004d88 .word 0x00004d88 + 2670: 00004d60 .word 0x00004d60 + 2674: 00004d74 .word 0x00004d74 + +00002678 : +// test that fork fails gracefully +// the forktest binary also does this, but it runs out of proc entries first. +// inside the bigger usertests binary, we run out of memory first. +void +forktest(void) +{ + 2678: e92d4818 push {r3, r4, fp, lr} + int n, pid; + + printf(1, "fork test\n"); + 267c: e3a00001 mov r0, #1 +// test that fork fails gracefully +// the forktest binary also does this, but it runs out of proc entries first. +// inside the bigger usertests binary, we run out of memory first. +void +forktest(void) +{ + 2680: e28db00c add fp, sp, #12 + int n, pid; + + printf(1, "fork test\n"); + 2684: e59f1088 ldr r1, [pc, #136] ; 2714 + 2688: eb00042d bl 3744 + + for(n=0; n<1000; n++){ + 268c: e3a04000 mov r4, #0 + 2690: ea000003 b 26a4 + pid = fork(); + if(pid < 0) + break; + if(pid == 0) + 2694: 0a00001a beq 2704 +{ + int n, pid; + + printf(1, "fork test\n"); + + for(n=0; n<1000; n++){ + 2698: e2844001 add r4, r4, #1 + 269c: e3540ffa cmp r4, #1000 ; 0x3e8 + 26a0: 0a000010 beq 26e8 + pid = fork(); + 26a4: eb0002c6 bl 31c4 + if(pid < 0) + 26a8: e3500000 cmp r0, #0 + 26ac: aafffff8 bge 2694 + if(n == 1000){ + printf(1, "fork claimed to work 1000 times!\n"); + exit(); + } + + for(; n > 0; n--){ + 26b0: e3540000 cmp r4, #0 + 26b4: 0a000004 beq 26cc + if(wait() < 0){ + 26b8: eb0002db bl 322c + 26bc: e3500000 cmp r0, #0 + 26c0: ba00000c blt 26f8 + if(n == 1000){ + printf(1, "fork claimed to work 1000 times!\n"); + exit(); + } + + for(; n > 0; n--){ + 26c4: e2544001 subs r4, r4, #1 + 26c8: 1afffffa bne 26b8 + printf(1, "wait stopped early\n"); + exit(); + } + } + + if(wait() != -1){ + 26cc: eb0002d6 bl 322c + 26d0: e3700001 cmn r0, #1 + printf(1, "wait got too many\n"); + 26d4: e3a00001 mov r0, #1 + printf(1, "wait stopped early\n"); + exit(); + } + } + + if(wait() != -1){ + 26d8: 1a00000a bne 2708 + printf(1, "wait got too many\n"); + exit(); + } + + printf(1, "fork test OK\n"); + 26dc: e59f1034 ldr r1, [pc, #52] ; 2718 +} + 26e0: e8bd4818 pop {r3, r4, fp, lr} + if(wait() != -1){ + printf(1, "wait got too many\n"); + exit(); + } + + printf(1, "fork test OK\n"); + 26e4: ea000416 b 3744 + if(pid == 0) + exit(); + } + + if(n == 1000){ + printf(1, "fork claimed to work 1000 times!\n"); + 26e8: e3a00001 mov r0, #1 + 26ec: e59f1028 ldr r1, [pc, #40] ; 271c + 26f0: eb000413 bl 3744 + exit(); + 26f4: eb0002bf bl 31f8 + } + + for(; n > 0; n--){ + if(wait() < 0){ + printf(1, "wait stopped early\n"); + 26f8: e3a00001 mov r0, #1 + 26fc: e59f101c ldr r1, [pc, #28] ; 2720 + 2700: eb00040f bl 3744 + exit(); + 2704: eb0002bb bl 31f8 + } + } + + if(wait() != -1){ + printf(1, "wait got too many\n"); + 2708: e59f1014 ldr r1, [pc, #20] ; 2724 + 270c: eb00040c bl 3744 + exit(); + 2710: eb0002b8 bl 31f8 + 2714: 00004d9c .word 0x00004d9c + 2718: 00004dd0 .word 0x00004dd0 + 271c: 00004de0 .word 0x00004de0 + 2720: 00004da8 .word 0x00004da8 + 2724: 00004dbc .word 0x00004dbc + +00002728 : + printf(1, "fork test OK\n"); +} + +void +sbrktest(void) +{ + 2728: e92d4df0 push {r4, r5, r6, r7, r8, sl, fp, lr} + 272c: e28db01c add fp, sp, #28 + int fds[2], pid, pids[10], ppid; + char *a, *b, *c, *lastaddr, *oldbrk, *p, scratch; + uint amt; + + printf(stdout, "sbrk test\n"); + 2730: e59f4358 ldr r4, [pc, #856] ; 2a90 + printf(1, "fork test OK\n"); +} + +void +sbrktest(void) +{ + 2734: e24dd040 sub sp, sp, #64 ; 0x40 + int fds[2], pid, pids[10], ppid; + char *a, *b, *c, *lastaddr, *oldbrk, *p, scratch; + uint amt; + + printf(stdout, "sbrk test\n"); + 2738: e59f1354 ldr r1, [pc, #852] ; 2a94 + 273c: e5940000 ldr r0, [r4] + 2740: eb0003ff bl 3744 + oldbrk = sbrk(0); + 2744: e3a00000 mov r0, #0 + 2748: eb000387 bl 356c + + // can one sbrk() less than a page? + a = sbrk(0); + int i; + for(i = 0; i < 5000; i++){ + 274c: e59f8344 ldr r8, [pc, #836] ; 2a98 + 2750: e3a07000 mov r7, #0 + b = sbrk(1); + 2754: e3a0a001 mov sl, #1 + int fds[2], pid, pids[10], ppid; + char *a, *b, *c, *lastaddr, *oldbrk, *p, scratch; + uint amt; + + printf(stdout, "sbrk test\n"); + oldbrk = sbrk(0); + 2758: e1a06000 mov r6, r0 + + // can one sbrk() less than a page? + a = sbrk(0); + 275c: e3a00000 mov r0, #0 + 2760: eb000381 bl 356c + 2764: e1a05000 mov r5, r0 + int i; + for(i = 0; i < 5000; i++){ + b = sbrk(1); + 2768: e3a00001 mov r0, #1 + 276c: eb00037e bl 356c + if(b != a){ + 2770: e1500005 cmp r0, r5 + + // can one sbrk() less than a page? + a = sbrk(0); + int i; + for(i = 0; i < 5000; i++){ + b = sbrk(1); + 2774: e1a0c000 mov ip, r0 + if(b != a){ + 2778: 1a000085 bne 2994 + oldbrk = sbrk(0); + + // can one sbrk() less than a page? + a = sbrk(0); + int i; + for(i = 0; i < 5000; i++){ + 277c: e2877001 add r7, r7, #1 + 2780: e1570008 cmp r7, r8 + b = sbrk(1); + if(b != a){ + printf(stdout, "sbrk test failed %d %x %x\n", i, a, b); + exit(); + } + *b = 1; + 2784: e4c5a001 strb sl, [r5], #1 + oldbrk = sbrk(0); + + // can one sbrk() less than a page? + a = sbrk(0); + int i; + for(i = 0; i < 5000; i++){ + 2788: 1afffff6 bne 2768 + exit(); + } + *b = 1; + a = b + 1; + } + pid = fork(); + 278c: eb00028c bl 31c4 + if(pid < 0){ + 2790: e2507000 subs r7, r0, #0 + 2794: ba0000b9 blt 2a80 + printf(stdout, "sbrk test fork failed\n"); + exit(); + } + c = sbrk(1); + 2798: e3a00001 mov r0, #1 + 279c: eb000372 bl 356c + c = sbrk(1); + 27a0: e3a00001 mov r0, #1 + 27a4: eb000370 bl 356c + if(c != a + 1){ + 27a8: e2855001 add r5, r5, #1 + 27ac: e1550000 cmp r5, r0 + 27b0: 1a0000ae bne 2a70 + printf(stdout, "sbrk test failed post-fork\n"); + exit(); + } + if(pid == 0) + 27b4: e3570000 cmp r7, #0 + 27b8: 0a0000ab beq 2a6c + exit(); + wait(); + 27bc: eb00029a bl 322c + + // can one grow address space to something big? +#define BIG (100*1024*1024) + a = sbrk(0); + 27c0: e3a00000 mov r0, #0 + 27c4: eb000368 bl 356c + 27c8: e1a05000 mov r5, r0 + amt = (BIG) - (uint)a; + p = sbrk(amt); + 27cc: e2600519 rsb r0, r0, #104857600 ; 0x6400000 + 27d0: eb000365 bl 356c + if (p != a) { + 27d4: e1550000 cmp r5, r0 + 27d8: 1a0000a0 bne 2a60 + printf(stdout, "sbrk test failed to grow big address space; enough phys mem?\n"); + exit(); + } + lastaddr = (char*) (BIG-1); + *lastaddr = 99; + 27dc: e59f32b8 ldr r3, [pc, #696] ; 2a9c + 27e0: e3a02063 mov r2, #99 ; 0x63 + + // can one de-allocate? + a = sbrk(0); + 27e4: e3a00000 mov r0, #0 + if (p != a) { + printf(stdout, "sbrk test failed to grow big address space; enough phys mem?\n"); + exit(); + } + lastaddr = (char*) (BIG-1); + *lastaddr = 99; + 27e8: e5c32000 strb r2, [r3] + + // can one de-allocate? + a = sbrk(0); + 27ec: eb00035e bl 356c + 27f0: e1a05000 mov r5, r0 + c = sbrk(-4096); + 27f4: e59f02a4 ldr r0, [pc, #676] ; 2aa0 + 27f8: eb00035b bl 356c + if(c == (char*)0xffffffff){ + 27fc: e3700001 cmn r0, #1 + 2800: 0a000092 beq 2a50 + printf(stdout, "sbrk could not deallocate\n"); + exit(); + } + c = sbrk(0); + 2804: e3a00000 mov r0, #0 + 2808: eb000357 bl 356c + if(c != a - 4096){ + 280c: e2452a01 sub r2, r5, #4096 ; 0x1000 + 2810: e1500002 cmp r0, r2 + c = sbrk(-4096); + if(c == (char*)0xffffffff){ + printf(stdout, "sbrk could not deallocate\n"); + exit(); + } + c = sbrk(0); + 2814: e1a03000 mov r3, r0 + if(c != a - 4096){ + 2818: 1a000087 bne 2a3c + printf(stdout, "sbrk deallocation produced wrong address, a %x c %x\n", a, c); + exit(); + } + + // can one re-allocate that page? + a = sbrk(0); + 281c: e3a00000 mov r0, #0 + 2820: eb000351 bl 356c + 2824: e1a07000 mov r7, r0 + c = sbrk(4096); + 2828: e3a00a01 mov r0, #4096 ; 0x1000 + 282c: eb00034e bl 356c + if(c != a || sbrk(0) != a + 4096){ + 2830: e1500007 cmp r0, r7 + exit(); + } + + // can one re-allocate that page? + a = sbrk(0); + c = sbrk(4096); + 2834: e1a05000 mov r5, r0 + if(c != a || sbrk(0) != a + 4096){ + 2838: 1a000079 bne 2a24 + 283c: e3a00000 mov r0, #0 + 2840: eb000349 bl 356c + 2844: e2853a01 add r3, r5, #4096 ; 0x1000 + 2848: e1530000 cmp r3, r0 + 284c: 1a000074 bne 2a24 + printf(stdout, "sbrk re-allocation failed, a %x c %x\n", a, c); + exit(); + } + if(*lastaddr == 99){ + 2850: e59f3244 ldr r3, [pc, #580] ; 2a9c + 2854: e5d33000 ldrb r3, [r3] + 2858: e3530063 cmp r3, #99 ; 0x63 + 285c: 0a00006c beq 2a14 + // should be zero + printf(stdout, "sbrk de-allocation didn't really deallocate\n"); + exit(); + } + + a = sbrk(0); + 2860: e3a00000 mov r0, #0 + 2864: eb000340 bl 356c + 2868: e1a05000 mov r5, r0 + c = sbrk(-(sbrk(0) - oldbrk)); + 286c: e3a00000 mov r0, #0 + 2870: eb00033d bl 356c + 2874: e0600006 rsb r0, r0, r6 + 2878: eb00033b bl 356c + if(c != a){ + 287c: e1500005 cmp r0, r5 + printf(stdout, "sbrk de-allocation didn't really deallocate\n"); + exit(); + } + + a = sbrk(0); + c = sbrk(-(sbrk(0) - oldbrk)); + 2880: e1a03000 mov r3, r0 + if(c != a){ + 2884: 1a00005d bne 2a00 + printf(stdout, "sbrk downsize failed, a %x c %x\n", a, c); + exit(); + } + + // can we read the kernel's memory? + for(a = (char*)(KERNBASE); a < (char*) (KERNBASE+2000000); a += 50000){ + 2888: e59f8214 ldr r8, [pc, #532] ; 2aa4 + exit(); + } + + a = sbrk(0); + c = sbrk(-(sbrk(0) - oldbrk)); + if(c != a){ + 288c: e3a07102 mov r7, #-2147483648 ; 0x80000000 + exit(); + } + + // can we read the kernel's memory? + for(a = (char*)(KERNBASE); a < (char*) (KERNBASE+2000000); a += 50000){ + ppid = getpid(); + 2890: eb000328 bl 3538 + 2894: e1a05000 mov r5, r0 + pid = fork(); + 2898: eb000249 bl 31c4 + if(pid < 0){ + 289c: e3500000 cmp r0, #0 + 28a0: ba000052 blt 29f0 + printf(stdout, "fork failed\n"); + exit(); + } + if(pid == 0){ + 28a4: 0a000049 beq 29d0 + printf(stdout, "sbrk downsize failed, a %x c %x\n", a, c); + exit(); + } + + // can we read the kernel's memory? + for(a = (char*)(KERNBASE); a < (char*) (KERNBASE+2000000); a += 50000){ + 28a8: e2877cc3 add r7, r7, #49920 ; 0xc300 + 28ac: e2877050 add r7, r7, #80 ; 0x50 + if(pid == 0){ + printf(stdout, "oops could read %x = %x\n", a, *a); + kill(ppid); + exit(); + } + wait(); + 28b0: eb00025d bl 322c + printf(stdout, "sbrk downsize failed, a %x c %x\n", a, c); + exit(); + } + + // can we read the kernel's memory? + for(a = (char*)(KERNBASE); a < (char*) (KERNBASE+2000000); a += 50000){ + 28b4: e1570008 cmp r7, r8 + 28b8: 1afffff4 bne 2890 + wait(); + } + + // if we run the system out of memory, does it clean up the last + // failed allocation? + if(pipe(fds) != 0){ + 28bc: e24b0028 sub r0, fp, #40 ; 0x28 + 28c0: eb000266 bl 3260 + 28c4: e3500000 cmp r0, #0 + printf(1, "pipe() failed\n"); + exit(); + 28c8: 024b5054 subeq r5, fp, #84 ; 0x54 + + printf(1, "fork test OK\n"); +} + +void +sbrktest(void) + 28cc: 024b802c subeq r8, fp, #44 ; 0x2c + 28d0: 01a07005 moveq r7, r5 + wait(); + } + + // if we run the system out of memory, does it clean up the last + // failed allocation? + if(pipe(fds) != 0){ + 28d4: 1a000039 bne 29c0 + printf(1, "pipe() failed\n"); + exit(); + } + + for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){ + if((pids[i] = fork()) == 0){ + 28d8: eb000239 bl 31c4 + 28dc: e3500000 cmp r0, #0 + 28e0: e5a70004 str r0, [r7, #4]! + 28e4: 0a000020 beq 296c + sbrk(BIG - (uint)sbrk(0)); + write(fds[1], "x", 1); + // sit around until killed + for(;;) sleep(1000); + } + if(pids[i] != -1) + 28e8: e3700001 cmn r0, #1 + 28ec: 0a000003 beq 2900 + read(fds[0], &scratch, 1); + 28f0: e51b0028 ldr r0, [fp, #-40] ; 0x28 + 28f4: e24b101d sub r1, fp, #29 + 28f8: e3a02001 mov r2, #1 + 28fc: eb000264 bl 3294 + if(pipe(fds) != 0){ + printf(1, "pipe() failed\n"); + exit(); + } + + for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){ + 2900: e1570008 cmp r7, r8 + 2904: 1afffff3 bne 28d8 + if(pids[i] != -1) + read(fds[0], &scratch, 1); + } + // if those failed allocations freed up the pages they did allocate, + // we'll be able to allocate here + c = sbrk(4096); + 2908: e3a00a01 mov r0, #4096 ; 0x1000 + 290c: eb000316 bl 356c + 2910: e1a07000 mov r7, r0 + for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){ + if(pids[i] == -1) + 2914: e5b50004 ldr r0, [r5, #4]! + 2918: e3700001 cmn r0, #1 + 291c: 0a000001 beq 2928 + continue; + kill(pids[i]); + 2920: eb000282 bl 3330 + wait(); + 2924: eb000240 bl 322c + read(fds[0], &scratch, 1); + } + // if those failed allocations freed up the pages they did allocate, + // we'll be able to allocate here + c = sbrk(4096); + for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){ + 2928: e1580005 cmp r8, r5 + 292c: 1afffff8 bne 2914 + if(pids[i] == -1) + continue; + kill(pids[i]); + wait(); + } + if(c == (char*)0xffffffff){ + 2930: e3770001 cmn r7, #1 + 2934: 0a00001d beq 29b0 + printf(stdout, "failed sbrk leaked memory\n"); + exit(); + } + + if(sbrk(0) > oldbrk) + 2938: e3a00000 mov r0, #0 + 293c: eb00030a bl 356c + 2940: e1560000 cmp r6, r0 + 2944: 2a000003 bcs 2958 + sbrk(-(sbrk(0) - oldbrk)); + 2948: e3a00000 mov r0, #0 + 294c: eb000306 bl 356c + 2950: e0600006 rsb r0, r0, r6 + 2954: eb000304 bl 356c + + printf(stdout, "sbrk test OK\n"); + 2958: e5940000 ldr r0, [r4] + 295c: e59f1144 ldr r1, [pc, #324] ; 2aa8 + 2960: eb000377 bl 3744 +} + 2964: e24bd01c sub sp, fp, #28 + 2968: e8bd8df0 pop {r4, r5, r6, r7, r8, sl, fp, pc} + } + + for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){ + if((pids[i] = fork()) == 0){ + // allocate a lot of memory + sbrk(BIG - (uint)sbrk(0)); + 296c: eb0002fe bl 356c + 2970: e2600519 rsb r0, r0, #104857600 ; 0x6400000 + 2974: eb0002fc bl 356c + write(fds[1], "x", 1); + 2978: e51b0024 ldr r0, [fp, #-36] ; 0x24 + 297c: e59f1128 ldr r1, [pc, #296] ; 2aac + 2980: e3a02001 mov r2, #1 + 2984: eb00024f bl 32c8 + // sit around until killed + for(;;) sleep(1000); + 2988: e3a00ffa mov r0, #1000 ; 0x3e8 + 298c: eb000303 bl 35a0 + 2990: eafffffc b 2988 + a = sbrk(0); + int i; + for(i = 0; i < 5000; i++){ + b = sbrk(1); + if(b != a){ + printf(stdout, "sbrk test failed %d %x %x\n", i, a, b); + 2994: e5940000 ldr r0, [r4] + 2998: e59f1110 ldr r1, [pc, #272] ; 2ab0 + 299c: e1a02007 mov r2, r7 + 29a0: e1a03005 mov r3, r5 + 29a4: e58dc000 str ip, [sp] + 29a8: eb000365 bl 3744 + exit(); + 29ac: eb000211 bl 31f8 + continue; + kill(pids[i]); + wait(); + } + if(c == (char*)0xffffffff){ + printf(stdout, "failed sbrk leaked memory\n"); + 29b0: e5940000 ldr r0, [r4] + 29b4: e59f10f8 ldr r1, [pc, #248] ; 2ab4 + 29b8: eb000361 bl 3744 + exit(); + 29bc: eb00020d bl 31f8 + } + + // if we run the system out of memory, does it clean up the last + // failed allocation? + if(pipe(fds) != 0){ + printf(1, "pipe() failed\n"); + 29c0: e3a00001 mov r0, #1 + 29c4: e59f10ec ldr r1, [pc, #236] ; 2ab8 + 29c8: eb00035d bl 3744 + exit(); + 29cc: eb000209 bl 31f8 + if(pid < 0){ + printf(stdout, "fork failed\n"); + exit(); + } + if(pid == 0){ + printf(stdout, "oops could read %x = %x\n", a, *a); + 29d0: e1a02007 mov r2, r7 + 29d4: e59f10e0 ldr r1, [pc, #224] ; 2abc + 29d8: e5d73000 ldrb r3, [r7] + 29dc: e5940000 ldr r0, [r4] + 29e0: eb000357 bl 3744 + kill(ppid); + 29e4: e1a00005 mov r0, r5 + 29e8: eb000250 bl 3330 + exit(); + 29ec: eb000201 bl 31f8 + // can we read the kernel's memory? + for(a = (char*)(KERNBASE); a < (char*) (KERNBASE+2000000); a += 50000){ + ppid = getpid(); + pid = fork(); + if(pid < 0){ + printf(stdout, "fork failed\n"); + 29f0: e5940000 ldr r0, [r4] + 29f4: e59f10c4 ldr r1, [pc, #196] ; 2ac0 + 29f8: eb000351 bl 3744 + exit(); + 29fc: eb0001fd bl 31f8 + } + + a = sbrk(0); + c = sbrk(-(sbrk(0) - oldbrk)); + if(c != a){ + printf(stdout, "sbrk downsize failed, a %x c %x\n", a, c); + 2a00: e5940000 ldr r0, [r4] + 2a04: e59f10b8 ldr r1, [pc, #184] ; 2ac4 + 2a08: e1a02005 mov r2, r5 + 2a0c: eb00034c bl 3744 + exit(); + 2a10: eb0001f8 bl 31f8 + printf(stdout, "sbrk re-allocation failed, a %x c %x\n", a, c); + exit(); + } + if(*lastaddr == 99){ + // should be zero + printf(stdout, "sbrk de-allocation didn't really deallocate\n"); + 2a14: e5940000 ldr r0, [r4] + 2a18: e59f10a8 ldr r1, [pc, #168] ; 2ac8 + 2a1c: eb000348 bl 3744 + exit(); + 2a20: eb0001f4 bl 31f8 + + // can one re-allocate that page? + a = sbrk(0); + c = sbrk(4096); + if(c != a || sbrk(0) != a + 4096){ + printf(stdout, "sbrk re-allocation failed, a %x c %x\n", a, c); + 2a24: e5940000 ldr r0, [r4] + 2a28: e59f109c ldr r1, [pc, #156] ; 2acc + 2a2c: e1a02007 mov r2, r7 + 2a30: e1a03005 mov r3, r5 + 2a34: eb000342 bl 3744 + exit(); + 2a38: eb0001ee bl 31f8 + printf(stdout, "sbrk could not deallocate\n"); + exit(); + } + c = sbrk(0); + if(c != a - 4096){ + printf(stdout, "sbrk deallocation produced wrong address, a %x c %x\n", a, c); + 2a3c: e5940000 ldr r0, [r4] + 2a40: e59f1088 ldr r1, [pc, #136] ; 2ad0 + 2a44: e1a02005 mov r2, r5 + 2a48: eb00033d bl 3744 + exit(); + 2a4c: eb0001e9 bl 31f8 + + // can one de-allocate? + a = sbrk(0); + c = sbrk(-4096); + if(c == (char*)0xffffffff){ + printf(stdout, "sbrk could not deallocate\n"); + 2a50: e5940000 ldr r0, [r4] + 2a54: e59f1078 ldr r1, [pc, #120] ; 2ad4 + 2a58: eb000339 bl 3744 + exit(); + 2a5c: eb0001e5 bl 31f8 +#define BIG (100*1024*1024) + a = sbrk(0); + amt = (BIG) - (uint)a; + p = sbrk(amt); + if (p != a) { + printf(stdout, "sbrk test failed to grow big address space; enough phys mem?\n"); + 2a60: e5940000 ldr r0, [r4] + 2a64: e59f106c ldr r1, [pc, #108] ; 2ad8 + 2a68: eb000335 bl 3744 + exit(); + 2a6c: eb0001e1 bl 31f8 + exit(); + } + c = sbrk(1); + c = sbrk(1); + if(c != a + 1){ + printf(stdout, "sbrk test failed post-fork\n"); + 2a70: e5940000 ldr r0, [r4] + 2a74: e59f1060 ldr r1, [pc, #96] ; 2adc + 2a78: eb000331 bl 3744 + exit(); + 2a7c: eb0001dd bl 31f8 + *b = 1; + a = b + 1; + } + pid = fork(); + if(pid < 0){ + printf(stdout, "sbrk test fork failed\n"); + 2a80: e5940000 ldr r0, [r4] + 2a84: e59f1054 ldr r1, [pc, #84] ; 2ae0 + 2a88: eb00032d bl 3744 + exit(); + 2a8c: eb0001d9 bl 31f8 + 2a90: 00005244 .word 0x00005244 + 2a94: 00004e04 .word 0x00004e04 + 2a98: 00001388 .word 0x00001388 + 2a9c: 063fffff .word 0x063fffff + 2aa0: fffff000 .word 0xfffff000 + 2aa4: 801e8480 .word 0x801e8480 + 2aa8: 00004fa8 .word 0x00004fa8 + 2aac: 00004760 .word 0x00004760 + 2ab0: 00004e10 .word 0x00004e10 + 2ab4: 00004f8c .word 0x00004f8c + 2ab8: 00003d90 .word 0x00003d90 + 2abc: 00004f70 .word 0x00004f70 + 2ac0: 00005148 .word 0x00005148 + 2ac4: 00004f4c .word 0x00004f4c + 2ac8: 00004f1c .word 0x00004f1c + 2acc: 00004ef4 .word 0x00004ef4 + 2ad0: 00004ebc .word 0x00004ebc + 2ad4: 00004ea0 .word 0x00004ea0 + 2ad8: 00004e60 .word 0x00004e60 + 2adc: 00004e44 .word 0x00004e44 + 2ae0: 00004e2c .word 0x00004e2c + +00002ae4 : + printf(stdout, "sbrk test OK\n"); +} + +void +validateint(int *p) +{ + 2ae4: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 2ae8: e28db000 add fp, sp, #0 + sleep(*p); + 2aec: e5900000 ldr r0, [r0] +} + 2af0: e28bd000 add sp, fp, #0 + 2af4: e8bd0800 pop {fp} +} + +void +validateint(int *p) +{ + sleep(*p); + 2af8: ea0002a8 b 35a0 + +00002afc : +} + +void +validatetest(void) +{ + 2afc: e92d4878 push {r3, r4, r5, r6, fp, lr} + 2b00: e28db014 add fp, sp, #20 + int hi, pid; + uint p; + + printf(stdout, "validate test\n"); + 2b04: e59f5080 ldr r5, [pc, #128] ; 2b8c + 2b08: e59f1080 ldr r1, [pc, #128] ; 2b90 + hi = 1100*1024; + + for(p = 0; p <= (uint)hi; p += 4096){ + 2b0c: e3a04000 mov r4, #0 +validatetest(void) +{ + int hi, pid; + uint p; + + printf(stdout, "validate test\n"); + 2b10: e5950000 ldr r0, [r5] + 2b14: eb00030a bl 3744 + hi = 1100*1024; + + for(p = 0; p <= (uint)hi; p += 4096){ + if((pid = fork()) == 0){ + 2b18: eb0001a9 bl 31c4 + 2b1c: e2506000 subs r6, r0, #0 + 2b20: 0a000012 beq 2b70 + // try to crash the kernel by passing in a badly placed integer + validateint((int*)p); + exit(); + } + sleep(0); + 2b24: e3a00000 mov r0, #0 + 2b28: eb00029c bl 35a0 + sleep(0); + 2b2c: e3a00000 mov r0, #0 + 2b30: eb00029a bl 35a0 + kill(pid); + 2b34: e1a00006 mov r0, r6 + 2b38: eb0001fc bl 3330 + wait(); + 2b3c: eb0001ba bl 322c + + // try to crash the kernel by passing in a bad string pointer + if(link("nosuchfile", (char*)p) != -1){ + 2b40: e59f004c ldr r0, [pc, #76] ; 2b94 + 2b44: e1a01004 mov r1, r4 + 2b48: eb000246 bl 3468 + 2b4c: e3700001 cmn r0, #1 + 2b50: 1a000009 bne 2b7c + uint p; + + printf(stdout, "validate test\n"); + hi = 1100*1024; + + for(p = 0; p <= (uint)hi; p += 4096){ + 2b54: e2844a01 add r4, r4, #4096 ; 0x1000 + 2b58: e3540945 cmp r4, #1130496 ; 0x114000 + 2b5c: 1affffed bne 2b18 + printf(stdout, "link should not succeed\n"); + exit(); + } + } + + printf(stdout, "validate ok\n"); + 2b60: e5950000 ldr r0, [r5] + 2b64: e59f102c ldr r1, [pc, #44] ; 2b98 +} + 2b68: e8bd4878 pop {r3, r4, r5, r6, fp, lr} + printf(stdout, "link should not succeed\n"); + exit(); + } + } + + printf(stdout, "validate ok\n"); + 2b6c: ea0002f4 b 3744 + hi = 1100*1024; + + for(p = 0; p <= (uint)hi; p += 4096){ + if((pid = fork()) == 0){ + // try to crash the kernel by passing in a badly placed integer + validateint((int*)p); + 2b70: e1a00004 mov r0, r4 + 2b74: ebffffda bl 2ae4 + exit(); + 2b78: eb00019e bl 31f8 + kill(pid); + wait(); + + // try to crash the kernel by passing in a bad string pointer + if(link("nosuchfile", (char*)p) != -1){ + printf(stdout, "link should not succeed\n"); + 2b7c: e5950000 ldr r0, [r5] + 2b80: e59f1014 ldr r1, [pc, #20] ; 2b9c + 2b84: eb0002ee bl 3744 + exit(); + 2b88: eb00019a bl 31f8 + 2b8c: 00005244 .word 0x00005244 + 2b90: 00004fb8 .word 0x00004fb8 + 2b94: 00004fc8 .word 0x00004fc8 + 2b98: 00004ff0 .word 0x00004ff0 + 2b9c: 00004fd4 .word 0x00004fd4 + +00002ba0 : + +// does unintialized data start out zero? +char uninit[10000]; +void +bsstest(void) +{ + 2ba0: e92d4818 push {r3, r4, fp, lr} + 2ba4: e28db00c add fp, sp, #12 + int i; + + printf(stdout, "bss test\n"); + 2ba8: e59f4050 ldr r4, [pc, #80] ; 2c00 + 2bac: e59f1050 ldr r1, [pc, #80] ; 2c04 + 2bb0: e5940000 ldr r0, [r4] + 2bb4: eb0002e2 bl 3744 + for(i = 0; i < sizeof(uninit); i++){ + if(uninit[i] != '\0'){ + 2bb8: e59f3048 ldr r3, [pc, #72] ; 2c08 + 2bbc: e5d32000 ldrb r2, [r3] + 2bc0: e3520000 cmp r2, #0 + 2bc4: 1a000009 bne 2bf0 +} + +// does unintialized data start out zero? +char uninit[10000]; +void +bsstest(void) + 2bc8: e59f103c ldr r1, [pc, #60] ; 2c0c +{ + int i; + + printf(stdout, "bss test\n"); + for(i = 0; i < sizeof(uninit); i++){ + if(uninit[i] != '\0'){ + 2bcc: e5f32001 ldrb r2, [r3, #1]! + 2bd0: e3520000 cmp r2, #0 + 2bd4: 1a000005 bne 2bf0 +bsstest(void) +{ + int i; + + printf(stdout, "bss test\n"); + for(i = 0; i < sizeof(uninit); i++){ + 2bd8: e1530001 cmp r3, r1 + 2bdc: 1afffffa bne 2bcc + if(uninit[i] != '\0'){ + printf(stdout, "bss test failed\n"); + exit(); + } + } + printf(stdout, "bss test ok\n"); + 2be0: e5940000 ldr r0, [r4] + 2be4: e59f1024 ldr r1, [pc, #36] ; 2c10 +} + 2be8: e8bd4818 pop {r3, r4, fp, lr} + if(uninit[i] != '\0'){ + printf(stdout, "bss test failed\n"); + exit(); + } + } + printf(stdout, "bss test ok\n"); + 2bec: ea0002d4 b 3744 + int i; + + printf(stdout, "bss test\n"); + for(i = 0; i < sizeof(uninit); i++){ + if(uninit[i] != '\0'){ + printf(stdout, "bss test failed\n"); + 2bf0: e5940000 ldr r0, [r4] + 2bf4: e59f1018 ldr r1, [pc, #24] ; 2c14 + 2bf8: eb0002d1 bl 3744 + exit(); + 2bfc: eb00017d bl 31f8 + 2c00: 00005244 .word 0x00005244 + 2c04: 00005000 .word 0x00005000 + 2c08: 000052ec .word 0x000052ec + 2c0c: 000079fb .word 0x000079fb + 2c10: 00005020 .word 0x00005020 + 2c14: 0000500c .word 0x0000500c + +00002c18 : +// does exec return an error if the arguments +// are larger than a page? or does it write +// below the stack and wreck the instructions/data? +void +bigargtest(void) +{ + 2c18: e92d4830 push {r4, r5, fp, lr} + 2c1c: e28db00c add fp, sp, #12 + int pid, fd; + + unlink("bigarg-ok"); + 2c20: e59f00c0 ldr r0, [pc, #192] ; 2ce8 + 2c24: eb0001f5 bl 3400 + pid = fork(); + 2c28: eb000165 bl 31c4 + if(pid == 0){ + 2c2c: e3500000 cmp r0, #0 + 2c30: 0a00000a beq 2c60 + exec("echo", args); + printf(stdout, "bigarg test ok\n"); + fd = open("bigarg-ok", O_CREATE); + close(fd); + exit(); + } else if(pid < 0){ + 2c34: ba000026 blt 2cd4 + printf(stdout, "bigargtest: fork failed\n"); + exit(); + } + wait(); + 2c38: eb00017b bl 322c + fd = open("bigarg-ok", 0); + 2c3c: e59f00a4 ldr r0, [pc, #164] ; 2ce8 + 2c40: e3a01000 mov r1, #0 + 2c44: eb0001d3 bl 3398 + if(fd < 0){ + 2c48: e3500000 cmp r0, #0 + 2c4c: ba00001b blt 2cc0 + printf(stdout, "bigarg test failed!\n"); + exit(); + } + close(fd); + 2c50: eb0001a9 bl 32fc + unlink("bigarg-ok"); + 2c54: e59f008c ldr r0, [pc, #140] ; 2ce8 +} + 2c58: e8bd4830 pop {r4, r5, fp, lr} + if(fd < 0){ + printf(stdout, "bigarg test failed!\n"); + exit(); + } + close(fd); + unlink("bigarg-ok"); + 2c5c: ea0001e7 b 3400 +{ + int pid, fd; + + unlink("bigarg-ok"); + pid = fork(); + if(pid == 0){ + 2c60: e59f3084 ldr r3, [pc, #132] ; 2cec + 2c64: e59f1084 ldr r1, [pc, #132] ; 2cf0 + +// does exec return an error if the arguments +// are larger than a page? or does it write +// below the stack and wreck the instructions/data? +void +bigargtest(void) + 2c68: e283207c add r2, r3, #124 ; 0x7c + pid = fork(); + if(pid == 0){ + static char *args[MAXARG]; + int i; + for(i = 0; i < MAXARG-1; i++) + args[i] = "bigargs test: failed\n "; + 2c6c: e5a31004 str r1, [r3, #4]! + unlink("bigarg-ok"); + pid = fork(); + if(pid == 0){ + static char *args[MAXARG]; + int i; + for(i = 0; i < MAXARG-1; i++) + 2c70: e1530002 cmp r3, r2 + 2c74: 1afffffc bne 2c6c + args[i] = "bigargs test: failed\n "; + args[MAXARG-1] = 0; + printf(stdout, "bigarg test\n"); + 2c78: e59f4074 ldr r4, [pc, #116] ; 2cf4 + if(pid == 0){ + static char *args[MAXARG]; + int i; + for(i = 0; i < MAXARG-1; i++) + args[i] = "bigargs test: failed\n "; + args[MAXARG-1] = 0; + 2c7c: e59f5074 ldr r5, [pc, #116] ; 2cf8 + 2c80: e3a03000 mov r3, #0 + printf(stdout, "bigarg test\n"); + 2c84: e59f1070 ldr r1, [pc, #112] ; 2cfc + 2c88: e5940000 ldr r0, [r4] + if(pid == 0){ + static char *args[MAXARG]; + int i; + for(i = 0; i < MAXARG-1; i++) + args[i] = "bigargs test: failed\n "; + args[MAXARG-1] = 0; + 2c8c: e585307c str r3, [r5, #124] ; 0x7c + printf(stdout, "bigarg test\n"); + 2c90: eb0002ab bl 3744 + exec("echo", args); + 2c94: e1a01005 mov r1, r5 + 2c98: e59f0060 ldr r0, [pc, #96] ; 2d00 + 2c9c: eb0001b0 bl 3364 + printf(stdout, "bigarg test ok\n"); + 2ca0: e5940000 ldr r0, [r4] + 2ca4: e59f1058 ldr r1, [pc, #88] ; 2d04 + 2ca8: eb0002a5 bl 3744 + fd = open("bigarg-ok", O_CREATE); + 2cac: e3a01c02 mov r1, #512 ; 0x200 + 2cb0: e59f0030 ldr r0, [pc, #48] ; 2ce8 + 2cb4: eb0001b7 bl 3398 + close(fd); + 2cb8: eb00018f bl 32fc + exit(); + 2cbc: eb00014d bl 31f8 + exit(); + } + wait(); + fd = open("bigarg-ok", 0); + if(fd < 0){ + printf(stdout, "bigarg test failed!\n"); + 2cc0: e59f302c ldr r3, [pc, #44] ; 2cf4 + 2cc4: e59f103c ldr r1, [pc, #60] ; 2d08 + 2cc8: e5930000 ldr r0, [r3] + 2ccc: eb00029c bl 3744 + exit(); + 2cd0: eb000148 bl 31f8 + printf(stdout, "bigarg test ok\n"); + fd = open("bigarg-ok", O_CREATE); + close(fd); + exit(); + } else if(pid < 0){ + printf(stdout, "bigargtest: fork failed\n"); + 2cd4: e59f3018 ldr r3, [pc, #24] ; 2cf4 + 2cd8: e59f102c ldr r1, [pc, #44] ; 2d0c + 2cdc: e5930000 ldr r0, [r3] + 2ce0: eb000297 bl 3744 + exit(); + 2ce4: eb000143 bl 31f8 + 2ce8: 00005030 .word 0x00005030 + 2cec: 0000525c .word 0x0000525c + 2cf0: 0000503c .word 0x0000503c + 2cf4: 00005244 .word 0x00005244 + 2cf8: 00005260 .word 0x00005260 + 2cfc: 0000511c .word 0x0000511c + 2d00: 00003a38 .word 0x00003a38 + 2d04: 0000512c .word 0x0000512c + 2d08: 00005158 .word 0x00005158 + 2d0c: 0000513c .word 0x0000513c + +00002d10 : + +// what happens when the file system runs out of blocks? +// answer: balloc panics, so this test is not useful. +void +fsfull() +{ + 2d10: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 2d14: e28db020 add fp, sp, #32 + 2d18: e24dd044 sub sp, sp, #68 ; 0x44 + int nfiles; + int fsblocks = 0; + + printf(1, "fsfull test\n"); + 2d1c: e3a00001 mov r0, #1 + 2d20: e59f11cc ldr r1, [pc, #460] ; 2ef4 + 2d24: eb000286 bl 3744 + + for(nfiles = 0; ; nfiles++){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + 2d28: e59f91c8 ldr r9, [pc, #456] ; 2ef8 + break; + } + int total = 0; + while(1){ + int cc = write(fd, buf, 512); + if(cc < 512) + 2d2c: e59f51c8 ldr r5, [pc, #456] ; 2efc + int nfiles; + int fsblocks = 0; + + printf(1, "fsfull test\n"); + + for(nfiles = 0; ; nfiles++){ + 2d30: e3a04000 mov r4, #0 + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + 2d34: e59f81c4 ldr r8, [pc, #452] ; 2f00 + printf(1, "fsfull test\n"); + + for(nfiles = 0; ; nfiles++){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + 2d38: e0cc1499 smull r1, ip, r9, r4 + name[2] = '0' + (nfiles % 1000) / 100; + name[3] = '0' + (nfiles % 100) / 10; + 2d3c: e0c23498 smull r3, r2, r8, r4 + 2d40: e59fa1bc ldr sl, [pc, #444] ; 2f04 + printf(1, "fsfull test\n"); + + for(nfiles = 0; ; nfiles++){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + 2d44: e1a06fc4 asr r6, r4, #31 + 2d48: e066c34c rsb ip, r6, ip, asr #6 + name[2] = '0' + (nfiles % 1000) / 100; + name[3] = '0' + (nfiles % 100) / 10; + 2d4c: e3a03064 mov r3, #100 ; 0x64 + 2d50: e06622c2 rsb r2, r6, r2, asr #5 + + for(nfiles = 0; ; nfiles++){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + 2d54: e3a00ffa mov r0, #1000 ; 0x3e8 + name[3] = '0' + (nfiles % 100) / 10; + 2d58: e0020293 mul r2, r3, r2 + + for(nfiles = 0; ; nfiles++){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + 2d5c: e0000c90 mul r0, r0, ip + name[3] = '0' + (nfiles % 100) / 10; + name[4] = '0' + (nfiles % 10); + 2d60: e0c3e49a smull lr, r3, sl, r4 + name[5] = '\0'; + printf(1, "writing %s\n", name); + 2d64: e59f119c ldr r1, [pc, #412] ; 2f08 + + for(nfiles = 0; ; nfiles++){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + 2d68: e0600004 rsb r0, r0, r4 + name[3] = '0' + (nfiles % 100) / 10; + 2d6c: e0622004 rsb r2, r2, r4 + + for(nfiles = 0; ; nfiles++){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + 2d70: e0c8e098 smull lr, r8, r8, r0 + name[3] = '0' + (nfiles % 100) / 10; + 2d74: e0cae29a smull lr, sl, sl, r2 + name[4] = '0' + (nfiles % 10); + 2d78: e0663143 rsb r3, r6, r3, asr #2 + + for(nfiles = 0; ; nfiles++){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + 2d7c: e1a00fc0 asr r0, r0, #31 + name[3] = '0' + (nfiles % 100) / 10; + 2d80: e1a02fc2 asr r2, r2, #31 + name[4] = '0' + (nfiles % 10); + 2d84: e0833103 add r3, r3, r3, lsl #2 + + for(nfiles = 0; ; nfiles++){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + 2d88: e06082c8 rsb r8, r0, r8, asr #5 + name[3] = '0' + (nfiles % 100) / 10; + 2d8c: e062a14a rsb sl, r2, sl, asr #2 + name[4] = '0' + (nfiles % 10); + 2d90: e0443083 sub r3, r4, r3, lsl #1 + printf(1, "fsfull test\n"); + + for(nfiles = 0; ; nfiles++){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + 2d94: e28cc030 add ip, ip, #48 ; 0x30 + name[2] = '0' + (nfiles % 1000) / 100; + name[3] = '0' + (nfiles % 100) / 10; + name[4] = '0' + (nfiles % 10); + 2d98: e2833030 add r3, r3, #48 ; 0x30 + + printf(1, "fsfull test\n"); + + for(nfiles = 0; ; nfiles++){ + char name[64]; + name[0] = 'f'; + 2d9c: e3a0e066 mov lr, #102 ; 0x66 + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + 2da0: e2888030 add r8, r8, #48 ; 0x30 + name[3] = '0' + (nfiles % 100) / 10; + name[4] = '0' + (nfiles % 10); + name[5] = '\0'; + printf(1, "writing %s\n", name); + 2da4: e24b2064 sub r2, fp, #100 ; 0x64 + 2da8: e3a00001 mov r0, #1 + for(nfiles = 0; ; nfiles++){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + name[3] = '0' + (nfiles % 100) / 10; + 2dac: e28aa030 add sl, sl, #48 ; 0x30 + name[4] = '0' + (nfiles % 10); + name[5] = '\0'; + 2db0: e3a07000 mov r7, #0 + + printf(1, "fsfull test\n"); + + for(nfiles = 0; ; nfiles++){ + char name[64]; + name[0] = 'f'; + 2db4: e54be064 strb lr, [fp, #-100] ; 0x64 + name[1] = '0' + nfiles / 1000; + 2db8: e54bc063 strb ip, [fp, #-99] ; 0x63 + name[2] = '0' + (nfiles % 1000) / 100; + 2dbc: e54b8062 strb r8, [fp, #-98] ; 0x62 + name[3] = '0' + (nfiles % 100) / 10; + name[4] = '0' + (nfiles % 10); + 2dc0: e54b3060 strb r3, [fp, #-96] ; 0x60 + for(nfiles = 0; ; nfiles++){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + name[3] = '0' + (nfiles % 100) / 10; + 2dc4: e54ba061 strb sl, [fp, #-97] ; 0x61 + name[4] = '0' + (nfiles % 10); + name[5] = '\0'; + 2dc8: e54b705f strb r7, [fp, #-95] ; 0x5f + printf(1, "writing %s\n", name); + 2dcc: eb00025c bl 3744 + int fd = open(name, O_CREATE|O_RDWR); + 2dd0: e24b0064 sub r0, fp, #100 ; 0x64 + 2dd4: e59f1130 ldr r1, [pc, #304] ; 2f0c + 2dd8: eb00016e bl 3398 + if(fd < 0){ + 2ddc: e2508000 subs r8, r0, #0 + 2de0: aa000001 bge 2dec + 2de4: ea000010 b 2e2c + int total = 0; + while(1){ + int cc = write(fd, buf, 512); + if(cc < 512) + break; + total += cc; + 2de8: e0877000 add r7, r7, r0 + printf(1, "open %s failed\n", name); + break; + } + int total = 0; + while(1){ + int cc = write(fd, buf, 512); + 2dec: e1a00008 mov r0, r8 + 2df0: e59f1118 ldr r1, [pc, #280] ; 2f10 + 2df4: e3a02c02 mov r2, #512 ; 0x200 + 2df8: eb000132 bl 32c8 + if(cc < 512) + 2dfc: e1500005 cmp r0, r5 + 2e00: cafffff8 bgt 2de8 + break; + total += cc; + fsblocks++; + } + printf(1, "wrote %d bytes\n", total); + 2e04: e59f1108 ldr r1, [pc, #264] ; 2f14 + 2e08: e1a02007 mov r2, r7 + 2e0c: e3a00001 mov r0, #1 + 2e10: eb00024b bl 3744 + close(fd); + 2e14: e1a00008 mov r0, r8 + 2e18: eb000137 bl 32fc + if(total == 0) + 2e1c: e3570000 cmp r7, #0 + 2e20: 0a000005 beq 2e3c + int nfiles; + int fsblocks = 0; + + printf(1, "fsfull test\n"); + + for(nfiles = 0; ; nfiles++){ + 2e24: e2844001 add r4, r4, #1 + } + printf(1, "wrote %d bytes\n", total); + close(fd); + if(total == 0) + break; + } + 2e28: eaffffc1 b 2d34 + name[4] = '0' + (nfiles % 10); + name[5] = '\0'; + printf(1, "writing %s\n", name); + int fd = open(name, O_CREATE|O_RDWR); + if(fd < 0){ + printf(1, "open %s failed\n", name); + 2e2c: e3a00001 mov r0, #1 + 2e30: e59f10e0 ldr r1, [pc, #224] ; 2f18 + 2e34: e24b2064 sub r2, fp, #100 ; 0x64 + 2e38: eb000241 bl 3744 + } + + while(nfiles >= 0){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + 2e3c: e59f80b4 ldr r8, [pc, #180] ; 2ef8 + name[2] = '0' + (nfiles % 1000) / 100; + 2e40: e59f70b8 ldr r7, [pc, #184] ; 2f00 + name[3] = '0' + (nfiles % 100) / 10; + 2e44: e59f50b8 ldr r5, [pc, #184] ; 2f04 + } + + while(nfiles >= 0){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + 2e48: e0cc1498 smull r1, ip, r8, r4 + name[2] = '0' + (nfiles % 1000) / 100; + name[3] = '0' + (nfiles % 100) / 10; + 2e4c: e0c32497 smull r2, r3, r7, r4 + name[4] = '0' + (nfiles % 10); + 2e50: e0cea495 smull sl, lr, r5, r4 + } + + while(nfiles >= 0){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + 2e54: e066c34c rsb ip, r6, ip, asr #6 + name[2] = '0' + (nfiles % 1000) / 100; + name[3] = '0' + (nfiles % 100) / 10; + 2e58: e3a02064 mov r2, #100 ; 0x64 + 2e5c: e06632c3 rsb r3, r6, r3, asr #5 + + while(nfiles >= 0){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + 2e60: e3a00ffa mov r0, #1000 ; 0x3e8 + name[3] = '0' + (nfiles % 100) / 10; + 2e64: e0030392 mul r3, r2, r3 + + while(nfiles >= 0){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + 2e68: e0000c90 mul r0, r0, ip + name[3] = '0' + (nfiles % 100) / 10; + 2e6c: e0633004 rsb r3, r3, r4 + + while(nfiles >= 0){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + 2e70: e0600004 rsb r0, r0, r4 + name[3] = '0' + (nfiles % 100) / 10; + name[4] = '0' + (nfiles % 10); + 2e74: e066614e rsb r6, r6, lr, asr #2 + + while(nfiles >= 0){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + 2e78: e0c12097 smull r2, r1, r7, r0 + name[3] = '0' + (nfiles % 100) / 10; + 2e7c: e0c2a395 smull sl, r2, r5, r3 + name[4] = '0' + (nfiles % 10); + 2e80: e0866106 add r6, r6, r6, lsl #2 + 2e84: e0446086 sub r6, r4, r6, lsl #1 + + while(nfiles >= 0){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + 2e88: e1a00fc0 asr r0, r0, #31 + name[3] = '0' + (nfiles % 100) / 10; + 2e8c: e1a03fc3 asr r3, r3, #31 + + while(nfiles >= 0){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + 2e90: e06012c1 rsb r1, r0, r1, asr #5 + name[3] = '0' + (nfiles % 100) / 10; + 2e94: e0632142 rsb r2, r3, r2, asr #2 + name[4] = '0' + (nfiles % 10); + 2e98: e2863030 add r3, r6, #48 ; 0x30 + } + + while(nfiles >= 0){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + 2e9c: e28cc030 add ip, ip, #48 ; 0x30 + name[2] = '0' + (nfiles % 1000) / 100; + 2ea0: e2811030 add r1, r1, #48 ; 0x30 + name[3] = '0' + (nfiles % 100) / 10; + 2ea4: e2822030 add r2, r2, #48 ; 0x30 + name[4] = '0' + (nfiles % 10); + name[5] = '\0'; + unlink(name); + nfiles--; + 2ea8: e2444001 sub r4, r4, #1 + break; + } + + while(nfiles >= 0){ + char name[64]; + name[0] = 'f'; + 2eac: e3a0e066 mov lr, #102 ; 0x66 + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + name[3] = '0' + (nfiles % 100) / 10; + name[4] = '0' + (nfiles % 10); + 2eb0: e54b3060 strb r3, [fp, #-96] ; 0x60 + name[5] = '\0'; + unlink(name); + 2eb4: e24b0064 sub r0, fp, #100 ; 0x64 + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + name[3] = '0' + (nfiles % 100) / 10; + name[4] = '0' + (nfiles % 10); + name[5] = '\0'; + 2eb8: e3a03000 mov r3, #0 + break; + } + + while(nfiles >= 0){ + char name[64]; + name[0] = 'f'; + 2ebc: e54be064 strb lr, [fp, #-100] ; 0x64 + name[1] = '0' + nfiles / 1000; + 2ec0: e54bc063 strb ip, [fp, #-99] ; 0x63 + name[2] = '0' + (nfiles % 1000) / 100; + 2ec4: e54b1062 strb r1, [fp, #-98] ; 0x62 + name[3] = '0' + (nfiles % 100) / 10; + 2ec8: e54b2061 strb r2, [fp, #-97] ; 0x61 + name[4] = '0' + (nfiles % 10); + name[5] = '\0'; + 2ecc: e54b305f strb r3, [fp, #-95] ; 0x5f + unlink(name); + 2ed0: eb00014a bl 3400 + close(fd); + if(total == 0) + break; + } + + while(nfiles >= 0){ + 2ed4: e3740001 cmn r4, #1 + 2ed8: e1a06fc4 asr r6, r4, #31 + 2edc: 1affffd9 bne 2e48 + name[5] = '\0'; + unlink(name); + nfiles--; + } + + printf(1, "fsfull test finished\n"); + 2ee0: e3a00001 mov r0, #1 + 2ee4: e59f1030 ldr r1, [pc, #48] ; 2f1c + 2ee8: eb000215 bl 3744 +} + 2eec: e24bd020 sub sp, fp, #32 + 2ef0: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} + 2ef4: 00005170 .word 0x00005170 + 2ef8: 10624dd3 .word 0x10624dd3 + 2efc: 000001ff .word 0x000001ff + 2f00: 51eb851f .word 0x51eb851f + 2f04: 66666667 .word 0x66666667 + 2f08: 00005180 .word 0x00005180 + 2f0c: 00000202 .word 0x00000202 + 2f10: 000079fc .word 0x000079fc + 2f14: 0000519c .word 0x0000519c + 2f18: 0000518c .word 0x0000518c + 2f1c: 000051ac .word 0x000051ac + +00002f20 : + +unsigned long randstate = 1; +unsigned int +rand() +{ + randstate = randstate * 1664525 + 1013904223; + 2f20: e59f3024 ldr r3, [pc, #36] ; 2f4c +} + +unsigned long randstate = 1; +unsigned int +rand() +{ + 2f24: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 2f28: e28db000 add fp, sp, #0 + randstate = randstate * 1664525 + 1013904223; + 2f2c: e5931018 ldr r1, [r3, #24] + 2f30: e59f0018 ldr r0, [pc, #24] ; 2f50 + 2f34: e59f2018 ldr r2, [pc, #24] ; 2f54 + 2f38: e0202190 mla r0, r0, r1, r2 + 2f3c: e5830018 str r0, [r3, #24] + return randstate; +} + 2f40: e28bd000 add sp, fp, #0 + 2f44: e8bd0800 pop {fp} + 2f48: e12fff1e bx lr + 2f4c: 00005244 .word 0x00005244 + 2f50: 0019660d .word 0x0019660d + 2f54: 3c6ef35f .word 0x3c6ef35f + +00002f58 : +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 2f58: e52db004 push {fp} ; (str fp, [sp, #-4]!) + char *os; + + os = s; + while((*s++ = *t++) != 0) + 2f5c: e1a02000 mov r2, r0 +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 2f60: e28db000 add fp, sp, #0 + char *os; + + os = s; + while((*s++ = *t++) != 0) + 2f64: e4d13001 ldrb r3, [r1], #1 + 2f68: e3530000 cmp r3, #0 + 2f6c: e4c23001 strb r3, [r2], #1 + 2f70: 1afffffb bne 2f64 + ; + return os; +} + 2f74: e28bd000 add sp, fp, #0 + 2f78: e8bd0800 pop {fp} + 2f7c: e12fff1e bx lr + +00002f80 : + +int +strcmp(const char *p, const char *q) +{ + 2f80: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 2f84: e28db000 add fp, sp, #0 + while(*p && *p == *q) + 2f88: e5d03000 ldrb r3, [r0] + 2f8c: e5d12000 ldrb r2, [r1] + 2f90: e3530000 cmp r3, #0 + 2f94: 1a000004 bne 2fac + 2f98: ea000005 b 2fb4 + 2f9c: e5f03001 ldrb r3, [r0, #1]! + 2fa0: e3530000 cmp r3, #0 + 2fa4: 0a000006 beq 2fc4 + 2fa8: e5f12001 ldrb r2, [r1, #1]! + 2fac: e1530002 cmp r3, r2 + 2fb0: 0afffff9 beq 2f9c + p++, q++; + return (uchar)*p - (uchar)*q; +} + 2fb4: e0620003 rsb r0, r2, r3 + 2fb8: e28bd000 add sp, fp, #0 + 2fbc: e8bd0800 pop {fp} + 2fc0: e12fff1e bx lr +} + +int +strcmp(const char *p, const char *q) +{ + while(*p && *p == *q) + 2fc4: e5d12001 ldrb r2, [r1, #1] + 2fc8: eafffff9 b 2fb4 + +00002fcc : + return (uchar)*p - (uchar)*q; +} + +uint +strlen(char *s) +{ + 2fcc: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 2fd0: e28db000 add fp, sp, #0 + int n; + + for(n = 0; s[n]; n++) + 2fd4: e5d03000 ldrb r3, [r0] + 2fd8: e3530000 cmp r3, #0 + 2fdc: 01a00003 moveq r0, r3 + 2fe0: 0a000006 beq 3000 + 2fe4: e1a02000 mov r2, r0 + 2fe8: e3a03000 mov r3, #0 + 2fec: e5f21001 ldrb r1, [r2, #1]! + 2ff0: e2833001 add r3, r3, #1 + 2ff4: e1a00003 mov r0, r3 + 2ff8: e3510000 cmp r1, #0 + 2ffc: 1afffffa bne 2fec + ; + return n; +} + 3000: e28bd000 add sp, fp, #0 + 3004: e8bd0800 pop {fp} + 3008: e12fff1e bx lr + +0000300c : +memset(void *dst, int c, uint n) +{ + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 300c: e3520000 cmp r2, #0 + return n; +} + +void* +memset(void *dst, int c, uint n) +{ + 3010: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 3014: e28db000 add fp, sp, #0 + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 3018: 0a000006 beq 3038 + 301c: e6ef1071 uxtb r1, r1 + 3020: e1a03002 mov r3, r2 +} + +void* +memset(void *dst, int c, uint n) +{ + char *p=dst; + 3024: e1a0c000 mov ip, r0 + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 3028: e2533001 subs r3, r3, #1 + 302c: e4cc1001 strb r1, [ip], #1 + 3030: 1afffffc bne 3028 + 3034: e0800002 add r0, r0, r2 + return (void *)p; +} + 3038: e28bd000 add sp, fp, #0 + 303c: e8bd0800 pop {fp} + 3040: e12fff1e bx lr + +00003044 : + +char* +strchr(const char *s, char c) +{ + 3044: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 3048: e28db000 add fp, sp, #0 + for(; *s; s++) + 304c: e5d03000 ldrb r3, [r0] + 3050: e3530000 cmp r3, #0 + 3054: 1a000004 bne 306c + 3058: ea000008 b 3080 + 305c: e5d03001 ldrb r3, [r0, #1] + 3060: e2800001 add r0, r0, #1 + 3064: e3530000 cmp r3, #0 + 3068: 0a000004 beq 3080 + if(*s == c) + 306c: e1530001 cmp r3, r1 + 3070: 1afffff9 bne 305c + return (char*)s; + return 0; +} + 3074: e28bd000 add sp, fp, #0 + 3078: e8bd0800 pop {fp} + 307c: e12fff1e bx lr +strchr(const char *s, char c) +{ + for(; *s; s++) + if(*s == c) + return (char*)s; + return 0; + 3080: e1a00003 mov r0, r3 + 3084: eafffffa b 3074 + +00003088 : +} + +char* +gets(char *buf, int max) +{ + 3088: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + 308c: e28db018 add fp, sp, #24 + 3090: e24dd00c sub sp, sp, #12 + 3094: e1a08000 mov r8, r0 + 3098: e1a07001 mov r7, r1 + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 309c: e1a06000 mov r6, r0 + 30a0: e3a05000 mov r5, #0 + 30a4: ea000008 b 30cc + cc = read(0, &c, 1); + 30a8: eb000079 bl 3294 + if(cc < 1) + 30ac: e3500000 cmp r0, #0 + 30b0: da00000b ble 30e4 + break; + buf[i++] = c; + 30b4: e55b301d ldrb r3, [fp, #-29] + if(c == '\n' || c == '\r') + 30b8: e1a05004 mov r5, r4 + 30bc: e353000a cmp r3, #10 + 30c0: 1353000d cmpne r3, #13 + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + if(cc < 1) + break; + buf[i++] = c; + 30c4: e4c63001 strb r3, [r6], #1 + if(c == '\n' || c == '\r') + 30c8: 0a00000a beq 30f8 +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + 30cc: e3a02001 mov r2, #1 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 30d0: e0854002 add r4, r5, r2 + 30d4: e1540007 cmp r4, r7 + cc = read(0, &c, 1); + 30d8: e3a00000 mov r0, #0 + 30dc: e24b101d sub r1, fp, #29 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 30e0: bafffff0 blt 30a8 + break; + buf[i++] = c; + if(c == '\n' || c == '\r') + break; + } + buf[i] = '\0'; + 30e4: e3a03000 mov r3, #0 + 30e8: e7c83005 strb r3, [r8, r5] + return buf; +} + 30ec: e1a00008 mov r0, r8 + 30f0: e24bd018 sub sp, fp, #24 + 30f4: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 30f8: e1a05004 mov r5, r4 + 30fc: eafffff8 b 30e4 + +00003100 : + return buf; +} + +int +stat(char *n, struct stat *st) +{ + 3100: e92d4830 push {r4, r5, fp, lr} + 3104: e1a05001 mov r5, r1 + 3108: e28db00c add fp, sp, #12 + int fd; + int r; + + fd = open(n, O_RDONLY); + 310c: e3a01000 mov r1, #0 + 3110: eb0000a0 bl 3398 + if(fd < 0) + 3114: e2504000 subs r4, r0, #0 + return -1; + 3118: b3e05000 mvnlt r5, #0 +{ + int fd; + int r; + + fd = open(n, O_RDONLY); + if(fd < 0) + 311c: ba000004 blt 3134 + return -1; + r = fstat(fd, st); + 3120: e1a01005 mov r1, r5 + 3124: eb0000c2 bl 3434 + 3128: e1a05000 mov r5, r0 + close(fd); + 312c: e1a00004 mov r0, r4 + 3130: eb000071 bl 32fc + return r; +} + 3134: e1a00005 mov r0, r5 + 3138: e8bd8830 pop {r4, r5, fp, pc} + +0000313c : + +int +atoi(const char *s) +{ + 313c: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 3140: e28db000 add fp, sp, #0 + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 3144: e5d03000 ldrb r3, [r0] + 3148: e2432030 sub r2, r3, #48 ; 0x30 + 314c: e6ef2072 uxtb r2, r2 + 3150: e3520009 cmp r2, #9 +int +atoi(const char *s) +{ + int n; + + n = 0; + 3154: 83a00000 movhi r0, #0 + while('0' <= *s && *s <= '9') + 3158: 8a000009 bhi 3184 + 315c: e1a02000 mov r2, r0 +int +atoi(const char *s) +{ + int n; + + n = 0; + 3160: e3a00000 mov r0, #0 + while('0' <= *s && *s <= '9') + n = n*10 + *s++ - '0'; + 3164: e0800100 add r0, r0, r0, lsl #2 + 3168: e0830080 add r0, r3, r0, lsl #1 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 316c: e5f23001 ldrb r3, [r2, #1]! + n = n*10 + *s++ - '0'; + 3170: e2400030 sub r0, r0, #48 ; 0x30 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 3174: e2431030 sub r1, r3, #48 ; 0x30 + 3178: e6ef1071 uxtb r1, r1 + 317c: e3510009 cmp r1, #9 + 3180: 9afffff7 bls 3164 + n = n*10 + *s++ - '0'; + return n; +} + 3184: e28bd000 add sp, fp, #0 + 3188: e8bd0800 pop {fp} + 318c: e12fff1e bx lr + +00003190 : +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 3190: e3520000 cmp r2, #0 + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) +{ + 3194: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 3198: e28db000 add fp, sp, #0 + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 319c: da000005 ble 31b8 + n = n*10 + *s++ - '0'; + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) + 31a0: e0802002 add r2, r0, r2 +{ + char *dst, *src; + + dst = vdst; + 31a4: e1a03000 mov r3, r0 + src = vsrc; + while(n-- > 0) + *dst++ = *src++; + 31a8: e4d1c001 ldrb ip, [r1], #1 + 31ac: e4c3c001 strb ip, [r3], #1 +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 31b0: e1530002 cmp r3, r2 + 31b4: 1afffffb bne 31a8 + *dst++ = *src++; + return vdst; +} + 31b8: e28bd000 add sp, fp, #0 + 31bc: e8bd0800 pop {fp} + 31c0: e12fff1e bx lr + +000031c4 : + 31c4: e92d4000 push {lr} + 31c8: e92d0008 push {r3} + 31cc: e92d0004 push {r2} + 31d0: e92d0002 push {r1} + 31d4: e92d0001 push {r0} + 31d8: e3a00001 mov r0, #1 + 31dc: ef000040 svc 0x00000040 + 31e0: e8bd0002 pop {r1} + 31e4: e8bd0002 pop {r1} + 31e8: e8bd0004 pop {r2} + 31ec: e8bd0008 pop {r3} + 31f0: e8bd4000 pop {lr} + 31f4: e12fff1e bx lr + +000031f8 : + 31f8: e92d4000 push {lr} + 31fc: e92d0008 push {r3} + 3200: e92d0004 push {r2} + 3204: e92d0002 push {r1} + 3208: e92d0001 push {r0} + 320c: e3a00002 mov r0, #2 + 3210: ef000040 svc 0x00000040 + 3214: e8bd0002 pop {r1} + 3218: e8bd0002 pop {r1} + 321c: e8bd0004 pop {r2} + 3220: e8bd0008 pop {r3} + 3224: e8bd4000 pop {lr} + 3228: e12fff1e bx lr + +0000322c : + 322c: e92d4000 push {lr} + 3230: e92d0008 push {r3} + 3234: e92d0004 push {r2} + 3238: e92d0002 push {r1} + 323c: e92d0001 push {r0} + 3240: e3a00003 mov r0, #3 + 3244: ef000040 svc 0x00000040 + 3248: e8bd0002 pop {r1} + 324c: e8bd0002 pop {r1} + 3250: e8bd0004 pop {r2} + 3254: e8bd0008 pop {r3} + 3258: e8bd4000 pop {lr} + 325c: e12fff1e bx lr + +00003260 : + 3260: e92d4000 push {lr} + 3264: e92d0008 push {r3} + 3268: e92d0004 push {r2} + 326c: e92d0002 push {r1} + 3270: e92d0001 push {r0} + 3274: e3a00004 mov r0, #4 + 3278: ef000040 svc 0x00000040 + 327c: e8bd0002 pop {r1} + 3280: e8bd0002 pop {r1} + 3284: e8bd0004 pop {r2} + 3288: e8bd0008 pop {r3} + 328c: e8bd4000 pop {lr} + 3290: e12fff1e bx lr + +00003294 : + 3294: e92d4000 push {lr} + 3298: e92d0008 push {r3} + 329c: e92d0004 push {r2} + 32a0: e92d0002 push {r1} + 32a4: e92d0001 push {r0} + 32a8: e3a00005 mov r0, #5 + 32ac: ef000040 svc 0x00000040 + 32b0: e8bd0002 pop {r1} + 32b4: e8bd0002 pop {r1} + 32b8: e8bd0004 pop {r2} + 32bc: e8bd0008 pop {r3} + 32c0: e8bd4000 pop {lr} + 32c4: e12fff1e bx lr + +000032c8 : + 32c8: e92d4000 push {lr} + 32cc: e92d0008 push {r3} + 32d0: e92d0004 push {r2} + 32d4: e92d0002 push {r1} + 32d8: e92d0001 push {r0} + 32dc: e3a00010 mov r0, #16 + 32e0: ef000040 svc 0x00000040 + 32e4: e8bd0002 pop {r1} + 32e8: e8bd0002 pop {r1} + 32ec: e8bd0004 pop {r2} + 32f0: e8bd0008 pop {r3} + 32f4: e8bd4000 pop {lr} + 32f8: e12fff1e bx lr + +000032fc : + 32fc: e92d4000 push {lr} + 3300: e92d0008 push {r3} + 3304: e92d0004 push {r2} + 3308: e92d0002 push {r1} + 330c: e92d0001 push {r0} + 3310: e3a00015 mov r0, #21 + 3314: ef000040 svc 0x00000040 + 3318: e8bd0002 pop {r1} + 331c: e8bd0002 pop {r1} + 3320: e8bd0004 pop {r2} + 3324: e8bd0008 pop {r3} + 3328: e8bd4000 pop {lr} + 332c: e12fff1e bx lr + +00003330 : + 3330: e92d4000 push {lr} + 3334: e92d0008 push {r3} + 3338: e92d0004 push {r2} + 333c: e92d0002 push {r1} + 3340: e92d0001 push {r0} + 3344: e3a00006 mov r0, #6 + 3348: ef000040 svc 0x00000040 + 334c: e8bd0002 pop {r1} + 3350: e8bd0002 pop {r1} + 3354: e8bd0004 pop {r2} + 3358: e8bd0008 pop {r3} + 335c: e8bd4000 pop {lr} + 3360: e12fff1e bx lr + +00003364 : + 3364: e92d4000 push {lr} + 3368: e92d0008 push {r3} + 336c: e92d0004 push {r2} + 3370: e92d0002 push {r1} + 3374: e92d0001 push {r0} + 3378: e3a00007 mov r0, #7 + 337c: ef000040 svc 0x00000040 + 3380: e8bd0002 pop {r1} + 3384: e8bd0002 pop {r1} + 3388: e8bd0004 pop {r2} + 338c: e8bd0008 pop {r3} + 3390: e8bd4000 pop {lr} + 3394: e12fff1e bx lr + +00003398 : + 3398: e92d4000 push {lr} + 339c: e92d0008 push {r3} + 33a0: e92d0004 push {r2} + 33a4: e92d0002 push {r1} + 33a8: e92d0001 push {r0} + 33ac: e3a0000f mov r0, #15 + 33b0: ef000040 svc 0x00000040 + 33b4: e8bd0002 pop {r1} + 33b8: e8bd0002 pop {r1} + 33bc: e8bd0004 pop {r2} + 33c0: e8bd0008 pop {r3} + 33c4: e8bd4000 pop {lr} + 33c8: e12fff1e bx lr + +000033cc : + 33cc: e92d4000 push {lr} + 33d0: e92d0008 push {r3} + 33d4: e92d0004 push {r2} + 33d8: e92d0002 push {r1} + 33dc: e92d0001 push {r0} + 33e0: e3a00011 mov r0, #17 + 33e4: ef000040 svc 0x00000040 + 33e8: e8bd0002 pop {r1} + 33ec: e8bd0002 pop {r1} + 33f0: e8bd0004 pop {r2} + 33f4: e8bd0008 pop {r3} + 33f8: e8bd4000 pop {lr} + 33fc: e12fff1e bx lr + +00003400 : + 3400: e92d4000 push {lr} + 3404: e92d0008 push {r3} + 3408: e92d0004 push {r2} + 340c: e92d0002 push {r1} + 3410: e92d0001 push {r0} + 3414: e3a00012 mov r0, #18 + 3418: ef000040 svc 0x00000040 + 341c: e8bd0002 pop {r1} + 3420: e8bd0002 pop {r1} + 3424: e8bd0004 pop {r2} + 3428: e8bd0008 pop {r3} + 342c: e8bd4000 pop {lr} + 3430: e12fff1e bx lr + +00003434 : + 3434: e92d4000 push {lr} + 3438: e92d0008 push {r3} + 343c: e92d0004 push {r2} + 3440: e92d0002 push {r1} + 3444: e92d0001 push {r0} + 3448: e3a00008 mov r0, #8 + 344c: ef000040 svc 0x00000040 + 3450: e8bd0002 pop {r1} + 3454: e8bd0002 pop {r1} + 3458: e8bd0004 pop {r2} + 345c: e8bd0008 pop {r3} + 3460: e8bd4000 pop {lr} + 3464: e12fff1e bx lr + +00003468 : + 3468: e92d4000 push {lr} + 346c: e92d0008 push {r3} + 3470: e92d0004 push {r2} + 3474: e92d0002 push {r1} + 3478: e92d0001 push {r0} + 347c: e3a00013 mov r0, #19 + 3480: ef000040 svc 0x00000040 + 3484: e8bd0002 pop {r1} + 3488: e8bd0002 pop {r1} + 348c: e8bd0004 pop {r2} + 3490: e8bd0008 pop {r3} + 3494: e8bd4000 pop {lr} + 3498: e12fff1e bx lr + +0000349c : + 349c: e92d4000 push {lr} + 34a0: e92d0008 push {r3} + 34a4: e92d0004 push {r2} + 34a8: e92d0002 push {r1} + 34ac: e92d0001 push {r0} + 34b0: e3a00014 mov r0, #20 + 34b4: ef000040 svc 0x00000040 + 34b8: e8bd0002 pop {r1} + 34bc: e8bd0002 pop {r1} + 34c0: e8bd0004 pop {r2} + 34c4: e8bd0008 pop {r3} + 34c8: e8bd4000 pop {lr} + 34cc: e12fff1e bx lr + +000034d0 : + 34d0: e92d4000 push {lr} + 34d4: e92d0008 push {r3} + 34d8: e92d0004 push {r2} + 34dc: e92d0002 push {r1} + 34e0: e92d0001 push {r0} + 34e4: e3a00009 mov r0, #9 + 34e8: ef000040 svc 0x00000040 + 34ec: e8bd0002 pop {r1} + 34f0: e8bd0002 pop {r1} + 34f4: e8bd0004 pop {r2} + 34f8: e8bd0008 pop {r3} + 34fc: e8bd4000 pop {lr} + 3500: e12fff1e bx lr + +00003504 : + 3504: e92d4000 push {lr} + 3508: e92d0008 push {r3} + 350c: e92d0004 push {r2} + 3510: e92d0002 push {r1} + 3514: e92d0001 push {r0} + 3518: e3a0000a mov r0, #10 + 351c: ef000040 svc 0x00000040 + 3520: e8bd0002 pop {r1} + 3524: e8bd0002 pop {r1} + 3528: e8bd0004 pop {r2} + 352c: e8bd0008 pop {r3} + 3530: e8bd4000 pop {lr} + 3534: e12fff1e bx lr + +00003538 : + 3538: e92d4000 push {lr} + 353c: e92d0008 push {r3} + 3540: e92d0004 push {r2} + 3544: e92d0002 push {r1} + 3548: e92d0001 push {r0} + 354c: e3a0000b mov r0, #11 + 3550: ef000040 svc 0x00000040 + 3554: e8bd0002 pop {r1} + 3558: e8bd0002 pop {r1} + 355c: e8bd0004 pop {r2} + 3560: e8bd0008 pop {r3} + 3564: e8bd4000 pop {lr} + 3568: e12fff1e bx lr + +0000356c : + 356c: e92d4000 push {lr} + 3570: e92d0008 push {r3} + 3574: e92d0004 push {r2} + 3578: e92d0002 push {r1} + 357c: e92d0001 push {r0} + 3580: e3a0000c mov r0, #12 + 3584: ef000040 svc 0x00000040 + 3588: e8bd0002 pop {r1} + 358c: e8bd0002 pop {r1} + 3590: e8bd0004 pop {r2} + 3594: e8bd0008 pop {r3} + 3598: e8bd4000 pop {lr} + 359c: e12fff1e bx lr + +000035a0 : + 35a0: e92d4000 push {lr} + 35a4: e92d0008 push {r3} + 35a8: e92d0004 push {r2} + 35ac: e92d0002 push {r1} + 35b0: e92d0001 push {r0} + 35b4: e3a0000d mov r0, #13 + 35b8: ef000040 svc 0x00000040 + 35bc: e8bd0002 pop {r1} + 35c0: e8bd0002 pop {r1} + 35c4: e8bd0004 pop {r2} + 35c8: e8bd0008 pop {r3} + 35cc: e8bd4000 pop {lr} + 35d0: e12fff1e bx lr + +000035d4 : + 35d4: e92d4000 push {lr} + 35d8: e92d0008 push {r3} + 35dc: e92d0004 push {r2} + 35e0: e92d0002 push {r1} + 35e4: e92d0001 push {r0} + 35e8: e3a0000e mov r0, #14 + 35ec: ef000040 svc 0x00000040 + 35f0: e8bd0002 pop {r1} + 35f4: e8bd0002 pop {r1} + 35f8: e8bd0004 pop {r2} + 35fc: e8bd0008 pop {r3} + 3600: e8bd4000 pop {lr} + 3604: e12fff1e bx lr + +00003608 : +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 3608: e92d4800 push {fp, lr} + 360c: e28db004 add fp, sp, #4 + 3610: e24b3004 sub r3, fp, #4 + 3614: e24dd008 sub sp, sp, #8 + write(fd, &c, 1); + 3618: e3a02001 mov r2, #1 +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 361c: e5631001 strb r1, [r3, #-1]! + write(fd, &c, 1); + 3620: e1a01003 mov r1, r3 + 3624: ebffff27 bl 32c8 +} + 3628: e24bd004 sub sp, fp, #4 + 362c: e8bd8800 pop {fp, pc} + +00003630 : + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 3630: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 3634: e1a04000 mov r4, r0 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 3638: e1a00fa1 lsr r0, r1, #31 + 363c: e3530000 cmp r3, #0 + 3640: 03a03000 moveq r3, #0 + 3644: 12003001 andne r3, r0, #1 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 3648: e28db020 add fp, sp, #32 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 364c: e3530000 cmp r3, #0 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 3650: e24dd014 sub sp, sp, #20 + 3654: e59f909c ldr r9, [pc, #156] ; 36f8 + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + x = -xx; + 3658: 12611000 rsbne r1, r1, #0 + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + 365c: 13a03001 movne r3, #1 + } else { + x = xx; + } + + b = base; + i = 0; + 3660: e3a0a000 mov sl, #0 + 3664: e24b6034 sub r6, fp, #52 ; 0x34 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 3668: e3a08001 mov r8, #1 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 366c: e3a07000 mov r7, #0 + int i; + + for(i=31;i>=0;i--){ + 3670: e3a0001f mov r0, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 3674: e1a0c007 mov ip, r7 + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 3678: e1a0e031 lsr lr, r1, r0 + 367c: e20ee001 and lr, lr, #1 + 3680: e18ec08c orr ip, lr, ip, lsl #1 + if(r >= d) { + 3684: e152000c cmp r2, ip + r = r - d; + q = q | (1 << i); + 3688: 91877018 orrls r7, r7, r8, lsl r0 + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 368c: 9062c00c rsbls ip, r2, ip +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 3690: e2500001 subs r0, r0, #1 + 3694: 2afffff7 bcs 3678 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 3698: e0000792 mul r0, r2, r7 + }while((x = y) != 0); + 369c: e3570000 cmp r7, #0 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 36a0: e0601001 rsb r1, r0, r1 + 36a4: e28a5001 add r5, sl, #1 + 36a8: e7d91001 ldrb r1, [r9, r1] + 36ac: e7c6100a strb r1, [r6, sl] + }while((x = y) != 0); + 36b0: 11a01007 movne r1, r7 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 36b4: 11a0a005 movne sl, r5 + 36b8: 1affffeb bne 366c + }while((x = y) != 0); + if(neg) + 36bc: e3530000 cmp r3, #0 + buf[i++] = '-'; + 36c0: 124b2024 subne r2, fp, #36 ; 0x24 + 36c4: 10823005 addne r3, r2, r5 + 36c8: 128a5002 addne r5, sl, #2 + + while(--i >= 0) + 36cc: e2455001 sub r5, r5, #1 + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + 36d0: 13a0202d movne r2, #45 ; 0x2d + 36d4: 15432010 strbne r2, [r3, #-16] + + while(--i >= 0) + putc(fd, buf[i]); + 36d8: e7d61005 ldrb r1, [r6, r5] + 36dc: e1a00004 mov r0, r4 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 36e0: e2455001 sub r5, r5, #1 + putc(fd, buf[i]); + 36e4: ebffffc7 bl 3608 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 36e8: e3750001 cmn r5, #1 + 36ec: 1afffff9 bne 36d8 + putc(fd, buf[i]); +} + 36f0: e24bd020 sub sp, fp, #32 + 36f4: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} + 36f8: 00005228 .word 0x00005228 + +000036fc
: + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 36fc: e3a03000 mov r3, #0 +{ + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + 3700: e92d0830 push {r4, r5, fp} + 3704: e1a02000 mov r2, r0 + 3708: e28db008 add fp, sp, #8 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 370c: e3a0c01f mov ip, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 3710: e1a00003 mov r0, r3 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 3714: e3a05001 mov r5, #1 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 3718: e1a04c32 lsr r4, r2, ip + 371c: e2044001 and r4, r4, #1 + 3720: e1843083 orr r3, r4, r3, lsl #1 + if(r >= d) { + 3724: e1530001 cmp r3, r1 + r = r - d; + q = q | (1 << i); + 3728: 21800c15 orrcs r0, r0, r5, lsl ip + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 372c: 20613003 rsbcs r3, r1, r3 +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 3730: e25cc001 subs ip, ip, #1 + 3734: 2afffff7 bcs 3718 + r = r - d; + q = q | (1 << i); + } + } + return q; +} + 3738: e24bd008 sub sp, fp, #8 + 373c: e8bd0830 pop {r4, r5, fp} + 3740: e12fff1e bx lr + +00003744 : +} + +// Print to the given fd. Only understands %d, %x, %p, %s. +void +printf(int fd, char *fmt, ...) +{ + 3744: e92d000e push {r1, r2, r3} + 3748: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 374c: e28db020 add fp, sp, #32 + 3750: e1a05000 mov r5, r0 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 3754: e59b4004 ldr r4, [fp, #4] + 3758: e5d48000 ldrb r8, [r4] + 375c: e3580000 cmp r8, #0 + 3760: 0a000027 beq 3804 + ap++; + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + 3764: e59f712c ldr r7, [pc, #300] ; 3898 + char *s; + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + 3768: e28b6008 add r6, fp, #8 +{ + char *s; + int c, i, state; + uint *ap; + + state = 0; + 376c: e3a0a000 mov sl, #0 + 3770: ea000008 b 3798 + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 3774: e3580025 cmp r8, #37 ; 0x25 + state = '%'; + 3778: 01a0a008 moveq sl, r8 + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 377c: 0a000002 beq 378c + state = '%'; + } else { + putc(fd, c); + 3780: e1a00005 mov r0, r5 + 3784: e1a01008 mov r1, r8 + 3788: ebffff9e bl 3608 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 378c: e5f48001 ldrb r8, [r4, #1]! + 3790: e3580000 cmp r8, #0 + 3794: 0a00001a beq 3804 + c = fmt[i] & 0xff; + if(state == 0){ + 3798: e35a0000 cmp sl, #0 + 379c: 0afffff4 beq 3774 + if(c == '%'){ + state = '%'; + } else { + putc(fd, c); + } + } else if(state == '%'){ + 37a0: e35a0025 cmp sl, #37 ; 0x25 + 37a4: 1afffff8 bne 378c + if(c == 'd'){ + 37a8: e3580064 cmp r8, #100 ; 0x64 + 37ac: 0a00002c beq 3864 + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + 37b0: e3580078 cmp r8, #120 ; 0x78 + 37b4: 13580070 cmpne r8, #112 ; 0x70 + 37b8: 13a09000 movne r9, #0 + 37bc: 03a09001 moveq r9, #1 + 37c0: 0a000013 beq 3814 + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + 37c4: e3580073 cmp r8, #115 ; 0x73 + 37c8: 0a000018 beq 3830 + s = "(null)"; + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + 37cc: e3580063 cmp r8, #99 ; 0x63 + 37d0: 0a00002a beq 3880 + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 37d4: e3580025 cmp r8, #37 ; 0x25 + putc(fd, c); + 37d8: e1a0100a mov r1, sl + 37dc: e1a00005 mov r0, r5 + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 37e0: 0a000002 beq 37f0 + putc(fd, c); + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + 37e4: ebffff87 bl 3608 + putc(fd, c); + 37e8: e1a00005 mov r0, r5 + 37ec: e1a01008 mov r1, r8 + 37f0: ebffff84 bl 3608 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 37f4: e5f48001 ldrb r8, [r4, #1]! + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 37f8: e1a0a009 mov sl, r9 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 37fc: e3580000 cmp r8, #0 + 3800: 1affffe4 bne 3798 + putc(fd, c); + } + state = 0; + } + } +} + 3804: e24bd020 sub sp, fp, #32 + 3808: e8bd4ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 380c: e28dd00c add sp, sp, #12 + 3810: e12fff1e bx lr + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + 3814: e1a00005 mov r0, r5 + 3818: e4961004 ldr r1, [r6], #4 + 381c: e3a02010 mov r2, #16 + 3820: e3a03000 mov r3, #0 + 3824: ebffff81 bl 3630 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 3828: e3a0a000 mov sl, #0 + 382c: eaffffd6 b 378c + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + s = (char*)*ap; + 3830: e4968004 ldr r8, [r6], #4 + ap++; + if(s == 0) + s = "(null)"; + 3834: e3580000 cmp r8, #0 + 3838: 01a08007 moveq r8, r7 + while(*s != 0){ + 383c: e5d81000 ldrb r1, [r8] + 3840: e3510000 cmp r1, #0 + 3844: 0a000004 beq 385c + putc(fd, *s); + 3848: e1a00005 mov r0, r5 + 384c: ebffff6d bl 3608 + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + while(*s != 0){ + 3850: e5f81001 ldrb r1, [r8, #1]! + 3854: e3510000 cmp r1, #0 + 3858: 1afffffa bne 3848 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 385c: e1a0a001 mov sl, r1 + 3860: eaffffc9 b 378c + } else { + putc(fd, c); + } + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + 3864: e1a00005 mov r0, r5 + 3868: e4961004 ldr r1, [r6], #4 + 386c: e3a0200a mov r2, #10 + 3870: e3a03001 mov r3, #1 + 3874: ebffff6d bl 3630 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 3878: e3a0a000 mov sl, #0 + 387c: eaffffc2 b 378c + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 3880: e4961004 ldr r1, [r6], #4 + 3884: e1a00005 mov r0, r5 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 3888: e1a0a009 mov sl, r9 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 388c: e6ef1071 uxtb r1, r1 + 3890: ebffff5c bl 3608 + 3894: eaffffbc b 378c + 3898: 0000523c .word 0x0000523c + +0000389c : +free(void *ap) +{ + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 389c: e59f3098 ldr r3, [pc, #152] ; 393c +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 38a0: e92d0830 push {r4, r5, fp} + Header *bp, *p; + + bp = (Header*)ap - 1; + 38a4: e240c008 sub ip, r0, #8 + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 38a8: e5932000 ldr r2, [r3] +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 38ac: e28db008 add fp, sp, #8 + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 38b0: e152000c cmp r2, ip + 38b4: e5921000 ldr r1, [r2] + 38b8: 2a000001 bcs 38c4 + 38bc: e15c0001 cmp ip, r1 + 38c0: 3a000007 bcc 38e4 + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + 38c4: e1520001 cmp r2, r1 + 38c8: 3a000003 bcc 38dc + 38cc: e152000c cmp r2, ip + 38d0: 3a000003 bcc 38e4 + 38d4: e15c0001 cmp ip, r1 + 38d8: 3a000001 bcc 38e4 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 38dc: e1a02001 mov r2, r1 + 38e0: eafffff2 b 38b0 + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + 38e4: e5104004 ldr r4, [r0, #-4] + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + freep = p; + 38e8: e5832000 str r2, [r3] + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + 38ec: e08c5184 add r5, ip, r4, lsl #3 + 38f0: e1550001 cmp r5, r1 + bp->s.size += p->s.ptr->s.size; + 38f4: 05911004 ldreq r1, [r1, #4] + 38f8: 00814004 addeq r4, r1, r4 + 38fc: 05004004 streq r4, [r0, #-4] + bp->s.ptr = p->s.ptr->s.ptr; + 3900: 05921000 ldreq r1, [r2] + 3904: 05911000 ldreq r1, [r1] + } else + bp->s.ptr = p->s.ptr; + 3908: e5001008 str r1, [r0, #-8] + if(p + p->s.size == bp){ + 390c: e5921004 ldr r1, [r2, #4] + 3910: e0824181 add r4, r2, r1, lsl #3 + 3914: e15c0004 cmp ip, r4 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + 3918: 1582c000 strne ip, [r2] + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + } else + bp->s.ptr = p->s.ptr; + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + 391c: 0510c004 ldreq ip, [r0, #-4] + 3920: 008c1001 addeq r1, ip, r1 + 3924: 05821004 streq r1, [r2, #4] + p->s.ptr = bp->s.ptr; + 3928: 05101008 ldreq r1, [r0, #-8] + 392c: 05821000 streq r1, [r2] + } else + p->s.ptr = bp; + freep = p; +} + 3930: e24bd008 sub sp, fp, #8 + 3934: e8bd0830 pop {r4, r5, fp} + 3938: e12fff1e bx lr + 393c: 000052e0 .word 0x000052e0 + +00003940 : + return freep; +} + +void* +malloc(uint nbytes) +{ + 3940: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + 3944: e2804007 add r4, r0, #7 + if((prevp = freep) == 0){ + 3948: e59f50d4 ldr r5, [pc, #212] ; 3a24 +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + 394c: e1a041a4 lsr r4, r4, #3 + return freep; +} + +void* +malloc(uint nbytes) +{ + 3950: e28db01c add fp, sp, #28 + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + 3954: e5953000 ldr r3, [r5] +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + 3958: e2844001 add r4, r4, #1 + if((prevp = freep) == 0){ + 395c: e3530000 cmp r3, #0 + 3960: 0a00002b beq 3a14 + 3964: e5930000 ldr r0, [r3] + 3968: e5902004 ldr r2, [r0, #4] + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + 396c: e1520004 cmp r2, r4 + 3970: 2a00001b bcs 39e4 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + 3974: e59f80ac ldr r8, [pc, #172] ; 3a28 + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + 3978: e1a07184 lsl r7, r4, #3 + 397c: ea000003 b 3990 + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + 3980: e5930000 ldr r0, [r3] + if(p->s.size >= nunits){ + 3984: e5902004 ldr r2, [r0, #4] + 3988: e1540002 cmp r4, r2 + 398c: 9a000014 bls 39e4 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + 3990: e5952000 ldr r2, [r5] + 3994: e1a03000 mov r3, r0 + 3998: e1500002 cmp r0, r2 + 399c: 1afffff7 bne 3980 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + 39a0: e1540008 cmp r4, r8 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + 39a4: 81a00007 movhi r0, r7 + 39a8: 93a00902 movls r0, #32768 ; 0x8000 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + 39ac: 81a06004 movhi r6, r4 + 39b0: 93a06a01 movls r6, #4096 ; 0x1000 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + 39b4: ebfffeec bl 356c + 39b8: e1a03000 mov r3, r0 + if(p == (char*)-1) + 39bc: e3730001 cmn r3, #1 + return 0; + hp = (Header*)p; + hp->s.size = nu; + free((void*)(hp + 1)); + 39c0: e2800008 add r0, r0, #8 + Header *hp; + + if(nu < 4096) + nu = 4096; + p = sbrk(nu * sizeof(Header)); + if(p == (char*)-1) + 39c4: 0a000010 beq 3a0c + return 0; + hp = (Header*)p; + hp->s.size = nu; + 39c8: e5836004 str r6, [r3, #4] + free((void*)(hp + 1)); + 39cc: ebffffb2 bl 389c + return freep; + 39d0: e5953000 ldr r3, [r5] + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + if((p = morecore(nunits)) == 0) + 39d4: e3530000 cmp r3, #0 + 39d8: 1affffe8 bne 3980 + return 0; + 39dc: e1a00003 mov r0, r3 + } +} + 39e0: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + 39e4: e1540002 cmp r4, r2 + prevp->s.ptr = p->s.ptr; + else { + p->s.size -= nunits; + 39e8: 10642002 rsbne r2, r4, r2 + 39ec: 15802004 strne r2, [r0, #4] + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + 39f0: 05902000 ldreq r2, [r0] + else { + p->s.size -= nunits; + p += p->s.size; + 39f4: 10800182 addne r0, r0, r2, lsl #3 + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + 39f8: 05832000 streq r2, [r3] + else { + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + 39fc: 15804004 strne r4, [r0, #4] + } + freep = prevp; + 3a00: e5853000 str r3, [r5] + return (void*)(p + 1); + 3a04: e2800008 add r0, r0, #8 + 3a08: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + } + if(p == freep) + if((p = morecore(nunits)) == 0) + return 0; + 3a0c: e3a00000 mov r0, #0 + 3a10: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + 3a14: e2850004 add r0, r5, #4 + 3a18: e5850000 str r0, [r5] + base.s.size = 0; + 3a1c: e9850009 stmib r5, {r0, r3} + 3a20: eaffffd3 b 3974 + 3a24: 000052e0 .word 0x000052e0 + 3a28: 00000fff .word 0x00000fff diff -r 000000000000 -r c450faca55f4 uprogs/usertests.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/usertests.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,1649 @@ +#include "param.h" +#include "types.h" +#include "stat.h" +#include "user.h" +#include "fs.h" +#include "fcntl.h" +#include "syscall.h" +#include "traps.h" +#include "memlayout.h" + +char buf[8192]; +char name[3]; +char *echoargv[] = { "echo", "ALL", "TESTS", "PASSED", 0 }; +int stdout = 1; + +// simple file system tests + +void +opentest(void) +{ + int fd; + + printf(stdout, "open test\n"); + fd = open("echo", 0); + if(fd < 0){ + printf(stdout, "open echo failed!\n"); + exit(); + } + close(fd); + fd = open("doesnotexist", 0); + if(fd >= 0){ + printf(stdout, "open doesnotexist succeeded!\n"); + exit(); + } + printf(stdout, "open test ok\n"); +} + +void +writetest(void) +{ + int fd; + int i; + + printf(stdout, "small file test\n"); + fd = open("small", O_CREATE|O_RDWR); + if(fd >= 0){ + printf(stdout, "creat small succeeded; ok\n"); + } else { + printf(stdout, "error: creat small failed!\n"); + exit(); + } + for(i = 0; i < 100; i++){ + if(write(fd, "aaaaaaaaaa", 10) != 10){ + printf(stdout, "error: write aa %d new file failed\n", i); + exit(); + } + if(write(fd, "bbbbbbbbbb", 10) != 10){ + printf(stdout, "error: write bb %d new file failed\n", i); + exit(); + } + } + printf(stdout, "writes ok\n"); + close(fd); + fd = open("small", O_RDONLY); + if(fd >= 0){ + printf(stdout, "open small succeeded ok\n"); + } else { + printf(stdout, "error: open small failed!\n"); + exit(); + } + i = read(fd, buf, 2000); + if(i == 2000){ + printf(stdout, "read succeeded ok\n"); + } else { + printf(stdout, "read failed\n"); + exit(); + } + close(fd); + + if(unlink("small") < 0){ + printf(stdout, "unlink small failed\n"); + exit(); + } + printf(stdout, "small file test ok\n"); +} + +void +writetest1(void) +{ + int i, fd, n; + + printf(stdout, "big files test\n"); + + fd = open("big", O_CREATE|O_RDWR); + if(fd < 0){ + printf(stdout, "error: creat big failed!\n"); + exit(); + } + + for(i = 0; i < MAXFILE; i++){ + ((int*)buf)[0] = i; + if(write(fd, buf, 512) != 512){ + printf(stdout, "error: write big file failed\n", i); + exit(); + } + } + + close(fd); + + fd = open("big", O_RDONLY); + if(fd < 0){ + printf(stdout, "error: open big failed!\n"); + exit(); + } + + n = 0; + for(;;){ + i = read(fd, buf, 512); + if(i == 0){ + if(n == MAXFILE - 1){ + printf(stdout, "read only %d blocks from big", n); + exit(); + } + break; + } else if(i != 512){ + printf(stdout, "read failed %d\n", i); + exit(); + } + if(((int*)buf)[0] != n){ + printf(stdout, "read content of block %d is %d\n", + n, ((int*)buf)[0]); + exit(); + } + n++; + } + close(fd); + if(unlink("big") < 0){ + printf(stdout, "unlink big failed\n"); + exit(); + } + printf(stdout, "big files ok\n"); +} + +void +createtest(void) +{ + int i, fd; + + printf(stdout, "many creates, followed by unlink test\n"); + + name[0] = 'a'; + name[2] = '\0'; + for(i = 0; i < 52; i++){ + name[1] = '0' + i; + fd = open(name, O_CREATE|O_RDWR); + close(fd); + } + name[0] = 'a'; + name[2] = '\0'; + for(i = 0; i < 52; i++){ + name[1] = '0' + i; + unlink(name); + } + printf(stdout, "many creates, followed by unlink; ok\n"); +} + +void dirtest(void) +{ + printf(stdout, "mkdir test\n"); + + if(mkdir("dir0") < 0){ + printf(stdout, "mkdir failed\n"); + exit(); + } + + if(chdir("dir0") < 0){ + printf(stdout, "chdir dir0 failed\n"); + exit(); + } + + if(chdir("..") < 0){ + printf(stdout, "chdir .. failed\n"); + exit(); + } + + if(unlink("dir0") < 0){ + printf(stdout, "unlink dir0 failed\n"); + exit(); + } + printf(stdout, "mkdir test\n"); +} + +void +exectest(void) +{ + printf(stdout, "exec test\n"); + if(exec("echo", echoargv) < 0){ + printf(stdout, "exec echo failed\n"); + exit(); + } +} + +// simple fork and pipe read/write + +void +pipe1(void) +{ + int fds[2], pid; + int seq, i, n, cc, total; + + if(pipe(fds) != 0){ + printf(1, "pipe() failed\n"); + exit(); + } + pid = fork(); + seq = 0; + if(pid == 0){ + close(fds[0]); + for(n = 0; n < 5; n++){ + for(i = 0; i < 1033; i++) + buf[i] = seq++; + if(write(fds[1], buf, 1033) != 1033){ + printf(1, "pipe1 oops 1\n"); + exit(); + } + } + exit(); + } else if(pid > 0){ + close(fds[1]); + total = 0; + cc = 1; + while((n = read(fds[0], buf, cc)) > 0){ + for(i = 0; i < n; i++){ + if((buf[i] & 0xff) != (seq++ & 0xff)){ + printf(1, "pipe1 oops 2\n"); + return; + } + } + total += n; + cc = cc * 2; + if(cc > sizeof(buf)) + cc = sizeof(buf); + } + if(total != 5 * 1033){ + printf(1, "pipe1 oops 3 total %d\n", total); + exit(); + } + close(fds[0]); + wait(); + } else { + printf(1, "fork() failed\n"); + exit(); + } + printf(1, "pipe1 ok\n"); +} + +// meant to be run w/ at most two CPUs +void +preempt(void) +{ + int pid1, pid2, pid3; + int pfds[2]; + + printf(1, "preempt: "); + pid1 = fork(); + if(pid1 == 0) + for(;;) + ; + + pid2 = fork(); + if(pid2 == 0) + for(;;) + ; + + pipe(pfds); + pid3 = fork(); + if(pid3 == 0){ + close(pfds[0]); + if(write(pfds[1], "x", 1) != 1) + printf(1, "preempt write error"); + close(pfds[1]); + for(;;) + ; + } + + close(pfds[1]); + if(read(pfds[0], buf, sizeof(buf)) != 1){ + printf(1, "preempt read error"); + return; + } + close(pfds[0]); + printf(1, "kill... "); + kill(pid1); + kill(pid2); + kill(pid3); + printf(1, "wait... "); + wait(); + wait(); + wait(); + printf(1, "preempt ok\n"); +} + +// try to find any races between exit and wait +void +exitwait(void) +{ + int i, pid; + + for(i = 0; i < 100; i++){ + pid = fork(); + if(pid < 0){ + printf(1, "fork failed\n"); + return; + } + if(pid){ + if(wait() != pid){ + printf(1, "wait wrong pid\n"); + return; + } + } else { + exit(); + } + } + printf(1, "exitwait ok\n"); +} + +void +mem(void) +{ + void *m1, *m2; + int pid, ppid; + + printf(1, "mem test\n"); + ppid = getpid(); + if((pid = fork()) == 0){ + m1 = 0; + while((m2 = malloc(10001)) != 0){ + *(char**)m2 = m1; + m1 = m2; + } + while(m1){ + m2 = *(char**)m1; + free(m1); + m1 = m2; + } + m1 = malloc(1024*20); + if(m1 == 0){ + printf(1, "couldn't allocate mem?!!\n"); + kill(ppid); + exit(); + } + free(m1); + printf(1, "mem ok\n"); + exit(); + } else { + wait(); + } +} + +// More file system tests + +// two processes write to the same file descriptor +// is the offset shared? does inode locking work? +void +sharedfd(void) +{ + int fd, pid, i, n, nc, np; + char buf[10]; + + printf(1, "sharedfd test\n"); + + unlink("sharedfd"); + fd = open("sharedfd", O_CREATE|O_RDWR); + if(fd < 0){ + printf(1, "fstests: cannot open sharedfd for writing"); + return; + } + pid = fork(); + memset(buf, pid==0?'c':'p', sizeof(buf)); + for(i = 0; i < 1000; i++){ + if(write(fd, buf, sizeof(buf)) != sizeof(buf)){ + printf(1, "fstests: write sharedfd failed\n"); + break; + } + } + if(pid == 0) + exit(); + else + wait(); + close(fd); + fd = open("sharedfd", 0); + if(fd < 0){ + printf(1, "fstests: cannot open sharedfd for reading\n"); + return; + } + nc = np = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + for(i = 0; i < sizeof(buf); i++){ + if(buf[i] == 'c') + nc++; + if(buf[i] == 'p') + np++; + } + } + close(fd); + unlink("sharedfd"); + if(nc == 10000 && np == 10000){ + printf(1, "sharedfd ok\n"); + } else { + printf(1, "sharedfd oops %d %d\n", nc, np); + exit(); + } +} + +// two processes write two different files at the same +// time, to test block allocation. +void +twofiles(void) +{ + int fd, pid, i, j, n, total; + char *fname; + + printf(1, "twofiles test\n"); + + unlink("f1"); + unlink("f2"); + + pid = fork(); + if(pid < 0){ + printf(1, "fork failed\n"); + exit(); + } + + fname = pid ? "f1" : "f2"; + fd = open(fname, O_CREATE | O_RDWR); + if(fd < 0){ + printf(1, "create failed\n"); + exit(); + } + + memset(buf, pid?'p':'c', 512); + for(i = 0; i < 12; i++){ + if((n = write(fd, buf, 500)) != 500){ + printf(1, "write failed %d\n", n); + exit(); + } + } + close(fd); + if(pid) + wait(); + else + exit(); + + for(i = 0; i < 2; i++){ + fd = open(i?"f1":"f2", 0); + total = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + for(j = 0; j < n; j++){ + if(buf[j] != (i?'p':'c')){ + printf(1, "wrong char\n"); + exit(); + } + } + total += n; + } + close(fd); + if(total != 12*500){ + printf(1, "wrong length %d\n", total); + exit(); + } + } + + unlink("f1"); + unlink("f2"); + + printf(1, "twofiles ok\n"); +} + +// two processes create and delete different files in same directory +void +createdelete(void) +{ + enum { N = 20 }; + int pid, i, fd; + char name[32]; + + printf(1, "createdelete test\n"); + pid = fork(); + if(pid < 0){ + printf(1, "fork failed\n"); + exit(); + } + + name[0] = pid ? 'p' : 'c'; + name[2] = '\0'; + for(i = 0; i < N; i++){ + name[1] = '0' + i; + fd = open(name, O_CREATE | O_RDWR); + if(fd < 0){ + printf(1, "create failed\n"); + exit(); + } + close(fd); + if(i > 0 && (i % 2 ) == 0){ + name[1] = '0' + (i / 2); + if(unlink(name) < 0){ + printf(1, "unlink failed\n"); + exit(); + } + } + } + + if(pid==0) + exit(); + else + wait(); + + for(i = 0; i < N; i++){ + name[0] = 'p'; + name[1] = '0' + i; + fd = open(name, 0); + if((i == 0 || i >= N/2) && fd < 0){ + printf(1, "oops createdelete %s didn't exist\n", name); + exit(); + } else if((i >= 1 && i < N/2) && fd >= 0){ + printf(1, "oops createdelete %s did exist\n", name); + exit(); + } + if(fd >= 0) + close(fd); + + name[0] = 'c'; + name[1] = '0' + i; + fd = open(name, 0); + if((i == 0 || i >= N/2) && fd < 0){ + printf(1, "oops createdelete %s didn't exist\n", name); + exit(); + } else if((i >= 1 && i < N/2) && fd >= 0){ + printf(1, "oops createdelete %s did exist\n", name); + exit(); + } + if(fd >= 0) + close(fd); + } + + for(i = 0; i < N; i++){ + name[0] = 'p'; + name[1] = '0' + i; + unlink(name); + name[0] = 'c'; + unlink(name); + } + + printf(1, "createdelete ok\n"); +} + +// can I unlink a file and still read it? +void +unlinkread(void) +{ + int fd, fd1; + + printf(1, "unlinkread test\n"); + fd = open("unlinkread", O_CREATE | O_RDWR); + if(fd < 0){ + printf(1, "create unlinkread failed\n"); + exit(); + } + write(fd, "hello", 5); + close(fd); + + fd = open("unlinkread", O_RDWR); + if(fd < 0){ + printf(1, "open unlinkread failed\n"); + exit(); + } + if(unlink("unlinkread") != 0){ + printf(1, "unlink unlinkread failed\n"); + exit(); + } + + fd1 = open("unlinkread", O_CREATE | O_RDWR); + write(fd1, "yyy", 3); + close(fd1); + + if(read(fd, buf, sizeof(buf)) != 5){ + printf(1, "unlinkread read failed"); + exit(); + } + if(buf[0] != 'h'){ + printf(1, "unlinkread wrong data\n"); + exit(); + } + if(write(fd, buf, 10) != 10){ + printf(1, "unlinkread write failed\n"); + exit(); + } + close(fd); + unlink("unlinkread"); + printf(1, "unlinkread ok\n"); +} + +void +linktest(void) +{ + int fd; + + printf(1, "linktest\n"); + + unlink("lf1"); + unlink("lf2"); + + fd = open("lf1", O_CREATE|O_RDWR); + if(fd < 0){ + printf(1, "create lf1 failed\n"); + exit(); + } + if(write(fd, "hello", 5) != 5){ + printf(1, "write lf1 failed\n"); + exit(); + } + close(fd); + + if(link("lf1", "lf2") < 0){ + printf(1, "link lf1 lf2 failed\n"); + exit(); + } + unlink("lf1"); + + if(open("lf1", 0) >= 0){ + printf(1, "unlinked lf1 but it is still there!\n"); + exit(); + } + + fd = open("lf2", 0); + if(fd < 0){ + printf(1, "open lf2 failed\n"); + exit(); + } + if(read(fd, buf, sizeof(buf)) != 5){ + printf(1, "read lf2 failed\n"); + exit(); + } + close(fd); + + if(link("lf2", "lf2") >= 0){ + printf(1, "link lf2 lf2 succeeded! oops\n"); + exit(); + } + + unlink("lf2"); + if(link("lf2", "lf1") >= 0){ + printf(1, "link non-existant succeeded! oops\n"); + exit(); + } + + if(link(".", "lf1") >= 0){ + printf(1, "link . lf1 succeeded! oops\n"); + exit(); + } + + printf(1, "linktest ok\n"); +} + +// test concurrent create/link/unlink of the same file +void +concreate(void) +{ + char file[3]; + int i, pid, n, fd; + char fa[40]; + struct { + ushort inum; + char name[14]; + } de; + + printf(1, "concreate test\n"); + file[0] = 'C'; + file[2] = '\0'; + for(i = 0; i < 40; i++){ + file[1] = '0' + i; + unlink(file); + pid = fork(); + if(pid && (i % 3) == 1){ + link("C0", file); + } else if(pid == 0 && (i % 5) == 1){ + link("C0", file); + } else { + fd = open(file, O_CREATE | O_RDWR); + if(fd < 0){ + printf(1, "concreate create %s failed\n", file); + exit(); + } + close(fd); + } + if(pid == 0) + exit(); + else + wait(); + } + + memset(fa, 0, sizeof(fa)); + fd = open(".", 0); + n = 0; + while(read(fd, &de, sizeof(de)) > 0){ + if(de.inum == 0) + continue; + if(de.name[0] == 'C' && de.name[2] == '\0'){ + i = de.name[1] - '0'; + if(i < 0 || i >= sizeof(fa)){ + printf(1, "concreate weird file %s\n", de.name); + exit(); + } + if(fa[i]){ + printf(1, "concreate duplicate file %s\n", de.name); + exit(); + } + fa[i] = 1; + n++; + } + } + close(fd); + + if(n != 40){ + printf(1, "concreate not enough files in directory listing\n"); + exit(); + } + + for(i = 0; i < 40; i++){ + file[1] = '0' + i; + pid = fork(); + if(pid < 0){ + printf(1, "fork failed\n"); + exit(); + } + if(((i % 3) == 0 && pid == 0) || + ((i % 3) == 1 && pid != 0)){ + close(open(file, 0)); + close(open(file, 0)); + close(open(file, 0)); + close(open(file, 0)); + } else { + unlink(file); + unlink(file); + unlink(file); + unlink(file); + } + if(pid == 0) + exit(); + else + wait(); + } + + printf(1, "concreate ok\n"); +} + +// another concurrent link/unlink/create test, +// to look for deadlocks. +void +linkunlink() +{ + int pid, i; + + printf(1, "linkunlink test\n"); + + unlink("x"); + pid = fork(); + if(pid < 0){ + printf(1, "fork failed\n"); + exit(); + } + + unsigned int x = (pid ? 1 : 97); + for(i = 0; i < 100; i++){ + x = x * 1103515245 + 12345; + if((x % 3) == 0){ + close(open("x", O_RDWR | O_CREATE)); + } else if((x % 3) == 1){ + link("cat", "x"); + } else { + unlink("x"); + } + } + + if(pid) + wait(); + else + exit(); + + printf(1, "linkunlink ok\n"); +} + +// directory that uses indirect blocks +void +bigdir(void) +{ + int i, fd; + char name[10]; + + printf(1, "bigdir test\n"); + unlink("bd"); + + fd = open("bd", O_CREATE); + if(fd < 0){ + printf(1, "bigdir create failed\n"); + exit(); + } + close(fd); + + for(i = 0; i < 500; i++){ + name[0] = 'x'; + name[1] = '0' + (i / 64); + name[2] = '0' + (i % 64); + name[3] = '\0'; + if(link("bd", name) != 0){ + printf(1, "bigdir link failed\n"); + exit(); + } + } + + unlink("bd"); + for(i = 0; i < 500; i++){ + name[0] = 'x'; + name[1] = '0' + (i / 64); + name[2] = '0' + (i % 64); + name[3] = '\0'; + if(unlink(name) != 0){ + printf(1, "bigdir unlink failed"); + exit(); + } + } + + printf(1, "bigdir ok\n"); +} + +void +subdir(void) +{ + int fd, cc; + + printf(1, "subdir test\n"); + + unlink("ff"); + if(mkdir("dd") != 0){ + printf(1, "subdir mkdir dd failed\n"); + exit(); + } + + fd = open("dd/ff", O_CREATE | O_RDWR); + if(fd < 0){ + printf(1, "create dd/ff failed\n"); + exit(); + } + write(fd, "ff", 2); + close(fd); + + if(unlink("dd") >= 0){ + printf(1, "unlink dd (non-empty dir) succeeded!\n"); + exit(); + } + + if(mkdir("/dd/dd") != 0){ + printf(1, "subdir mkdir dd/dd failed\n"); + exit(); + } + + fd = open("dd/dd/ff", O_CREATE | O_RDWR); + if(fd < 0){ + printf(1, "create dd/dd/ff failed\n"); + exit(); + } + write(fd, "FF", 2); + close(fd); + + fd = open("dd/dd/../ff", 0); + if(fd < 0){ + printf(1, "open dd/dd/../ff failed\n"); + exit(); + } + cc = read(fd, buf, sizeof(buf)); + if(cc != 2 || buf[0] != 'f'){ + printf(1, "dd/dd/../ff wrong content\n"); + exit(); + } + close(fd); + + if(link("dd/dd/ff", "dd/dd/ffff") != 0){ + printf(1, "link dd/dd/ff dd/dd/ffff failed\n"); + exit(); + } + + if(unlink("dd/dd/ff") != 0){ + printf(1, "unlink dd/dd/ff failed\n"); + exit(); + } + if(open("dd/dd/ff", O_RDONLY) >= 0){ + printf(1, "open (unlinked) dd/dd/ff succeeded\n"); + exit(); + } + + if(chdir("dd") != 0){ + printf(1, "chdir dd failed\n"); + exit(); + } + if(chdir("dd/../../dd") != 0){ + printf(1, "chdir dd/../../dd failed\n"); + exit(); + } + if(chdir("dd/../../../dd") != 0){ + printf(1, "chdir dd/../../dd failed\n"); + exit(); + } + if(chdir("./..") != 0){ + printf(1, "chdir ./.. failed\n"); + exit(); + } + + fd = open("dd/dd/ffff", 0); + if(fd < 0){ + printf(1, "open dd/dd/ffff failed\n"); + exit(); + } + if(read(fd, buf, sizeof(buf)) != 2){ + printf(1, "read dd/dd/ffff wrong len\n"); + exit(); + } + close(fd); + + if(open("dd/dd/ff", O_RDONLY) >= 0){ + printf(1, "open (unlinked) dd/dd/ff succeeded!\n"); + exit(); + } + + if(open("dd/ff/ff", O_CREATE|O_RDWR) >= 0){ + printf(1, "create dd/ff/ff succeeded!\n"); + exit(); + } + if(open("dd/xx/ff", O_CREATE|O_RDWR) >= 0){ + printf(1, "create dd/xx/ff succeeded!\n"); + exit(); + } + if(open("dd", O_CREATE) >= 0){ + printf(1, "create dd succeeded!\n"); + exit(); + } + if(open("dd", O_RDWR) >= 0){ + printf(1, "open dd rdwr succeeded!\n"); + exit(); + } + if(open("dd", O_WRONLY) >= 0){ + printf(1, "open dd wronly succeeded!\n"); + exit(); + } + if(link("dd/ff/ff", "dd/dd/xx") == 0){ + printf(1, "link dd/ff/ff dd/dd/xx succeeded!\n"); + exit(); + } + if(link("dd/xx/ff", "dd/dd/xx") == 0){ + printf(1, "link dd/xx/ff dd/dd/xx succeeded!\n"); + exit(); + } + if(link("dd/ff", "dd/dd/ffff") == 0){ + printf(1, "link dd/ff dd/dd/ffff succeeded!\n"); + exit(); + } + if(mkdir("dd/ff/ff") == 0){ + printf(1, "mkdir dd/ff/ff succeeded!\n"); + exit(); + } + if(mkdir("dd/xx/ff") == 0){ + printf(1, "mkdir dd/xx/ff succeeded!\n"); + exit(); + } + if(mkdir("dd/dd/ffff") == 0){ + printf(1, "mkdir dd/dd/ffff succeeded!\n"); + exit(); + } + if(unlink("dd/xx/ff") == 0){ + printf(1, "unlink dd/xx/ff succeeded!\n"); + exit(); + } + if(unlink("dd/ff/ff") == 0){ + printf(1, "unlink dd/ff/ff succeeded!\n"); + exit(); + } + if(chdir("dd/ff") == 0){ + printf(1, "chdir dd/ff succeeded!\n"); + exit(); + } + if(chdir("dd/xx") == 0){ + printf(1, "chdir dd/xx succeeded!\n"); + exit(); + } + + if(unlink("dd/dd/ffff") != 0){ + printf(1, "unlink dd/dd/ff failed\n"); + exit(); + } + if(unlink("dd/ff") != 0){ + printf(1, "unlink dd/ff failed\n"); + exit(); + } + if(unlink("dd") == 0){ + printf(1, "unlink non-empty dd succeeded!\n"); + exit(); + } + if(unlink("dd/dd") < 0){ + printf(1, "unlink dd/dd failed\n"); + exit(); + } + if(unlink("dd") < 0){ + printf(1, "unlink dd failed\n"); + exit(); + } + + printf(1, "subdir ok\n"); +} + +// test writes that are larger than the log. +void +bigwrite(void) +{ + int fd, sz; + + printf(1, "bigwrite test\n"); + + unlink("bigwrite"); + for(sz = 499; sz < 12*512; sz += 471){ + fd = open("bigwrite", O_CREATE | O_RDWR); + if(fd < 0){ + printf(1, "cannot create bigwrite\n"); + exit(); + } + int i; + for(i = 0; i < 2; i++){ + int cc = write(fd, buf, sz); + if(cc != sz){ + printf(1, "write(%d) ret %d\n", sz, cc); + exit(); + } + } + close(fd); + unlink("bigwrite"); + } + + printf(1, "bigwrite ok\n"); +} + +void +bigfile(void) +{ + int fd, i, total, cc; + + printf(1, "bigfile test\n"); + + unlink("bigfile"); + fd = open("bigfile", O_CREATE | O_RDWR); + if(fd < 0){ + printf(1, "cannot create bigfile"); + exit(); + } + for(i = 0; i < 20; i++){ + memset(buf, i, 600); + if(write(fd, buf, 600) != 600){ + printf(1, "write bigfile failed\n"); + exit(); + } + } + close(fd); + + fd = open("bigfile", 0); + if(fd < 0){ + printf(1, "cannot open bigfile\n"); + exit(); + } + total = 0; + for(i = 0; ; i++){ + cc = read(fd, buf, 300); + if(cc < 0){ + printf(1, "read bigfile failed\n"); + exit(); + } + if(cc == 0) + break; + if(cc != 300){ + printf(1, "short read bigfile\n"); + exit(); + } + if(buf[0] != i/2 || buf[299] != i/2){ + printf(1, "read bigfile wrong data\n"); + exit(); + } + total += cc; + } + close(fd); + if(total != 20*600){ + printf(1, "read bigfile wrong total\n"); + exit(); + } + unlink("bigfile"); + + printf(1, "bigfile test ok\n"); +} + +void +fourteen(void) +{ + int fd; + + // DIRSIZ is 14. + printf(1, "fourteen test\n"); + + if(mkdir("12345678901234") != 0){ + printf(1, "mkdir 12345678901234 failed\n"); + exit(); + } + if(mkdir("12345678901234/123456789012345") != 0){ + printf(1, "mkdir 12345678901234/123456789012345 failed\n"); + exit(); + } + fd = open("123456789012345/123456789012345/123456789012345", O_CREATE); + if(fd < 0){ + printf(1, "create 123456789012345/123456789012345/123456789012345 failed\n"); + exit(); + } + close(fd); + fd = open("12345678901234/12345678901234/12345678901234", 0); + if(fd < 0){ + printf(1, "open 12345678901234/12345678901234/12345678901234 failed\n"); + exit(); + } + close(fd); + + if(mkdir("12345678901234/12345678901234") == 0){ + printf(1, "mkdir 12345678901234/12345678901234 succeeded!\n"); + exit(); + } + if(mkdir("123456789012345/12345678901234") == 0){ + printf(1, "mkdir 12345678901234/123456789012345 succeeded!\n"); + exit(); + } + + printf(1, "fourteen ok\n"); +} + +void +rmdot(void) +{ + printf(1, "rmdot test\n"); + if(mkdir("dots") != 0){ + printf(1, "mkdir dots failed\n"); + exit(); + } + if(chdir("dots") != 0){ + printf(1, "chdir dots failed\n"); + exit(); + } + if(unlink(".") == 0){ + printf(1, "rm . worked!\n"); + exit(); + } + if(unlink("..") == 0){ + printf(1, "rm .. worked!\n"); + exit(); + } + if(chdir("/") != 0){ + printf(1, "chdir / failed\n"); + exit(); + } + if(unlink("dots/.") == 0){ + printf(1, "unlink dots/. worked!\n"); + exit(); + } + if(unlink("dots/..") == 0){ + printf(1, "unlink dots/.. worked!\n"); + exit(); + } + if(unlink("dots") != 0){ + printf(1, "unlink dots failed!\n"); + exit(); + } + printf(1, "rmdot ok\n"); +} + +void +dirfile(void) +{ + int fd; + + printf(1, "dir vs file\n"); + + fd = open("dirfile", O_CREATE); + if(fd < 0){ + printf(1, "create dirfile failed\n"); + exit(); + } + close(fd); + if(chdir("dirfile") == 0){ + printf(1, "chdir dirfile succeeded!\n"); + exit(); + } + fd = open("dirfile/xx", 0); + if(fd >= 0){ + printf(1, "create dirfile/xx succeeded!\n"); + exit(); + } + fd = open("dirfile/xx", O_CREATE); + if(fd >= 0){ + printf(1, "create dirfile/xx succeeded!\n"); + exit(); + } + if(mkdir("dirfile/xx") == 0){ + printf(1, "mkdir dirfile/xx succeeded!\n"); + exit(); + } + if(unlink("dirfile/xx") == 0){ + printf(1, "unlink dirfile/xx succeeded!\n"); + exit(); + } + if(link("README", "dirfile/xx") == 0){ + printf(1, "link to dirfile/xx succeeded!\n"); + exit(); + } + if(unlink("dirfile") != 0){ + printf(1, "unlink dirfile failed!\n"); + exit(); + } + + fd = open(".", O_RDWR); + if(fd >= 0){ + printf(1, "open . for writing succeeded!\n"); + exit(); + } + fd = open(".", 0); + if(write(fd, "x", 1) > 0){ + printf(1, "write . succeeded!\n"); + exit(); + } + close(fd); + + printf(1, "dir vs file OK\n"); +} + +// test that iput() is called at the end of _namei() +void +iref(void) +{ + int i, fd; + + printf(1, "empty file name\n"); + + // the 50 is NINODE + for(i = 0; i < 50 + 1; i++){ + if(mkdir("irefd") != 0){ + printf(1, "mkdir irefd failed\n"); + exit(); + } + if(chdir("irefd") != 0){ + printf(1, "chdir irefd failed\n"); + exit(); + } + + mkdir(""); + link("README", ""); + fd = open("", O_CREATE); + if(fd >= 0) + close(fd); + fd = open("xx", O_CREATE); + if(fd >= 0) + close(fd); + unlink("xx"); + } + + chdir("/"); + printf(1, "empty file name OK\n"); +} + +// test that fork fails gracefully +// the forktest binary also does this, but it runs out of proc entries first. +// inside the bigger usertests binary, we run out of memory first. +void +forktest(void) +{ + int n, pid; + + printf(1, "fork test\n"); + + for(n=0; n<1000; n++){ + pid = fork(); + if(pid < 0) + break; + if(pid == 0) + exit(); + } + + if(n == 1000){ + printf(1, "fork claimed to work 1000 times!\n"); + exit(); + } + + for(; n > 0; n--){ + if(wait() < 0){ + printf(1, "wait stopped early\n"); + exit(); + } + } + + if(wait() != -1){ + printf(1, "wait got too many\n"); + exit(); + } + + printf(1, "fork test OK\n"); +} + +void +sbrktest(void) +{ + int fds[2], pid, pids[10], ppid; + char *a, *b, *c, *lastaddr, *oldbrk, *p, scratch; + uint amt; + + printf(stdout, "sbrk test\n"); + oldbrk = sbrk(0); + + // can one sbrk() less than a page? + a = sbrk(0); + int i; + for(i = 0; i < 5000; i++){ + b = sbrk(1); + if(b != a){ + printf(stdout, "sbrk test failed %d %x %x\n", i, a, b); + exit(); + } + *b = 1; + a = b + 1; + } + pid = fork(); + if(pid < 0){ + printf(stdout, "sbrk test fork failed\n"); + exit(); + } + c = sbrk(1); + c = sbrk(1); + if(c != a + 1){ + printf(stdout, "sbrk test failed post-fork\n"); + exit(); + } + if(pid == 0) + exit(); + wait(); + + // can one grow address space to something big? +#define BIG (100*1024*1024) + a = sbrk(0); + amt = (BIG) - (uint)a; + p = sbrk(amt); + if (p != a) { + printf(stdout, "sbrk test failed to grow big address space; enough phys mem?\n"); + exit(); + } + lastaddr = (char*) (BIG-1); + *lastaddr = 99; + + // can one de-allocate? + a = sbrk(0); + c = sbrk(-4096); + if(c == (char*)0xffffffff){ + printf(stdout, "sbrk could not deallocate\n"); + exit(); + } + c = sbrk(0); + if(c != a - 4096){ + printf(stdout, "sbrk deallocation produced wrong address, a %x c %x\n", a, c); + exit(); + } + + // can one re-allocate that page? + a = sbrk(0); + c = sbrk(4096); + if(c != a || sbrk(0) != a + 4096){ + printf(stdout, "sbrk re-allocation failed, a %x c %x\n", a, c); + exit(); + } + if(*lastaddr == 99){ + // should be zero + printf(stdout, "sbrk de-allocation didn't really deallocate\n"); + exit(); + } + + a = sbrk(0); + c = sbrk(-(sbrk(0) - oldbrk)); + if(c != a){ + printf(stdout, "sbrk downsize failed, a %x c %x\n", a, c); + exit(); + } + + // can we read the kernel's memory? + for(a = (char*)(KERNBASE); a < (char*) (KERNBASE+2000000); a += 50000){ + ppid = getpid(); + pid = fork(); + if(pid < 0){ + printf(stdout, "fork failed\n"); + exit(); + } + if(pid == 0){ + printf(stdout, "oops could read %x = %x\n", a, *a); + kill(ppid); + exit(); + } + wait(); + } + + // if we run the system out of memory, does it clean up the last + // failed allocation? + if(pipe(fds) != 0){ + printf(1, "pipe() failed\n"); + exit(); + } + + for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){ + if((pids[i] = fork()) == 0){ + // allocate a lot of memory + sbrk(BIG - (uint)sbrk(0)); + write(fds[1], "x", 1); + // sit around until killed + for(;;) sleep(1000); + } + if(pids[i] != -1) + read(fds[0], &scratch, 1); + } + // if those failed allocations freed up the pages they did allocate, + // we'll be able to allocate here + c = sbrk(4096); + for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){ + if(pids[i] == -1) + continue; + kill(pids[i]); + wait(); + } + if(c == (char*)0xffffffff){ + printf(stdout, "failed sbrk leaked memory\n"); + exit(); + } + + if(sbrk(0) > oldbrk) + sbrk(-(sbrk(0) - oldbrk)); + + printf(stdout, "sbrk test OK\n"); +} + +void +validateint(int *p) +{ + sleep(*p); +} + +void +validatetest(void) +{ + int hi, pid; + uint p; + + printf(stdout, "validate test\n"); + hi = 1100*1024; + + for(p = 0; p <= (uint)hi; p += 4096){ + if((pid = fork()) == 0){ + // try to crash the kernel by passing in a badly placed integer + validateint((int*)p); + exit(); + } + sleep(0); + sleep(0); + kill(pid); + wait(); + + // try to crash the kernel by passing in a bad string pointer + if(link("nosuchfile", (char*)p) != -1){ + printf(stdout, "link should not succeed\n"); + exit(); + } + } + + printf(stdout, "validate ok\n"); +} + +// does unintialized data start out zero? +char uninit[10000]; +void +bsstest(void) +{ + int i; + + printf(stdout, "bss test\n"); + for(i = 0; i < sizeof(uninit); i++){ + if(uninit[i] != '\0'){ + printf(stdout, "bss test failed\n"); + exit(); + } + } + printf(stdout, "bss test ok\n"); +} + +// does exec return an error if the arguments +// are larger than a page? or does it write +// below the stack and wreck the instructions/data? +void +bigargtest(void) +{ + int pid, fd; + + unlink("bigarg-ok"); + pid = fork(); + if(pid == 0){ + static char *args[MAXARG]; + int i; + for(i = 0; i < MAXARG-1; i++) + args[i] = "bigargs test: failed\n "; + args[MAXARG-1] = 0; + printf(stdout, "bigarg test\n"); + exec("echo", args); + printf(stdout, "bigarg test ok\n"); + fd = open("bigarg-ok", O_CREATE); + close(fd); + exit(); + } else if(pid < 0){ + printf(stdout, "bigargtest: fork failed\n"); + exit(); + } + wait(); + fd = open("bigarg-ok", 0); + if(fd < 0){ + printf(stdout, "bigarg test failed!\n"); + exit(); + } + close(fd); + unlink("bigarg-ok"); +} + +// what happens when the file system runs out of blocks? +// answer: balloc panics, so this test is not useful. +void +fsfull() +{ + int nfiles; + int fsblocks = 0; + + printf(1, "fsfull test\n"); + + for(nfiles = 0; ; nfiles++){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + name[3] = '0' + (nfiles % 100) / 10; + name[4] = '0' + (nfiles % 10); + name[5] = '\0'; + printf(1, "writing %s\n", name); + int fd = open(name, O_CREATE|O_RDWR); + if(fd < 0){ + printf(1, "open %s failed\n", name); + break; + } + int total = 0; + while(1){ + int cc = write(fd, buf, 512); + if(cc < 512) + break; + total += cc; + fsblocks++; + } + printf(1, "wrote %d bytes\n", total); + close(fd); + if(total == 0) + break; + } + + while(nfiles >= 0){ + char name[64]; + name[0] = 'f'; + name[1] = '0' + nfiles / 1000; + name[2] = '0' + (nfiles % 1000) / 100; + name[3] = '0' + (nfiles % 100) / 10; + name[4] = '0' + (nfiles % 10); + name[5] = '\0'; + unlink(name); + nfiles--; + } + + printf(1, "fsfull test finished\n"); +} + +unsigned long randstate = 1; +unsigned int +rand() +{ + randstate = randstate * 1664525 + 1013904223; + return randstate; +} + +int +main(int argc, char *argv[]) +{ + printf(1, "usertests starting\n"); + + if(open("usertests.ran", 0) >= 0){ + printf(1, "already ran user tests -- rebuild fs.img\n"); + exit(); + } + close(open("usertests.ran", O_CREATE)); + + bigargtest(); + bigwrite(); + bigargtest(); + bsstest(); + sbrktest(); + validatetest(); + + opentest(); + writetest(); + writetest1(); + createtest(); + + mem(); + pipe1(); + preempt(); + exitwait(); + + rmdot(); + fourteen(); + bigfile(); + subdir(); + concreate(); + linkunlink(); + linktest(); + unlinkread(); + createdelete(); + twofiles(); + sharedfd(); + dirfile(); + iref(); + forktest(); + bigdir(); // slow + + exectest(); + + exit(); +} diff -r 000000000000 -r c450faca55f4 uprogs/usertests.sym --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/usertests.sym Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,105 @@ +00000000 .text +00003a2c .rodata +00005244 .data +00005260 .bss +00000000 .comment +00000000 .ARM.attributes +00000000 .debug_aranges +00000000 .debug_info +00000000 .debug_abbrev +00000000 .debug_line +00000000 .debug_frame +00000000 .debug_str +00000000 .debug_loc +00000000 .debug_ranges +00000000 usertests.c +00005260 args.1316 +00000000 ulib.c +00000000 printf.c +00003608 putc +00003630 printint +00005228 digits.993 +00000000 umalloc.c +000052e0 freep +000052e4 base +00002f58 strcpy +0000091c exitwait +00003744 printf +00005244 stdout +00002c18 bigargtest +00003190 memmove +000033cc mknod +00009a00 _bss_end__ +00003088 gets +00003538 getpid +00000650 pipe1 +00002590 iref +00003940 malloc +000035a0 sleep +00005260 __bss_start__ +00002d10 fsfull +00001774 bigdir +00002678 forktest +00000304 writetest1 +00001eb4 bigwrite +00000a4c sharedfd +0000525c randstate +00003260 pipe +000052ec uninit +000023c8 dirfile +000032c8 write +00002ba0 bsstest +00005248 echoargv +00003434 fstat +00003330 kill +00002afc validatetest +00002268 rmdot +000034d0 chdir +00000604 exectest +00003364 exec +00009a00 __bss_end__ +0000322c wait +00002f20 rand +00003294 read +000007ec preempt +00003400 unlink +00000990 mem +000031c4 fork +0000356c sbrk +000035d4 uptime +00005260 __bss_start +0000300c memset +00000494 createtest +00000000 main +00000dc4 createdelete +00009a00 __end__ +00002f80 strcmp +0000015c writetest +00003504 dup +00002728 sbrktest +000000d0 opentest +000018a4 subdir +00000be8 twofiles +00001188 linktest +000079fc buf +00000540 dirtest +00003100 stat +00001f98 bigfile +00005260 _edata +00009a00 _end +00001010 unlinkread +00003468 link +000031f8 exit +0000313c atoi +00001684 linkunlink +000099fc name +00002fcc strlen +00003398 open +000036fc div +00003044 strchr +00001360 concreate +00002140 fourteen +00002ae4 validateint +0000349c mkdir +000032fc close +0000389c free diff -r 000000000000 -r c450faca55f4 uprogs/usys.S --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/usys.S Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,374 @@ +/***************************************************************** +* usys.S +* by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + + +#include "syscall.h" +#include "traps.h" + +/* This is clumsy, but don't know how to make it smart */ +.globl fork +fork: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_fork + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl exit +exit: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_exit + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl wait +wait: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_wait + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl pipe +pipe: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_pipe + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl read +read: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_read + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl write +write: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_write + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl close +close: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_close + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + + +.globl kill +kill: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_kill + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl exec +exec: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_exec + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl open +open: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_open + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl mknod +mknod: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_mknod + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl unlink +unlink: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_unlink + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl fstat +fstat: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_fstat + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl link +link: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_link + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl mkdir +mkdir: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_mkdir + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl chdir +chdir: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_chdir + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl dup +dup: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_dup + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl getpid +getpid: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_getpid + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl sbrk +sbrk: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_sbrk + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl sleep +sleep: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_sleep + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + +.globl uptime +uptime: + push {lr} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_uptime + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {lr} + bx lr + + +/* +SYSCALL(fork) +SYSCALL(exit) +SYSCALL(wait) +SYSCALL(pipe) +SYSCALL(read) +SYSCALL(write) +SYSCALL(close) +SYSCALL(kill) +SYSCALL(exec) +SYSCALL(open) +SYSCALL(mknod) +SYSCALL(unlink) +SYSCALL(fstat) +SYSCALL(link) +SYSCALL(mkdir) +SYSCALL(chdir) +SYSCALL(dup) +SYSCALL(getpid) +SYSCALL(sbrk) +SYSCALL(sleep) +SYSCALL(uptime) +*/ diff -r 000000000000 -r c450faca55f4 uprogs/usys.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/usys.asm Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,193 @@ + +usys.o: file format elf32-littlearm + + +Disassembly of section .text: + +00000000 : + 0: e92d5fff push {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, lr} + 4: e3a00001 mov r0, #1 + 8: ef000040 svc 0x00000040 + c: e8bd1ffe pop {r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip} + 10: e8bd0002 pop {r1} + 14: e12fff1e bx lr + +00000018 : + 18: e92d1000 push {ip} + 1c: e3a0c002 mov ip, #2 + 20: e92d4000 push {lr} + 24: ef000040 svc 0x00000040 + 28: e8bd4000 pop {lr} + 2c: e8bd1000 pop {ip} + 30: e12fff1e bx lr + +00000034 : + 34: e92d1000 push {ip} + 38: e3a0c003 mov ip, #3 + 3c: e92d4000 push {lr} + 40: ef000040 svc 0x00000040 + 44: e8bd4000 pop {lr} + 48: e8bd1000 pop {ip} + 4c: e12fff1e bx lr + +00000050 : + 50: e92d1000 push {ip} + 54: e3a0c004 mov ip, #4 + 58: e92d4000 push {lr} + 5c: ef000040 svc 0x00000040 + 60: e8bd4000 pop {lr} + 64: e8bd1000 pop {ip} + 68: e12fff1e bx lr + +0000006c : + 6c: e92d1000 push {ip} + 70: e3a0c005 mov ip, #5 + 74: e92d4000 push {lr} + 78: ef000040 svc 0x00000040 + 7c: e8bd4000 pop {lr} + 80: e8bd1000 pop {ip} + 84: e12fff1e bx lr + +00000088 : + 88: e92d1000 push {ip} + 8c: e3a0c010 mov ip, #16 + 90: e92d4000 push {lr} + 94: ef000040 svc 0x00000040 + 98: e8bd4000 pop {lr} + 9c: e8bd1000 pop {ip} + a0: e12fff1e bx lr + +000000a4 : + a4: e92d1000 push {ip} + a8: e3a0c015 mov ip, #21 + ac: e92d4000 push {lr} + b0: ef000040 svc 0x00000040 + b4: e8bd4000 pop {lr} + b8: e8bd1000 pop {ip} + bc: e12fff1e bx lr + +000000c0 : + c0: e92d1000 push {ip} + c4: e3a0c006 mov ip, #6 + c8: e92d4000 push {lr} + cc: ef000040 svc 0x00000040 + d0: e8bd4000 pop {lr} + d4: e8bd1000 pop {ip} + d8: e12fff1e bx lr + +000000dc : + dc: e92d1000 push {ip} + e0: e3a0c007 mov ip, #7 + e4: e92d4000 push {lr} + e8: ef000040 svc 0x00000040 + ec: e8bd4000 pop {lr} + f0: e8bd1000 pop {ip} + f4: e12fff1e bx lr + +000000f8 : + f8: e92d1000 push {ip} + fc: e3a0c00f mov ip, #15 + 100: e92d4000 push {lr} + 104: ef000040 svc 0x00000040 + 108: e8bd4000 pop {lr} + 10c: e8bd1000 pop {ip} + 110: e12fff1e bx lr + +00000114 : + 114: e92d1000 push {ip} + 118: e3a0c011 mov ip, #17 + 11c: e92d4000 push {lr} + 120: ef000040 svc 0x00000040 + 124: e8bd4000 pop {lr} + 128: e8bd1000 pop {ip} + 12c: e12fff1e bx lr + +00000130 : + 130: e92d1000 push {ip} + 134: e3a0c012 mov ip, #18 + 138: e92d4000 push {lr} + 13c: ef000040 svc 0x00000040 + 140: e8bd4000 pop {lr} + 144: e8bd1000 pop {ip} + 148: e12fff1e bx lr + +0000014c : + 14c: e92d1000 push {ip} + 150: e3a0c008 mov ip, #8 + 154: e92d4000 push {lr} + 158: ef000040 svc 0x00000040 + 15c: e8bd4000 pop {lr} + 160: e8bd1000 pop {ip} + 164: e12fff1e bx lr + +00000168 : + 168: e92d1000 push {ip} + 16c: e3a0c013 mov ip, #19 + 170: e92d4000 push {lr} + 174: ef000040 svc 0x00000040 + 178: e8bd4000 pop {lr} + 17c: e8bd1000 pop {ip} + 180: e12fff1e bx lr + +00000184 : + 184: e92d1000 push {ip} + 188: e3a0c014 mov ip, #20 + 18c: e92d4000 push {lr} + 190: ef000040 svc 0x00000040 + 194: e8bd4000 pop {lr} + 198: e8bd1000 pop {ip} + 19c: e12fff1e bx lr + +000001a0 : + 1a0: e92d1000 push {ip} + 1a4: e3a0c009 mov ip, #9 + 1a8: e92d4000 push {lr} + 1ac: ef000040 svc 0x00000040 + 1b0: e8bd4000 pop {lr} + 1b4: e8bd1000 pop {ip} + 1b8: e12fff1e bx lr + +000001bc : + 1bc: e92d1000 push {ip} + 1c0: e3a0c00a mov ip, #10 + 1c4: e92d4000 push {lr} + 1c8: ef000040 svc 0x00000040 + 1cc: e8bd4000 pop {lr} + 1d0: e8bd1000 pop {ip} + 1d4: e12fff1e bx lr + +000001d8 : + 1d8: e92d1000 push {ip} + 1dc: e3a0c00b mov ip, #11 + 1e0: e92d4000 push {lr} + 1e4: ef000040 svc 0x00000040 + 1e8: e8bd4000 pop {lr} + 1ec: e8bd1000 pop {ip} + 1f0: e12fff1e bx lr + +000001f4 : + 1f4: e92d1000 push {ip} + 1f8: e3a0c00c mov ip, #12 + 1fc: e92d4000 push {lr} + 200: ef000040 svc 0x00000040 + 204: e8bd4000 pop {lr} + 208: e8bd1000 pop {ip} + 20c: e12fff1e bx lr + +00000210 : + 210: e92d1000 push {ip} + 214: e3a0c00d mov ip, #13 + 218: e92d4000 push {lr} + 21c: ef000040 svc 0x00000040 + 220: e8bd4000 pop {lr} + 224: e8bd1000 pop {ip} + 228: e12fff1e bx lr + +0000022c : + 22c: e92d1000 push {ip} + 230: e3a0c00e mov ip, #14 + 234: e92d4000 push {lr} + 238: ef000040 svc 0x00000040 + 23c: e8bd4000 pop {lr} + 240: e8bd1000 pop {ip} + 244: e12fff1e bx lr diff -r 000000000000 -r c450faca55f4 uprogs/usys_old.S --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/usys_old.S Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,743 @@ +#include "syscall.h" +#include "traps.h" + +/* This is clumsy, but don't know how to make it smart */ +.globl fork +fork: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_fork + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl exit +exit: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_exit + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl wait +wait: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_wait + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl pipe +pipe: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_pipe + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl read +read: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_read + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl write +write: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_write + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl close +close: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_close + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + + +.globl kill +kill: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_kill + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl exec +exec: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_exec + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl open +open: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_open + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl mknod +mknod: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_mknod + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl unlink +unlink: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_unlink + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl fstat +fstat: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_fstat + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl link +link: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_link + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl mkdir +mkdir: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_mkdir + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl chdir +chdir: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_chdir + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl dup +dup: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_dup + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl getpid +getpid: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_getpid + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl sbrk +sbrk: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_sbrk + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl sleep +sleep: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_sleep + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + +.globl uptime +uptime: + push {lr} + push {r12} + push {r11} + push {r10} + push {r9} + push {r8} + push {r7} + push {r6} + push {r5} + push {r4} + push {r3} + push {r2} + push {r1} + push {r0} + mov r0, #SYS_uptime + swi #T_SYSCALL + pop {r1} /* to avoid overwrite of r0 */ + pop {r1} + pop {r2} + pop {r3} + pop {r4} + pop {r5} + pop {r6} + pop {r7} + pop {r8} + pop {r9} + pop {r10} + pop {r11} + pop {r12} + pop {lr} + bx lr + + +/* +SYSCALL(fork) +SYSCALL(exit) +SYSCALL(wait) +SYSCALL(pipe) +SYSCALL(read) +SYSCALL(write) +SYSCALL(close) +SYSCALL(kill) +SYSCALL(exec) +SYSCALL(open) +SYSCALL(mknod) +SYSCALL(unlink) +SYSCALL(fstat) +SYSCALL(link) +SYSCALL(mkdir) +SYSCALL(chdir) +SYSCALL(dup) +SYSCALL(getpid) +SYSCALL(sbrk) +SYSCALL(sleep) +SYSCALL(uptime) +*/ diff -r 000000000000 -r c450faca55f4 uprogs/wc.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/wc.asm Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,1904 @@ + +_wc: file format elf32-littlearm + + +Disassembly of section .text: + +00000000
: +int +main(int argc, char *argv[]) +{ + int fd, i; + + if(argc <= 1){ + 0: e3500001 cmp r0, #1 + printf(1, "%d %d %d %s\n", l, w, c, name); +} + +int +main(int argc, char *argv[]) +{ + 4: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + 8: e1a08000 mov r8, r0 + c: e28db01c add fp, sp, #28 + } + printf(1, "%d %d %d %s\n", l, w, c, name); +} + +int +main(int argc, char *argv[]) + 10: c2814004 addgt r4, r1, #4 + 14: c3a05001 movgt r5, #1 +{ + int fd, i; + + if(argc <= 1){ + 18: da000013 ble 6c + wc(0, ""); + exit(); + } + + for(i = 1; i < argc; i++){ + if((fd = open(argv[i], 0)) < 0){ + 1c: e5940000 ldr r0, [r4] + 20: e3a01000 mov r1, #0 + 24: eb000164 bl 5bc + 28: e1a06004 mov r6, r4 + 2c: e2844004 add r4, r4, #4 + 30: e2507000 subs r7, r0, #0 + 34: ba000007 blt 58 + printf(1, "wc: cannot open %s\n", argv[i]); + exit(); + } + wc(fd, argv[i]); + 38: e5141004 ldr r1, [r4, #-4] + 3c: eb000010 bl 84 + if(argc <= 1){ + wc(0, ""); + exit(); + } + + for(i = 1; i < argc; i++){ + 40: e2855001 add r5, r5, #1 + if((fd = open(argv[i], 0)) < 0){ + printf(1, "wc: cannot open %s\n", argv[i]); + exit(); + } + wc(fd, argv[i]); + close(fd); + 44: e1a00007 mov r0, r7 + 48: eb000134 bl 520 + if(argc <= 1){ + wc(0, ""); + exit(); + } + + for(i = 1; i < argc; i++){ + 4c: e1550008 cmp r5, r8 + 50: 1afffff1 bne 1c + exit(); + } + wc(fd, argv[i]); + close(fd); + } + exit(); + 54: eb0000f0 bl 41c + exit(); + } + + for(i = 1; i < argc; i++){ + if((fd = open(argv[i], 0)) < 0){ + printf(1, "wc: cannot open %s\n", argv[i]); + 58: e3a00001 mov r0, #1 + 5c: e59f1018 ldr r1, [pc, #24] ; 7c + 60: e5962000 ldr r2, [r6] + 64: eb00023f bl 968 + exit(); + 68: eb0000eb bl 41c +main(int argc, char *argv[]) +{ + int fd, i; + + if(argc <= 1){ + wc(0, ""); + 6c: e3a00000 mov r0, #0 + 70: e59f1008 ldr r1, [pc, #8] ; 80 + 74: eb000002 bl 84 + exit(); + 78: eb0000e7 bl 41c + 7c: 00000c78 .word 0x00000c78 + 80: 00000c74 .word 0x00000c74 + +00000084 : + +char buf[512]; + +void +wc(int fd, char *name) +{ + 84: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 88: e28db020 add fp, sp, #32 + 8c: e24dd014 sub sp, sp, #20 + 90: e50b0028 str r0, [fp, #-40] ; 0x28 + 94: e50b102c str r1, [fp, #-44] ; 0x2c + int i, n; + int l, w, c, inword; + + l = w = c = 0; + inword = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + 98: e51b0028 ldr r0, [fp, #-40] ; 0x28 + 9c: e59f10c8 ldr r1, [pc, #200] ; 16c + a0: e3a02c02 mov r2, #512 ; 0x200 + a4: eb000103 bl 4b8 +{ + int i, n; + int l, w, c, inword; + + l = w = c = 0; + inword = 0; + a8: e3a05000 mov r5, #0 +wc(int fd, char *name) +{ + int i, n; + int l, w, c, inword; + + l = w = c = 0; + ac: e1a04005 mov r4, r5 + b0: e1a07005 mov r7, r5 + b4: e1a06005 mov r6, r5 + inword = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + b8: e250a000 subs sl, r0, #0 + bc: da00001c ble 134 + c0: e59f90a4 ldr r9, [pc, #164] ; 16c + c4: e3a08000 mov r8, #0 + c8: ea000002 b d8 + for(i=0; i + c++; + if(buf[i] == '\n') + d8: e7d91008 ldrb r1, [r9, r8] + l++; + if(strchr(" \r\t\n\v", buf[i])) + dc: e59f008c ldr r0, [pc, #140] ; 170 + l = w = c = 0; + inword = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + for(i=0; i + ec: e3500000 cmp r0, #0 + inword = 0; + f0: 13a05000 movne r5, #0 + while((n = read(fd, buf, sizeof(buf))) > 0){ + for(i=0; i + inword = 0; + else if(!inword){ + f8: e3550000 cmp r5, #0 + w++; + fc: 02877001 addeq r7, r7, #1 + inword = 1; + 100: 03a05001 moveq r5, #1 + c++; + if(buf[i] == '\n') + l++; + if(strchr(" \r\t\n\v", buf[i])) + inword = 0; + else if(!inword){ + 104: 0afffff0 beq cc + int l, w, c, inword; + + l = w = c = 0; + inword = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + for(i=0; i 0){ + for(i=0; i + int i, n; + int l, w, c, inword; + + l = w = c = 0; + inword = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + 118: e51b0028 ldr r0, [fp, #-40] ; 0x28 + 11c: e59f1048 ldr r1, [pc, #72] ; 16c + 120: e3a02c02 mov r2, #512 ; 0x200 + 124: eb0000e3 bl 4b8 +#include "user.h" + +char buf[512]; + +void +wc(int fd, char *name) + 128: e0844008 add r4, r4, r8 + int i, n; + int l, w, c, inword; + + l = w = c = 0; + inword = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + 12c: e250a000 subs sl, r0, #0 + 130: caffffe2 bgt c0 + inword = 1; + } + } + } + if(n < 0){ + printf(1, "wc: read error\n"); + 134: e3a00001 mov r0, #1 + w++; + inword = 1; + } + } + } + if(n < 0){ + 138: 1a000008 bne 160 + printf(1, "wc: read error\n"); + exit(); + } + printf(1, "%d %d %d %s\n", l, w, c, name); + 13c: e51bc02c ldr ip, [fp, #-44] ; 0x2c + 140: e59f102c ldr r1, [pc, #44] ; 174 + 144: e1a02006 mov r2, r6 + 148: e1a03007 mov r3, r7 + 14c: e58d4000 str r4, [sp] + 150: e58dc004 str ip, [sp, #4] + 154: eb000203 bl 968 +} + 158: e24bd020 sub sp, fp, #32 + 15c: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} + inword = 1; + } + } + } + if(n < 0){ + printf(1, "wc: read error\n"); + 160: e59f1010 ldr r1, [pc, #16] ; 178 + 164: eb0001ff bl 968 + exit(); + 168: eb0000ab bl 41c + 16c: 00000cb4 .word 0x00000cb4 + 170: 00000c50 .word 0x00000c50 + 174: 00000c68 .word 0x00000c68 + 178: 00000c58 .word 0x00000c58 + +0000017c : +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 17c: e52db004 push {fp} ; (str fp, [sp, #-4]!) + char *os; + + os = s; + while((*s++ = *t++) != 0) + 180: e1a02000 mov r2, r0 +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 184: e28db000 add fp, sp, #0 + char *os; + + os = s; + while((*s++ = *t++) != 0) + 188: e4d13001 ldrb r3, [r1], #1 + 18c: e3530000 cmp r3, #0 + 190: e4c23001 strb r3, [r2], #1 + 194: 1afffffb bne 188 + ; + return os; +} + 198: e28bd000 add sp, fp, #0 + 19c: e8bd0800 pop {fp} + 1a0: e12fff1e bx lr + +000001a4 : + +int +strcmp(const char *p, const char *q) +{ + 1a4: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 1a8: e28db000 add fp, sp, #0 + while(*p && *p == *q) + 1ac: e5d03000 ldrb r3, [r0] + 1b0: e5d12000 ldrb r2, [r1] + 1b4: e3530000 cmp r3, #0 + 1b8: 1a000004 bne 1d0 + 1bc: ea000005 b 1d8 + 1c0: e5f03001 ldrb r3, [r0, #1]! + 1c4: e3530000 cmp r3, #0 + 1c8: 0a000006 beq 1e8 + 1cc: e5f12001 ldrb r2, [r1, #1]! + 1d0: e1530002 cmp r3, r2 + 1d4: 0afffff9 beq 1c0 + p++, q++; + return (uchar)*p - (uchar)*q; +} + 1d8: e0620003 rsb r0, r2, r3 + 1dc: e28bd000 add sp, fp, #0 + 1e0: e8bd0800 pop {fp} + 1e4: e12fff1e bx lr +} + +int +strcmp(const char *p, const char *q) +{ + while(*p && *p == *q) + 1e8: e5d12001 ldrb r2, [r1, #1] + 1ec: eafffff9 b 1d8 + +000001f0 : + return (uchar)*p - (uchar)*q; +} + +uint +strlen(char *s) +{ + 1f0: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 1f4: e28db000 add fp, sp, #0 + int n; + + for(n = 0; s[n]; n++) + 1f8: e5d03000 ldrb r3, [r0] + 1fc: e3530000 cmp r3, #0 + 200: 01a00003 moveq r0, r3 + 204: 0a000006 beq 224 + 208: e1a02000 mov r2, r0 + 20c: e3a03000 mov r3, #0 + 210: e5f21001 ldrb r1, [r2, #1]! + 214: e2833001 add r3, r3, #1 + 218: e1a00003 mov r0, r3 + 21c: e3510000 cmp r1, #0 + 220: 1afffffa bne 210 + ; + return n; +} + 224: e28bd000 add sp, fp, #0 + 228: e8bd0800 pop {fp} + 22c: e12fff1e bx lr + +00000230 : +memset(void *dst, int c, uint n) +{ + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 230: e3520000 cmp r2, #0 + return n; +} + +void* +memset(void *dst, int c, uint n) +{ + 234: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 238: e28db000 add fp, sp, #0 + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 23c: 0a000006 beq 25c + 240: e6ef1071 uxtb r1, r1 + 244: e1a03002 mov r3, r2 +} + +void* +memset(void *dst, int c, uint n) +{ + char *p=dst; + 248: e1a0c000 mov ip, r0 + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 24c: e2533001 subs r3, r3, #1 + 250: e4cc1001 strb r1, [ip], #1 + 254: 1afffffc bne 24c + 258: e0800002 add r0, r0, r2 + return (void *)p; +} + 25c: e28bd000 add sp, fp, #0 + 260: e8bd0800 pop {fp} + 264: e12fff1e bx lr + +00000268 : + +char* +strchr(const char *s, char c) +{ + 268: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 26c: e28db000 add fp, sp, #0 + for(; *s; s++) + 270: e5d03000 ldrb r3, [r0] + 274: e3530000 cmp r3, #0 + 278: 1a000004 bne 290 + 27c: ea000008 b 2a4 + 280: e5d03001 ldrb r3, [r0, #1] + 284: e2800001 add r0, r0, #1 + 288: e3530000 cmp r3, #0 + 28c: 0a000004 beq 2a4 + if(*s == c) + 290: e1530001 cmp r3, r1 + 294: 1afffff9 bne 280 + return (char*)s; + return 0; +} + 298: e28bd000 add sp, fp, #0 + 29c: e8bd0800 pop {fp} + 2a0: e12fff1e bx lr +strchr(const char *s, char c) +{ + for(; *s; s++) + if(*s == c) + return (char*)s; + return 0; + 2a4: e1a00003 mov r0, r3 + 2a8: eafffffa b 298 + +000002ac : +} + +char* +gets(char *buf, int max) +{ + 2ac: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + 2b0: e28db018 add fp, sp, #24 + 2b4: e24dd00c sub sp, sp, #12 + 2b8: e1a08000 mov r8, r0 + 2bc: e1a07001 mov r7, r1 + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 2c0: e1a06000 mov r6, r0 + 2c4: e3a05000 mov r5, #0 + 2c8: ea000008 b 2f0 + cc = read(0, &c, 1); + 2cc: eb000079 bl 4b8 + if(cc < 1) + 2d0: e3500000 cmp r0, #0 + 2d4: da00000b ble 308 + break; + buf[i++] = c; + 2d8: e55b301d ldrb r3, [fp, #-29] + if(c == '\n' || c == '\r') + 2dc: e1a05004 mov r5, r4 + 2e0: e353000a cmp r3, #10 + 2e4: 1353000d cmpne r3, #13 + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + if(cc < 1) + break; + buf[i++] = c; + 2e8: e4c63001 strb r3, [r6], #1 + if(c == '\n' || c == '\r') + 2ec: 0a00000a beq 31c +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + 2f0: e3a02001 mov r2, #1 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 2f4: e0854002 add r4, r5, r2 + 2f8: e1540007 cmp r4, r7 + cc = read(0, &c, 1); + 2fc: e3a00000 mov r0, #0 + 300: e24b101d sub r1, fp, #29 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 304: bafffff0 blt 2cc + break; + buf[i++] = c; + if(c == '\n' || c == '\r') + break; + } + buf[i] = '\0'; + 308: e3a03000 mov r3, #0 + 30c: e7c83005 strb r3, [r8, r5] + return buf; +} + 310: e1a00008 mov r0, r8 + 314: e24bd018 sub sp, fp, #24 + 318: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 31c: e1a05004 mov r5, r4 + 320: eafffff8 b 308 + +00000324 : + return buf; +} + +int +stat(char *n, struct stat *st) +{ + 324: e92d4830 push {r4, r5, fp, lr} + 328: e1a05001 mov r5, r1 + 32c: e28db00c add fp, sp, #12 + int fd; + int r; + + fd = open(n, O_RDONLY); + 330: e3a01000 mov r1, #0 + 334: eb0000a0 bl 5bc + if(fd < 0) + 338: e2504000 subs r4, r0, #0 + return -1; + 33c: b3e05000 mvnlt r5, #0 +{ + int fd; + int r; + + fd = open(n, O_RDONLY); + if(fd < 0) + 340: ba000004 blt 358 + return -1; + r = fstat(fd, st); + 344: e1a01005 mov r1, r5 + 348: eb0000c2 bl 658 + 34c: e1a05000 mov r5, r0 + close(fd); + 350: e1a00004 mov r0, r4 + 354: eb000071 bl 520 + return r; +} + 358: e1a00005 mov r0, r5 + 35c: e8bd8830 pop {r4, r5, fp, pc} + +00000360 : + +int +atoi(const char *s) +{ + 360: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 364: e28db000 add fp, sp, #0 + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 368: e5d03000 ldrb r3, [r0] + 36c: e2432030 sub r2, r3, #48 ; 0x30 + 370: e6ef2072 uxtb r2, r2 + 374: e3520009 cmp r2, #9 +int +atoi(const char *s) +{ + int n; + + n = 0; + 378: 83a00000 movhi r0, #0 + while('0' <= *s && *s <= '9') + 37c: 8a000009 bhi 3a8 + 380: e1a02000 mov r2, r0 +int +atoi(const char *s) +{ + int n; + + n = 0; + 384: e3a00000 mov r0, #0 + while('0' <= *s && *s <= '9') + n = n*10 + *s++ - '0'; + 388: e0800100 add r0, r0, r0, lsl #2 + 38c: e0830080 add r0, r3, r0, lsl #1 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 390: e5f23001 ldrb r3, [r2, #1]! + n = n*10 + *s++ - '0'; + 394: e2400030 sub r0, r0, #48 ; 0x30 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 398: e2431030 sub r1, r3, #48 ; 0x30 + 39c: e6ef1071 uxtb r1, r1 + 3a0: e3510009 cmp r1, #9 + 3a4: 9afffff7 bls 388 + n = n*10 + *s++ - '0'; + return n; +} + 3a8: e28bd000 add sp, fp, #0 + 3ac: e8bd0800 pop {fp} + 3b0: e12fff1e bx lr + +000003b4 : +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 3b4: e3520000 cmp r2, #0 + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) +{ + 3b8: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 3bc: e28db000 add fp, sp, #0 + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 3c0: da000005 ble 3dc + n = n*10 + *s++ - '0'; + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) + 3c4: e0802002 add r2, r0, r2 +{ + char *dst, *src; + + dst = vdst; + 3c8: e1a03000 mov r3, r0 + src = vsrc; + while(n-- > 0) + *dst++ = *src++; + 3cc: e4d1c001 ldrb ip, [r1], #1 + 3d0: e4c3c001 strb ip, [r3], #1 +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 3d4: e1530002 cmp r3, r2 + 3d8: 1afffffb bne 3cc + *dst++ = *src++; + return vdst; +} + 3dc: e28bd000 add sp, fp, #0 + 3e0: e8bd0800 pop {fp} + 3e4: e12fff1e bx lr + +000003e8 : + 3e8: e92d4000 push {lr} + 3ec: e92d0008 push {r3} + 3f0: e92d0004 push {r2} + 3f4: e92d0002 push {r1} + 3f8: e92d0001 push {r0} + 3fc: e3a00001 mov r0, #1 + 400: ef000040 svc 0x00000040 + 404: e8bd0002 pop {r1} + 408: e8bd0002 pop {r1} + 40c: e8bd0004 pop {r2} + 410: e8bd0008 pop {r3} + 414: e8bd4000 pop {lr} + 418: e12fff1e bx lr + +0000041c : + 41c: e92d4000 push {lr} + 420: e92d0008 push {r3} + 424: e92d0004 push {r2} + 428: e92d0002 push {r1} + 42c: e92d0001 push {r0} + 430: e3a00002 mov r0, #2 + 434: ef000040 svc 0x00000040 + 438: e8bd0002 pop {r1} + 43c: e8bd0002 pop {r1} + 440: e8bd0004 pop {r2} + 444: e8bd0008 pop {r3} + 448: e8bd4000 pop {lr} + 44c: e12fff1e bx lr + +00000450 : + 450: e92d4000 push {lr} + 454: e92d0008 push {r3} + 458: e92d0004 push {r2} + 45c: e92d0002 push {r1} + 460: e92d0001 push {r0} + 464: e3a00003 mov r0, #3 + 468: ef000040 svc 0x00000040 + 46c: e8bd0002 pop {r1} + 470: e8bd0002 pop {r1} + 474: e8bd0004 pop {r2} + 478: e8bd0008 pop {r3} + 47c: e8bd4000 pop {lr} + 480: e12fff1e bx lr + +00000484 : + 484: e92d4000 push {lr} + 488: e92d0008 push {r3} + 48c: e92d0004 push {r2} + 490: e92d0002 push {r1} + 494: e92d0001 push {r0} + 498: e3a00004 mov r0, #4 + 49c: ef000040 svc 0x00000040 + 4a0: e8bd0002 pop {r1} + 4a4: e8bd0002 pop {r1} + 4a8: e8bd0004 pop {r2} + 4ac: e8bd0008 pop {r3} + 4b0: e8bd4000 pop {lr} + 4b4: e12fff1e bx lr + +000004b8 : + 4b8: e92d4000 push {lr} + 4bc: e92d0008 push {r3} + 4c0: e92d0004 push {r2} + 4c4: e92d0002 push {r1} + 4c8: e92d0001 push {r0} + 4cc: e3a00005 mov r0, #5 + 4d0: ef000040 svc 0x00000040 + 4d4: e8bd0002 pop {r1} + 4d8: e8bd0002 pop {r1} + 4dc: e8bd0004 pop {r2} + 4e0: e8bd0008 pop {r3} + 4e4: e8bd4000 pop {lr} + 4e8: e12fff1e bx lr + +000004ec : + 4ec: e92d4000 push {lr} + 4f0: e92d0008 push {r3} + 4f4: e92d0004 push {r2} + 4f8: e92d0002 push {r1} + 4fc: e92d0001 push {r0} + 500: e3a00010 mov r0, #16 + 504: ef000040 svc 0x00000040 + 508: e8bd0002 pop {r1} + 50c: e8bd0002 pop {r1} + 510: e8bd0004 pop {r2} + 514: e8bd0008 pop {r3} + 518: e8bd4000 pop {lr} + 51c: e12fff1e bx lr + +00000520 : + 520: e92d4000 push {lr} + 524: e92d0008 push {r3} + 528: e92d0004 push {r2} + 52c: e92d0002 push {r1} + 530: e92d0001 push {r0} + 534: e3a00015 mov r0, #21 + 538: ef000040 svc 0x00000040 + 53c: e8bd0002 pop {r1} + 540: e8bd0002 pop {r1} + 544: e8bd0004 pop {r2} + 548: e8bd0008 pop {r3} + 54c: e8bd4000 pop {lr} + 550: e12fff1e bx lr + +00000554 : + 554: e92d4000 push {lr} + 558: e92d0008 push {r3} + 55c: e92d0004 push {r2} + 560: e92d0002 push {r1} + 564: e92d0001 push {r0} + 568: e3a00006 mov r0, #6 + 56c: ef000040 svc 0x00000040 + 570: e8bd0002 pop {r1} + 574: e8bd0002 pop {r1} + 578: e8bd0004 pop {r2} + 57c: e8bd0008 pop {r3} + 580: e8bd4000 pop {lr} + 584: e12fff1e bx lr + +00000588 : + 588: e92d4000 push {lr} + 58c: e92d0008 push {r3} + 590: e92d0004 push {r2} + 594: e92d0002 push {r1} + 598: e92d0001 push {r0} + 59c: e3a00007 mov r0, #7 + 5a0: ef000040 svc 0x00000040 + 5a4: e8bd0002 pop {r1} + 5a8: e8bd0002 pop {r1} + 5ac: e8bd0004 pop {r2} + 5b0: e8bd0008 pop {r3} + 5b4: e8bd4000 pop {lr} + 5b8: e12fff1e bx lr + +000005bc : + 5bc: e92d4000 push {lr} + 5c0: e92d0008 push {r3} + 5c4: e92d0004 push {r2} + 5c8: e92d0002 push {r1} + 5cc: e92d0001 push {r0} + 5d0: e3a0000f mov r0, #15 + 5d4: ef000040 svc 0x00000040 + 5d8: e8bd0002 pop {r1} + 5dc: e8bd0002 pop {r1} + 5e0: e8bd0004 pop {r2} + 5e4: e8bd0008 pop {r3} + 5e8: e8bd4000 pop {lr} + 5ec: e12fff1e bx lr + +000005f0 : + 5f0: e92d4000 push {lr} + 5f4: e92d0008 push {r3} + 5f8: e92d0004 push {r2} + 5fc: e92d0002 push {r1} + 600: e92d0001 push {r0} + 604: e3a00011 mov r0, #17 + 608: ef000040 svc 0x00000040 + 60c: e8bd0002 pop {r1} + 610: e8bd0002 pop {r1} + 614: e8bd0004 pop {r2} + 618: e8bd0008 pop {r3} + 61c: e8bd4000 pop {lr} + 620: e12fff1e bx lr + +00000624 : + 624: e92d4000 push {lr} + 628: e92d0008 push {r3} + 62c: e92d0004 push {r2} + 630: e92d0002 push {r1} + 634: e92d0001 push {r0} + 638: e3a00012 mov r0, #18 + 63c: ef000040 svc 0x00000040 + 640: e8bd0002 pop {r1} + 644: e8bd0002 pop {r1} + 648: e8bd0004 pop {r2} + 64c: e8bd0008 pop {r3} + 650: e8bd4000 pop {lr} + 654: e12fff1e bx lr + +00000658 : + 658: e92d4000 push {lr} + 65c: e92d0008 push {r3} + 660: e92d0004 push {r2} + 664: e92d0002 push {r1} + 668: e92d0001 push {r0} + 66c: e3a00008 mov r0, #8 + 670: ef000040 svc 0x00000040 + 674: e8bd0002 pop {r1} + 678: e8bd0002 pop {r1} + 67c: e8bd0004 pop {r2} + 680: e8bd0008 pop {r3} + 684: e8bd4000 pop {lr} + 688: e12fff1e bx lr + +0000068c : + 68c: e92d4000 push {lr} + 690: e92d0008 push {r3} + 694: e92d0004 push {r2} + 698: e92d0002 push {r1} + 69c: e92d0001 push {r0} + 6a0: e3a00013 mov r0, #19 + 6a4: ef000040 svc 0x00000040 + 6a8: e8bd0002 pop {r1} + 6ac: e8bd0002 pop {r1} + 6b0: e8bd0004 pop {r2} + 6b4: e8bd0008 pop {r3} + 6b8: e8bd4000 pop {lr} + 6bc: e12fff1e bx lr + +000006c0 : + 6c0: e92d4000 push {lr} + 6c4: e92d0008 push {r3} + 6c8: e92d0004 push {r2} + 6cc: e92d0002 push {r1} + 6d0: e92d0001 push {r0} + 6d4: e3a00014 mov r0, #20 + 6d8: ef000040 svc 0x00000040 + 6dc: e8bd0002 pop {r1} + 6e0: e8bd0002 pop {r1} + 6e4: e8bd0004 pop {r2} + 6e8: e8bd0008 pop {r3} + 6ec: e8bd4000 pop {lr} + 6f0: e12fff1e bx lr + +000006f4 : + 6f4: e92d4000 push {lr} + 6f8: e92d0008 push {r3} + 6fc: e92d0004 push {r2} + 700: e92d0002 push {r1} + 704: e92d0001 push {r0} + 708: e3a00009 mov r0, #9 + 70c: ef000040 svc 0x00000040 + 710: e8bd0002 pop {r1} + 714: e8bd0002 pop {r1} + 718: e8bd0004 pop {r2} + 71c: e8bd0008 pop {r3} + 720: e8bd4000 pop {lr} + 724: e12fff1e bx lr + +00000728 : + 728: e92d4000 push {lr} + 72c: e92d0008 push {r3} + 730: e92d0004 push {r2} + 734: e92d0002 push {r1} + 738: e92d0001 push {r0} + 73c: e3a0000a mov r0, #10 + 740: ef000040 svc 0x00000040 + 744: e8bd0002 pop {r1} + 748: e8bd0002 pop {r1} + 74c: e8bd0004 pop {r2} + 750: e8bd0008 pop {r3} + 754: e8bd4000 pop {lr} + 758: e12fff1e bx lr + +0000075c : + 75c: e92d4000 push {lr} + 760: e92d0008 push {r3} + 764: e92d0004 push {r2} + 768: e92d0002 push {r1} + 76c: e92d0001 push {r0} + 770: e3a0000b mov r0, #11 + 774: ef000040 svc 0x00000040 + 778: e8bd0002 pop {r1} + 77c: e8bd0002 pop {r1} + 780: e8bd0004 pop {r2} + 784: e8bd0008 pop {r3} + 788: e8bd4000 pop {lr} + 78c: e12fff1e bx lr + +00000790 : + 790: e92d4000 push {lr} + 794: e92d0008 push {r3} + 798: e92d0004 push {r2} + 79c: e92d0002 push {r1} + 7a0: e92d0001 push {r0} + 7a4: e3a0000c mov r0, #12 + 7a8: ef000040 svc 0x00000040 + 7ac: e8bd0002 pop {r1} + 7b0: e8bd0002 pop {r1} + 7b4: e8bd0004 pop {r2} + 7b8: e8bd0008 pop {r3} + 7bc: e8bd4000 pop {lr} + 7c0: e12fff1e bx lr + +000007c4 : + 7c4: e92d4000 push {lr} + 7c8: e92d0008 push {r3} + 7cc: e92d0004 push {r2} + 7d0: e92d0002 push {r1} + 7d4: e92d0001 push {r0} + 7d8: e3a0000d mov r0, #13 + 7dc: ef000040 svc 0x00000040 + 7e0: e8bd0002 pop {r1} + 7e4: e8bd0002 pop {r1} + 7e8: e8bd0004 pop {r2} + 7ec: e8bd0008 pop {r3} + 7f0: e8bd4000 pop {lr} + 7f4: e12fff1e bx lr + +000007f8 : + 7f8: e92d4000 push {lr} + 7fc: e92d0008 push {r3} + 800: e92d0004 push {r2} + 804: e92d0002 push {r1} + 808: e92d0001 push {r0} + 80c: e3a0000e mov r0, #14 + 810: ef000040 svc 0x00000040 + 814: e8bd0002 pop {r1} + 818: e8bd0002 pop {r1} + 81c: e8bd0004 pop {r2} + 820: e8bd0008 pop {r3} + 824: e8bd4000 pop {lr} + 828: e12fff1e bx lr + +0000082c : +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 82c: e92d4800 push {fp, lr} + 830: e28db004 add fp, sp, #4 + 834: e24b3004 sub r3, fp, #4 + 838: e24dd008 sub sp, sp, #8 + write(fd, &c, 1); + 83c: e3a02001 mov r2, #1 +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 840: e5631001 strb r1, [r3, #-1]! + write(fd, &c, 1); + 844: e1a01003 mov r1, r3 + 848: ebffff27 bl 4ec +} + 84c: e24bd004 sub sp, fp, #4 + 850: e8bd8800 pop {fp, pc} + +00000854 : + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 854: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 858: e1a04000 mov r4, r0 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 85c: e1a00fa1 lsr r0, r1, #31 + 860: e3530000 cmp r3, #0 + 864: 03a03000 moveq r3, #0 + 868: 12003001 andne r3, r0, #1 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 86c: e28db020 add fp, sp, #32 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 870: e3530000 cmp r3, #0 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 874: e24dd014 sub sp, sp, #20 + 878: e59f909c ldr r9, [pc, #156] ; 91c + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + x = -xx; + 87c: 12611000 rsbne r1, r1, #0 + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + 880: 13a03001 movne r3, #1 + } else { + x = xx; + } + + b = base; + i = 0; + 884: e3a0a000 mov sl, #0 + 888: e24b6034 sub r6, fp, #52 ; 0x34 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 88c: e3a08001 mov r8, #1 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 890: e3a07000 mov r7, #0 + int i; + + for(i=31;i>=0;i--){ + 894: e3a0001f mov r0, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 898: e1a0c007 mov ip, r7 + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 89c: e1a0e031 lsr lr, r1, r0 + 8a0: e20ee001 and lr, lr, #1 + 8a4: e18ec08c orr ip, lr, ip, lsl #1 + if(r >= d) { + 8a8: e152000c cmp r2, ip + r = r - d; + q = q | (1 << i); + 8ac: 91877018 orrls r7, r7, r8, lsl r0 + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 8b0: 9062c00c rsbls ip, r2, ip +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 8b4: e2500001 subs r0, r0, #1 + 8b8: 2afffff7 bcs 89c + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 8bc: e0000792 mul r0, r2, r7 + }while((x = y) != 0); + 8c0: e3570000 cmp r7, #0 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 8c4: e0601001 rsb r1, r0, r1 + 8c8: e28a5001 add r5, sl, #1 + 8cc: e7d91001 ldrb r1, [r9, r1] + 8d0: e7c6100a strb r1, [r6, sl] + }while((x = y) != 0); + 8d4: 11a01007 movne r1, r7 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 8d8: 11a0a005 movne sl, r5 + 8dc: 1affffeb bne 890 + }while((x = y) != 0); + if(neg) + 8e0: e3530000 cmp r3, #0 + buf[i++] = '-'; + 8e4: 124b2024 subne r2, fp, #36 ; 0x24 + 8e8: 10823005 addne r3, r2, r5 + 8ec: 128a5002 addne r5, sl, #2 + + while(--i >= 0) + 8f0: e2455001 sub r5, r5, #1 + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + 8f4: 13a0202d movne r2, #45 ; 0x2d + 8f8: 15432010 strbne r2, [r3, #-16] + + while(--i >= 0) + putc(fd, buf[i]); + 8fc: e7d61005 ldrb r1, [r6, r5] + 900: e1a00004 mov r0, r4 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 904: e2455001 sub r5, r5, #1 + putc(fd, buf[i]); + 908: ebffffc7 bl 82c + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 90c: e3750001 cmn r5, #1 + 910: 1afffff9 bne 8fc + putc(fd, buf[i]); +} + 914: e24bd020 sub sp, fp, #32 + 918: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} + 91c: 00000c8c .word 0x00000c8c + +00000920
: + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 920: e3a03000 mov r3, #0 +{ + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + 924: e92d0830 push {r4, r5, fp} + 928: e1a02000 mov r2, r0 + 92c: e28db008 add fp, sp, #8 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 930: e3a0c01f mov ip, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 934: e1a00003 mov r0, r3 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 938: e3a05001 mov r5, #1 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 93c: e1a04c32 lsr r4, r2, ip + 940: e2044001 and r4, r4, #1 + 944: e1843083 orr r3, r4, r3, lsl #1 + if(r >= d) { + 948: e1530001 cmp r3, r1 + r = r - d; + q = q | (1 << i); + 94c: 21800c15 orrcs r0, r0, r5, lsl ip + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 950: 20613003 rsbcs r3, r1, r3 +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 954: e25cc001 subs ip, ip, #1 + 958: 2afffff7 bcs 93c + r = r - d; + q = q | (1 << i); + } + } + return q; +} + 95c: e24bd008 sub sp, fp, #8 + 960: e8bd0830 pop {r4, r5, fp} + 964: e12fff1e bx lr + +00000968 : +} + +// Print to the given fd. Only understands %d, %x, %p, %s. +void +printf(int fd, char *fmt, ...) +{ + 968: e92d000e push {r1, r2, r3} + 96c: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 970: e28db020 add fp, sp, #32 + 974: e1a05000 mov r5, r0 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 978: e59b4004 ldr r4, [fp, #4] + 97c: e5d48000 ldrb r8, [r4] + 980: e3580000 cmp r8, #0 + 984: 0a000027 beq a28 + ap++; + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + 988: e59f712c ldr r7, [pc, #300] ; abc + char *s; + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + 98c: e28b6008 add r6, fp, #8 +{ + char *s; + int c, i, state; + uint *ap; + + state = 0; + 990: e3a0a000 mov sl, #0 + 994: ea000008 b 9bc + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 998: e3580025 cmp r8, #37 ; 0x25 + state = '%'; + 99c: 01a0a008 moveq sl, r8 + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 9a0: 0a000002 beq 9b0 + state = '%'; + } else { + putc(fd, c); + 9a4: e1a00005 mov r0, r5 + 9a8: e1a01008 mov r1, r8 + 9ac: ebffff9e bl 82c + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 9b0: e5f48001 ldrb r8, [r4, #1]! + 9b4: e3580000 cmp r8, #0 + 9b8: 0a00001a beq a28 + c = fmt[i] & 0xff; + if(state == 0){ + 9bc: e35a0000 cmp sl, #0 + 9c0: 0afffff4 beq 998 + if(c == '%'){ + state = '%'; + } else { + putc(fd, c); + } + } else if(state == '%'){ + 9c4: e35a0025 cmp sl, #37 ; 0x25 + 9c8: 1afffff8 bne 9b0 + if(c == 'd'){ + 9cc: e3580064 cmp r8, #100 ; 0x64 + 9d0: 0a00002c beq a88 + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + 9d4: e3580078 cmp r8, #120 ; 0x78 + 9d8: 13580070 cmpne r8, #112 ; 0x70 + 9dc: 13a09000 movne r9, #0 + 9e0: 03a09001 moveq r9, #1 + 9e4: 0a000013 beq a38 + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + 9e8: e3580073 cmp r8, #115 ; 0x73 + 9ec: 0a000018 beq a54 + s = "(null)"; + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + 9f0: e3580063 cmp r8, #99 ; 0x63 + 9f4: 0a00002a beq aa4 + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 9f8: e3580025 cmp r8, #37 ; 0x25 + putc(fd, c); + 9fc: e1a0100a mov r1, sl + a00: e1a00005 mov r0, r5 + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + ap++; + } else if(c == '%'){ + a04: 0a000002 beq a14 + putc(fd, c); + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + a08: ebffff87 bl 82c + putc(fd, c); + a0c: e1a00005 mov r0, r5 + a10: e1a01008 mov r1, r8 + a14: ebffff84 bl 82c + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + a18: e5f48001 ldrb r8, [r4, #1]! + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + a1c: e1a0a009 mov sl, r9 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + a20: e3580000 cmp r8, #0 + a24: 1affffe4 bne 9bc + putc(fd, c); + } + state = 0; + } + } +} + a28: e24bd020 sub sp, fp, #32 + a2c: e8bd4ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, lr} + a30: e28dd00c add sp, sp, #12 + a34: e12fff1e bx lr + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + a38: e1a00005 mov r0, r5 + a3c: e4961004 ldr r1, [r6], #4 + a40: e3a02010 mov r2, #16 + a44: e3a03000 mov r3, #0 + a48: ebffff81 bl 854 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + a4c: e3a0a000 mov sl, #0 + a50: eaffffd6 b 9b0 + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + s = (char*)*ap; + a54: e4968004 ldr r8, [r6], #4 + ap++; + if(s == 0) + s = "(null)"; + a58: e3580000 cmp r8, #0 + a5c: 01a08007 moveq r8, r7 + while(*s != 0){ + a60: e5d81000 ldrb r1, [r8] + a64: e3510000 cmp r1, #0 + a68: 0a000004 beq a80 + putc(fd, *s); + a6c: e1a00005 mov r0, r5 + a70: ebffff6d bl 82c + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + while(*s != 0){ + a74: e5f81001 ldrb r1, [r8, #1]! + a78: e3510000 cmp r1, #0 + a7c: 1afffffa bne a6c + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + a80: e1a0a001 mov sl, r1 + a84: eaffffc9 b 9b0 + } else { + putc(fd, c); + } + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + a88: e1a00005 mov r0, r5 + a8c: e4961004 ldr r1, [r6], #4 + a90: e3a0200a mov r2, #10 + a94: e3a03001 mov r3, #1 + a98: ebffff6d bl 854 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + a9c: e3a0a000 mov sl, #0 + aa0: eaffffc2 b 9b0 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + aa4: e4961004 ldr r1, [r6], #4 + aa8: e1a00005 mov r0, r5 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + aac: e1a0a009 mov sl, r9 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + ab0: e6ef1071 uxtb r1, r1 + ab4: ebffff5c bl 82c + ab8: eaffffbc b 9b0 + abc: 00000ca0 .word 0x00000ca0 + +00000ac0 : +free(void *ap) +{ + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + ac0: e59f3098 ldr r3, [pc, #152] ; b60 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + ac4: e92d0830 push {r4, r5, fp} + Header *bp, *p; + + bp = (Header*)ap - 1; + ac8: e240c008 sub ip, r0, #8 + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + acc: e5932000 ldr r2, [r3] +static Header base; +static Header *freep; + +void +free(void *ap) +{ + ad0: e28db008 add fp, sp, #8 + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + ad4: e152000c cmp r2, ip + ad8: e5921000 ldr r1, [r2] + adc: 2a000001 bcs ae8 + ae0: e15c0001 cmp ip, r1 + ae4: 3a000007 bcc b08 + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + ae8: e1520001 cmp r2, r1 + aec: 3a000003 bcc b00 + af0: e152000c cmp r2, ip + af4: 3a000003 bcc b08 + af8: e15c0001 cmp ip, r1 + afc: 3a000001 bcc b08 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + b00: e1a02001 mov r2, r1 + b04: eafffff2 b ad4 + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + b08: e5104004 ldr r4, [r0, #-4] + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + freep = p; + b0c: e5832000 str r2, [r3] + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + b10: e08c5184 add r5, ip, r4, lsl #3 + b14: e1550001 cmp r5, r1 + bp->s.size += p->s.ptr->s.size; + b18: 05911004 ldreq r1, [r1, #4] + b1c: 00814004 addeq r4, r1, r4 + b20: 05004004 streq r4, [r0, #-4] + bp->s.ptr = p->s.ptr->s.ptr; + b24: 05921000 ldreq r1, [r2] + b28: 05911000 ldreq r1, [r1] + } else + bp->s.ptr = p->s.ptr; + b2c: e5001008 str r1, [r0, #-8] + if(p + p->s.size == bp){ + b30: e5921004 ldr r1, [r2, #4] + b34: e0824181 add r4, r2, r1, lsl #3 + b38: e15c0004 cmp ip, r4 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + b3c: 1582c000 strne ip, [r2] + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + } else + bp->s.ptr = p->s.ptr; + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + b40: 0510c004 ldreq ip, [r0, #-4] + b44: 008c1001 addeq r1, ip, r1 + b48: 05821004 streq r1, [r2, #4] + p->s.ptr = bp->s.ptr; + b4c: 05101008 ldreq r1, [r0, #-8] + b50: 05821000 streq r1, [r2] + } else + p->s.ptr = bp; + freep = p; +} + b54: e24bd008 sub sp, fp, #8 + b58: e8bd0830 pop {r4, r5, fp} + b5c: e12fff1e bx lr + b60: 00000ca8 .word 0x00000ca8 + +00000b64 : + return freep; +} + +void* +malloc(uint nbytes) +{ + b64: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + b68: e2804007 add r4, r0, #7 + if((prevp = freep) == 0){ + b6c: e59f50d4 ldr r5, [pc, #212] ; c48 +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + b70: e1a041a4 lsr r4, r4, #3 + return freep; +} + +void* +malloc(uint nbytes) +{ + b74: e28db01c add fp, sp, #28 + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + b78: e5953000 ldr r3, [r5] +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + b7c: e2844001 add r4, r4, #1 + if((prevp = freep) == 0){ + b80: e3530000 cmp r3, #0 + b84: 0a00002b beq c38 + b88: e5930000 ldr r0, [r3] + b8c: e5902004 ldr r2, [r0, #4] + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + b90: e1520004 cmp r2, r4 + b94: 2a00001b bcs c08 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + b98: e59f80ac ldr r8, [pc, #172] ; c4c + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + b9c: e1a07184 lsl r7, r4, #3 + ba0: ea000003 b bb4 + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + ba4: e5930000 ldr r0, [r3] + if(p->s.size >= nunits){ + ba8: e5902004 ldr r2, [r0, #4] + bac: e1540002 cmp r4, r2 + bb0: 9a000014 bls c08 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + bb4: e5952000 ldr r2, [r5] + bb8: e1a03000 mov r3, r0 + bbc: e1500002 cmp r0, r2 + bc0: 1afffff7 bne ba4 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + bc4: e1540008 cmp r4, r8 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + bc8: 81a00007 movhi r0, r7 + bcc: 93a00902 movls r0, #32768 ; 0x8000 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + bd0: 81a06004 movhi r6, r4 + bd4: 93a06a01 movls r6, #4096 ; 0x1000 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + bd8: ebfffeec bl 790 + bdc: e1a03000 mov r3, r0 + if(p == (char*)-1) + be0: e3730001 cmn r3, #1 + return 0; + hp = (Header*)p; + hp->s.size = nu; + free((void*)(hp + 1)); + be4: e2800008 add r0, r0, #8 + Header *hp; + + if(nu < 4096) + nu = 4096; + p = sbrk(nu * sizeof(Header)); + if(p == (char*)-1) + be8: 0a000010 beq c30 + return 0; + hp = (Header*)p; + hp->s.size = nu; + bec: e5836004 str r6, [r3, #4] + free((void*)(hp + 1)); + bf0: ebffffb2 bl ac0 + return freep; + bf4: e5953000 ldr r3, [r5] + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + if((p = morecore(nunits)) == 0) + bf8: e3530000 cmp r3, #0 + bfc: 1affffe8 bne ba4 + return 0; + c00: e1a00003 mov r0, r3 + } +} + c04: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + c08: e1540002 cmp r4, r2 + prevp->s.ptr = p->s.ptr; + else { + p->s.size -= nunits; + c0c: 10642002 rsbne r2, r4, r2 + c10: 15802004 strne r2, [r0, #4] + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + c14: 05902000 ldreq r2, [r0] + else { + p->s.size -= nunits; + p += p->s.size; + c18: 10800182 addne r0, r0, r2, lsl #3 + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + c1c: 05832000 streq r2, [r3] + else { + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + c20: 15804004 strne r4, [r0, #4] + } + freep = prevp; + c24: e5853000 str r3, [r5] + return (void*)(p + 1); + c28: e2800008 add r0, r0, #8 + c2c: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + } + if(p == freep) + if((p = morecore(nunits)) == 0) + return 0; + c30: e3a00000 mov r0, #0 + c34: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + c38: e2850004 add r0, r5, #4 + c3c: e5850000 str r0, [r5] + base.s.size = 0; + c40: e9850009 stmib r5, {r0, r3} + c44: eaffffd3 b b98 + c48: 00000ca8 .word 0x00000ca8 + c4c: 00000fff .word 0x00000fff diff -r 000000000000 -r c450faca55f4 uprogs/wc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/wc.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,54 @@ +#include "types.h" +#include "stat.h" +#include "user.h" + +char buf[512]; + +void +wc(int fd, char *name) +{ + int i, n; + int l, w, c, inword; + + l = w = c = 0; + inword = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + for(i=0; i: +#include "stat.h" +#include "user.h" + +int +main(void) +{ + 0: e92d4800 push {fp, lr} + 4: e28db004 add fp, sp, #4 + if(fork() > 0){ + 8: eb0000a8 bl 2b0 + c: e3500000 cmp r0, #0 + 10: da000005 ble 2c + sleep(5); // Let child exit before parent. + 14: e3a00005 mov r0, #5 + 18: eb00019b bl 68c + printf(2, "Parent exits!\n"); + 1c: e3a00002 mov r0, #2 + 20: e59f1014 ldr r1, [pc, #20] ; 3c + 24: eb000201 bl 830 + exit(); + 28: eb0000ad bl 2e4 + } + printf(2, "Child exits!\n"); + 2c: e3a00002 mov r0, #2 + 30: e59f1008 ldr r1, [pc, #8] ; 40 + 34: eb0001fd bl 830 + exit(); + 38: eb0000a9 bl 2e4 + 3c: 00000b18 .word 0x00000b18 + 40: 00000b28 .word 0x00000b28 + +00000044 : +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 44: e52db004 push {fp} ; (str fp, [sp, #-4]!) + char *os; + + os = s; + while((*s++ = *t++) != 0) + 48: e1a02000 mov r2, r0 +#include "user.h" +#include "arm.h" + +char* +strcpy(char *s, char *t) +{ + 4c: e28db000 add fp, sp, #0 + char *os; + + os = s; + while((*s++ = *t++) != 0) + 50: e4d13001 ldrb r3, [r1], #1 + 54: e3530000 cmp r3, #0 + 58: e4c23001 strb r3, [r2], #1 + 5c: 1afffffb bne 50 + ; + return os; +} + 60: e28bd000 add sp, fp, #0 + 64: e8bd0800 pop {fp} + 68: e12fff1e bx lr + +0000006c : + +int +strcmp(const char *p, const char *q) +{ + 6c: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 70: e28db000 add fp, sp, #0 + while(*p && *p == *q) + 74: e5d03000 ldrb r3, [r0] + 78: e5d12000 ldrb r2, [r1] + 7c: e3530000 cmp r3, #0 + 80: 1a000004 bne 98 + 84: ea000005 b a0 + 88: e5f03001 ldrb r3, [r0, #1]! + 8c: e3530000 cmp r3, #0 + 90: 0a000006 beq b0 + 94: e5f12001 ldrb r2, [r1, #1]! + 98: e1530002 cmp r3, r2 + 9c: 0afffff9 beq 88 + p++, q++; + return (uchar)*p - (uchar)*q; +} + a0: e0620003 rsb r0, r2, r3 + a4: e28bd000 add sp, fp, #0 + a8: e8bd0800 pop {fp} + ac: e12fff1e bx lr +} + +int +strcmp(const char *p, const char *q) +{ + while(*p && *p == *q) + b0: e5d12001 ldrb r2, [r1, #1] + b4: eafffff9 b a0 + +000000b8 : + return (uchar)*p - (uchar)*q; +} + +uint +strlen(char *s) +{ + b8: e52db004 push {fp} ; (str fp, [sp, #-4]!) + bc: e28db000 add fp, sp, #0 + int n; + + for(n = 0; s[n]; n++) + c0: e5d03000 ldrb r3, [r0] + c4: e3530000 cmp r3, #0 + c8: 01a00003 moveq r0, r3 + cc: 0a000006 beq ec + d0: e1a02000 mov r2, r0 + d4: e3a03000 mov r3, #0 + d8: e5f21001 ldrb r1, [r2, #1]! + dc: e2833001 add r3, r3, #1 + e0: e1a00003 mov r0, r3 + e4: e3510000 cmp r1, #0 + e8: 1afffffa bne d8 + ; + return n; +} + ec: e28bd000 add sp, fp, #0 + f0: e8bd0800 pop {fp} + f4: e12fff1e bx lr + +000000f8 : +memset(void *dst, int c, uint n) +{ + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + f8: e3520000 cmp r2, #0 + return n; +} + +void* +memset(void *dst, int c, uint n) +{ + fc: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 100: e28db000 add fp, sp, #0 + char *p=dst; + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 104: 0a000006 beq 124 + 108: e6ef1071 uxtb r1, r1 + 10c: e1a03002 mov r3, r2 +} + +void* +memset(void *dst, int c, uint n) +{ + char *p=dst; + 110: e1a0c000 mov ip, r0 + u32 rc=n; + + while (rc-- > 0) *p++ = c; + 114: e2533001 subs r3, r3, #1 + 118: e4cc1001 strb r1, [ip], #1 + 11c: 1afffffc bne 114 + 120: e0800002 add r0, r0, r2 + return (void *)p; +} + 124: e28bd000 add sp, fp, #0 + 128: e8bd0800 pop {fp} + 12c: e12fff1e bx lr + +00000130 : + +char* +strchr(const char *s, char c) +{ + 130: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 134: e28db000 add fp, sp, #0 + for(; *s; s++) + 138: e5d03000 ldrb r3, [r0] + 13c: e3530000 cmp r3, #0 + 140: 1a000004 bne 158 + 144: ea000008 b 16c + 148: e5d03001 ldrb r3, [r0, #1] + 14c: e2800001 add r0, r0, #1 + 150: e3530000 cmp r3, #0 + 154: 0a000004 beq 16c + if(*s == c) + 158: e1530001 cmp r3, r1 + 15c: 1afffff9 bne 148 + return (char*)s; + return 0; +} + 160: e28bd000 add sp, fp, #0 + 164: e8bd0800 pop {fp} + 168: e12fff1e bx lr +strchr(const char *s, char c) +{ + for(; *s; s++) + if(*s == c) + return (char*)s; + return 0; + 16c: e1a00003 mov r0, r3 + 170: eafffffa b 160 + +00000174 : +} + +char* +gets(char *buf, int max) +{ + 174: e92d49f0 push {r4, r5, r6, r7, r8, fp, lr} + 178: e28db018 add fp, sp, #24 + 17c: e24dd00c sub sp, sp, #12 + 180: e1a08000 mov r8, r0 + 184: e1a07001 mov r7, r1 + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 188: e1a06000 mov r6, r0 + 18c: e3a05000 mov r5, #0 + 190: ea000008 b 1b8 + cc = read(0, &c, 1); + 194: eb000079 bl 380 + if(cc < 1) + 198: e3500000 cmp r0, #0 + 19c: da00000b ble 1d0 + break; + buf[i++] = c; + 1a0: e55b301d ldrb r3, [fp, #-29] + if(c == '\n' || c == '\r') + 1a4: e1a05004 mov r5, r4 + 1a8: e353000a cmp r3, #10 + 1ac: 1353000d cmpne r3, #13 + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + if(cc < 1) + break; + buf[i++] = c; + 1b0: e4c63001 strb r3, [r6], #1 + if(c == '\n' || c == '\r') + 1b4: 0a00000a beq 1e4 +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + cc = read(0, &c, 1); + 1b8: e3a02001 mov r2, #1 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 1bc: e0854002 add r4, r5, r2 + 1c0: e1540007 cmp r4, r7 + cc = read(0, &c, 1); + 1c4: e3a00000 mov r0, #0 + 1c8: e24b101d sub r1, fp, #29 +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 1cc: bafffff0 blt 194 + break; + buf[i++] = c; + if(c == '\n' || c == '\r') + break; + } + buf[i] = '\0'; + 1d0: e3a03000 mov r3, #0 + 1d4: e7c83005 strb r3, [r8, r5] + return buf; +} + 1d8: e1a00008 mov r0, r8 + 1dc: e24bd018 sub sp, fp, #24 + 1e0: e8bd89f0 pop {r4, r5, r6, r7, r8, fp, pc} +gets(char *buf, int max) +{ + int i, cc; + char c; + + for(i=0; i+1 < max; ){ + 1e4: e1a05004 mov r5, r4 + 1e8: eafffff8 b 1d0 + +000001ec : + return buf; +} + +int +stat(char *n, struct stat *st) +{ + 1ec: e92d4830 push {r4, r5, fp, lr} + 1f0: e1a05001 mov r5, r1 + 1f4: e28db00c add fp, sp, #12 + int fd; + int r; + + fd = open(n, O_RDONLY); + 1f8: e3a01000 mov r1, #0 + 1fc: eb0000a0 bl 484 + if(fd < 0) + 200: e2504000 subs r4, r0, #0 + return -1; + 204: b3e05000 mvnlt r5, #0 +{ + int fd; + int r; + + fd = open(n, O_RDONLY); + if(fd < 0) + 208: ba000004 blt 220 + return -1; + r = fstat(fd, st); + 20c: e1a01005 mov r1, r5 + 210: eb0000c2 bl 520 + 214: e1a05000 mov r5, r0 + close(fd); + 218: e1a00004 mov r0, r4 + 21c: eb000071 bl 3e8 + return r; +} + 220: e1a00005 mov r0, r5 + 224: e8bd8830 pop {r4, r5, fp, pc} + +00000228 : + +int +atoi(const char *s) +{ + 228: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 22c: e28db000 add fp, sp, #0 + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 230: e5d03000 ldrb r3, [r0] + 234: e2432030 sub r2, r3, #48 ; 0x30 + 238: e6ef2072 uxtb r2, r2 + 23c: e3520009 cmp r2, #9 +int +atoi(const char *s) +{ + int n; + + n = 0; + 240: 83a00000 movhi r0, #0 + while('0' <= *s && *s <= '9') + 244: 8a000009 bhi 270 + 248: e1a02000 mov r2, r0 +int +atoi(const char *s) +{ + int n; + + n = 0; + 24c: e3a00000 mov r0, #0 + while('0' <= *s && *s <= '9') + n = n*10 + *s++ - '0'; + 250: e0800100 add r0, r0, r0, lsl #2 + 254: e0830080 add r0, r3, r0, lsl #1 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 258: e5f23001 ldrb r3, [r2, #1]! + n = n*10 + *s++ - '0'; + 25c: e2400030 sub r0, r0, #48 ; 0x30 +atoi(const char *s) +{ + int n; + + n = 0; + while('0' <= *s && *s <= '9') + 260: e2431030 sub r1, r3, #48 ; 0x30 + 264: e6ef1071 uxtb r1, r1 + 268: e3510009 cmp r1, #9 + 26c: 9afffff7 bls 250 + n = n*10 + *s++ - '0'; + return n; +} + 270: e28bd000 add sp, fp, #0 + 274: e8bd0800 pop {fp} + 278: e12fff1e bx lr + +0000027c : +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 27c: e3520000 cmp r2, #0 + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) +{ + 280: e52db004 push {fp} ; (str fp, [sp, #-4]!) + 284: e28db000 add fp, sp, #0 + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 288: da000005 ble 2a4 + n = n*10 + *s++ - '0'; + return n; +} + +void* +memmove(void *vdst, void *vsrc, int n) + 28c: e0802002 add r2, r0, r2 +{ + char *dst, *src; + + dst = vdst; + 290: e1a03000 mov r3, r0 + src = vsrc; + while(n-- > 0) + *dst++ = *src++; + 294: e4d1c001 ldrb ip, [r1], #1 + 298: e4c3c001 strb ip, [r3], #1 +{ + char *dst, *src; + + dst = vdst; + src = vsrc; + while(n-- > 0) + 29c: e1530002 cmp r3, r2 + 2a0: 1afffffb bne 294 + *dst++ = *src++; + return vdst; +} + 2a4: e28bd000 add sp, fp, #0 + 2a8: e8bd0800 pop {fp} + 2ac: e12fff1e bx lr + +000002b0 : + 2b0: e92d4000 push {lr} + 2b4: e92d0008 push {r3} + 2b8: e92d0004 push {r2} + 2bc: e92d0002 push {r1} + 2c0: e92d0001 push {r0} + 2c4: e3a00001 mov r0, #1 + 2c8: ef000040 svc 0x00000040 + 2cc: e8bd0002 pop {r1} + 2d0: e8bd0002 pop {r1} + 2d4: e8bd0004 pop {r2} + 2d8: e8bd0008 pop {r3} + 2dc: e8bd4000 pop {lr} + 2e0: e12fff1e bx lr + +000002e4 : + 2e4: e92d4000 push {lr} + 2e8: e92d0008 push {r3} + 2ec: e92d0004 push {r2} + 2f0: e92d0002 push {r1} + 2f4: e92d0001 push {r0} + 2f8: e3a00002 mov r0, #2 + 2fc: ef000040 svc 0x00000040 + 300: e8bd0002 pop {r1} + 304: e8bd0002 pop {r1} + 308: e8bd0004 pop {r2} + 30c: e8bd0008 pop {r3} + 310: e8bd4000 pop {lr} + 314: e12fff1e bx lr + +00000318 : + 318: e92d4000 push {lr} + 31c: e92d0008 push {r3} + 320: e92d0004 push {r2} + 324: e92d0002 push {r1} + 328: e92d0001 push {r0} + 32c: e3a00003 mov r0, #3 + 330: ef000040 svc 0x00000040 + 334: e8bd0002 pop {r1} + 338: e8bd0002 pop {r1} + 33c: e8bd0004 pop {r2} + 340: e8bd0008 pop {r3} + 344: e8bd4000 pop {lr} + 348: e12fff1e bx lr + +0000034c : + 34c: e92d4000 push {lr} + 350: e92d0008 push {r3} + 354: e92d0004 push {r2} + 358: e92d0002 push {r1} + 35c: e92d0001 push {r0} + 360: e3a00004 mov r0, #4 + 364: ef000040 svc 0x00000040 + 368: e8bd0002 pop {r1} + 36c: e8bd0002 pop {r1} + 370: e8bd0004 pop {r2} + 374: e8bd0008 pop {r3} + 378: e8bd4000 pop {lr} + 37c: e12fff1e bx lr + +00000380 : + 380: e92d4000 push {lr} + 384: e92d0008 push {r3} + 388: e92d0004 push {r2} + 38c: e92d0002 push {r1} + 390: e92d0001 push {r0} + 394: e3a00005 mov r0, #5 + 398: ef000040 svc 0x00000040 + 39c: e8bd0002 pop {r1} + 3a0: e8bd0002 pop {r1} + 3a4: e8bd0004 pop {r2} + 3a8: e8bd0008 pop {r3} + 3ac: e8bd4000 pop {lr} + 3b0: e12fff1e bx lr + +000003b4 : + 3b4: e92d4000 push {lr} + 3b8: e92d0008 push {r3} + 3bc: e92d0004 push {r2} + 3c0: e92d0002 push {r1} + 3c4: e92d0001 push {r0} + 3c8: e3a00010 mov r0, #16 + 3cc: ef000040 svc 0x00000040 + 3d0: e8bd0002 pop {r1} + 3d4: e8bd0002 pop {r1} + 3d8: e8bd0004 pop {r2} + 3dc: e8bd0008 pop {r3} + 3e0: e8bd4000 pop {lr} + 3e4: e12fff1e bx lr + +000003e8 : + 3e8: e92d4000 push {lr} + 3ec: e92d0008 push {r3} + 3f0: e92d0004 push {r2} + 3f4: e92d0002 push {r1} + 3f8: e92d0001 push {r0} + 3fc: e3a00015 mov r0, #21 + 400: ef000040 svc 0x00000040 + 404: e8bd0002 pop {r1} + 408: e8bd0002 pop {r1} + 40c: e8bd0004 pop {r2} + 410: e8bd0008 pop {r3} + 414: e8bd4000 pop {lr} + 418: e12fff1e bx lr + +0000041c : + 41c: e92d4000 push {lr} + 420: e92d0008 push {r3} + 424: e92d0004 push {r2} + 428: e92d0002 push {r1} + 42c: e92d0001 push {r0} + 430: e3a00006 mov r0, #6 + 434: ef000040 svc 0x00000040 + 438: e8bd0002 pop {r1} + 43c: e8bd0002 pop {r1} + 440: e8bd0004 pop {r2} + 444: e8bd0008 pop {r3} + 448: e8bd4000 pop {lr} + 44c: e12fff1e bx lr + +00000450 : + 450: e92d4000 push {lr} + 454: e92d0008 push {r3} + 458: e92d0004 push {r2} + 45c: e92d0002 push {r1} + 460: e92d0001 push {r0} + 464: e3a00007 mov r0, #7 + 468: ef000040 svc 0x00000040 + 46c: e8bd0002 pop {r1} + 470: e8bd0002 pop {r1} + 474: e8bd0004 pop {r2} + 478: e8bd0008 pop {r3} + 47c: e8bd4000 pop {lr} + 480: e12fff1e bx lr + +00000484 : + 484: e92d4000 push {lr} + 488: e92d0008 push {r3} + 48c: e92d0004 push {r2} + 490: e92d0002 push {r1} + 494: e92d0001 push {r0} + 498: e3a0000f mov r0, #15 + 49c: ef000040 svc 0x00000040 + 4a0: e8bd0002 pop {r1} + 4a4: e8bd0002 pop {r1} + 4a8: e8bd0004 pop {r2} + 4ac: e8bd0008 pop {r3} + 4b0: e8bd4000 pop {lr} + 4b4: e12fff1e bx lr + +000004b8 : + 4b8: e92d4000 push {lr} + 4bc: e92d0008 push {r3} + 4c0: e92d0004 push {r2} + 4c4: e92d0002 push {r1} + 4c8: e92d0001 push {r0} + 4cc: e3a00011 mov r0, #17 + 4d0: ef000040 svc 0x00000040 + 4d4: e8bd0002 pop {r1} + 4d8: e8bd0002 pop {r1} + 4dc: e8bd0004 pop {r2} + 4e0: e8bd0008 pop {r3} + 4e4: e8bd4000 pop {lr} + 4e8: e12fff1e bx lr + +000004ec : + 4ec: e92d4000 push {lr} + 4f0: e92d0008 push {r3} + 4f4: e92d0004 push {r2} + 4f8: e92d0002 push {r1} + 4fc: e92d0001 push {r0} + 500: e3a00012 mov r0, #18 + 504: ef000040 svc 0x00000040 + 508: e8bd0002 pop {r1} + 50c: e8bd0002 pop {r1} + 510: e8bd0004 pop {r2} + 514: e8bd0008 pop {r3} + 518: e8bd4000 pop {lr} + 51c: e12fff1e bx lr + +00000520 : + 520: e92d4000 push {lr} + 524: e92d0008 push {r3} + 528: e92d0004 push {r2} + 52c: e92d0002 push {r1} + 530: e92d0001 push {r0} + 534: e3a00008 mov r0, #8 + 538: ef000040 svc 0x00000040 + 53c: e8bd0002 pop {r1} + 540: e8bd0002 pop {r1} + 544: e8bd0004 pop {r2} + 548: e8bd0008 pop {r3} + 54c: e8bd4000 pop {lr} + 550: e12fff1e bx lr + +00000554 : + 554: e92d4000 push {lr} + 558: e92d0008 push {r3} + 55c: e92d0004 push {r2} + 560: e92d0002 push {r1} + 564: e92d0001 push {r0} + 568: e3a00013 mov r0, #19 + 56c: ef000040 svc 0x00000040 + 570: e8bd0002 pop {r1} + 574: e8bd0002 pop {r1} + 578: e8bd0004 pop {r2} + 57c: e8bd0008 pop {r3} + 580: e8bd4000 pop {lr} + 584: e12fff1e bx lr + +00000588 : + 588: e92d4000 push {lr} + 58c: e92d0008 push {r3} + 590: e92d0004 push {r2} + 594: e92d0002 push {r1} + 598: e92d0001 push {r0} + 59c: e3a00014 mov r0, #20 + 5a0: ef000040 svc 0x00000040 + 5a4: e8bd0002 pop {r1} + 5a8: e8bd0002 pop {r1} + 5ac: e8bd0004 pop {r2} + 5b0: e8bd0008 pop {r3} + 5b4: e8bd4000 pop {lr} + 5b8: e12fff1e bx lr + +000005bc : + 5bc: e92d4000 push {lr} + 5c0: e92d0008 push {r3} + 5c4: e92d0004 push {r2} + 5c8: e92d0002 push {r1} + 5cc: e92d0001 push {r0} + 5d0: e3a00009 mov r0, #9 + 5d4: ef000040 svc 0x00000040 + 5d8: e8bd0002 pop {r1} + 5dc: e8bd0002 pop {r1} + 5e0: e8bd0004 pop {r2} + 5e4: e8bd0008 pop {r3} + 5e8: e8bd4000 pop {lr} + 5ec: e12fff1e bx lr + +000005f0 : + 5f0: e92d4000 push {lr} + 5f4: e92d0008 push {r3} + 5f8: e92d0004 push {r2} + 5fc: e92d0002 push {r1} + 600: e92d0001 push {r0} + 604: e3a0000a mov r0, #10 + 608: ef000040 svc 0x00000040 + 60c: e8bd0002 pop {r1} + 610: e8bd0002 pop {r1} + 614: e8bd0004 pop {r2} + 618: e8bd0008 pop {r3} + 61c: e8bd4000 pop {lr} + 620: e12fff1e bx lr + +00000624 : + 624: e92d4000 push {lr} + 628: e92d0008 push {r3} + 62c: e92d0004 push {r2} + 630: e92d0002 push {r1} + 634: e92d0001 push {r0} + 638: e3a0000b mov r0, #11 + 63c: ef000040 svc 0x00000040 + 640: e8bd0002 pop {r1} + 644: e8bd0002 pop {r1} + 648: e8bd0004 pop {r2} + 64c: e8bd0008 pop {r3} + 650: e8bd4000 pop {lr} + 654: e12fff1e bx lr + +00000658 : + 658: e92d4000 push {lr} + 65c: e92d0008 push {r3} + 660: e92d0004 push {r2} + 664: e92d0002 push {r1} + 668: e92d0001 push {r0} + 66c: e3a0000c mov r0, #12 + 670: ef000040 svc 0x00000040 + 674: e8bd0002 pop {r1} + 678: e8bd0002 pop {r1} + 67c: e8bd0004 pop {r2} + 680: e8bd0008 pop {r3} + 684: e8bd4000 pop {lr} + 688: e12fff1e bx lr + +0000068c : + 68c: e92d4000 push {lr} + 690: e92d0008 push {r3} + 694: e92d0004 push {r2} + 698: e92d0002 push {r1} + 69c: e92d0001 push {r0} + 6a0: e3a0000d mov r0, #13 + 6a4: ef000040 svc 0x00000040 + 6a8: e8bd0002 pop {r1} + 6ac: e8bd0002 pop {r1} + 6b0: e8bd0004 pop {r2} + 6b4: e8bd0008 pop {r3} + 6b8: e8bd4000 pop {lr} + 6bc: e12fff1e bx lr + +000006c0 : + 6c0: e92d4000 push {lr} + 6c4: e92d0008 push {r3} + 6c8: e92d0004 push {r2} + 6cc: e92d0002 push {r1} + 6d0: e92d0001 push {r0} + 6d4: e3a0000e mov r0, #14 + 6d8: ef000040 svc 0x00000040 + 6dc: e8bd0002 pop {r1} + 6e0: e8bd0002 pop {r1} + 6e4: e8bd0004 pop {r2} + 6e8: e8bd0008 pop {r3} + 6ec: e8bd4000 pop {lr} + 6f0: e12fff1e bx lr + +000006f4 : +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 6f4: e92d4800 push {fp, lr} + 6f8: e28db004 add fp, sp, #4 + 6fc: e24b3004 sub r3, fp, #4 + 700: e24dd008 sub sp, sp, #8 + write(fd, &c, 1); + 704: e3a02001 mov r2, #1 +#include "stat.h" +#include "user.h" + +static void +putc(int fd, char c) +{ + 708: e5631001 strb r1, [r3, #-1]! + write(fd, &c, 1); + 70c: e1a01003 mov r1, r3 + 710: ebffff27 bl 3b4 +} + 714: e24bd004 sub sp, fp, #4 + 718: e8bd8800 pop {fp, pc} + +0000071c : + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 71c: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 720: e1a04000 mov r4, r0 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 724: e1a00fa1 lsr r0, r1, #31 + 728: e3530000 cmp r3, #0 + 72c: 03a03000 moveq r3, #0 + 730: 12003001 andne r3, r0, #1 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 734: e28db020 add fp, sp, #32 + char buf[16]; + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + 738: e3530000 cmp r3, #0 + return q; +} + +static void +printint(int fd, int xx, int base, int sgn) +{ + 73c: e24dd014 sub sp, sp, #20 + 740: e59f909c ldr r9, [pc, #156] ; 7e4 + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + x = -xx; + 744: 12611000 rsbne r1, r1, #0 + int i, neg; + uint x, y, b; + + neg = 0; + if(sgn && xx < 0){ + neg = 1; + 748: 13a03001 movne r3, #1 + } else { + x = xx; + } + + b = base; + i = 0; + 74c: e3a0a000 mov sl, #0 + 750: e24b6034 sub r6, fp, #52 ; 0x34 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 754: e3a08001 mov r8, #1 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 758: e3a07000 mov r7, #0 + int i; + + for(i=31;i>=0;i--){ + 75c: e3a0001f mov r0, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 760: e1a0c007 mov ip, r7 + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 764: e1a0e031 lsr lr, r1, r0 + 768: e20ee001 and lr, lr, #1 + 76c: e18ec08c orr ip, lr, ip, lsl #1 + if(r >= d) { + 770: e152000c cmp r2, ip + r = r - d; + q = q | (1 << i); + 774: 91877018 orrls r7, r7, r8, lsl r0 + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 778: 9062c00c rsbls ip, r2, ip +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 77c: e2500001 subs r0, r0, #1 + 780: 2afffff7 bcs 764 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 784: e0000792 mul r0, r2, r7 + }while((x = y) != 0); + 788: e3570000 cmp r7, #0 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 78c: e0601001 rsb r1, r0, r1 + 790: e28a5001 add r5, sl, #1 + 794: e7d91001 ldrb r1, [r9, r1] + 798: e7c6100a strb r1, [r6, sl] + }while((x = y) != 0); + 79c: 11a01007 movne r1, r7 + + b = base; + i = 0; + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + 7a0: 11a0a005 movne sl, r5 + 7a4: 1affffeb bne 758 + }while((x = y) != 0); + if(neg) + 7a8: e3530000 cmp r3, #0 + buf[i++] = '-'; + 7ac: 124b2024 subne r2, fp, #36 ; 0x24 + 7b0: 10823005 addne r3, r2, r5 + 7b4: 128a5002 addne r5, sl, #2 + + while(--i >= 0) + 7b8: e2455001 sub r5, r5, #1 + do{ + y = div(x, b); + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + 7bc: 13a0202d movne r2, #45 ; 0x2d + 7c0: 15432010 strbne r2, [r3, #-16] + + while(--i >= 0) + putc(fd, buf[i]); + 7c4: e7d61005 ldrb r1, [r6, r5] + 7c8: e1a00004 mov r0, r4 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 7cc: e2455001 sub r5, r5, #1 + putc(fd, buf[i]); + 7d0: ebffffc7 bl 6f4 + buf[i++] = digits[x - y * b]; + }while((x = y) != 0); + if(neg) + buf[i++] = '-'; + + while(--i >= 0) + 7d4: e3750001 cmn r5, #1 + 7d8: 1afffff9 bne 7c4 + putc(fd, buf[i]); +} + 7dc: e24bd020 sub sp, fp, #32 + 7e0: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc} + 7e4: 00000b38 .word 0x00000b38 + +000007e8
: + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 7e8: e3a03000 mov r3, #0 +{ + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + 7ec: e92d0830 push {r4, r5, fp} + 7f0: e1a02000 mov r2, r0 + 7f4: e28db008 add fp, sp, #8 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 7f8: e3a0c01f mov ip, #31 + write(fd, &c, 1); +} + +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + 7fc: e1a00003 mov r0, r3 + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + q = q | (1 << i); + 800: e3a05001 mov r5, #1 + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + 804: e1a04c32 lsr r4, r2, ip + 808: e2044001 and r4, r4, #1 + 80c: e1843083 orr r3, r4, r3, lsl #1 + if(r >= d) { + 810: e1530001 cmp r3, r1 + r = r - d; + q = q | (1 << i); + 814: 21800c15 orrcs r0, r0, r5, lsl ip + + for(i=31;i>=0;i--){ + r = r << 1; + r = r | ((n >> i) & 1); + if(r >= d) { + r = r - d; + 818: 20613003 rsbcs r3, r1, r3 +u32 div(u32 n, u32 d) // long division +{ + u32 q=0, r=0; + int i; + + for(i=31;i>=0;i--){ + 81c: e25cc001 subs ip, ip, #1 + 820: 2afffff7 bcs 804 + r = r - d; + q = q | (1 << i); + } + } + return q; +} + 824: e24bd008 sub sp, fp, #8 + 828: e8bd0830 pop {r4, r5, fp} + 82c: e12fff1e bx lr + +00000830 : +} + +// Print to the given fd. Only understands %d, %x, %p, %s. +void +printf(int fd, char *fmt, ...) +{ + 830: e92d000e push {r1, r2, r3} + 834: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 838: e28db020 add fp, sp, #32 + 83c: e1a05000 mov r5, r0 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 840: e59b4004 ldr r4, [fp, #4] + 844: e5d48000 ldrb r8, [r4] + 848: e3580000 cmp r8, #0 + 84c: 0a000027 beq 8f0 + ap++; + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + 850: e59f712c ldr r7, [pc, #300] ; 984 + char *s; + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + 854: e28b6008 add r6, fp, #8 +{ + char *s; + int c, i, state; + uint *ap; + + state = 0; + 858: e3a0a000 mov sl, #0 + 85c: ea000008 b 884 + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 860: e3580025 cmp r8, #37 ; 0x25 + state = '%'; + 864: 01a0a008 moveq sl, r8 + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + c = fmt[i] & 0xff; + if(state == 0){ + if(c == '%'){ + 868: 0a000002 beq 878 + state = '%'; + } else { + putc(fd, c); + 86c: e1a00005 mov r0, r5 + 870: e1a01008 mov r1, r8 + 874: ebffff9e bl 6f4 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 878: e5f48001 ldrb r8, [r4, #1]! + 87c: e3580000 cmp r8, #0 + 880: 0a00001a beq 8f0 + c = fmt[i] & 0xff; + if(state == 0){ + 884: e35a0000 cmp sl, #0 + 888: 0afffff4 beq 860 + if(c == '%'){ + state = '%'; + } else { + putc(fd, c); + } + } else if(state == '%'){ + 88c: e35a0025 cmp sl, #37 ; 0x25 + 890: 1afffff8 bne 878 + if(c == 'd'){ + 894: e3580064 cmp r8, #100 ; 0x64 + 898: 0a00002c beq 950 + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + 89c: e3580078 cmp r8, #120 ; 0x78 + 8a0: 13580070 cmpne r8, #112 ; 0x70 + 8a4: 13a09000 movne r9, #0 + 8a8: 03a09001 moveq r9, #1 + 8ac: 0a000013 beq 900 + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + 8b0: e3580073 cmp r8, #115 ; 0x73 + 8b4: 0a000018 beq 91c + s = "(null)"; + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + 8b8: e3580063 cmp r8, #99 ; 0x63 + 8bc: 0a00002a beq 96c + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 8c0: e3580025 cmp r8, #37 ; 0x25 + putc(fd, c); + 8c4: e1a0100a mov r1, sl + 8c8: e1a00005 mov r0, r5 + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + ap++; + } else if(c == '%'){ + 8cc: 0a000002 beq 8dc + putc(fd, c); + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + 8d0: ebffff87 bl 6f4 + putc(fd, c); + 8d4: e1a00005 mov r0, r5 + 8d8: e1a01008 mov r1, r8 + 8dc: ebffff84 bl 6f4 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 8e0: e5f48001 ldrb r8, [r4, #1]! + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 8e4: e1a0a009 mov sl, r9 + int c, i, state; + uint *ap; + + state = 0; + ap = (uint*)(void*)&fmt + 1; + for(i = 0; fmt[i]; i++){ + 8e8: e3580000 cmp r8, #0 + 8ec: 1affffe4 bne 884 + putc(fd, c); + } + state = 0; + } + } +} + 8f0: e24bd020 sub sp, fp, #32 + 8f4: e8bd4ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 8f8: e28dd00c add sp, sp, #12 + 8fc: e12fff1e bx lr + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + 900: e1a00005 mov r0, r5 + 904: e4961004 ldr r1, [r6], #4 + 908: e3a02010 mov r2, #16 + 90c: e3a03000 mov r3, #0 + 910: ebffff81 bl 71c + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 914: e3a0a000 mov sl, #0 + 918: eaffffd6 b 878 + ap++; + } else if(c == 'x' || c == 'p'){ + printint(fd, *ap, 16, 0); + ap++; + } else if(c == 's'){ + s = (char*)*ap; + 91c: e4968004 ldr r8, [r6], #4 + ap++; + if(s == 0) + s = "(null)"; + 920: e3580000 cmp r8, #0 + 924: 01a08007 moveq r8, r7 + while(*s != 0){ + 928: e5d81000 ldrb r1, [r8] + 92c: e3510000 cmp r1, #0 + 930: 0a000004 beq 948 + putc(fd, *s); + 934: e1a00005 mov r0, r5 + 938: ebffff6d bl 6f4 + } else if(c == 's'){ + s = (char*)*ap; + ap++; + if(s == 0) + s = "(null)"; + while(*s != 0){ + 93c: e5f81001 ldrb r1, [r8, #1]! + 940: e3510000 cmp r1, #0 + 944: 1afffffa bne 934 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 948: e1a0a001 mov sl, r1 + 94c: eaffffc9 b 878 + } else { + putc(fd, c); + } + } else if(state == '%'){ + if(c == 'd'){ + printint(fd, *ap, 10, 1); + 950: e1a00005 mov r0, r5 + 954: e4961004 ldr r1, [r6], #4 + 958: e3a0200a mov r2, #10 + 95c: e3a03001 mov r3, #1 + 960: ebffff6d bl 71c + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 964: e3a0a000 mov sl, #0 + 968: eaffffc2 b 878 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 96c: e4961004 ldr r1, [r6], #4 + 970: e1a00005 mov r0, r5 + } else { + // Unknown % sequence. Print it to draw attention. + putc(fd, '%'); + putc(fd, c); + } + state = 0; + 974: e1a0a009 mov sl, r9 + while(*s != 0){ + putc(fd, *s); + s++; + } + } else if(c == 'c'){ + putc(fd, *ap); + 978: e6ef1071 uxtb r1, r1 + 97c: ebffff5c bl 6f4 + 980: eaffffbc b 878 + 984: 00000b4c .word 0x00000b4c + +00000988 : +free(void *ap) +{ + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 988: e59f3098 ldr r3, [pc, #152] ; a28 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 98c: e92d0830 push {r4, r5, fp} + Header *bp, *p; + + bp = (Header*)ap - 1; + 990: e240c008 sub ip, r0, #8 + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 994: e5932000 ldr r2, [r3] +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 998: e28db008 add fp, sp, #8 + Header *bp, *p; + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + 99c: e152000c cmp r2, ip + 9a0: e5921000 ldr r1, [r2] + 9a4: 2a000001 bcs 9b0 + 9a8: e15c0001 cmp ip, r1 + 9ac: 3a000007 bcc 9d0 + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + 9b0: e1520001 cmp r2, r1 + 9b4: 3a000003 bcc 9c8 + 9b8: e152000c cmp r2, ip + 9bc: 3a000003 bcc 9d0 + 9c0: e15c0001 cmp ip, r1 + 9c4: 3a000001 bcc 9d0 +static Header base; +static Header *freep; + +void +free(void *ap) +{ + 9c8: e1a02001 mov r2, r1 + 9cc: eafffff2 b 99c + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + 9d0: e5104004 ldr r4, [r0, #-4] + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + freep = p; + 9d4: e5832000 str r2, [r3] + + bp = (Header*)ap - 1; + for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) + if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) + break; + if(bp + bp->s.size == p->s.ptr){ + 9d8: e08c5184 add r5, ip, r4, lsl #3 + 9dc: e1550001 cmp r5, r1 + bp->s.size += p->s.ptr->s.size; + 9e0: 05911004 ldreq r1, [r1, #4] + 9e4: 00814004 addeq r4, r1, r4 + 9e8: 05004004 streq r4, [r0, #-4] + bp->s.ptr = p->s.ptr->s.ptr; + 9ec: 05921000 ldreq r1, [r2] + 9f0: 05911000 ldreq r1, [r1] + } else + bp->s.ptr = p->s.ptr; + 9f4: e5001008 str r1, [r0, #-8] + if(p + p->s.size == bp){ + 9f8: e5921004 ldr r1, [r2, #4] + 9fc: e0824181 add r4, r2, r1, lsl #3 + a00: e15c0004 cmp ip, r4 + p->s.size += bp->s.size; + p->s.ptr = bp->s.ptr; + } else + p->s.ptr = bp; + a04: 1582c000 strne ip, [r2] + bp->s.size += p->s.ptr->s.size; + bp->s.ptr = p->s.ptr->s.ptr; + } else + bp->s.ptr = p->s.ptr; + if(p + p->s.size == bp){ + p->s.size += bp->s.size; + a08: 0510c004 ldreq ip, [r0, #-4] + a0c: 008c1001 addeq r1, ip, r1 + a10: 05821004 streq r1, [r2, #4] + p->s.ptr = bp->s.ptr; + a14: 05101008 ldreq r1, [r0, #-8] + a18: 05821000 streq r1, [r2] + } else + p->s.ptr = bp; + freep = p; +} + a1c: e24bd008 sub sp, fp, #8 + a20: e8bd0830 pop {r4, r5, fp} + a24: e12fff1e bx lr + a28: 00000b54 .word 0x00000b54 + +00000a2c : + return freep; +} + +void* +malloc(uint nbytes) +{ + a2c: e92d49f8 push {r3, r4, r5, r6, r7, r8, fp, lr} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + a30: e2804007 add r4, r0, #7 + if((prevp = freep) == 0){ + a34: e59f50d4 ldr r5, [pc, #212] ; b10 +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + a38: e1a041a4 lsr r4, r4, #3 + return freep; +} + +void* +malloc(uint nbytes) +{ + a3c: e28db01c add fp, sp, #28 + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + a40: e5953000 ldr r3, [r5] +malloc(uint nbytes) +{ + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + a44: e2844001 add r4, r4, #1 + if((prevp = freep) == 0){ + a48: e3530000 cmp r3, #0 + a4c: 0a00002b beq b00 + a50: e5930000 ldr r0, [r3] + a54: e5902004 ldr r2, [r0, #4] + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + a58: e1520004 cmp r2, r4 + a5c: 2a00001b bcs ad0 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + a60: e59f80ac ldr r8, [pc, #172] ; b14 + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + a64: e1a07184 lsl r7, r4, #3 + a68: ea000003 b a7c + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + a6c: e5930000 ldr r0, [r3] + if(p->s.size >= nunits){ + a70: e5902004 ldr r2, [r0, #4] + a74: e1540002 cmp r4, r2 + a78: 9a000014 bls ad0 + p->s.size = nunits; + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + a7c: e5952000 ldr r2, [r5] + a80: e1a03000 mov r3, r0 + a84: e1500002 cmp r0, r2 + a88: 1afffff7 bne a6c +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + a8c: e1540008 cmp r4, r8 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + a90: 81a00007 movhi r0, r7 + a94: 93a00902 movls r0, #32768 ; 0x8000 +morecore(uint nu) +{ + char *p; + Header *hp; + + if(nu < 4096) + a98: 81a06004 movhi r6, r4 + a9c: 93a06a01 movls r6, #4096 ; 0x1000 + nu = 4096; + p = sbrk(nu * sizeof(Header)); + aa0: ebfffeec bl 658 + aa4: e1a03000 mov r3, r0 + if(p == (char*)-1) + aa8: e3730001 cmn r3, #1 + return 0; + hp = (Header*)p; + hp->s.size = nu; + free((void*)(hp + 1)); + aac: e2800008 add r0, r0, #8 + Header *hp; + + if(nu < 4096) + nu = 4096; + p = sbrk(nu * sizeof(Header)); + if(p == (char*)-1) + ab0: 0a000010 beq af8 + return 0; + hp = (Header*)p; + hp->s.size = nu; + ab4: e5836004 str r6, [r3, #4] + free((void*)(hp + 1)); + ab8: ebffffb2 bl 988 + return freep; + abc: e5953000 ldr r3, [r5] + } + freep = prevp; + return (void*)(p + 1); + } + if(p == freep) + if((p = morecore(nunits)) == 0) + ac0: e3530000 cmp r3, #0 + ac4: 1affffe8 bne a6c + return 0; + ac8: e1a00003 mov r0, r3 + } +} + acc: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + base.s.ptr = freep = prevp = &base; + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + ad0: e1540002 cmp r4, r2 + prevp->s.ptr = p->s.ptr; + else { + p->s.size -= nunits; + ad4: 10642002 rsbne r2, r4, r2 + ad8: 15802004 strne r2, [r0, #4] + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + adc: 05902000 ldreq r2, [r0] + else { + p->s.size -= nunits; + p += p->s.size; + ae0: 10800182 addne r0, r0, r2, lsl #3 + base.s.size = 0; + } + for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ + if(p->s.size >= nunits){ + if(p->s.size == nunits) + prevp->s.ptr = p->s.ptr; + ae4: 05832000 streq r2, [r3] + else { + p->s.size -= nunits; + p += p->s.size; + p->s.size = nunits; + ae8: 15804004 strne r4, [r0, #4] + } + freep = prevp; + aec: e5853000 str r3, [r5] + return (void*)(p + 1); + af0: e2800008 add r0, r0, #8 + af4: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + } + if(p == freep) + if((p = morecore(nunits)) == 0) + return 0; + af8: e3a00000 mov r0, #0 + afc: e8bd89f8 pop {r3, r4, r5, r6, r7, r8, fp, pc} + Header *p, *prevp; + uint nunits; + + nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; + if((prevp = freep) == 0){ + base.s.ptr = freep = prevp = &base; + b00: e2850004 add r0, r5, #4 + b04: e5850000 str r0, [r5] + base.s.size = 0; + b08: e9850009 stmib r5, {r0, r3} + b0c: eaffffd3 b a60 + b10: 00000b54 .word 0x00000b54 + b14: 00000fff .word 0x00000fff diff -r 000000000000 -r c450faca55f4 uprogs/zombie.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/zombie.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,18 @@ +// Create a zombie process that +// must be reparented at exit. + +#include "types.h" +#include "stat.h" +#include "user.h" + +int +main(void) +{ + if(fork() > 0){ + sleep(5); // Let child exit before parent. + printf(2, "Parent exits!\n"); + exit(); + } + printf(2, "Child exits!\n"); + exit(); +} diff -r 000000000000 -r c450faca55f4 uprogs/zombie.sym --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uprogs/zombie.sym Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,64 @@ +00000000 .text +00000b18 .rodata +00000b54 .bss +00000000 .comment +00000000 .ARM.attributes +00000000 .debug_aranges +00000000 .debug_info +00000000 .debug_abbrev +00000000 .debug_line +00000000 .debug_frame +00000000 .debug_str +00000000 .debug_loc +00000000 .debug_ranges +00000000 zombie.c +00000000 ulib.c +00000000 printf.c +000006f4 putc +0000071c printint +00000b38 digits.993 +00000000 umalloc.c +00000b54 freep +00000b58 base +00000044 strcpy +00000830 printf +0000027c memmove +000004b8 mknod +00000b60 _bss_end__ +00000174 gets +00000624 getpid +00000a2c malloc +0000068c sleep +00000b54 __bss_start__ +0000034c pipe +000003b4 write +00000520 fstat +0000041c kill +000005bc chdir +00000450 exec +00000b60 __bss_end__ +00000318 wait +00000380 read +000004ec unlink +000002b0 fork +00000658 sbrk +000006c0 uptime +00000b54 __bss_start +000000f8 memset +00000000 main +00000b60 __end__ +0000006c strcmp +000005f0 dup +000001ec stat +00000b54 _edata +00000b60 _end +00000554 link +000002e4 exit +00000228 atoi +000000b8 strlen +00000484 open +000007e8 div +00000130 strchr +00000588 mkdir +000003e8 close +00000988 free