diff options
author | Freya Murphy <freya@freyacat.org> | 2025-03-25 17:36:52 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2025-03-25 17:38:22 -0400 |
commit | 6af21e6a4f2251e71353562d5df7f376fdffc270 (patch) | |
tree | de20c7afc9878422c81e34f30c6b010075e9e69a | |
download | comus-6af21e6a4f2251e71353562d5df7f376fdffc270.tar.gz comus-6af21e6a4f2251e71353562d5df7f376fdffc270.tar.bz2 comus-6af21e6a4f2251e71353562d5df7f376fdffc270.zip |
initial checkout from wrc
-rw-r--r-- | 0.S | 11 | ||||
-rw-r--r-- | 0.c | 35 | ||||
-rw-r--r-- | 0.h | 38 | ||||
-rwxr-xr-x | BuildImage | bin | 0 -> 22896 bytes | |||
-rwxr-xr-x | MK | 36 | ||||
-rwxr-xr-x | MKV | 36 | ||||
-rw-r--r-- | Makefile | 319 | ||||
-rwxr-xr-x | QRUN | 16 | ||||
-rw-r--r-- | boot/Make.mk | 43 | ||||
-rw-r--r-- | boot/boot.S | 666 | ||||
-rw-r--r-- | doc/Memory.txt | 92 | ||||
-rw-r--r-- | doc/NOTES | 162 | ||||
-rw-r--r-- | doc/user_image.txt | 5841 | ||||
-rw-r--r-- | doc/usermatrix.txt | 53 | ||||
-rw-r--r-- | include/bootstrap.h | 120 | ||||
-rw-r--r-- | include/cio.h | 287 | ||||
-rw-r--r-- | include/clock.h | 55 | ||||
-rw-r--r-- | include/common.h | 31 | ||||
-rw-r--r-- | include/compat.h | 131 | ||||
-rw-r--r-- | include/debug.h | 324 | ||||
-rw-r--r-- | include/defs.h | 129 | ||||
-rw-r--r-- | include/elf.h | 235 | ||||
-rw-r--r-- | include/kdefs.h | 146 | ||||
-rw-r--r-- | include/klib.h | 57 | ||||
-rw-r--r-- | include/kmem.h | 138 | ||||
-rw-r--r-- | include/lib.h | 287 | ||||
-rw-r--r-- | include/list.h | 68 | ||||
-rw-r--r-- | include/params.h | 31 | ||||
-rw-r--r-- | include/procs.h | 452 | ||||
-rw-r--r-- | include/sio.h | 168 | ||||
-rw-r--r-- | include/support.h | 87 | ||||
-rw-r--r-- | include/syscalls.h | 80 | ||||
-rw-r--r-- | include/types.h | 58 | ||||
-rw-r--r-- | include/udefs.h | 113 | ||||
-rw-r--r-- | include/ulib.h | 315 | ||||
-rw-r--r-- | include/user.h | 138 | ||||
-rw-r--r-- | include/userids.h | 33 | ||||
-rw-r--r-- | include/vm.h | 433 | ||||
-rw-r--r-- | include/vmtables.h | 43 | ||||
-rw-r--r-- | include/x86/arch.h | 303 | ||||
-rw-r--r-- | include/x86/bios.h | 73 | ||||
-rw-r--r-- | include/x86/ops.h | 443 | ||||
-rw-r--r-- | include/x86/pic.h | 139 | ||||
-rw-r--r-- | include/x86/pit.h | 82 | ||||
-rw-r--r-- | include/x86/uart.h | 349 | ||||
-rw-r--r-- | kernel/Make.mk | 66 | ||||
-rw-r--r-- | kernel/cio.c | 796 | ||||
-rw-r--r-- | kernel/clock.c | 163 | ||||
-rw-r--r-- | kernel/isrs.S | 374 | ||||
-rw-r--r-- | kernel/kernel.c | 381 | ||||
-rw-r--r-- | kernel/kernel.ld | 57 | ||||
-rw-r--r-- | kernel/kmem.c | 681 | ||||
-rw-r--r-- | kernel/list.c | 64 | ||||
-rw-r--r-- | kernel/procs.c | 1136 | ||||
-rw-r--r-- | kernel/sio.c | 694 | ||||
-rw-r--r-- | kernel/startup.S | 153 | ||||
-rw-r--r-- | kernel/support.c | 279 | ||||
-rw-r--r-- | kernel/syscalls.c | 829 | ||||
-rw-r--r-- | kernel/user.c | 774 | ||||
-rw-r--r-- | kernel/vm.c | 585 | ||||
-rw-r--r-- | kernel/vmtables.c | 270 | ||||
-rw-r--r-- | lib/Make.mk | 73 | ||||
-rw-r--r-- | lib/bound.c | 37 | ||||
-rw-r--r-- | lib/cvtdec.c | 43 | ||||
-rw-r--r-- | lib/cvtdec0.c | 44 | ||||
-rw-r--r-- | lib/cvthex.c | 49 | ||||
-rw-r--r-- | lib/cvtoct.c | 54 | ||||
-rw-r--r-- | lib/cvtuns.c | 37 | ||||
-rw-r--r-- | lib/cvtuns0.c | 39 | ||||
-rw-r--r-- | lib/entry.S | 25 | ||||
-rw-r--r-- | lib/klibc.c | 112 | ||||
-rw-r--r-- | lib/memclr.c | 37 | ||||
-rw-r--r-- | lib/memcpy.c | 41 | ||||
-rw-r--r-- | lib/memset.c | 38 | ||||
-rw-r--r-- | lib/pad.c | 35 | ||||
-rw-r--r-- | lib/padstr.c | 61 | ||||
-rw-r--r-- | lib/sprint.c | 133 | ||||
-rw-r--r-- | lib/str2int.c | 51 | ||||
-rw-r--r-- | lib/strcat.c | 38 | ||||
-rw-r--r-- | lib/strcmp.c | 32 | ||||
-rw-r--r-- | lib/strcpy.c | 35 | ||||
-rw-r--r-- | lib/strlen.c | 32 | ||||
-rw-r--r-- | lib/ulibc.c | 162 | ||||
-rw-r--r-- | lib/ulibs.S | 93 | ||||
-rw-r--r-- | user/Make.mk | 64 | ||||
-rw-r--r-- | user/README | 25 | ||||
-rw-r--r-- | user/idle.c | 51 | ||||
-rw-r--r-- | user/init.c | 185 | ||||
-rw-r--r-- | user/progABC.c | 68 | ||||
-rw-r--r-- | user/progDE.c | 56 | ||||
-rw-r--r-- | user/progFG.c | 55 | ||||
-rw-r--r-- | user/progH.c | 66 | ||||
-rw-r--r-- | user/progI.c | 104 | ||||
-rw-r--r-- | user/progJ.c | 52 | ||||
-rw-r--r-- | user/progKL.c | 61 | ||||
-rw-r--r-- | user/progMN.c | 72 | ||||
-rw-r--r-- | user/progP.c | 51 | ||||
-rw-r--r-- | user/progQ.c | 43 | ||||
-rw-r--r-- | user/progR.c | 99 | ||||
-rw-r--r-- | user/progS.c | 50 | ||||
-rw-r--r-- | user/progTUV.c | 169 | ||||
-rw-r--r-- | user/progW.c | 57 | ||||
-rw-r--r-- | user/progX.c | 48 | ||||
-rw-r--r-- | user/progY.c | 49 | ||||
-rw-r--r-- | user/progZ.c | 57 | ||||
-rw-r--r-- | user/shell.c | 343 | ||||
-rw-r--r-- | user/user.ld | 51 | ||||
-rw-r--r-- | util/BuildImage.c | 415 | ||||
-rw-r--r-- | util/Make.mk | 59 | ||||
-rw-r--r-- | util/Offsets.c | 250 | ||||
-rw-r--r-- | util/alternatives/Make.mk | 56 | ||||
-rw-r--r-- | util/alternatives/README | 31 | ||||
-rw-r--r-- | util/alternatives/kmem.c | 749 | ||||
-rw-r--r-- | util/alternatives/lib.c | 56 | ||||
-rw-r--r-- | util/gdbinit.tmpl | 31 | ||||
-rw-r--r-- | util/listblob.c | 248 | ||||
-rw-r--r-- | util/mergedep.pl | 86 | ||||
-rw-r--r-- | util/mkblob.c | 324 | ||||
-rw-r--r-- | vmtables.d | 5 |
119 files changed, 25485 insertions, 0 deletions
@@ -0,0 +1,11 @@ +/** +** @file ? +** +** @author CSCI-452 class of 20245 +** +** @brief ? +*/ + +#define ASM_SRC + + .arch i386 @@ -0,0 +1,35 @@ +/** +** @file ? +** +** @author CSCI-452 class of 20245 +** +** @brief ? +*/ + +#define KERNEL_SRC + +#include <common.h> + +/* +** PRIVATE DEFINITIONS +*/ + +/* +** PRIVATE DATA TYPES +*/ + +/* +** PRIVATE GLOBAL VARIABLES +*/ + +/* +** PUBLIC GLOBAL VARIABLES +*/ + +/* +** PRIVATE FUNCTIONS +*/ + +/* +** PUBLIC FUNCTIONS +*/ @@ -0,0 +1,38 @@ +/** +** @file ? +** +** @author CSCI-452 class of 20245 +** +** @brief ? +*/ + +#ifndef ?_H_ +#define ?_H_ + +#include <common.h> + +/* +** General (C and/or assembly) definitions +*/ + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +*/ + +/* +** Types +*/ + +/* +** Globals +*/ + +/* +** Prototypes +*/ + +#endif /* !ASM_SRC */ + +#endif diff --git a/BuildImage b/BuildImage Binary files differnew file mode 100755 index 0000000..c281af3 --- /dev/null +++ b/BuildImage @@ -0,0 +1,36 @@ +#!/bin/bash +# +# Run 'make', saving all output into a file named LOG +# +# usage: +# MK [args] - prints timestamps and status +# MKV [args] - echoes and saves 'make' output +# + +# remember this so we know what to do +name="`basename $0`" + +# starting timestamp +time1="`date`" + +if [ "$name" = "MK" ] +then + # run make, save output, check status + echo -n + make $* '> LOG 2>&1 ... ' + if make $* > LOG 2>&1 + then + echo done + else + echo check LOG for build errors + fi +else + # just do the make and save a copy of the output + echo + make $* '2>&1 | tee LOG' + make $* 2>&1 | tee LOG +fi + +# ending timestamp +time2="`date`" + +echo Start: $time1 +echo "End: " $time2 @@ -0,0 +1,36 @@ +#!/bin/bash +# +# Run 'make', saving all output into a file named LOG +# +# usage: +# MK [args] - prints timestamps and status +# MKV [args] - echoes and saves 'make' output +# + +# remember this so we know what to do +name="`basename $0`" + +# starting timestamp +time1="`date`" + +if [ "$name" = "MK" ] +then + # run make, save output, check status + echo -n + make $* '> LOG 2>&1 ... ' + if make $* > LOG 2>&1 + then + echo done + else + echo check LOG for build errors + fi +else + # just do the make and save a copy of the output + echo + make $* '2>&1 | tee LOG' + make $* 2>&1 | tee LOG +fi + +# ending timestamp +time2="`date`" + +echo Start: $time1 +echo "End: " $time2 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..67353ce --- /dev/null +++ b/Makefile @@ -0,0 +1,319 @@ +# +# Makefile for the 20245 operating system. +# + +######################################## +# Compilation/assembly definable options +######################################## + +# +# General options: +# CLEAR_BSS include code to clear all BSS space +# GET_MMAP get BIOS memory map via int 0x15 0xE820 +# OS_CONFIG OS-related (vs. just standalone) variations +# FORCE_INLINING force "inline" functions to be inlined even if +# we aren't compiling with at least -O2 +# MAKE_IDENTITY_MAP Compile vmtables.c with an "identity" page +# map table for the first 4MB of the address space. +# + +GEN_OPTIONS = -DCLEAR_BSS -DGET_MMAP -DOS_CONFIG + +# +# Debugging options: +# ANNOUNCE_ENTRY announce entry and exit from kernel functions +# RPT_INT_UNEXP report any 'unexpected' interrupts +# RPT_INT_MYSTERY report interrupt 0x27 specifically +# TRACE_CX context restore tracing +# SANITY=n enable "sanity check" level 'n' (0/1/2/3/4) +# T_* tracing options (see below) +# +# Some modules have their own internal debugging options, described +# in their introductory comments. +# +# Define SANITY as 0 for minimal runtime checking (critical errors only). +# If not defined, SANITY defaults to 9999. +# + +DBG_OPTIONS = -DRPT_INT_UNEXP +# DBG_OPTIONS += -DTRACE_CX + +# +# T_ options are used to define bits in a "tracing" bitmask, to allow +# checking of individual conditions. The following are defined: +# +# T_PCB PCB alloc/dealloc +# T_VM VM-related tasks +# T_QUE PCB queue manipulation +# T_SCH, T_DSP Scheduler and dispatcher +# T_SCALL, T_SRET System call entry and exit +# T_EXIT Process exit actions +# T_FORK, T_EXEC Fork and exec actions +# T_INIT Module init function tracing +# T_KM, T_KMFR, T_KMIN Kmem module tracing +# T_SIO, T_SIOR, T_SIOW General SIO module checks +# T_USER, T_ELF User module operations +# +# You can add compilation options "on the fly" by using EXTRAS=thing +# on the command line. For example, to compile with -H (to show the +# hierarchy of #includes): +# +# make EXTRAS=-H +# + +TRACE_OPTIONS = -DT_INIT -DT_USER -DT_ELF -DT_KMIN -DT_VM + +USER_OPTIONS = $(GEN_OPTIONS) $(DBG_OPTIONS) $(TRACE_OPTIONS) $(EXTRAS) + +############################################################## +# YOU SHOULD NOT NEED TO CHANGE ANYTHING BELOW THIS POINT!!! # +############################################################## + +# +# Compilation/assembly control +# + +# +# We only want to include from the common header directory +# +INCLUDES = -I./include + +# +# All our object code will live here +# +BUILDDIR = build +LIBDIR = $(BUILDDIR)/lib + +# +# Things we need to convert to object form +# +SUBDIRS := + +# +# Compilation/assembly/linking commands and options +# +CPP = cpp +CPPFLAGS = $(USER_OPTIONS) -nostdinc $(INCLUDES) + +# +# Compiler/assembler/etc. settings for 32-bit binaries +# +CC = gcc -pipe +CFLAGS = -m32 -fno-pie -std=c99 -fno-stack-protector -fno-builtin -Wall -Wstrict-prototypes -MD $(CPPFLAGS) +# CFLAGS += -O2 + +AS = as +ASFLAGS = --32 + +LD = ld +LDFLAGS = -melf_i386 -no-pie -nostdlib -L$(LIBDIR) + +AR = ar +#ARFLAGS = rvU +ARFLAGS = rsU + +# other programs we use +OBJDUMP = objdump +OBJCOPY = objcopy +NM = nm +READELF = readelf +PERL = perl + +# delete target files if there is an error, or if make is interrupted +.DELETE_ON_ERROR: + +# don't delete intermediate files +.PRECIOUS: %.o $(BUILDDIR)/boot/%.o $(BUILDDIR)/kernel/%.o \ + $(BUILDDIR)/lib/%.o $(BUILDDIR)/user/%.o + +# +# Update $(BUILDDIR)/.vars.X if variable X has changed since the last time +# 'make' was run. +# +# Rules that use variable X should depend on $(BUILDDIR)/.vars.X. If +# the variable's value has changed, this will update the vars file and +# force a rebuild of the rule that depends on it. +# + +$(BUILDDIR)/.vars.%: FORCE + echo "$($*)" | cmp -s $@ || echo "$($*)" > $@ + +.PRECIOUS: $(BUILDDIR)/.vars.% + +.PHONY: FORCE + +# +# Transformation rules - these ensure that all necessary compilation +# flags are specified +# +# Note use of 'cpp' to convert .S files to temporary .s files: this allows +# use of #include/#define/#ifdef statements. However, the line numbers of +# error messages reflect the .s file rather than the original .S file. +# (If the .s file already exists before a .S file is assembled, then +# the temporary .s file is not deleted. This is useful for figuring +# out the line numbers of error messages, but take care not to accidentally +# start fixing things by editing the .s file.) +# +# The .c.X rule produces a .X file which contains the original C source +# code from the file being compiled mixed in with the generated +# assembly language code. Can be helpful when you need to figure out +# exactly what C statement generated which assembly statements! +# + +.SUFFIXES: .S .b .X .i + +.c.X: + $(CC) $(CFLAGS) -g -c -Wa,-adhln $*.c > $*.X + +.c.s: + $(CC) $(CFLAGS) -S $*.c + +#.S.s: +# $(CPP) $(CPPFLAGS) -o $*.s $*.S + +#.S.o: +# $(CPP) $(CPPFLAGS) -o $*.s $*.S +# $(AS) $(ASFLAGS) -o $*.o $*.s -a=$*.lst +# $(RM) -f $*.s + +.s.b: + $(AS) $(ASFLAGS) -o $*.o $*.s -a=$*.lst + $(LD) $(LDFLAGS) -Ttext 0x0 -s --oformat binary -e begtext -o $*.b $*.o + +#.c.o: +# $(CC) $(CFLAGS) -c $*.c + +.c.i: + $(CC) -E $(CFLAGS) -c $*.c > $*.i + +# +# Location of the QEMU binary +# +QEMU = /home/course/csci352/bin/qemu-system-i386 + +# try to generate a unique GDB port +GDBPORT = $(shell expr `id -u` % 5000 + 25000) + +# QEMU's gdb stub command line changed in 0.11 +QEMUGDB = $(shell if $(QEMU) -help | grep -q '^-gdb'; \ + then echo "-gdb tcp::$(GDBPORT)"; \ + else echo "-s -p $(GDBPORT)"; fi) + +# options for QEMU +# +# run 'make' with -DQEMUEXTRA=xxx to add option 'xxx' when QEMU is run +# +# does not include a '-serial' option, as that may or may not be needed +QEMUOPTS = -drive file=disk.img,index=0,media=disk,format=raw $(QEMUEXTRA) + +######################################## +# RULES SECTION +######################################## + +# +# All the individual parts +# + +# +# We have a bit of a chicken/egg problem here. When we create the +# user.img file, a new version of include/userids.h is generated +# in build/new_userids.h; this is compared to the existing userids.h +# file, and if they differ, it is copied into include/userids.h. +# This, unfortunately, should trigger a rebuild of anything that +# includes <userids.h>, but that is all of the user/*.c files along +# with kernel/kernel.c. We could move the user.img creation earlier, +# which would automatically be incorporated into the build of the +# kernel, but it wouldn't automatically trigger recreating the +# userland stuff. We settle for having the build process tell the +# user that a rebuild is required. +# + +all: lib bootstrap kernel userland util user.img disk.img + +# Rules etc. for the various sections of the system +include lib/Make.mk +include boot/Make.mk +include user/Make.mk +include kernel/Make.mk +include util/Make.mk + +# +# Rules for building the disk image +# + +disk.img: $(BUILDDIR)/kernel/kernel.b $(BUILDDIR)/boot/boot user.img BuildImage + ./BuildImage -d usb -o disk.img -b $(BUILDDIR)/boot/boot \ + $(BUILDDIR)/kernel/kernel.b 0x10000 \ + user.img 0x30000 + +# +# Rules for running with QEMU +# + +# how to create the .gdbinit config file if we need it +.gdbinit: util/gdbinit.tmpl + sed "s/localhost:1234/localhost:$(GDBPORT)/" < $^ > $@ + +# "ordinary" gdb +gdb: + gdb -q -n -x .gdbinit + +# gdb with the super-fancy Text User Interface +gdb-tui: + gdb -q -n -x .gdbinit -tui + +qemu: disk.img + $(QEMU) -serial mon:stdio $(QEMUOPTS) + +qemu-nox: disk.img + $(QEMU) -nographic $(QEMUOPTS) + +qemu-gdb: disk.img .gdbinit + @echo "*** Now run 'gdb'." 1>&2 + $(QEMU) -serial mon:stdio $(QEMUOPTS) -S $(QEMUGDB) + +qemu-nox-gdb: disk.img .gdbinit + @echo "*** Now run 'gdb'." 1>&2 + $(QEMU) -nographic $(QEMUOPTS) -S $(QEMUGDB) + +# +# Create a printable namelist from the kernel file +# +# kernel.nl: only global symbols +# kernel.nll: all symbols +# + +kernel.nl: $(BUILDDIR)/kernel/kernel + nm -Bng $(BUILDDIR)/kernel/kernel.o | pr -w80 -3 > kernel.nl + +kernel.nll: $(BUILDDIR)/kernel/kernel + nm -Bn $(BUILDDIR)/kernel/kernel.o | pr -w80 -3 > kernel.nll + +# +# Generate a disassembly +# + +kernel.dis: $(BUILDDIR)/kernel/kernel + objdump -d $(BUILDDIR)/kernel/kernel > kernel.dis + +# +# Cleanup etc. +# + +clean: + rm -rf $(BUILDDIR) .gdbinit *.nl *.nll *.lst *.i *.X *.dis + +realclean: clean + rm -f LOG *.img $(UTIL_BIN) + +# +# Automatically generate dependencies for header files included +# from C source files. +# +$(BUILDDIR)/.deps: $(foreach dir, $(SUBDIRS), $(wildcard $(BUILDDIR)/$(dir)/*.d)) + @mkdir -p $(@D) + $(PERL) util/mergedep.pl $@ $^ + +-include $(BUILDDIR)/.deps + +.PHONY: all clean realclean @@ -0,0 +1,16 @@ +#!/bin/bash +# +# Run qemu-system-i386 on the baseline OS +# + +# +# other options: +# -nographic +# -display gtk +# + +QEMU=/home/course/csci352/bin/qemu-system-i386 + +exec $QEMU \ + -serial mon:stdio \ + -drive file=disk.img,index=0,media=disk,format=raw diff --git a/boot/Make.mk b/boot/Make.mk new file mode 100644 index 0000000..a7396fb --- /dev/null +++ b/boot/Make.mk @@ -0,0 +1,43 @@ +# +# Makefile fragment for the bootstrap component of the system. +# +# THIS IS NOT A COMPLETE Makefile - run GNU make in the top-level +# directory, and this will be pulled in automatically. +# + +SUBDIRS += boot + +################### +# FILES SECTION # +################### + +BOOT_SRC := boot/boot.S + +BOOT_OBJ := $(BUILDDIR)/boot/boot.o + +# BLDFLAGS := -Ttext 0x7c00 -s --oformat binary -e bootentry +# BLDFLAGS := -Ttext 0 -s --oformat binary -e bootentry +# BLDFLAGS := -N -Ttext 0x7c00 -s -e bootentry +BLDFLAGS := -N -Ttext 0 -s -e bootentry + +################### +# RULES SECTION # +################### + +bootstrap: $(BUILDDIR)/boot/boot + +$(BUILDDIR)/boot/%.o: boot/%.c $(BUILDDIR)/.vars.CFLAGS + @mkdir -p $(@D) + $(CC) $(CFLAGS) -c -o $@ $< + +$(BUILDDIR)/boot/%.o: boot/%.S $(BUILDDIR)/.vars.CFLAGS + @mkdir -p $(@D) + $(CPP) $(CPPFLAGS) -o $(@D)/$*.s $< + $(AS) $(ASFLAGS) -o $@ $(@D)/$*.s -a=$(@D)/$*.lst + $(RM) -f $(@D)/$*.s + $(NM) -n $@ > $(@D)/$*.sym + +$(BUILDDIR)/boot/boot: $(BOOT_OBJ) + @mkdir -p $(@D) + $(LD) $(LDFLAGS) $(BLDFLAGS) -o $@.out $^ + $(OBJCOPY) -S -O binary -j .text $@.out $@ diff --git a/boot/boot.S b/boot/boot.S new file mode 100644 index 0000000..50d6188 --- /dev/null +++ b/boot/boot.S @@ -0,0 +1,666 @@ +/** +** SCCS ID: @(#)boot.S 2.4 1/22/25 +** +** @file boot.S +** +** @author Jon Coles +** copyleft 1999 Jon Coles +** +** @author Warren R. Carithers, K. Reek, Garrett C. Smith +** @author Walter Litwinczyk, David C. Larsen, Sean T. Congden +** +** Bootstrap routine. +** +** This bootstrap program is loaded by the PC BIOS into memory at +** location 0000:7C00. It must be exactly 512 bytes long, and must +** end with the hex sequence AA55 at location 1FE. +** +** The bootstrap initially sets up a stack in low memory. Next, it +** loads a second sector at 0000:7E00 (immediately following the +** boot block). Then it loads the target program at TARGET_ADDR, +** switches to protected mode, and branches to the target program. +** +** NOTE: To zero out the BSS segment, define CLEAR_BSS when this code +** is assembled. +** +** Must assemble this as 16-bit code. +*/ + .code16 + +#define ASM_SRC + +#include <bootstrap.h> +#include <x86/bios.h> +#include <x86/arch.h> + +/* +** Symbol for locating the beginning of the code. +*/ + .globl bootentry + + .text +bootentry: + +/* +** Entry point. Disable interrupts and set up a runtime stack. +*/ + cli + + movw $BOOT_SEG, %ax /* data seg. base address */ + movw %ax, %ds + movw %ax, %ss /* also stack seg. base */ + movw $BOOT_SP_DISP, %ax + movw %ax, %sp + +/* +** Next, verify that the disk is there and working. +*/ + movb $BD_CHECK, %ah /* test the disk status and make sure */ + movb drive, %dl /* it's safe to proceed */ + int $BIOS_DISK + jnc diskok + + movw $err_diskstatus, %si /* Something went wrong; print a message */ + call dispMsg /* and freeze. */ + jmp . + +/* +** The disk is there. Reset it, and retrieve the disk parameters. +*/ +diskok: + movw $BD_RESET, %ax /* Reset the disk */ + movb drive, %dl + int $BIOS_DISK + + /* determine number of heads and sectors/track */ + xorw %ax, %ax /* set ES:DI = 0000:0000 in case of BIOS bugs */ + movw %ax, %es + movw %ax, %di + movb $BD_PARAMS, %ah /* get drive parameters */ + movb drive, %dl /* hard disk or floppy */ + int $BIOS_DISK + + /* store (max + 1) - CL[5:0] = maximum head, DH = maximum head */ + andb $0x3F, %cl + incb %cl + incb %dh + + movb %cl, max_sec + movb %dh, max_head + +/* +** The disk is OK, so we now need to load the second half of the bootstrap. +** It must immediately follow the boot sector on the disk, and the target +** program(s) must immediately follow that. +*/ + movw $msg_loading, %si /* Print the Loading message */ + call dispMsg + + movw $1, %ax /* sector count = 1 */ + movw $BOOT_SEG, %bx /* read this into memory that */ + movw %bx, %es /* immediately follows this code. */ + movw $PART2_DISP, %bx + call readprog + +/* +** We've got the second block of the bootstrap program in memory. Now +** read all of the user's program blocks. Use %di to point to the +** count field for the next block to load. +*/ + movw $k_sect, %di + + pushw %ds + movw (%di), %bx + movw $MMAP_SEG, %ax + movw %ax, %ds + movw %bx, MMAP_SECTORS /* store kernel image size */ + popw %ds + +/* +** Each target program has three values in the array at the end of the +** second half of the bootstrap: the offset and segment base address +** where the program should go, and the sector count. +*/ +nextblock: + movw (%di), %ax /* get the # of sectors */ + testw %ax, %ax /* is it zero? */ + jz done_loading /* yes, nothing more to load. */ + + subw $2, %di + movw (%di), %bx /* get the segment value */ + movw %bx, %es /* and copy it to %es */ + subw $2, %di + movw (%di), %bx /* get the address offset */ + subw $2, %di + pushw %di /* save di */ + call readprog /* read this program block, */ + popw %di /* and restore di */ + jmp nextblock /* then go back and read the next one. */ + +/* +** Read one complete program block into memory. +** +** ax: number of sectors to read +** es:bx = starting address for the block +*/ +readprog: + pushw %ax /* save sector count */ + + movw $3, %cx /* initial retry count is 3 */ +retry: + pushw %cx /* push the retry count on the stack. */ + + movw sec, %cx /* get sector number */ + movw head, %dx /* get head number */ + movb drive, %dl + + movw $BD_READ1, %ax /* read 1 sector */ + int $BIOS_DISK + jnc readcont /* jmp if it worked ok */ + + movw $err_diskread, %si /* report the error */ + call dispMsg + popw %cx /* get the retry count back */ + loop retry /* and go try again. */ + movw $err_diskfail, %si /* can't proceed, */ + call dispMsg /* print message and freeze. */ + jmp . + +readcont: + movw $msg_dot, %si /* print status: a dot */ + call dispMsg + cmpw $OFFSET_LIMIT, %bx /* have we reached the offset limit? */ + je adjust /* Yes--must adjust the es register */ + addw $SECTOR_SIZE, %bx /* No--just adjust the block size to */ + jmp readcont2 /* the offset and continue. */ + +adjust: + movw $0, %bx /* start offset over again */ + movw %es, %ax + addw $0x1000,%ax /* move segment pointer to next chunk */ + movw %ax, %es + +readcont2: + incb %cl /* not done - move to the next sector */ + cmpb max_sec, %cl /* see if we need */ + jnz save_sector /* to switch heads or tracks */ + + movb $1, %cl /* reset sector number */ + incb %dh /* first, switch heads */ + cmpb max_head, %dh /* there are only two - if we've already */ + jnz save_sector /* used both, we need to switch tracks */ + + xorb %dh, %dh /* reset to head 0 */ + incb %ch /* inc track number */ + cmpb $80, %ch /* 80 tracks per side - have we read all? */ + jnz save_sector /* read another track */ + + movw $err_toobig, %si /* report the error */ + call dispMsg + jmp . /* and freeze */ + +save_sector: + movw %cx, sec /* save sector number */ + movw %dx, head /* and head number */ + + popw %ax /* discard the retry count */ + popw %ax /* get the sector count from the stack */ + decw %ax /* and decrement it. */ + jg readprog /* If it is zero, we're done reading. */ + +readdone: + movw $msg_bar, %si /* print message saying this block is done */ + call dispMsg + ret /* and return to the caller */ + +/* +** We've loaded the whole target program into memory, +** so it's time to transfer to the startup code. +*/ +done_loading: + movw $msg_go, %si /* last status message */ + call dispMsg + + jmp switch /* move to the next phase */ + +/* +** Support routine - display a message byte by byte to the monitor. +*/ +dispMsg: + pushw %ax + pushw %bx +repeat: + lodsb /* grab next character */ + + movb $BV_W_ADV, %ah /* write and advance cursor */ + movw $0x07, %bx /* page 0, white on blank, no blink */ + orb %al, %al /* AL is character to write */ + jz getOut /* if we've reached the NUL, get out */ + + int $BIOS_VIDEO /* otherwise, print and repeat */ + jmp repeat + +getOut: /* we're done, so return */ + popw %bx + popw %ax + ret + +/* +** Support routine - move the GDT entries from where they are to +** location 0050:0000. We need to add BOOT_ADDR because the bootstrap +** is linked at 0, but loaded at 0x7c00. +*/ +move_gdt: + movw %cs, %si + movw %si, %ds + movw $start_gdt + BOOT_ADDR, %si + movw $GDT_SEG, %di + movw %di, %es + xorw %di, %di + movl $gdt_len, %ecx + cld + rep movsb + ret + +/* +** DATA AREAS. +** +** Next sector number and head number to read from. +*/ +sec: .word 2 /* cylinder=0, sector=1 */ +head: .word 0 /* head=0 */ +max_sec: .byte 19 /* up to 18 sectors per floppy track */ +max_head: .byte 2 /* only two r/w heads per floppy drive */ + +/* +** Status and error messages. +*/ +msg_loading: .asciz "Loading" +msg_dot: .asciz "." +msg_go: .asciz "done." +msg_bar: .asciz "|" + +/* +** Error messages. +*/ +err_diskstatus: .asciz "Disk not ready.\n\r" +err_diskread: .asciz "Read failed\n\r" +err_toobig: .asciz "Too big\n\r" +err_diskfail: .asciz "Can't proceed\n\r" + +/* +** Data areas. +*/ + +/* +** The GDTR and IDTR contents. +*/ +gdt_48: + .word 0x2000 /* 1024 GDT entries x 8 bytes/entry = 8192 */ + .quad GDT_ADDR + +idt_48: + .word 0x0800 /* 256 interrupts */ + .quad IDT_ADDR + +/* +** Depending on the age of the BIOS, it may expect there to be a +** partition table for the hard drive you're booting from at this point +** in the boot sector; only the first 446 bytes (0x000-0x1bd) can be +** used for bootstrap code/data. To make life easy, we'll just skip +** over the rest of the sector. +** +** Note: when booting from floppy, this isn't a problem, because floppy +** disks don't have partition tables. On some machines, USB-type storage +** devices are treated as floppies, so they also don't have partition +** maps; however, on other systems, USB storage is treated as hard disk +** storage. +*/ + +/* +** End of the first sector of the boot program. The last two bytes +** of this sector must be AA55 in order for the disk to be recognized +** by the BIOS as bootable. +*/ + .org SECTOR_SIZE-4 + +drive: .word BDEV /* 0x00 = floppy, 0x80 = usb */ + +boot_sig: + .word 0xAA55 + +/******************************************************* +******* BEGINNING OF SECTOR TWO OF THE BOOTSTRAP ******* +*******************************************************/ + +/* +** This code configures the GDT, enters protected mode, and then +** transfers to the OS entry point. +*/ + +switch: + cli + movb $NMI_DISABLE, %al /* also disable NMIs */ + outb %al, $CMOS_ADDR + +#ifdef USE_FLOPPY + call floppy_off +#endif + call enable_A20 + call move_gdt +#ifdef GET_MMAP + call check_memory +#endif + +/* +** Get the memory address for the "user blob" out of the table +** at the end of this sector, and pass the three values to the +** protected mode code in %bx, %cx, and %dx. We could figure out +** how to find it from there, but this is easier. +*/ +# movw u_off+BOOT_ADDR, %bx +# movw u_seg+BOOT_ADDR, %cx +# movw u_sect+BOOT_ADDR, %dx + +/* +** The IDTR and GDTR are loaded relative to this segment, so we must +** use the full offsets from the beginning of the segment (0000:0000); +** however, we were loaded at 0000:7c00, so we need to add that in. +*/ + lidt idt_48 + BOOT_ADDR + lgdt gdt_48 + BOOT_ADDR + + movl %cr0, %eax /* get current CR0 */ + orl $1, %eax /* set the PE bit */ + movl %eax, %cr0 /* and store it back. */ + + /* + ** We'll be in protected mode at the start of the user's code + ** right after this jump executes. + ** + ** First, a byte to force 32-bit mode execution, followed by + ** a 32-bit long jump. The long ("far") jump loads both EIP + ** and CS with the proper values so that when we land at the + ** destination address in protected mode, the next instruction + ** fetch doesn't cause a fault. + ** + ** The old code for this: + ** + ** .byte 0x66, 0xEA + ** .long TARGET_ADDR + ** .word GDT_CODE + */ + + .byte 0x66 + .code32 + ljmp $GDT_CODE, $TARGET_ADDR + .code16 + +/* +** Supporting functions. +*/ + +#ifdef USE_FLOPPY +/* +** Turn off the motor on the floppy disk drive. +*/ +floppy_off: + push %dx + movw $0x3f2, %dx + xorb %al, %al + outb %al, %dx + pop %dx + ret +#endif + +/* +** Enable the A20 gate for full memory access. +*/ +enable_A20: + call a20wait + movb $KBD_P1_DISABLE, %al + outb %al, $KBD_CMD + + call a20wait + movb $KBD_RD_OPORT, %al + outb %al, $KBD_CMD + + call a20wait2 + inb $KBD_DATA, %al + pushl %eax + + call a20wait + movb $KBD_WT_OPORT, %al + outb %al, $KBD_CMD + + call a20wait + popl %eax + orb $2, %al + outb %al, $KBD_DATA + + call a20wait + mov $KBD_P1_ENABLE, %al + out %al, $KBD_CMD + + call a20wait + ret + +a20wait: /* wait until bit 1 of the device register is clear */ + movl $65536, %ecx /* loop a lot if need be */ +wait_loop: + inb $KBD_STAT, %al /* grab the byte */ + test $2, %al /* is the bit clear? */ + jz wait_exit /* yes */ + loop wait_loop /* no, so loop */ + jmp a20wait /* if still not clear, go again */ +wait_exit: + ret + +a20wait2: /* like a20wait, but waits until bit 0 is set. */ + mov $65536, %ecx +wait2_loop: + in $KBD_STAT, %al + test $1, %al + jnz wait2_exit + loop wait2_loop + jmp a20wait2 +wait2_exit: + ret + +#ifdef GET_MMAP +/* +** Query the BIOS to get the list of usable memory regions +** +** Adapted from: http://wiki.osdev.org/Detecting_Memory_%28x86%29 +** (see section "BIOS Function INT 0x15. EAX = 0xE820") +** +** After the first 'int', if the location 0x2D00 (4 bytes) contains -1, +** then this method failed to detect memory properly; otherwise, this +** location contains the number of elements read. +** +** The start of the array is at 0x2D04. The elements are tightly +** packed following the layout as defined below. Each entry in the +** array contains the following information: +** +** uint64_t base address of region +** uint64_t length of region (0 --> ignore the entry) +** uint32_t type of region +** uint32_t ACIP 3.0 Extended Attributes +** +** The C struct definition is as follows: +** +** struct MemMapEntry +** { +** uint32_t base[2]; // 64-bit base address +** uint32_t length[2]; // 64-bit length +** uint32_t type; // 32-bit region type +** uint32_t ACPI; // 32-bit ACPI "extended attributes" bitfield +** }; +** +** This structure must be packed in memory. This shouldn't be a problem, +** but if it is, you may need to add this attribute at the end of the +** struct declaration before the semicolon: +** +** __attribute__((packed)) +** +** Parameters: +** None +**/ +check_memory: + // save everything + // pushaw won't work here because we're still in real mode + pushw %ds + pushw %es + pushw %ax + pushw %bx + pushw %cx + pushw %dx + pushw %si + pushw %di + + // Set the start of the buffer + movw $MMAP_SEG, %bx // 0x2D0 + mov %bx, %ds // Data segment now starts at 0x2D00 + mov %bx, %es // Extended segment also starts at 0x2D00 + + // Reserve the first 4 bytes for the # of entries + movw $0x4, %di + // Make a valid ACPI 3.X entry + movw $1, %es:20(%di) + + xorw %bp, %bp // Count of entries in the list + xorl %ebx, %ebx // EBX must contain zeroes + + movl $MMAP_MAGIC_NUM, %edx // Magic number into EDX + movl $MMAP_CODE, %eax // E820 memory command + movl $MMAP_ENT, %ecx // Ask the BIOS for 24 bytes + int $BIOS_MISC // Call the BIOS + + // check for success + jc cm_failed // C == 1 --> failure + movl $MMAP_MAGIC_NUM, %edx // sometimes EDX changes + cmpl %eax, %edx // EAX should equal EDX after the call + jne cm_failed + testl %ebx, %ebx // Should have at least one more entry + je cm_failed + + jmp cm_jumpin // Good to go - start us off + +cm_loop: + movl $MMAP_CODE, %eax // Reset our registers + movw $1, 20(%di) + movl $MMAP_ENT, %ecx + int $BIOS_MISC + jc cm_end_of_list // C == 1 --> end of list + movl $MMAP_MAGIC_NUM, %edx + +cm_jumpin: + jcxz cm_skip_entry // Did we get any data? + + cmp $20, %cl // Check the byte count + jbe cm_no_text // Skip the next test if only 20 bytes + + testb $1, %es:20(%di) // Check the "ignore this entry" flag + je cm_skip_entry + +cm_no_text: + mov %es:8(%di), %ecx // lower half of length + or %es:12(%di), %ecx // now, full length + jz cm_skip_entry + + inc %bp // one more valid entry + + // make sure we don't overflow our space + cmpw $MMAP_MAX_ENTS, %bp + jge cm_end_of_list + + // we're ok - move the pointer to the next struct in the array + add $24, %di + +cm_skip_entry: + // are there more entries to retrieve? + testl %ebx, %ebx + jne cm_loop + +cm_end_of_list: + // All done! Store the number of elements in 0x2D00 + movw %bp, %ds:0x0 + + clc // Clear the carry bit and return + jmp cm_ret + +cm_failed: + movl $-1, %ds:0x0 // indicate failure + stc + +cm_ret: + // restore everything we saved + // popaw won't work here (still in real mode!) + popw %di + popw %si + popw %dx + popw %cx + popw %bx + popw %ax + popw %es + popw %ds + ret +#endif + +/* +** The GDT. This cannot be created in C because the bootstrap is not +** linked with that code. We could just have a simple "dummy" GDT here +** but that would only save us a couple of entries. Also, we could save +** some space by not having the separate 'linear' and 'stack' entries +** (they're identical to the 'data' entry). +*/ + .p2align 2 // force 4-byte alignment +start_gdt: + // selector 0x0000 is unused + SEGNULL + + // selector 0x0008 - basic linear access to all of memory + SEGMENT( 0x0, 0xffffffff, SEG_DPL_0, SEG_DATA_RW ) + + // selector 0x0010 - kernel code segment + SEGMENT( 0x0, 0xffffffff, SEG_DPL_0, SEG_CODE_XR ) + + // selector 0x0018 - kernel data segment + SEGMENT( 0x0, 0xffffffff, SEG_DPL_0, SEG_DATA_RW ) + + // selector 0x0020 - kernel stack segment + SEGMENT( 0x0, 0xffffffff, SEG_DPL_0, SEG_DATA_RW ) + + // could put additional entries here for user mode - e.g., + // 0x0028 code: SEGMENT( 0x0, 0xffffffff, SEG_DPL_3, SEG_CODE_XR ) + // 0x0030 data: SEGMENT( 0x0, 0xffffffff, SEG_DPL_3, SEG_DATA_RW ) + // 0x0038 stack: SEGMENT( 0x0, 0xffffffff, SEG_DPL_3, SEG_DATA_RW ) + +end_gdt: +gdt_len = end_gdt - start_gdt + +/* +** The end of this program will contain a list of the sizes and load +** addresses of all of the blocks to be loaded. These values are +** inserted here by the BuildImage program, which checks that there are +** not so many blocks that the GDT would be overwritten. The layout +** of the data is: +** +** struct info_s { +** short offset; +** short segment; +** short sectors; +** }; +** +** with the data for the first program at k_off, k_seg, and k_sect. +** If additional blocks are to be loaded, their values appear just +** before the previous set. +*/ + + .org BOOT_SIZE-12 +u_off: .word 0 // the "user blob" +u_seg: .word 0 +u_sect: .word 0 +k_off: .word 0 // the kernel +k_seg: .word 0 +k_sect: .word 0 diff --git a/doc/Memory.txt b/doc/Memory.txt new file mode 100644 index 0000000..cecfea3 --- /dev/null +++ b/doc/Memory.txt @@ -0,0 +1,92 @@ +Systems Programming framework memory layout + +Version: @(#)Memory.txt 2.2a +Date: 3/23/25 +--------------------------------------------------------------------------- + +This diagram shows important areas in the first 1MB of memory as seen +by the standalone framework code. + +Each row in the diagram represents 0x100 (256) bytes of memory, except in +"elided" areas (< ... >). The starting address is indicated for each +region in hex; if a CPP #define exists for that region in either +bootstrap.h or x86/bios.h, its name is also given. + + ----------------------- + | Interrupt Vector | 0x00000 + | 256 x 4 bytes | + | (1024, 0x400) | + | | + ----------------------- + | BIOS Data Area (BDA)| 0x00400 BIOS_BDA + ----------------------- + | GDT | 0x00500 GDT_ADDR + | 1024 x 8 bytes | + | (8192, 0x2000) | + | | + < . . . > + | | + ----------------------- + | IDT | 0x02500 IDT_ADDR + | 256 x 8 bytes | + | (2048, 0x800) | + | | + | | + | | + | | + | | + ----------------------- + | Mmap data | 0x02D00 MMAP_ADDR + | | + | | + | | + | | + < . . . > + | | + ----------------------- + | Bootstrap sector 1 | 0x07c00 BOOT_ADDR + | | + ----------------------- + | Bootstrap sector 2 | 0x07e00 PART2_ADDR + | | + ----------------------- + | | 0x08000 + | | + < . . . > + | ^ | + | Bootstrap stack | | + ----------------------- + | | 0x0bc00 BOOT_SP_ADDR + | | + | | + < . . . > + | OS stack | + ----------------------- + | Operating System | 0x10000 TARGET_ADDR, TARGET_STACK + | (size varies) | + | | + < . . . > + | | + ----------------------- + | User Code Blob | 0x30000 + | (size varies) | + | | + < . . . > + | | + ----------------------- + | Extended BIOS Data | 0x9fc00 + | Area (EBDA) | + | | + < . . . > + | | + ----------------------- + | Video memory | 0xb8000 VID_BASE_ADDR + | | + < . . . > + | | + ----------------------- + | The BIOS | 0xf0000 + | | + < . . . > + | | + ----------------------- 0xfffff diff --git a/doc/NOTES b/doc/NOTES new file mode 100644 index 0000000..0d05ca2 --- /dev/null +++ b/doc/NOTES @@ -0,0 +1,162 @@ +Systems Programming standalone framework information + +Version: @(#)NOTES 2.3 +Date: 12/4/23 +--------------------------------------------------------------------------- + +Notes on the Makefile: + + DO NOT USE gmakemake! You must edit the given Makefile to tell + it about the file(s) you create. Add your own file names (both + source and object versions) to the APP_* macros at the top of the + Makefile. + + After adding or removing files from the Makefile (or changing + your #includes), do a "make depend" to adjust the Makefile's + dependency entries. + +To create your program: + + * run 'make' in your project directory + +To copy it onto a USB flash drive: + + All machines in the DSL have at least two front-panel USB slots + (typically, two USB-2 and one blue USB-3). Under Ubuntu, you + can use any of these slots; insert a flash drive, and the OS + automatically creates device entries for the drive, using the + next available disk name in /dev (e.g., /dev/sdg). + + To copy your bootable image to the flash drive, plug the drive + into a USB socket, wait a few moments for Ubuntu to recognize + it and create the device entries in /dev, and type + + make usb + + This will remake the disk.img file (if necessary), and will then + copy it out to the USB drive. In order to find the correct + drive, the installation uses a local command named 'dcopy'. This + command runs a second command named 'dfind' to identify the USB + drive(s) plugged into the system, and then runs a 'dd' command + to copy the disk.img file to the first USB device it finds. + (You can run 'dfind' yourself if you want to be sure that 'dcopy' + will be able to find the flash drive.) + + Note: the Makefile still has a "floppy" target for creating a + bootable floppy disk image. However, this hasn't been used for + quite a while, and the necessary support tools to do the copying + don't exist on the current systems. If you want to try using the + floppy disk as a boot device, let me know. + +To boot your program once you have copied it to a bootable medium: + + * DO NOT USE the machine named 'sherlock' - it's a server for + the lab, and should not be shut down + * shut down Ubuntu by using the standard Ubuntu "shut down" + menu entry + * insert the bootable medium + * make sure the terminal connected to this machine is turned on + * push the reset button on the front panel (at the top, on + the righthand side - the larger button on the lefthand + side is the power button) + + DO NOT just push the reset button - Ubuntu must be shut down + correctly in order to avoid damaging the filesystems. + + Unfortunately, the motherboards in the current lab machines are + somewhat stupid; once a flash drive is unplugged, they forget + that we want to give boot priority to flash drives once the + flash drive is unplugged. For now, you will need to interrupt + the boot process in one of the following two ways: + + 1. When the ASUS logo appears on the screen, press the + F8 key to bring up the boot device screen. Scroll + down the list using the arrow keys until the flash + drive is highlighted, and press ENTER to boot from it. + + 2. When the ASUS log appears on the screen, press either + the F2 or the DEL key on the keyboard to bring up the + BIOS screen. Use the right arrow key to select the + "Boot" menu, then the down arrow key to the bottom of + the "Boot" menu, where you will find an "Override" + section. Select the flash drive entry and press + ENTER. + + If you miss your window of opportunity (about five seconds) + to press one of these function keys and Ubuntu boots up, don't + panic; just shut Ubuntu down and try again. + + If you want to run your program again, leave the flash drive + inserted and press the reset button again. + +To reboot Ubuntu: + + * take your bootable medium out of the machine + * push the reset button + +Compiling your program creates several files: + + prog.o: linked, object form of the system + + prog.b: binary version of the system - generated from prog.o + by removing all the object file headers and symbol table + + prog.nl: namelist of the prog.o file - lists all global symbols, + their values, and the program section they're defined in + (Text, Data, Bss) + + *.img: the binary system image - contains the bootstrap, the + protected mode startup code, and your stuff, in this layout: + + bootstrap first sector + switch code second sector + your program sectors 3 through n+2 + next file n+3 through p+n+2 + next file p+n+3 through q+p+n+2 + etc. (see below) + + This file will be named floppy.img or disk.img, + depending on which device you'll be using. + + BuildImage: is used to patch the system length into the boot + sector of the *.img file + + Offsets: prints byte offsets for major structures (only present + in distributions of the baseline OS written by the class + in Systems Programming) + +Other things you can 'make': + + prog.dis: a disassembly of the prog.o file - a text version of + the binary machine code + + prog.nll: like prog.nl, but includes non-global symbols as well + as globals (e.g., static local variables in files) + + file.X: generates an assembly listing from the C source file + named "file.c" which has the C source code inserted around + the assembly code + + clean: deletes all object, listing, and binary files + + depend: recreates the dependency lists in the Makefile + +Loading additional files: + + You can load additional files into memory by adding the name of + the file and the address where you want it loaded to the end of + the BuildImage command in the Makefile. However, because the + loading is done in real mode, you cannot load into addresses + above 0x9ffff. See the code in BuildImage.c for more details. + +Modifying the bootstrap: + + You can add some code to the bootstrap without significantly + changing its size. The baseline bootstrap assembles to 0x2ad + bytes without the memory map code, or 0x353 with that code; this + leaves about 330 (or 170) bytes available at the end of the second + sector. If you need to add more than will fit there, you will + need to change the definition of BOOT_SIZE at the beginning of + the file, the code which loads the second half of the bootstrap + from the device, and the ".org" at the end of the file to reflect + the new length of the bootstrap. diff --git a/doc/user_image.txt b/doc/user_image.txt new file mode 100644 index 0000000..9527e12 --- /dev/null +++ b/doc/user_image.txt @@ -0,0 +1,5841 @@ +Partial disassembly of user.img, 2025/03/22 + +Blob header: +00000000 42 4c 42 00 14 00 00 00 |BLB.....| "BLB", 00000014 entries + +Program table [0]: +00000000 69 6e 69 74 00 00 00 00 |init....| +00000010 00 00 00 00 00 00 00 00 00 00 00 00 88 02 00 00 |................| offset 00000288 +00000020 68 17 00 00 00 00 00 00 |h.......| + +Program table [1]: +00000020 69 64 6c 65 00 00 00 00 |idle....| +00000030 00 00 00 00 00 00 00 00 00 00 00 00 f0 19 00 00 |................| offset 000019f0 +00000040 78 16 00 00 00 00 00 00 |x.......| + +Program table [2] - [19]: +00000040 73 68 65 6c 6c 00 00 00 |shell...| +00000050 00 00 00 00 00 00 00 00 00 00 00 00 68 30 00 00 |............h0..| +00000060 34 1b 00 00 01 00 00 00 70 72 6f 67 41 42 43 00 |4.......progABC.| +00000070 00 00 00 00 00 00 00 00 00 00 00 00 a0 4b 00 00 |.............K..| +00000080 ac 16 00 00 01 00 00 00 70 72 6f 67 44 45 00 00 |........progDE..| +00000090 00 00 00 00 00 00 00 00 00 00 00 00 50 62 00 00 |............Pb..| +000000a0 ac 16 00 00 01 00 00 00 70 72 6f 67 46 47 00 00 |........progFG..| +000000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 79 00 00 |.............y..| +000000c0 ac 16 00 00 01 00 00 00 70 72 6f 67 48 00 00 00 |........progH...| +000000d0 00 00 00 00 00 00 00 00 00 00 00 00 b0 8f 00 00 |................| +000000e0 ac 16 00 00 01 00 00 00 70 72 6f 67 49 00 00 00 |........progI...| +000000f0 00 00 00 00 00 00 00 00 00 00 00 00 60 a6 00 00 |............`...| +00000100 ac 16 00 00 01 00 00 00 70 72 6f 67 4a 00 00 00 |........progJ...| +00000110 00 00 00 00 00 00 00 00 00 00 00 00 10 bd 00 00 |................| +00000120 ac 16 00 00 01 00 00 00 70 72 6f 67 4b 4c 00 00 |........progKL..| +00000130 00 00 00 00 00 00 00 00 00 00 00 00 c0 d3 00 00 |................| +00000140 ac 16 00 00 01 00 00 00 70 72 6f 67 4d 4e 00 00 |........progMN..| +00000150 00 00 00 00 00 00 00 00 00 00 00 00 70 ea 00 00 |............p...| +00000160 ac 16 00 00 01 00 00 00 70 72 6f 67 50 00 00 00 |........progP...| +00000170 00 00 00 00 00 00 00 00 00 00 00 00 20 01 01 00 |............ ...| +00000180 ac 16 00 00 01 00 00 00 70 72 6f 67 51 00 00 00 |........progQ...| +00000190 00 00 00 00 00 00 00 00 00 00 00 00 d0 17 01 00 |................| +000001a0 78 16 00 00 00 00 00 00 70 72 6f 67 52 00 00 00 |x.......progR...| +000001b0 00 00 00 00 00 00 00 00 00 00 00 00 48 2e 01 00 |............H...| +000001c0 ac 16 00 00 01 00 00 00 70 72 6f 67 53 00 00 00 |........progS...| +000001d0 00 00 00 00 00 00 00 00 00 00 00 00 f8 44 01 00 |.............D..| +000001e0 ac 16 00 00 01 00 00 00 70 72 6f 67 54 55 56 00 |........progTUV.| +000001f0 00 00 00 00 00 00 00 00 00 00 00 00 a8 5b 01 00 |.............[..| +00000200 ac 16 00 00 01 00 00 00 70 72 6f 67 57 00 00 00 |........progW...| +00000210 00 00 00 00 00 00 00 00 00 00 00 00 58 72 01 00 |............Xr..| +00000220 ac 16 00 00 01 00 00 00 70 72 6f 67 58 00 00 00 |........progX...| +00000230 00 00 00 00 00 00 00 00 00 00 00 00 08 89 01 00 |................| +00000240 ac 16 00 00 01 00 00 00 70 72 6f 67 59 00 00 00 |........progY...| +00000250 00 00 00 00 00 00 00 00 00 00 00 00 b8 9f 01 00 |................| +00000260 ac 16 00 00 01 00 00 00 70 72 6f 67 5a 00 00 00 |........progZ...| +00000270 00 00 00 00 00 00 00 00 00 00 00 00 68 b6 01 00 |............h...| +00000280 ac 16 00 00 01 00 00 00 |........| + +Program #0 ELF file: +00000280 7f 45 4c 46 01 01 01 00 |.ELF....| <-- init @ 00000288 +00000290 00 00 00 00 00 00 00 00 02 00 03 00 01 00 00 00 |................| +000002a0 49 14 00 00 34 00 00 00 28 16 00 00 00 00 00 00 |I...4...(.......| +000002b0 34 00 20 00 02 00 28 00 08 00 07 00 01 00 00 00 |4. ...(.........| +000002c0 80 00 00 00 00 10 00 00 00 10 00 00 9d 10 00 00 |................| +000002d0 00 20 00 00 07 00 00 00 20 00 00 00 51 e5 74 64 |. ...... ...Q.td| +000002e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +000002f0 00 00 00 00 07 00 00 00 10 00 00 00 00 00 00 00 |................| +00000300 00 00 00 00 00 00 00 00 55 89 e5 81 ec 98 00 00 |........U.......| +00000310 00 e8 d5 03 00 00 89 45 f4 83 7d f4 00 79 34 8b |.......E..}..y4.| +00000320 45 08 8b 00 83 ec 04 50 68 39 1a 00 00 8d 85 74 |E......Ph9.....t| +00000330 ff ff ff 50 e8 28 04 00 00 83 c4 10 83 ec 0c 8d |...P.(..........| +00000340 85 74 ff ff ff 50 e8 df 02 00 00 83 c4 10 e9 84 |.t...P..........| +00000350 00 00 00 83 7d f4 00 75 5f 8b 45 08 0f b6 40 08 |....}..u_.E...@.| +00000360 0f b6 c0 83 ec 0c 50 e8 bf 03 00 00 83 c4 10 8b |......P.........| +00000370 45 08 8d 50 0c 8b 45 08 8b 00 83 ec 08 52 50 e8 |E..P..E......RP.| +00000380 6f 03 00 00 83 c4 10 8b 45 08 8b 00 83 ec 04 50 |o.......E......P| +00000390 68 54 1a 00 00 8d 85 74 ff ff ff 50 e8 c0 03 00 |hT.....t...P....| +000003a0 00 83 c4 10 83 ec 0c 8d 85 74 ff ff ff 50 e8 77 |.........t...P.w| +000003b0 02 00 00 83 c4 10 eb 1f 0f b6 05 9c 20 00 00 0f |............ ...| +000003c0 be c0 83 ec 0c 50 e8 a7 02 00 00 83 c4 10 8b 55 |.....P.........U| +000003d0 f4 8b 45 08 89 50 04 90 c9 c3 8d 4c 24 04 83 e4 |..E..P.....L$...| +000003e0 f0 ff 71 fc 55 89 e5 51 81 ec a4 00 00 00 89 c8 |..q.U..Q........| +000003f0 83 38 01 7e 2d 8b 50 04 83 c2 04 8b 12 0f b6 12 |.8.~-.P.........| +00000400 0f be d2 89 55 ec 83 7d ec 20 76 16 83 7d ec 7e |....U..}. v..}.~| +00000410 77 10 8b 40 04 83 c0 04 8b 00 0f b6 00 a2 9c 20 |w..@........... | +00000420 00 00 83 ec 0c 68 6f 1a 00 00 e8 fb 01 00 00 83 |.....ho.........| +00000430 c4 10 83 ec 0c 6a 1a e8 36 02 00 00 83 c4 10 c7 |.....j..6.......| +00000440 45 f4 00 00 00 00 eb 04 83 45 f4 01 81 7d f4 9f |E........E...}..| +00000450 25 26 00 7e f3 83 ec 0c 68 80 1a 00 00 e8 31 02 |%&.~....h.....1.| +00000460 00 00 83 c4 10 83 ec 0c 68 a8 1a 00 00 e8 b8 01 |........h.......| +00000470 00 00 83 c4 10 c7 45 f0 00 20 00 00 eb 12 83 ec |......E.. ......| +00000480 0c ff 75 f0 e8 7f fe ff ff 83 c4 10 83 45 f0 34 |..u..........E.4| +00000490 8b 45 f0 8b 00 3d 62 60 01 00 75 e2 83 ec 0c 68 |.E...=b`..u....h| +000004a0 c7 1a 00 00 e8 ea 01 00 00 83 c4 10 83 ec 0c 68 |...............h| +000004b0 d0 1a 00 00 e8 71 01 00 00 83 c4 10 83 ec 08 8d |.....q..........| +000004c0 85 64 ff ff ff 50 6a 00 e8 16 02 00 00 83 c4 10 |.d...Pj.........| +000004d0 89 45 e8 83 7d e8 00 7f 2e 83 ec 04 ff 75 e8 68 |.E..}........u.h| +000004e0 f4 1a 00 00 8d 85 68 ff ff ff 50 e8 71 02 00 00 |......h...P.q...| +000004f0 83 c4 10 83 ec 0c 8d 85 68 ff ff ff 50 e8 28 01 |........h...P.(.| +00000500 00 00 83 c4 10 eb b5 8b 85 64 ff ff ff 50 ff 75 |.........d...P.u| +00000510 e8 68 14 1b 00 00 8d 85 68 ff ff ff 50 e8 3f 02 |.h......h...P.?.| +00000520 00 00 83 c4 10 83 ec 0c 8d 85 68 ff ff ff 50 e8 |..........h...P.| +00000530 f6 00 00 00 83 c4 10 c7 45 f0 00 20 00 00 eb 2b |........E.. ...+| +00000540 8b 45 f0 8b 50 04 8b 45 e8 39 c2 75 1a 8b 45 f0 |.E..P..E.9.u..E.| +00000550 c7 40 04 00 00 00 00 83 ec 0c ff 75 f0 e8 a6 fd |.@.........u....| +00000560 ff ff 83 c4 10 eb 10 83 45 f0 34 8b 45 f0 8b 00 |........E.4.E...| +00000570 3d 62 60 01 00 75 c9 e9 40 ff ff ff 55 89 e5 83 |=b`..u..@...U...| +00000580 ec 08 83 ec 08 ff 75 08 6a 00 e8 54 01 00 00 83 |......u.j..T....| +00000590 c4 10 c9 c3 55 89 e5 81 ec 18 01 00 00 e8 49 01 |....U.........I.| +000005a0 00 00 89 45 f4 83 7d f4 00 74 05 8b 45 f4 eb 57 |...E..}..t..E..W| +000005b0 e8 56 01 00 00 89 45 f4 83 ec 08 ff 75 0c ff 75 |.V....E.....u..u| +000005c0 08 e8 2d 01 00 00 83 c4 10 ff 75 08 ff 75 f4 68 |..-.......u..u.h| +000005d0 2b 1b 00 00 8d 85 f4 fe ff ff 50 e8 81 01 00 00 |+.........P.....| +000005e0 83 c4 10 83 ec 0c 8d 85 f4 fe ff ff 50 e8 38 00 |............P.8.| +000005f0 00 00 83 c4 10 83 ec 0c 6a ff e8 dc 00 00 00 83 |........j.......| +00000600 c4 10 b8 00 00 00 00 c9 c3 55 89 e5 83 ec 18 8b |.........U......| +00000610 45 08 88 45 f4 83 ec 04 6a 01 8d 45 f4 50 6a 00 |E..E....j..E.Pj.| +00000620 e8 de 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 |..........U.....| +00000630 83 ec 0c ff 75 08 e8 9b 03 00 00 83 c4 10 89 45 |....u..........E| +00000640 f4 8b 45 f4 83 ec 04 50 ff 75 08 6a 00 e8 b1 00 |..E....P.u.j....| +00000650 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 08 83 ec 04 |.......U........| +00000660 ff 75 0c ff 75 08 6a 00 e8 96 00 00 00 83 c4 10 |.u..u.j.........| +00000670 c9 c3 55 89 e5 83 ec 18 8b 45 08 88 45 f4 83 ec |..U......E..E...| +00000680 04 6a 01 8d 45 f4 50 6a 01 e8 75 00 00 00 83 c4 |.j..E.Pj..u.....| +00000690 10 c9 c3 55 89 e5 83 ec 18 83 ec 0c ff 75 08 e8 |...U.........u..| +000006a0 32 03 00 00 83 c4 10 89 45 f4 8b 45 f4 83 ec 04 |2.......E..E....| +000006b0 50 ff 75 08 6a 01 e8 48 00 00 00 83 c4 10 c9 c3 |P.u.j..H........| +000006c0 55 89 e5 83 ec 08 83 ec 04 ff 75 0c ff 75 08 6a |U.........u..u.j| +000006d0 01 e8 2d 00 00 00 83 c4 10 c9 c3 b8 00 00 00 00 |..-.............| +000006e0 cd 80 c3 b8 01 00 00 00 cd 80 c3 b8 02 00 00 00 |................| +000006f0 cd 80 c3 b8 03 00 00 00 cd 80 c3 b8 04 00 00 00 |................| +00000700 cd 80 c3 b8 05 00 00 00 cd 80 c3 b8 06 00 00 00 |................| +00000710 cd 80 c3 b8 07 00 00 00 cd 80 c3 b8 08 00 00 00 |................| +00000720 cd 80 c3 b8 09 00 00 00 cd 80 c3 b8 0a 00 00 00 |................| +00000730 cd 80 c3 b8 0b 00 00 00 cd 80 c3 b8 0c 00 00 00 |................| +00000740 cd 80 c3 b8 ad 0b 00 00 cd 80 c3 50 e8 8a ff ff |...........P....| +00000750 ff e8 84 fc ff ff 83 ec 0c 50 e8 7c ff ff ff eb |.........P.|....| +00000760 fe 55 89 e5 83 ec 38 8d 45 0c 83 c0 04 89 45 f4 |.U....8.E.....E.| +00000770 e9 3f 02 00 00 80 7d f3 25 0f 85 26 02 00 00 c7 |.?....}.%..&....| +00000780 45 ec 00 00 00 00 c7 45 e4 20 00 00 00 c7 45 e8 |E......E. ....E.| +00000790 00 00 00 00 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 |.....E..P..U....| +000007a0 88 45 f3 80 7d f3 2d 75 16 c7 45 ec 01 00 00 00 |.E..}.-u..E.....| +000007b0 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 |.E..P..U.....E..| +000007c0 7d f3 30 75 40 c7 45 e4 30 00 00 00 8b 45 0c 8d |}.0u@.E.0....E..| +000007d0 50 01 89 55 0c 0f b6 00 88 45 f3 eb 28 8b 55 e8 |P..U.....E..(.U.| +000007e0 89 d0 c1 e0 02 01 d0 01 c0 89 45 e8 0f be 45 f3 |..........E...E.| +000007f0 83 e8 30 01 45 e8 8b 45 0c 8d 50 01 89 55 0c 0f |..0.E..E..P..U..| +00000800 b6 00 88 45 f3 80 7d f3 2f 7e 06 80 7d f3 39 7e |...E..}./~..}.9~| +00000810 cc 0f be 45 f3 83 e8 63 83 f8 15 0f 87 93 01 00 |...E...c........| +00000820 00 8b 04 85 48 1b 00 00 ff e0 8b 45 f4 8d 50 04 |....H......E..P.| +00000830 89 55 f4 8b 00 88 45 f3 0f b6 45 f3 88 45 d0 c6 |.U....E...E..E..| +00000840 45 d1 00 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 6a |E......u..u..u.j| +00000850 01 8d 45 d0 50 ff 75 08 e8 17 04 00 00 83 c4 20 |..E.P.u........ | +00000860 89 45 08 e9 4c 01 00 00 8b 45 f4 8d 50 04 89 55 |.E..L....E..P..U| +00000870 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 78 01 00 00 |......P.E.P.x...| +00000880 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff |....E.....u..u..| +00000890 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 d3 03 00 |u..u..E.P.u.....| +000008a0 00 83 c4 20 89 45 08 e9 08 01 00 00 8b 45 f4 8d |... .E.......E..| +000008b0 50 04 89 55 f4 8b 00 89 45 dc 83 ec 08 ff 75 e4 |P..U....E.....u.| +000008c0 ff 75 ec ff 75 e8 6a ff ff 75 dc ff 75 08 e8 a1 |.u..u.j..u..u...| +000008d0 03 00 00 83 c4 20 89 45 08 e9 d6 00 00 00 8b 45 |..... .E.......E| +000008e0 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 |..P..U......P.E.| +000008f0 50 e8 d2 01 00 00 83 c4 10 89 45 e0 83 ec 08 ff |P.........E.....| +00000900 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff |u..u..u..u..E.P.| +00000910 75 08 e8 5d 03 00 00 83 c4 20 89 45 08 e9 92 00 |u..]..... .E....| +00000920 00 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 |...E..P..U......| +00000930 50 8d 45 d0 50 e8 18 02 00 00 83 c4 10 89 45 e0 |P.E.P.........E.| +00000940 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d |....u..u..u..u..| +00000950 45 d0 50 ff 75 08 e8 19 03 00 00 83 c4 20 89 45 |E.P.u........ .E| +00000960 08 eb 51 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec |..Q.E..P..U.....| +00000970 08 50 8d 45 d0 50 e8 61 02 00 00 83 c4 10 89 45 |.P.E.P.a.......E| +00000980 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 |.....u..u..u..u.| +00000990 8d 45 d0 50 ff 75 08 e8 d8 02 00 00 83 c4 20 89 |.E.P.u........ .| +000009a0 45 08 90 eb 0f 8b 45 08 8d 50 01 89 55 08 0f b6 |E.....E..P..U...| +000009b0 55 f3 88 10 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 |U....E..P..U....| +000009c0 88 45 f3 80 7d f3 00 0f 85 a8 fd ff ff 8b 45 08 |.E..}.........E.| +000009d0 c6 00 00 90 c9 c3 55 89 e5 53 8b 55 08 bb 00 00 |......U..S.U....| +000009e0 00 00 eb 03 83 c3 01 89 d0 8d 50 01 0f b6 00 84 |..........P.....| +000009f0 c0 75 f1 89 d8 5b 5d c3 55 89 e5 83 ec 18 8b 45 |.u...[].U......E| +00000a00 08 89 45 f4 83 7d 0c 00 79 0f 8b 45 f4 8d 50 01 |..E..}..y..E..P.| +00000a10 89 55 f4 c6 00 2d f7 5d 0c 83 ec 08 ff 75 0c ff |.U...-.].....u..| +00000a20 75 f4 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 |u..........E..E.| +00000a30 c6 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 |....U..E.).....U| +00000a40 89 e5 83 ec 18 8b 4d 0c ba 67 66 66 66 89 c8 f7 |......M..gfff...| +00000a50 ea c1 fa 02 89 c8 c1 f8 1f 29 c2 89 d0 89 45 f4 |.........)....E.| +00000a60 83 7d f4 00 79 0e c7 45 f4 cc cc cc 0c c7 45 0c |.}..y..E......E.| +00000a70 08 00 00 00 83 7d f4 00 74 14 83 ec 08 ff 75 f4 |.....}..t.....u.| +00000a80 ff 75 08 e8 b7 ff ff ff 83 c4 10 89 45 08 8b 4d |.u..........E..M| +00000a90 0c ba 67 66 66 66 89 c8 f7 ea c1 fa 02 89 c8 c1 |..gfff..........| +00000aa0 f8 1f 29 c2 89 d0 c1 e0 02 01 d0 01 c0 29 c1 89 |..)..........)..| +00000ab0 ca 89 d0 8d 48 30 8b 45 08 8d 50 01 89 55 08 89 |....H0.E..P..U..| +00000ac0 ca 88 10 8b 45 08 c9 c3 55 89 e5 83 ec 20 c7 45 |....E...U.... .E| +00000ad0 e3 30 31 32 33 c7 45 e7 34 35 36 37 c7 45 eb 38 |.0123.E.4567.E.8| +00000ae0 39 41 42 c7 45 ef 43 44 45 46 c6 45 f3 00 c7 45 |9AB.E.CDEF.E...E| +00000af0 fc 00 00 00 00 c7 45 f8 00 00 00 00 eb 43 8b 45 |......E......C.E| +00000b00 0c 25 00 00 00 f0 89 45 f4 83 7d fc 00 75 0c 83 |.%.....E..}..u..| +00000b10 7d f4 00 75 06 83 7d f8 07 75 1e 83 45 fc 01 c1 |}..u..}..u..E...| +00000b20 6d f4 1c 8b 45 08 8d 50 01 89 55 08 8d 4d e3 8b |m...E..P..U..M..| +00000b30 55 f4 01 ca 0f b6 12 88 10 c1 65 0c 04 83 45 f8 |U.........e...E.| +00000b40 01 83 7d f8 07 7e b7 8b 45 08 c6 00 00 8b 45 fc |..}..~..E.....E.| +00000b50 c9 c3 55 89 e5 83 ec 10 c7 45 f8 00 00 00 00 8b |..U......E......| +00000b60 45 08 89 45 f4 8b 45 0c 25 00 00 00 c0 89 45 f0 |E..E..E.%.....E.| +00000b70 c1 6d f0 1e c7 45 fc 00 00 00 00 eb 47 83 7d fc |.m...E......G.}.| +00000b80 0a 74 0c 83 7d f0 00 75 06 83 7d f8 00 74 1e c7 |.t..}..u..}..t..| +00000b90 45 f8 01 00 00 00 83 65 f0 07 8b 45 f0 8d 48 30 |E......e...E..H0| +00000ba0 8b 45 f4 8d 50 01 89 55 f4 89 ca 88 10 c1 65 0c |.E..P..U......e.| +00000bb0 03 8b 45 0c 25 00 00 00 e0 89 45 f0 c1 6d f0 1d |..E.%.....E..m..| +00000bc0 83 45 fc 01 83 7d fc 0a 7e b3 8b 45 f4 c6 00 00 |.E...}..~..E....| +00000bd0 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 |.U..E.).....U...| +00000be0 ec 18 8b 45 08 89 45 f4 83 ec 08 ff 75 0c ff 75 |...E..E.....u..u| +00000bf0 f4 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 c6 |..........E..E..| +00000c00 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 |...U..E.).....U.| +00000c10 e5 83 ec 18 8b 45 0c ba cd cc cc cc f7 e2 89 d0 |.....E..........| +00000c20 c1 e8 03 89 45 f4 83 7d f4 00 74 15 8b 45 f4 83 |....E..}..t..E..| +00000c30 ec 08 50 ff 75 08 e8 04 fe ff ff 83 c4 10 89 45 |..P.u..........E| +00000c40 08 8b 4d 0c ba cd cc cc cc 89 c8 f7 e2 c1 ea 03 |..M.............| +00000c50 89 d0 c1 e0 02 01 d0 01 c0 29 c1 89 ca 89 d0 8d |.........)......| +00000c60 48 30 8b 45 08 8d 50 01 89 55 08 89 ca 88 10 8b |H0.E..P..U......| +00000c70 45 08 c9 c3 55 89 e5 83 ec 18 83 7d 10 00 79 11 |E...U......}..y.| +00000c80 83 ec 0c ff 75 0c e8 4b fd ff ff 83 c4 10 89 45 |....u..K.......E| +00000c90 10 8b 45 14 2b 45 10 89 45 f0 83 7d f0 00 7e 1d |..E.+E..E..}..~.| +00000ca0 83 7d 18 00 75 17 83 ec 04 ff 75 1c ff 75 f0 ff |.}..u.....u..u..| +00000cb0 75 08 e8 5a 00 00 00 83 c4 10 89 45 08 c7 45 f4 |u..Z.......E..E.| +00000cc0 00 00 00 00 eb 1b 8b 55 f4 8b 45 0c 8d 0c 02 8b |.......U..E.....| +00000cd0 45 08 8d 50 01 89 55 08 0f b6 11 88 10 83 45 f4 |E..P..U.......E.| +00000ce0 01 8b 45 f4 3b 45 10 7c dd 83 7d f0 00 7e 1d 83 |..E.;E.|..}..~..| +00000cf0 7d 18 00 74 17 83 ec 04 ff 75 1c ff 75 f0 ff 75 |}..t.....u..u..u| +00000d00 08 e8 0b 00 00 00 83 c4 10 89 45 08 8b 45 08 c9 |..........E..E..| +00000d10 c3 55 89 e5 eb 12 8b 45 08 8d 50 01 89 55 08 8b |.U.....E..P..U..| +00000d20 55 10 88 10 83 6d 0c 01 83 7d 0c 00 7f e8 8b 45 |U....m...}.....E| +00000d30 08 5d c3 00 69 64 6c 65 00 2e 00 73 68 65 6c 6c |.]..idle...shell| +00000d40 00 49 4e 49 54 3a 20 66 6f 72 6b 20 66 6f 72 20 |.INIT: fork for | +00000d50 23 25 64 20 66 61 69 6c 65 64 0a 00 49 4e 49 54 |#%d failed..INIT| +00000d60 3a 20 65 78 65 63 28 30 78 25 30 38 78 29 20 66 |: exec(0x%08x) f| +00000d70 61 69 6c 65 64 0a 00 49 6e 69 74 20 73 74 61 72 |ailed..Init star| +00000d80 74 65 64 0a 00 00 00 00 0a 0a 53 70 65 6d 20 72 |ted.......Spem r| +00000d90 65 6c 69 6e 71 75 75 6e 74 20 71 75 69 20 68 75 |elinquunt qui hu| +00000da0 63 20 69 6e 74 72 61 73 74 69 21 0a 0a 0d 00 00 |c intrasti!.....| +00000db0 49 4e 49 54 3a 20 73 74 61 72 74 69 6e 67 20 75 |INIT: starting u| +00000dc0 73 65 72 20 70 72 6f 63 65 73 73 65 73 0a 00 20 |ser processes.. | +00000dd0 21 21 21 0d 0a 0a 00 00 49 4e 49 54 3a 20 74 72 |!!!.....INIT: tr| +00000de0 61 6e 73 69 74 69 6f 6e 69 6e 67 20 74 6f 20 77 |ansitioning to w| +00000df0 61 69 74 28 29 20 6d 6f 64 65 0a 00 49 4e 49 54 |ait() mode..INIT| +00000e00 3a 20 77 61 69 74 70 69 64 28 29 20 72 65 74 75 |: waitpid() retu| +00000e10 72 6e 65 64 20 25 64 3f 3f 3f 0a 00 49 4e 49 54 |rned %d???..INIT| +00000e20 3a 20 70 69 64 20 25 64 20 65 78 69 74 28 25 64 |: pid %d exit(%d| +00000e30 29 0a 00 43 68 69 6c 64 20 25 64 20 65 78 65 63 |)..Child %d exec| +00000e40 28 29 20 23 25 75 20 66 61 69 6c 65 64 0a 00 00 |() #%u failed...| +00000e50 22 15 00 00 60 15 00 00 ac 16 00 00 ac 16 00 00 |"...`...........| +00000e60 ac 16 00 00 ac 16 00 00 ac 16 00 00 ac 16 00 00 |................| +* +00000e80 1a 16 00 00 ac 16 00 00 ac 16 00 00 ac 16 00 00 |................| +00000e90 a4 15 00 00 ac 16 00 00 5b 16 00 00 ac 16 00 00 |........[.......| +00000ea0 ac 16 00 00 d6 15 00 00 00 00 00 00 00 00 00 00 |................| +00000eb0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00001300 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 |................| +00001310 03 21 00 00 2c 1a 00 00 31 1a 00 00 00 00 00 00 |.!..,...1.......| +00001320 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00001330 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 |................| +00001340 00 00 00 00 01 40 00 00 33 1a 00 00 00 00 00 00 |.....@..3.......| +00001350 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00001370 62 60 01 00 00 00 00 00 00 00 00 00 00 00 00 00 |b`..............| +00001380 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +000013a0 00 00 00 00 2b 00 00 00 00 00 00 00 00 00 00 00 |....+...........| +000013b0 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 |................| +000013c0 00 00 00 00 03 00 01 00 00 00 00 00 2c 1a 00 00 |............,...| +000013d0 00 00 00 00 03 00 02 00 00 00 00 00 00 20 00 00 |............. ..| +000013e0 00 00 00 00 03 00 03 00 00 00 00 00 00 30 00 00 |.............0..| +000013f0 00 00 00 00 03 00 04 00 01 00 00 00 00 00 00 00 |................| +00001400 00 00 00 00 04 00 f1 ff 08 00 00 00 00 20 00 00 |............. ..| +00001410 9c 00 00 00 01 00 03 00 39 01 00 00 9c 20 00 00 |........9.... ..| +00001420 01 00 00 00 01 00 03 00 14 00 00 00 00 10 00 00 |................| +00001430 d2 00 00 00 02 00 01 00 1c 00 00 00 00 00 00 00 |................| +00001440 00 00 00 00 04 00 f1 ff 24 00 00 00 00 00 00 00 |........$.......| +00001450 00 00 00 00 04 00 f1 ff 2d 00 00 00 00 00 00 00 |........-.......| +00001460 00 00 00 00 04 00 f1 ff 36 00 00 00 00 00 00 00 |........6.......| +00001470 00 00 00 00 04 00 f1 ff 3f 00 00 00 00 00 00 00 |........?.......| +00001480 00 00 00 00 04 00 f1 ff 49 00 00 00 00 00 00 00 |........I.......| +00001490 00 00 00 00 04 00 f1 ff 52 00 00 00 00 00 00 00 |........R.......| +000014a0 00 00 00 00 04 00 f1 ff 5b 00 00 00 00 00 00 00 |........[.......| +000014b0 00 00 00 00 04 00 f1 ff 64 00 00 00 00 00 00 00 |........d.......| +000014c0 00 00 00 00 04 00 f1 ff 6e 00 00 00 00 00 00 00 |........n.......| +000014d0 00 00 00 00 04 00 f1 ff 77 00 00 00 00 00 00 00 |........w.......| +000014e0 00 00 00 00 04 00 f1 ff 7d 00 00 00 6a 13 00 00 |........}...j...| +000014f0 21 00 00 00 12 00 01 00 86 00 00 00 db 13 00 00 |!...............| +00001500 00 00 00 00 10 00 01 00 8e 00 00 00 4f 13 00 00 |............O...| +00001510 1b 00 00 00 12 00 01 00 95 00 00 00 d4 18 00 00 |................| +00001520 32 00 00 00 12 00 01 00 9c 00 00 00 03 14 00 00 |2...............| +00001530 00 00 00 00 10 00 01 00 a3 00 00 00 33 14 00 00 |............3...| +00001540 00 00 00 00 10 00 01 00 a9 00 00 00 b8 13 00 00 |................| +00001550 1b 00 00 00 12 00 01 00 b0 00 00 00 09 1a 00 00 |................| +00001560 22 00 00 00 12 00 01 00 b4 00 00 00 8c 12 00 00 |"...............| +00001570 75 00 00 00 12 00 01 00 ba 00 00 00 59 14 00 00 |u...........Y...| +00001580 75 02 00 00 12 00 01 00 c1 00 00 00 c0 17 00 00 |u...............| +00001590 8a 00 00 00 12 00 01 00 c8 00 00 00 06 19 00 00 |................| +000015a0 66 00 00 00 12 00 01 00 8f 00 00 00 fb 13 00 00 |f...............| +000015b0 00 00 00 00 10 00 01 00 d0 00 00 00 2b 14 00 00 |............+...| +000015c0 00 00 00 00 10 00 01 00 d5 00 00 00 22 13 00 00 |............"...| +000015d0 2d 00 00 00 12 00 01 00 dd 00 00 00 eb 13 00 00 |-...............| +000015e0 00 00 00 00 10 00 01 00 e2 00 00 00 74 12 00 00 |............t...| +000015f0 18 00 00 00 12 00 01 00 e7 00 00 00 8b 13 00 00 |................| +00001600 2d 00 00 00 12 00 01 00 ef 00 00 00 49 14 00 00 |-...........I...| +00001610 00 00 00 00 10 00 01 00 f6 00 00 00 f3 13 00 00 |................| +00001620 00 00 00 00 10 00 01 00 fb 00 00 00 1b 14 00 00 |................| +00001630 00 00 00 00 10 00 01 00 03 01 00 00 37 17 00 00 |............7...| +00001640 89 00 00 00 12 00 01 00 0b 01 00 00 e3 13 00 00 |................| +00001650 00 00 00 00 10 00 01 00 10 01 00 00 d2 10 00 00 |................| +00001660 a2 01 00 00 12 00 01 00 15 01 00 00 0b 14 00 00 |................| +00001670 00 00 00 00 10 00 01 00 1d 01 00 00 6c 19 00 00 |............l...| +00001680 9d 00 00 00 12 00 01 00 24 01 00 00 23 14 00 00 |........$...#...| +00001690 00 00 00 00 10 00 01 00 2c 01 00 00 4a 18 00 00 |........,...J...| +000016a0 8a 00 00 00 12 00 01 00 33 01 00 00 01 13 00 00 |........3.......| +000016b0 21 00 00 00 12 00 01 00 3c 01 00 00 13 14 00 00 |!.......<.......| +000016c0 00 00 00 00 10 00 01 00 44 01 00 00 f0 16 00 00 |........D.......| +000016d0 47 00 00 00 12 00 01 00 5d 01 00 00 d3 13 00 00 |G.......].......| +000016e0 00 00 00 00 10 00 01 00 4b 01 00 00 ce 16 00 00 |........K.......| +000016f0 22 00 00 00 12 00 01 00 52 01 00 00 3b 14 00 00 |".......R...;...| +00001700 00 00 00 00 10 00 01 00 58 01 00 00 43 14 00 00 |........X...C...| +00001710 00 00 00 00 10 00 01 00 00 69 6e 69 74 2e 63 00 |.........init.c.| +00001720 73 70 61 77 6e 5f 74 61 62 6c 65 00 70 72 6f 63 |spawn_table.proc| +00001730 65 73 73 00 75 6c 69 62 63 2e 63 00 73 70 72 69 |ess.ulibc.c.spri| +00001740 6e 74 2e 63 00 73 74 72 6c 65 6e 2e 63 00 63 76 |nt.c.strlen.c.cv| +00001750 74 64 65 63 2e 63 00 63 76 74 64 65 63 30 2e 63 |tdec.c.cvtdec0.c| +00001760 00 63 76 74 68 65 78 2e 63 00 63 76 74 6f 63 74 |.cvthex.c.cvtoct| +00001770 2e 63 00 63 76 74 75 6e 73 2e 63 00 63 76 74 75 |.c.cvtuns.c.cvtu| +00001780 6e 73 30 2e 63 00 70 61 64 73 74 72 2e 63 00 70 |ns0.c.padstr.c.p| +00001790 61 64 2e 63 00 73 77 72 69 74 65 63 68 00 77 61 |ad.c.swritech.wa| +000017a0 69 74 70 69 64 00 63 77 72 69 74 65 00 63 76 74 |itpid.cwrite.cvt| +000017b0 75 6e 73 00 67 65 74 70 69 64 00 73 6c 65 65 70 |uns.getpid.sleep| +000017c0 00 73 77 72 69 74 65 00 70 61 64 00 73 70 61 77 |.swrite.pad.spaw| +000017d0 6e 00 73 70 72 69 6e 74 00 63 76 74 68 65 78 00 |n.sprint.cvthex.| +000017e0 63 76 74 75 6e 73 30 00 6b 69 6c 6c 00 63 77 72 |cvtuns0.kill.cwr| +000017f0 69 74 65 73 00 65 78 65 63 00 77 61 69 74 00 73 |ites.exec.wait.s| +00001800 77 72 69 74 65 73 00 5f 73 74 61 72 74 00 72 65 |writes._start.re| +00001810 61 64 00 67 65 74 70 72 69 6f 00 63 76 74 64 65 |ad.getprio.cvtde| +00001820 63 30 00 66 6f 72 6b 00 6d 61 69 6e 00 67 65 74 |c0.fork.main.get| +00001830 70 70 69 64 00 70 61 64 73 74 72 00 73 65 74 70 |ppid.padstr.setp| +00001840 72 69 6f 00 63 76 74 6f 63 74 00 63 77 72 69 74 |rio.cvtoct.cwrit| +00001850 65 63 68 00 67 65 74 74 69 6d 65 00 63 76 74 64 |ech.gettime.cvtd| +00001860 65 63 00 73 74 72 6c 65 6e 00 62 6f 67 75 73 00 |ec.strlen.bogus.| +00001870 66 61 6b 65 5f 65 78 69 74 00 00 2e 73 79 6d 74 |fake_exit...symt| +00001880 61 62 00 2e 73 74 72 74 61 62 00 2e 73 68 73 74 |ab..strtab..shst| +00001890 72 74 61 62 00 2e 74 65 78 74 00 2e 72 6f 64 61 |rtab..text..roda| +000018a0 74 61 00 2e 64 61 74 61 00 2e 62 73 73 00 00 00 |ta..data..bss...| +000018b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +000018d0 00 00 00 00 00 00 00 00 1b 00 00 00 01 00 00 00 |................| +000018e0 06 00 00 00 00 10 00 00 80 00 00 00 2b 0a 00 00 |............+...| +000018f0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 |................| +00001900 21 00 00 00 01 00 00 00 02 00 00 00 2c 1a 00 00 |!...........,...| +00001910 ac 0a 00 00 74 01 00 00 00 00 00 00 00 00 00 00 |....t...........| +00001920 04 00 00 00 00 00 00 00 29 00 00 00 01 00 00 00 |........).......| +00001930 03 00 00 00 00 20 00 00 80 10 00 00 9d 00 00 00 |..... ..........| +00001940 00 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00 |........ .......| +00001950 2f 00 00 00 08 00 00 00 03 00 00 00 00 30 00 00 |/............0..| +00001960 1d 11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00001970 01 00 00 00 00 00 00 00 01 00 00 00 02 00 00 00 |................| +00001980 00 00 00 00 00 00 00 00 20 11 00 00 70 03 00 00 |........ ...p...| +00001990 06 00 00 00 14 00 00 00 04 00 00 00 10 00 00 00 |................| +000019a0 09 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 |................| +000019b0 90 14 00 00 62 01 00 00 00 00 00 00 00 00 00 00 |....b...........| +000019c0 01 00 00 00 00 00 00 00 11 00 00 00 03 00 00 00 |................| +000019d0 00 00 00 00 00 00 00 00 f2 15 00 00 34 00 00 00 |............4...| +000019e0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 |................| + +Program #1-#19 ELF binaries: +000019f0 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| +00001a00 02 00 03 00 01 00 00 00 85 12 00 00 34 00 00 00 |............4...| +00001a10 38 15 00 00 00 00 00 00 34 00 20 00 02 00 28 00 |8.......4. ...(.| +00001a20 08 00 07 00 01 00 00 00 74 00 00 00 00 10 00 00 |........t.......| +00001a30 00 10 00 00 00 10 00 00 00 10 00 00 07 00 00 00 |................| +00001a40 04 00 00 00 51 e5 74 64 00 00 00 00 00 00 00 00 |....Q.td........| +00001a50 00 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 |................| +00001a60 10 00 00 00 8d 4c 24 04 83 e4 f0 ff 71 fc 55 89 |.....L$.....q.U.| +00001a70 e5 51 81 ec a4 00 00 00 c6 45 e7 2e e8 22 02 00 |.Q.......E..."..| +00001a80 00 89 45 f0 e8 2a 02 00 00 89 45 ec e8 2a 02 00 |..E..*....E..*..| +00001a90 00 89 45 e8 83 ec 0c ff 75 ec ff 75 e8 ff 75 f0 |..E.....u..u..u.| +00001aa0 68 68 18 00 00 8d 85 67 ff ff ff 50 e8 48 02 00 |hh.....g...P.H..| +00001ab0 00 83 c4 20 83 ec 0c 8d 85 67 ff ff ff 50 e8 ff |... .....g...P..| +00001ac0 00 00 00 83 c4 10 83 ec 0c 68 81 18 00 00 e8 ef |.........h......| +00001ad0 00 00 00 83 c4 10 83 ec 04 6a 01 8d 45 e7 50 6a |.........j..E.Pj| +00001ae0 01 e8 b5 01 00 00 83 c4 10 c7 45 f4 00 00 00 00 |..........E.....| +00001af0 eb 04 83 45 f4 01 81 7d f4 ff e0 f5 05 7e f3 83 |...E...}.....~..| +00001b00 ec 04 6a 01 8d 45 e7 50 6a 01 e8 8c 01 00 00 83 |..j..E.Pj.......| +00001b10 c4 10 eb d5 55 89 e5 83 ec 08 83 ec 08 ff 75 08 |....U.........u.| +00001b20 6a 00 e8 54 01 00 00 83 c4 10 c9 c3 55 89 e5 81 |j..T........U...| +00001b30 ec 18 01 00 00 e8 49 01 00 00 89 45 f4 83 7d f4 |......I....E..}.| +00001b40 00 74 05 8b 45 f4 eb 57 e8 56 01 00 00 89 45 f4 |.t..E..W.V....E.| +00001b50 83 ec 08 ff 75 0c ff 75 08 e8 2d 01 00 00 83 c4 |....u..u..-.....| +00001b60 10 ff 75 08 ff 75 f4 68 8f 18 00 00 8d 85 f4 fe |..u..u.h........| +00001b70 ff ff 50 e8 81 01 00 00 83 c4 10 83 ec 0c 8d 85 |..P.............| +00001b80 f4 fe ff ff 50 e8 38 00 00 00 83 c4 10 83 ec 0c |....P.8.........| +00001b90 6a ff e8 dc 00 00 00 83 c4 10 b8 00 00 00 00 c9 |j...............| +00001ba0 c3 55 89 e5 83 ec 18 8b 45 08 88 45 f4 83 ec 04 |.U......E..E....| +00001bb0 6a 01 8d 45 f4 50 6a 00 e8 de 00 00 00 83 c4 10 |j..E.Pj.........| +00001bc0 c9 c3 55 89 e5 83 ec 18 83 ec 0c ff 75 08 e8 9b |..U.........u...| +00001bd0 03 00 00 83 c4 10 89 45 f4 8b 45 f4 83 ec 04 50 |.......E..E....P| +00001be0 ff 75 08 6a 00 e8 b1 00 00 00 83 c4 10 c9 c3 55 |.u.j...........U| +00001bf0 89 e5 83 ec 08 83 ec 04 ff 75 0c ff 75 08 6a 00 |.........u..u.j.| +00001c00 e8 96 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 |..........U.....| +00001c10 8b 45 08 88 45 f4 83 ec 04 6a 01 8d 45 f4 50 6a |.E..E....j..E.Pj| +00001c20 01 e8 75 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec |..u........U....| +00001c30 18 83 ec 0c ff 75 08 e8 32 03 00 00 83 c4 10 89 |.....u..2.......| +00001c40 45 f4 8b 45 f4 83 ec 04 50 ff 75 08 6a 01 e8 48 |E..E....P.u.j..H| +00001c50 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 08 83 ec |........U.......| +00001c60 04 ff 75 0c ff 75 08 6a 01 e8 2d 00 00 00 83 c4 |..u..u.j..-.....| +00001c70 10 c9 c3 b8 00 00 00 00 cd 80 c3 b8 01 00 00 00 |................| +00001c80 cd 80 c3 b8 02 00 00 00 cd 80 c3 b8 03 00 00 00 |................| +00001c90 cd 80 c3 b8 04 00 00 00 cd 80 c3 b8 05 00 00 00 |................| +00001ca0 cd 80 c3 b8 06 00 00 00 cd 80 c3 b8 07 00 00 00 |................| +00001cb0 cd 80 c3 b8 08 00 00 00 cd 80 c3 b8 09 00 00 00 |................| +00001cc0 cd 80 c3 b8 0a 00 00 00 cd 80 c3 b8 0b 00 00 00 |................| +00001cd0 cd 80 c3 b8 0c 00 00 00 cd 80 c3 b8 ad 0b 00 00 |................| +00001ce0 cd 80 c3 50 e8 8a ff ff ff e8 76 fd ff ff 83 ec |...P......v.....| +00001cf0 0c 50 e8 7c ff ff ff eb fe 55 89 e5 83 ec 38 8d |.P.|.....U....8.| +00001d00 45 0c 83 c0 04 89 45 f4 e9 3f 02 00 00 80 7d f3 |E.....E..?....}.| +00001d10 25 0f 85 26 02 00 00 c7 45 ec 00 00 00 00 c7 45 |%..&....E......E| +00001d20 e4 20 00 00 00 c7 45 e8 00 00 00 00 8b 45 0c 8d |. ....E......E..| +00001d30 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 2d 75 |P..U.....E..}.-u| +00001d40 16 c7 45 ec 01 00 00 00 8b 45 0c 8d 50 01 89 55 |..E......E..P..U| +00001d50 0c 0f b6 00 88 45 f3 80 7d f3 30 75 40 c7 45 e4 |.....E..}.0u@.E.| +00001d60 30 00 00 00 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 |0....E..P..U....| +00001d70 88 45 f3 eb 28 8b 55 e8 89 d0 c1 e0 02 01 d0 01 |.E..(.U.........| +00001d80 c0 89 45 e8 0f be 45 f3 83 e8 30 01 45 e8 8b 45 |..E...E...0.E..E| +00001d90 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 |..P..U.....E..}.| +00001da0 2f 7e 06 80 7d f3 39 7e cc 0f be 45 f3 83 e8 63 |/~..}.9~...E...c| +00001db0 83 f8 15 0f 87 93 01 00 00 8b 04 85 ac 18 00 00 |................| +00001dc0 ff e0 8b 45 f4 8d 50 04 89 55 f4 8b 00 88 45 f3 |...E..P..U....E.| +00001dd0 0f b6 45 f3 88 45 d0 c6 45 d1 00 83 ec 08 ff 75 |..E..E..E......u| +00001de0 e4 ff 75 ec ff 75 e8 6a 01 8d 45 d0 50 ff 75 08 |..u..u.j..E.P.u.| +00001df0 e8 17 04 00 00 83 c4 20 89 45 08 e9 4c 01 00 00 |....... .E..L...| +00001e00 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d |.E..P..U......P.| +00001e10 45 d0 50 e8 78 01 00 00 83 c4 10 89 45 e0 83 ec |E.P.x.......E...| +00001e20 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 |..u..u..u..u..E.| +00001e30 50 ff 75 08 e8 d3 03 00 00 83 c4 20 89 45 08 e9 |P.u........ .E..| +00001e40 08 01 00 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 89 |.....E..P..U....| +00001e50 45 dc 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 6a ff |E.....u..u..u.j.| +00001e60 ff 75 dc ff 75 08 e8 a1 03 00 00 83 c4 20 89 45 |.u..u........ .E| +00001e70 08 e9 d6 00 00 00 8b 45 f4 8d 50 04 89 55 f4 8b |.......E..P..U..| +00001e80 00 83 ec 08 50 8d 45 d0 50 e8 d2 01 00 00 83 c4 |....P.E.P.......| +00001e90 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 |..E.....u..u..u.| +00001ea0 ff 75 e0 8d 45 d0 50 ff 75 08 e8 5d 03 00 00 83 |.u..E.P.u..]....| +00001eb0 c4 20 89 45 08 e9 92 00 00 00 8b 45 f4 8d 50 04 |. .E.......E..P.| +00001ec0 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 18 02 |.U......P.E.P...| +00001ed0 00 00 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 |......E.....u..u| +00001ee0 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 19 |..u..u..E.P.u...| +00001ef0 03 00 00 83 c4 20 89 45 08 eb 51 8b 45 f4 8d 50 |..... .E..Q.E..P| +00001f00 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 61 |..U......P.E.P.a| +00001f10 02 00 00 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff |.......E.....u..| +00001f20 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 |u..u..u..E.P.u..| +00001f30 d8 02 00 00 83 c4 20 89 45 08 90 eb 0f 8b 45 08 |...... .E.....E.| +00001f40 8d 50 01 89 55 08 0f b6 55 f3 88 10 8b 45 0c 8d |.P..U...U....E..| +00001f50 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 00 0f |P..U.....E..}...| +00001f60 85 a8 fd ff ff 8b 45 08 c6 00 00 90 c9 c3 55 89 |......E.......U.| +00001f70 e5 53 8b 55 08 bb 00 00 00 00 eb 03 83 c3 01 89 |.S.U............| +00001f80 d0 8d 50 01 0f b6 00 84 c0 75 f1 89 d8 5b 5d c3 |..P......u...[].| +00001f90 55 89 e5 83 ec 18 8b 45 08 89 45 f4 83 7d 0c 00 |U......E..E..}..| +00001fa0 79 0f 8b 45 f4 8d 50 01 89 55 f4 c6 00 2d f7 5d |y..E..P..U...-.]| +00001fb0 0c 83 ec 08 ff 75 0c ff 75 f4 e8 18 00 00 00 83 |.....u..u.......| +00001fc0 c4 10 89 45 f4 8b 45 f4 c6 00 00 8b 55 f4 8b 45 |...E..E.....U..E| +00001fd0 08 29 c2 89 d0 c9 c3 55 89 e5 83 ec 18 8b 4d 0c |.).....U......M.| +00001fe0 ba 67 66 66 66 89 c8 f7 ea c1 fa 02 89 c8 c1 f8 |.gfff...........| +00001ff0 1f 29 c2 89 d0 89 45 f4 83 7d f4 00 79 0e c7 45 |.)....E..}..y..E| +00002000 f4 cc cc cc 0c c7 45 0c 08 00 00 00 83 7d f4 00 |......E......}..| +00002010 74 14 83 ec 08 ff 75 f4 ff 75 08 e8 b7 ff ff ff |t.....u..u......| +00002020 83 c4 10 89 45 08 8b 4d 0c ba 67 66 66 66 89 c8 |....E..M..gfff..| +00002030 f7 ea c1 fa 02 89 c8 c1 f8 1f 29 c2 89 d0 c1 e0 |..........).....| +00002040 02 01 d0 01 c0 29 c1 89 ca 89 d0 8d 48 30 8b 45 |.....)......H0.E| +00002050 08 8d 50 01 89 55 08 89 ca 88 10 8b 45 08 c9 c3 |..P..U......E...| +00002060 55 89 e5 83 ec 20 c7 45 e3 30 31 32 33 c7 45 e7 |U.... .E.0123.E.| +00002070 34 35 36 37 c7 45 eb 38 39 41 42 c7 45 ef 43 44 |4567.E.89AB.E.CD| +00002080 45 46 c6 45 f3 00 c7 45 fc 00 00 00 00 c7 45 f8 |EF.E...E......E.| +00002090 00 00 00 00 eb 43 8b 45 0c 25 00 00 00 f0 89 45 |.....C.E.%.....E| +000020a0 f4 83 7d fc 00 75 0c 83 7d f4 00 75 06 83 7d f8 |..}..u..}..u..}.| +000020b0 07 75 1e 83 45 fc 01 c1 6d f4 1c 8b 45 08 8d 50 |.u..E...m...E..P| +000020c0 01 89 55 08 8d 4d e3 8b 55 f4 01 ca 0f b6 12 88 |..U..M..U.......| +000020d0 10 c1 65 0c 04 83 45 f8 01 83 7d f8 07 7e b7 8b |..e...E...}..~..| +000020e0 45 08 c6 00 00 8b 45 fc c9 c3 55 89 e5 83 ec 10 |E.....E...U.....| +000020f0 c7 45 f8 00 00 00 00 8b 45 08 89 45 f4 8b 45 0c |.E......E..E..E.| +00002100 25 00 00 00 c0 89 45 f0 c1 6d f0 1e c7 45 fc 00 |%.....E..m...E..| +00002110 00 00 00 eb 47 83 7d fc 0a 74 0c 83 7d f0 00 75 |....G.}..t..}..u| +00002120 06 83 7d f8 00 74 1e c7 45 f8 01 00 00 00 83 65 |..}..t..E......e| +00002130 f0 07 8b 45 f0 8d 48 30 8b 45 f4 8d 50 01 89 55 |...E..H0.E..P..U| +00002140 f4 89 ca 88 10 c1 65 0c 03 8b 45 0c 25 00 00 00 |......e...E.%...| +00002150 e0 89 45 f0 c1 6d f0 1d 83 45 fc 01 83 7d fc 0a |..E..m...E...}..| +00002160 7e b3 8b 45 f4 c6 00 00 8b 55 f4 8b 45 08 29 c2 |~..E.....U..E.).| +00002170 89 d0 c9 c3 55 89 e5 83 ec 18 8b 45 08 89 45 f4 |....U......E..E.| +00002180 83 ec 08 ff 75 0c ff 75 f4 e8 18 00 00 00 83 c4 |....u..u........| +00002190 10 89 45 f4 8b 45 f4 c6 00 00 8b 55 f4 8b 45 08 |..E..E.....U..E.| +000021a0 29 c2 89 d0 c9 c3 55 89 e5 83 ec 18 8b 45 0c ba |).....U......E..| +000021b0 cd cc cc cc f7 e2 89 d0 c1 e8 03 89 45 f4 83 7d |............E..}| +000021c0 f4 00 74 15 8b 45 f4 83 ec 08 50 ff 75 08 e8 04 |..t..E....P.u...| +000021d0 fe ff ff 83 c4 10 89 45 08 8b 4d 0c ba cd cc cc |.......E..M.....| +000021e0 cc 89 c8 f7 e2 c1 ea 03 89 d0 c1 e0 02 01 d0 01 |................| +000021f0 c0 29 c1 89 ca 89 d0 8d 48 30 8b 45 08 8d 50 01 |.)......H0.E..P.| +00002200 89 55 08 89 ca 88 10 8b 45 08 c9 c3 55 89 e5 83 |.U......E...U...| +00002210 ec 18 83 7d 10 00 79 11 83 ec 0c ff 75 0c e8 4b |...}..y.....u..K| +00002220 fd ff ff 83 c4 10 89 45 10 8b 45 14 2b 45 10 89 |.......E..E.+E..| +00002230 45 f0 83 7d f0 00 7e 1d 83 7d 18 00 75 17 83 ec |E..}..~..}..u...| +00002240 04 ff 75 1c ff 75 f0 ff 75 08 e8 5a 00 00 00 83 |..u..u..u..Z....| +00002250 c4 10 89 45 08 c7 45 f4 00 00 00 00 eb 1b 8b 55 |...E..E........U| +00002260 f4 8b 45 0c 8d 0c 02 8b 45 08 8d 50 01 89 55 08 |..E.....E..P..U.| +00002270 0f b6 11 88 10 83 45 f4 01 8b 45 f4 3b 45 10 7c |......E...E.;E.|| +00002280 dd 83 7d f0 00 7e 1d 83 7d 18 00 74 17 83 ec 04 |..}..~..}..t....| +00002290 ff 75 1c ff 75 f0 ff 75 08 e8 0b 00 00 00 83 c4 |.u..u..u........| +000022a0 10 89 45 08 8b 45 08 c9 c3 55 89 e5 eb 12 8b 45 |..E..E...U.....E| +000022b0 08 8d 50 01 89 55 08 8b 55 10 88 10 83 6d 0c 01 |..P..U..U....m..| +000022c0 83 7d 0c 00 7f e8 8b 45 08 5d c3 00 49 64 6c 65 |.}.....E.]..Idle| +000022d0 20 5b 25 64 5d 2c 20 73 74 61 72 74 65 64 20 40 | [%d], started @| +000022e0 20 25 75 0a 00 49 64 6c 65 20 73 74 61 72 74 65 | %u..Idle starte| +000022f0 64 0a 00 43 68 69 6c 64 20 25 64 20 65 78 65 63 |d..Child %d exec| +00002300 28 29 20 23 25 75 20 66 61 69 6c 65 64 0a 00 00 |() #%u failed...| +00002310 5e 13 00 00 9c 13 00 00 e8 14 00 00 e8 14 00 00 |^...............| +00002320 e8 14 00 00 e8 14 00 00 e8 14 00 00 e8 14 00 00 |................| +* +00002340 56 14 00 00 e8 14 00 00 e8 14 00 00 e8 14 00 00 |V...............| +00002350 e0 13 00 00 e8 14 00 00 97 14 00 00 e8 14 00 00 |................| +00002360 e8 14 00 00 12 14 00 00 00 00 00 00 00 00 00 00 |................| +00002370 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00002a70 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 |................| +00002a80 03 00 01 00 00 00 00 00 68 18 00 00 00 00 00 00 |........h.......| +00002a90 03 00 02 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +00002aa0 03 00 03 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +00002ab0 03 00 04 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +00002ac0 04 00 f1 ff 08 00 00 00 00 00 00 00 00 00 00 00 |................| +00002ad0 04 00 f1 ff 10 00 00 00 00 00 00 00 00 00 00 00 |................| +00002ae0 04 00 f1 ff 19 00 00 00 00 00 00 00 00 00 00 00 |................| +00002af0 04 00 f1 ff 22 00 00 00 00 00 00 00 00 00 00 00 |...."...........| +00002b00 04 00 f1 ff 2b 00 00 00 00 00 00 00 00 00 00 00 |....+...........| +00002b10 04 00 f1 ff 35 00 00 00 00 00 00 00 00 00 00 00 |....5...........| +00002b20 04 00 f1 ff 3e 00 00 00 00 00 00 00 00 00 00 00 |....>...........| +00002b30 04 00 f1 ff 47 00 00 00 00 00 00 00 00 00 00 00 |....G...........| +00002b40 04 00 f1 ff 50 00 00 00 00 00 00 00 00 00 00 00 |....P...........| +00002b50 04 00 f1 ff 5a 00 00 00 00 00 00 00 00 00 00 00 |....Z...........| +00002b60 04 00 f1 ff 63 00 00 00 00 00 00 00 00 00 00 00 |....c...........| +00002b70 04 00 f1 ff 69 00 00 00 a6 11 00 00 21 00 00 00 |....i.......!...| +00002b80 12 00 01 00 72 00 00 00 17 12 00 00 00 00 00 00 |....r...........| +00002b90 10 00 01 00 7a 00 00 00 8b 11 00 00 1b 00 00 00 |....z...........| +00002ba0 12 00 01 00 81 00 00 00 10 17 00 00 32 00 00 00 |............2...| +00002bb0 12 00 01 00 88 00 00 00 3f 12 00 00 00 00 00 00 |........?.......| +00002bc0 10 00 01 00 8f 00 00 00 6f 12 00 00 00 00 00 00 |........o.......| +00002bd0 10 00 01 00 95 00 00 00 f4 11 00 00 1b 00 00 00 |................| +00002be0 12 00 01 00 9c 00 00 00 45 18 00 00 22 00 00 00 |........E..."...| +00002bf0 12 00 01 00 a0 00 00 00 c8 10 00 00 75 00 00 00 |............u...| +00002c00 12 00 01 00 a6 00 00 00 95 12 00 00 75 02 00 00 |............u...| +00002c10 12 00 01 00 ad 00 00 00 fc 15 00 00 8a 00 00 00 |................| +00002c20 12 00 01 00 b4 00 00 00 42 17 00 00 66 00 00 00 |........B...f...| +00002c30 12 00 01 00 7b 00 00 00 37 12 00 00 00 00 00 00 |....{...7.......| +00002c40 10 00 01 00 bc 00 00 00 67 12 00 00 00 00 00 00 |........g.......| +00002c50 10 00 01 00 c1 00 00 00 5e 11 00 00 2d 00 00 00 |........^...-...| +00002c60 12 00 01 00 c9 00 00 00 27 12 00 00 00 00 00 00 |........'.......| +00002c70 10 00 01 00 ce 00 00 00 b0 10 00 00 18 00 00 00 |................| +00002c80 12 00 01 00 d3 00 00 00 c7 11 00 00 2d 00 00 00 |............-...| +00002c90 12 00 01 00 db 00 00 00 85 12 00 00 00 00 00 00 |................| +00002ca0 10 00 01 00 e2 00 00 00 2f 12 00 00 00 00 00 00 |......../.......| +00002cb0 10 00 01 00 e7 00 00 00 57 12 00 00 00 00 00 00 |........W.......| +00002cc0 10 00 01 00 ef 00 00 00 73 15 00 00 89 00 00 00 |........s.......| +00002cd0 12 00 01 00 f7 00 00 00 1f 12 00 00 00 00 00 00 |................| +00002ce0 10 00 01 00 fc 00 00 00 00 10 00 00 b0 00 00 00 |................| +00002cf0 12 00 01 00 01 01 00 00 47 12 00 00 00 00 00 00 |........G.......| +00002d00 10 00 01 00 09 01 00 00 a8 17 00 00 9d 00 00 00 |................| +00002d10 12 00 01 00 10 01 00 00 5f 12 00 00 00 00 00 00 |........_.......| +00002d20 10 00 01 00 18 01 00 00 86 16 00 00 8a 00 00 00 |................| +00002d30 12 00 01 00 1f 01 00 00 3d 11 00 00 21 00 00 00 |........=...!...| +00002d40 12 00 01 00 28 01 00 00 4f 12 00 00 00 00 00 00 |....(...O.......| +00002d50 10 00 01 00 30 01 00 00 2c 15 00 00 47 00 00 00 |....0...,...G...| +00002d60 12 00 01 00 49 01 00 00 0f 12 00 00 00 00 00 00 |....I...........| +00002d70 10 00 01 00 37 01 00 00 0a 15 00 00 22 00 00 00 |....7......."...| +00002d80 12 00 01 00 3e 01 00 00 77 12 00 00 00 00 00 00 |....>...w.......| +00002d90 10 00 01 00 44 01 00 00 7f 12 00 00 00 00 00 00 |....D...........| +00002da0 10 00 01 00 00 69 64 6c 65 2e 63 00 75 6c 69 62 |.....idle.c.ulib| +00002db0 63 2e 63 00 73 70 72 69 6e 74 2e 63 00 73 74 72 |c.c.sprint.c.str| +00002dc0 6c 65 6e 2e 63 00 63 76 74 64 65 63 2e 63 00 63 |len.c.cvtdec.c.c| +00002dd0 76 74 64 65 63 30 2e 63 00 63 76 74 68 65 78 2e |vtdec0.c.cvthex.| +00002de0 63 00 63 76 74 6f 63 74 2e 63 00 63 76 74 75 6e |c.cvtoct.c.cvtun| +00002df0 73 2e 63 00 63 76 74 75 6e 73 30 2e 63 00 70 61 |s.c.cvtuns0.c.pa| +00002e00 64 73 74 72 2e 63 00 70 61 64 2e 63 00 73 77 72 |dstr.c.pad.c.swr| +00002e10 69 74 65 63 68 00 77 61 69 74 70 69 64 00 63 77 |itech.waitpid.cw| +00002e20 72 69 74 65 00 63 76 74 75 6e 73 00 67 65 74 70 |rite.cvtuns.getp| +00002e30 69 64 00 73 6c 65 65 70 00 73 77 72 69 74 65 00 |id.sleep.swrite.| +00002e40 70 61 64 00 73 70 61 77 6e 00 73 70 72 69 6e 74 |pad.spawn.sprint| +00002e50 00 63 76 74 68 65 78 00 63 76 74 75 6e 73 30 00 |.cvthex.cvtuns0.| +00002e60 6b 69 6c 6c 00 63 77 72 69 74 65 73 00 65 78 65 |kill.cwrites.exe| +00002e70 63 00 77 61 69 74 00 73 77 72 69 74 65 73 00 5f |c.wait.swrites._| +00002e80 73 74 61 72 74 00 72 65 61 64 00 67 65 74 70 72 |start.read.getpr| +00002e90 69 6f 00 63 76 74 64 65 63 30 00 66 6f 72 6b 00 |io.cvtdec0.fork.| +00002ea0 6d 61 69 6e 00 67 65 74 70 70 69 64 00 70 61 64 |main.getppid.pad| +00002eb0 73 74 72 00 73 65 74 70 72 69 6f 00 63 76 74 6f |str.setprio.cvto| +00002ec0 63 74 00 63 77 72 69 74 65 63 68 00 67 65 74 74 |ct.cwritech.gett| +00002ed0 69 6d 65 00 63 76 74 64 65 63 00 73 74 72 6c 65 |ime.cvtdec.strle| +00002ee0 6e 00 62 6f 67 75 73 00 66 61 6b 65 5f 65 78 69 |n.bogus.fake_exi| +00002ef0 74 00 00 2e 73 79 6d 74 61 62 00 2e 73 74 72 74 |t...symtab..strt| +00002f00 61 62 00 2e 73 68 73 74 72 74 61 62 00 2e 74 65 |ab..shstrtab..te| +00002f10 78 74 00 2e 72 6f 64 61 74 61 00 2e 64 61 74 61 |xt..rodata..data| +00002f20 00 2e 62 73 73 00 00 00 00 00 00 00 00 00 00 00 |..bss...........| +00002f30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00002f50 1b 00 00 00 01 00 00 00 06 00 00 00 00 10 00 00 |................| +00002f60 74 00 00 00 67 08 00 00 00 00 00 00 00 00 00 00 |t...g...........| +00002f70 01 00 00 00 00 00 00 00 21 00 00 00 01 00 00 00 |........!.......| +00002f80 02 00 00 00 68 18 00 00 dc 08 00 00 9c 00 00 00 |....h...........| +00002f90 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 |................| +00002fa0 29 00 00 00 01 00 00 00 03 00 00 00 00 20 00 00 |)............ ..| +00002fb0 74 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |t...............| +00002fc0 01 00 00 00 00 00 00 00 2f 00 00 00 08 00 00 00 |......../.......| +00002fd0 03 00 00 00 00 20 00 00 74 10 00 00 00 00 00 00 |..... ..t.......| +00002fe0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 |................| +00002ff0 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 |................| +00003000 74 10 00 00 40 03 00 00 06 00 00 00 11 00 00 00 |t...@...........| +00003010 04 00 00 00 10 00 00 00 09 00 00 00 03 00 00 00 |................| +00003020 00 00 00 00 00 00 00 00 b4 13 00 00 4e 01 00 00 |............N...| +00003030 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 |................| +00003040 11 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 |................| +00003050 02 15 00 00 34 00 00 00 00 00 00 00 00 00 00 00 |....4...........| +00003060 01 00 00 00 00 00 00 00 7f 45 4c 46 01 01 01 00 |.........ELF....| +00003070 00 00 00 00 00 00 00 00 02 00 03 00 01 00 00 00 |................| +00003080 87 15 00 00 34 00 00 00 f4 19 00 00 00 00 00 00 |....4...........| +00003090 34 00 20 00 02 00 28 00 08 00 07 00 01 00 00 00 |4. ...(.........| +000030a0 80 00 00 00 00 10 00 00 00 10 00 00 20 14 00 00 |............ ...| +000030b0 08 20 00 00 07 00 00 00 20 00 00 00 51 e5 74 64 |. ...... ...Q.td| +000030c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +000030d0 00 00 00 00 07 00 00 00 10 00 00 00 00 00 00 00 |................| +000030e0 00 00 00 00 00 00 00 00 55 89 e5 83 ec 18 83 ec |........U.......| +000030f0 0c 68 38 1c 00 00 e8 b6 04 00 00 83 c4 10 c7 45 |.h8............E| +00003100 f4 00 20 00 00 eb 23 83 ec 0c 6a 20 e8 7f 04 00 |.. ...#...j ....| +00003110 00 83 c4 10 8b 45 f4 0f b6 40 05 0f be c0 83 ec |.....E...@......| +00003120 0c 50 e8 69 04 00 00 83 c4 10 8b 45 f4 8b 00 3d |.P.i.......E...=| +00003130 62 60 01 00 75 d1 83 ec 0c 68 70 1c 00 00 e8 6e |b`..u....hp....n| +00003140 04 00 00 83 c4 10 90 c9 c3 55 89 e5 53 81 ec a4 |.........U..S...| +00003150 00 00 00 8b 45 08 88 85 64 ff ff ff 80 bd 64 ff |....E...d.....d.| +00003160 ff ff 68 75 0a e8 7e ff ff ff e9 e0 00 00 00 80 |..hu..~.........| +00003170 bd 64 ff ff ff 78 75 0c c6 05 00 30 00 00 01 e9 |.d...xu....0....| +00003180 cb 00 00 00 80 bd 64 ff ff ff 2a 75 40 bb 00 20 |......d...*u@.. | +00003190 00 00 eb 2b 8d 53 08 8b 03 83 ec 08 52 50 e8 0f |...+.S......RP..| +000031a0 03 00 00 83 c4 10 89 45 f0 83 7d f0 00 7e 0d a1 |.......E..}..~..| +000031b0 04 30 00 00 83 c0 01 a3 04 30 00 00 83 c3 30 8b |.0.......0....0.| +000031c0 03 3d 62 60 01 00 75 cc e9 82 00 00 00 bb 00 20 |.=b`..u........ | +000031d0 00 00 eb 3c 0f b6 43 05 38 85 64 ff ff ff 75 2d |...<..C.8.d...u-| +000031e0 8d 53 08 8b 03 83 ec 08 52 50 e8 c3 02 00 00 83 |.S......RP......| +000031f0 c4 10 89 45 f4 83 7d f4 00 7e 0d a1 04 30 00 00 |...E..}..~...0..| +00003200 83 c0 01 a3 04 30 00 00 8b 45 f4 eb 47 83 c3 30 |.....0...E..G..0| +00003210 8b 03 3d 62 60 01 00 75 bb 0f be 85 64 ff ff ff |..=b`..u....d...| +00003220 83 ec 04 50 68 a1 1c 00 00 8d 85 70 ff ff ff 50 |...Ph......p...P| +00003230 e8 4a 04 00 00 83 c4 10 83 ec 0c 8d 85 70 ff ff |.J...........p..| +00003240 ff 50 e8 6a 03 00 00 83 c4 10 e8 99 fe ff ff b8 |.P.j............| +00003250 00 00 00 00 8b 5d fc c9 c3 55 89 e5 83 ec 10 8b |.....]...U......| +00003260 45 0c 8d 50 ff 8b 45 08 01 d0 89 45 fc eb 18 8b |E..P..E....E....| +00003270 45 fc 0f b6 00 3c 0a 74 0a 8b 45 fc 0f b6 00 3c |E....<.t..E....<| +00003280 0d 75 0a 83 6d 0c 01 83 7d 0c 00 7f e2 83 7d 0c |.u..m...}.....}.| +00003290 00 7e 0b 8b 55 0c 8b 45 08 01 d0 c6 00 00 8b 45 |.~..U..E.......E| +000032a0 0c c9 c3 8d 4c 24 04 83 e4 f0 ff 71 fc 55 89 e5 |....L$.....q.U..| +000032b0 51 81 ec 24 01 00 00 83 ec 0c 68 ba 1c 00 00 e8 |Q..$......h.....| +000032c0 ed 02 00 00 83 c4 10 e8 1c fe ff ff e9 90 01 00 |................| +000032d0 00 83 ec 0c 68 ca 1c 00 00 e8 d3 02 00 00 83 c4 |....h...........| +000032e0 10 83 ec 04 68 80 00 00 00 8d 85 e0 fe ff ff 50 |....h..........P| +000032f0 6a 01 e8 22 03 00 00 83 c4 10 89 45 ec 83 7d ec |j..".......E..}.| +00003300 02 0f 8e 56 01 00 00 83 ec 08 ff 75 ec 8d 85 e0 |...V.......u....| +00003310 fe ff ff 50 e8 40 ff ff ff 83 c4 10 89 45 ec 83 |...P.@.......E..| +00003320 7d ec 01 0f 8e 37 01 00 00 c7 45 f0 00 00 00 00 |}....7....E.....| +00003330 8d 85 e0 fe ff ff 89 45 f4 eb 12 8b 45 f4 0f b6 |.......E....E...| +00003340 00 3c 40 74 12 83 45 f0 01 83 45 f4 01 8b 45 f0 |.<@t..E...E...E.| +00003350 3b 45 ec 7c e6 eb 01 90 8b 45 f0 3b 45 ec 0f 8d |;E.|.....E.;E...| +00003360 fd 00 00 00 83 45 f4 01 eb 60 8b 45 f4 0f b6 00 |.....E...`.E....| +00003370 0f be c0 83 ec 0c 50 e8 cd fd ff ff 83 c4 10 89 |......P.........| +00003380 45 e8 83 7d e8 00 79 33 8b 45 f4 0f b6 00 0f be |E..}..y3.E......| +00003390 c0 ff 75 e8 50 68 d0 1c 00 00 8d 85 60 ff ff ff |..u.Ph......`...| +000033a0 50 e8 d9 02 00 00 83 c4 10 83 ec 0c 8d 85 60 ff |P.............`.| +000033b0 ff ff 50 e8 90 01 00 00 83 c4 10 0f b6 05 00 30 |..P............0| +000033c0 00 00 84 c0 75 10 83 45 f4 01 8b 45 f4 0f b6 00 |....u..E...E....| +000033d0 84 c0 75 96 eb 79 90 eb 76 83 ec 08 8d 45 e0 50 |..u..y..v....E.P| +000033e0 6a 00 e8 1a 02 00 00 83 c4 10 89 45 e4 83 7d e4 |j..........E..}.| +000033f0 fc 74 67 83 7d e4 00 7f 1c 83 ec 04 ff 75 e4 68 |.tg.}........u.h| +00003400 f4 1c 00 00 8d 85 60 ff ff ff 50 e8 6f 02 00 00 |......`...P.o...| +00003410 83 c4 10 eb 28 a1 04 30 00 00 83 e8 01 a3 04 30 |....(..0.......0| +00003420 00 00 8b 45 e0 50 ff 75 e4 68 12 1d 00 00 8d 85 |...E.P.u.h......| +00003430 60 ff ff ff 50 e8 45 02 00 00 83 c4 10 83 ec 0c |`...P.E.........| +00003440 8d 85 60 ff ff ff 50 e8 65 01 00 00 83 c4 10 a1 |..`...P.e.......| +00003450 04 30 00 00 85 c0 7f 81 eb 07 90 eb 04 90 eb 01 |.0..............| +00003460 90 0f b6 05 00 30 00 00 84 c0 0f 84 61 fe ff ff |.....0......a...| +00003470 83 ec 0c 68 30 1d 00 00 e8 cb 00 00 00 83 c4 10 |...h0...........| +00003480 83 ec 0c 6a 01 e8 6f 01 00 00 83 c4 10 b8 00 00 |...j..o.........| +00003490 00 00 8b 4d fc c9 8d 61 fc c3 55 89 e5 83 ec 08 |...M...a..U.....| +000034a0 83 ec 08 ff 75 08 6a 00 e8 54 01 00 00 83 c4 10 |....u.j..T......| +000034b0 c9 c3 55 89 e5 81 ec 18 01 00 00 e8 49 01 00 00 |..U.........I...| +000034c0 89 45 f4 83 7d f4 00 74 05 8b 45 f4 eb 57 e8 56 |.E..}..t..E..W.V| +000034d0 01 00 00 89 45 f4 83 ec 08 ff 75 0c ff 75 08 e8 |....E.....u..u..| +000034e0 2d 01 00 00 83 c4 10 ff 75 08 ff 75 f4 68 4a 1d |-.......u..u.hJ.| +000034f0 00 00 8d 85 f4 fe ff ff 50 e8 81 01 00 00 83 c4 |........P.......| +00003500 10 83 ec 0c 8d 85 f4 fe ff ff 50 e8 38 00 00 00 |..........P.8...| +00003510 83 c4 10 83 ec 0c 6a ff e8 dc 00 00 00 83 c4 10 |......j.........| +00003520 b8 00 00 00 00 c9 c3 55 89 e5 83 ec 18 8b 45 08 |.......U......E.| +00003530 88 45 f4 83 ec 04 6a 01 8d 45 f4 50 6a 00 e8 de |.E....j..E.Pj...| +00003540 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 83 ec |........U.......| +00003550 0c ff 75 08 e8 9b 03 00 00 83 c4 10 89 45 f4 8b |..u..........E..| +00003560 45 f4 83 ec 04 50 ff 75 08 6a 00 e8 b1 00 00 00 |E....P.u.j......| +00003570 83 c4 10 c9 c3 55 89 e5 83 ec 08 83 ec 04 ff 75 |.....U.........u| +00003580 0c ff 75 08 6a 00 e8 96 00 00 00 83 c4 10 c9 c3 |..u.j...........| +00003590 55 89 e5 83 ec 18 8b 45 08 88 45 f4 83 ec 04 6a |U......E..E....j| +000035a0 01 8d 45 f4 50 6a 01 e8 75 00 00 00 83 c4 10 c9 |..E.Pj..u.......| +000035b0 c3 55 89 e5 83 ec 18 83 ec 0c ff 75 08 e8 32 03 |.U.........u..2.| +000035c0 00 00 83 c4 10 89 45 f4 8b 45 f4 83 ec 04 50 ff |......E..E....P.| +000035d0 75 08 6a 01 e8 48 00 00 00 83 c4 10 c9 c3 55 89 |u.j..H........U.| +000035e0 e5 83 ec 08 83 ec 04 ff 75 0c ff 75 08 6a 01 e8 |........u..u.j..| +000035f0 2d 00 00 00 83 c4 10 c9 c3 b8 00 00 00 00 cd 80 |-...............| +00003600 c3 b8 01 00 00 00 cd 80 c3 b8 02 00 00 00 cd 80 |................| +00003610 c3 b8 03 00 00 00 cd 80 c3 b8 04 00 00 00 cd 80 |................| +00003620 c3 b8 05 00 00 00 cd 80 c3 b8 06 00 00 00 cd 80 |................| +00003630 c3 b8 07 00 00 00 cd 80 c3 b8 08 00 00 00 cd 80 |................| +00003640 c3 b8 09 00 00 00 cd 80 c3 b8 0a 00 00 00 cd 80 |................| +00003650 c3 b8 0b 00 00 00 cd 80 c3 b8 0c 00 00 00 cd 80 |................| +00003660 c3 b8 ad 0b 00 00 cd 80 c3 50 e8 8a ff ff ff e8 |.........P......| +00003670 2f fc ff ff 83 ec 0c 50 e8 7c ff ff ff eb fe 55 |/......P.|.....U| +00003680 89 e5 83 ec 38 8d 45 0c 83 c0 04 89 45 f4 e9 3f |....8.E.....E..?| +00003690 02 00 00 80 7d f3 25 0f 85 26 02 00 00 c7 45 ec |....}.%..&....E.| +000036a0 00 00 00 00 c7 45 e4 20 00 00 00 c7 45 e8 00 00 |.....E. ....E...| +000036b0 00 00 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 |...E..P..U.....E| +000036c0 f3 80 7d f3 2d 75 16 c7 45 ec 01 00 00 00 8b 45 |..}.-u..E......E| +000036d0 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 |..P..U.....E..}.| +000036e0 30 75 40 c7 45 e4 30 00 00 00 8b 45 0c 8d 50 01 |0u@.E.0....E..P.| +000036f0 89 55 0c 0f b6 00 88 45 f3 eb 28 8b 55 e8 89 d0 |.U.....E..(.U...| +00003700 c1 e0 02 01 d0 01 c0 89 45 e8 0f be 45 f3 83 e8 |........E...E...| +00003710 30 01 45 e8 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 |0.E..E..P..U....| +00003720 88 45 f3 80 7d f3 2f 7e 06 80 7d f3 39 7e cc 0f |.E..}./~..}.9~..| +00003730 be 45 f3 83 e8 63 83 f8 15 0f 87 93 01 00 00 8b |.E...c..........| +00003740 04 85 68 1d 00 00 ff e0 8b 45 f4 8d 50 04 89 55 |..h......E..P..U| +00003750 f4 8b 00 88 45 f3 0f b6 45 f3 88 45 d0 c6 45 d1 |....E...E..E..E.| +00003760 00 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 6a 01 8d |.....u..u..u.j..| +00003770 45 d0 50 ff 75 08 e8 17 04 00 00 83 c4 20 89 45 |E.P.u........ .E| +00003780 08 e9 4c 01 00 00 8b 45 f4 8d 50 04 89 55 f4 8b |..L....E..P..U..| +00003790 00 83 ec 08 50 8d 45 d0 50 e8 78 01 00 00 83 c4 |....P.E.P.x.....| +000037a0 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 |..E.....u..u..u.| +000037b0 ff 75 e0 8d 45 d0 50 ff 75 08 e8 d3 03 00 00 83 |.u..E.P.u.......| +000037c0 c4 20 89 45 08 e9 08 01 00 00 8b 45 f4 8d 50 04 |. .E.......E..P.| +000037d0 89 55 f4 8b 00 89 45 dc 83 ec 08 ff 75 e4 ff 75 |.U....E.....u..u| +000037e0 ec ff 75 e8 6a ff ff 75 dc ff 75 08 e8 a1 03 00 |..u.j..u..u.....| +000037f0 00 83 c4 20 89 45 08 e9 d6 00 00 00 8b 45 f4 8d |... .E.......E..| +00003800 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 |P..U......P.E.P.| +00003810 d2 01 00 00 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 |........E.....u.| +00003820 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 |.u..u..u..E.P.u.| +00003830 e8 5d 03 00 00 83 c4 20 89 45 08 e9 92 00 00 00 |.]..... .E......| +00003840 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d |.E..P..U......P.| +00003850 45 d0 50 e8 18 02 00 00 83 c4 10 89 45 e0 83 ec |E.P.........E...| +00003860 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 |..u..u..u..u..E.| +00003870 50 ff 75 08 e8 19 03 00 00 83 c4 20 89 45 08 eb |P.u........ .E..| +00003880 51 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 |Q.E..P..U......P| +00003890 8d 45 d0 50 e8 61 02 00 00 83 c4 10 89 45 e0 83 |.E.P.a.......E..| +000038a0 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 |...u..u..u..u..E| +000038b0 d0 50 ff 75 08 e8 d8 02 00 00 83 c4 20 89 45 08 |.P.u........ .E.| +000038c0 90 eb 0f 8b 45 08 8d 50 01 89 55 08 0f b6 55 f3 |....E..P..U...U.| +000038d0 88 10 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 |...E..P..U.....E| +000038e0 f3 80 7d f3 00 0f 85 a8 fd ff ff 8b 45 08 c6 00 |..}.........E...| +000038f0 00 90 c9 c3 55 89 e5 53 8b 55 08 bb 00 00 00 00 |....U..S.U......| +00003900 eb 03 83 c3 01 89 d0 8d 50 01 0f b6 00 84 c0 75 |........P......u| +00003910 f1 89 d8 5b 5d c3 55 89 e5 83 ec 18 8b 45 08 89 |...[].U......E..| +00003920 45 f4 83 7d 0c 00 79 0f 8b 45 f4 8d 50 01 89 55 |E..}..y..E..P..U| +00003930 f4 c6 00 2d f7 5d 0c 83 ec 08 ff 75 0c ff 75 f4 |...-.].....u..u.| +00003940 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 c6 00 |.........E..E...| +00003950 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 |..U..E.).....U..| +00003960 83 ec 18 8b 4d 0c ba 67 66 66 66 89 c8 f7 ea c1 |....M..gfff.....| +00003970 fa 02 89 c8 c1 f8 1f 29 c2 89 d0 89 45 f4 83 7d |.......)....E..}| +00003980 f4 00 79 0e c7 45 f4 cc cc cc 0c c7 45 0c 08 00 |..y..E......E...| +00003990 00 00 83 7d f4 00 74 14 83 ec 08 ff 75 f4 ff 75 |...}..t.....u..u| +000039a0 08 e8 b7 ff ff ff 83 c4 10 89 45 08 8b 4d 0c ba |..........E..M..| +000039b0 67 66 66 66 89 c8 f7 ea c1 fa 02 89 c8 c1 f8 1f |gfff............| +000039c0 29 c2 89 d0 c1 e0 02 01 d0 01 c0 29 c1 89 ca 89 |)..........)....| +000039d0 d0 8d 48 30 8b 45 08 8d 50 01 89 55 08 89 ca 88 |..H0.E..P..U....| +000039e0 10 8b 45 08 c9 c3 55 89 e5 83 ec 20 c7 45 e3 30 |..E...U.... .E.0| +000039f0 31 32 33 c7 45 e7 34 35 36 37 c7 45 eb 38 39 41 |123.E.4567.E.89A| +00003a00 42 c7 45 ef 43 44 45 46 c6 45 f3 00 c7 45 fc 00 |B.E.CDEF.E...E..| +00003a10 00 00 00 c7 45 f8 00 00 00 00 eb 43 8b 45 0c 25 |....E......C.E.%| +00003a20 00 00 00 f0 89 45 f4 83 7d fc 00 75 0c 83 7d f4 |.....E..}..u..}.| +00003a30 00 75 06 83 7d f8 07 75 1e 83 45 fc 01 c1 6d f4 |.u..}..u..E...m.| +00003a40 1c 8b 45 08 8d 50 01 89 55 08 8d 4d e3 8b 55 f4 |..E..P..U..M..U.| +00003a50 01 ca 0f b6 12 88 10 c1 65 0c 04 83 45 f8 01 83 |........e...E...| +00003a60 7d f8 07 7e b7 8b 45 08 c6 00 00 8b 45 fc c9 c3 |}..~..E.....E...| +00003a70 55 89 e5 83 ec 10 c7 45 f8 00 00 00 00 8b 45 08 |U......E......E.| +00003a80 89 45 f4 8b 45 0c 25 00 00 00 c0 89 45 f0 c1 6d |.E..E.%.....E..m| +00003a90 f0 1e c7 45 fc 00 00 00 00 eb 47 83 7d fc 0a 74 |...E......G.}..t| +00003aa0 0c 83 7d f0 00 75 06 83 7d f8 00 74 1e c7 45 f8 |..}..u..}..t..E.| +00003ab0 01 00 00 00 83 65 f0 07 8b 45 f0 8d 48 30 8b 45 |.....e...E..H0.E| +00003ac0 f4 8d 50 01 89 55 f4 89 ca 88 10 c1 65 0c 03 8b |..P..U......e...| +00003ad0 45 0c 25 00 00 00 e0 89 45 f0 c1 6d f0 1d 83 45 |E.%.....E..m...E| +00003ae0 fc 01 83 7d fc 0a 7e b3 8b 45 f4 c6 00 00 8b 55 |...}..~..E.....U| +00003af0 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 ec 18 |..E.).....U.....| +00003b00 8b 45 08 89 45 f4 83 ec 08 ff 75 0c ff 75 f4 e8 |.E..E.....u..u..| +00003b10 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 c6 00 00 |........E..E....| +00003b20 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 |.U..E.).....U...| +00003b30 ec 18 8b 45 0c ba cd cc cc cc f7 e2 89 d0 c1 e8 |...E............| +00003b40 03 89 45 f4 83 7d f4 00 74 15 8b 45 f4 83 ec 08 |..E..}..t..E....| +00003b50 50 ff 75 08 e8 04 fe ff ff 83 c4 10 89 45 08 8b |P.u..........E..| +00003b60 4d 0c ba cd cc cc cc 89 c8 f7 e2 c1 ea 03 89 d0 |M...............| +00003b70 c1 e0 02 01 d0 01 c0 29 c1 89 ca 89 d0 8d 48 30 |.......)......H0| +00003b80 8b 45 08 8d 50 01 89 55 08 89 ca 88 10 8b 45 08 |.E..P..U......E.| +00003b90 c9 c3 55 89 e5 83 ec 18 83 7d 10 00 79 11 83 ec |..U......}..y...| +00003ba0 0c ff 75 0c e8 4b fd ff ff 83 c4 10 89 45 10 8b |..u..K.......E..| +00003bb0 45 14 2b 45 10 89 45 f0 83 7d f0 00 7e 1d 83 7d |E.+E..E..}..~..}| +00003bc0 18 00 75 17 83 ec 04 ff 75 1c ff 75 f0 ff 75 08 |..u.....u..u..u.| +00003bd0 e8 5a 00 00 00 83 c4 10 89 45 08 c7 45 f4 00 00 |.Z.......E..E...| +00003be0 00 00 eb 1b 8b 55 f4 8b 45 0c 8d 0c 02 8b 45 08 |.....U..E.....E.| +00003bf0 8d 50 01 89 55 08 0f b6 11 88 10 83 45 f4 01 8b |.P..U.......E...| +00003c00 45 f4 3b 45 10 7c dd 83 7d f0 00 7e 1d 83 7d 18 |E.;E.|..}..~..}.| +00003c10 00 74 17 83 ec 04 ff 75 1c ff 75 f0 ff 75 08 e8 |.t.....u..u..u..| +00003c20 0b 00 00 00 83 c4 10 89 45 08 8b 45 08 c9 c3 55 |........E..E...U| +00003c30 89 e5 eb 12 8b 45 08 8d 50 01 89 55 08 8b 55 10 |.....E..P..U..U.| +00003c40 88 10 83 6d 0c 01 83 7d 0c 00 7f e8 8b 45 08 5d |...m...}.....E.]| +00003c50 c3 00 00 00 75 73 65 72 41 00 41 00 33 30 00 75 |....userA.A.30.u| +00003c60 73 65 72 42 00 42 00 75 73 65 72 43 00 43 00 75 |serB.B.userC.C.u| +00003c70 73 65 72 44 00 44 00 32 30 00 75 73 65 72 45 00 |serD.D.20.userE.| +00003c80 45 00 75 73 65 72 46 00 46 00 75 73 65 72 47 00 |E.userF.F.userG.| +00003c90 47 00 31 30 00 75 73 65 72 48 00 48 00 34 00 75 |G.10.userH.H.4.u| +00003ca0 73 65 72 49 00 49 00 75 73 65 72 4a 00 4a 00 75 |serI.I.userJ.J.u| +00003cb0 73 65 72 4b 00 4b 00 38 00 75 73 65 72 4c 00 4c |serK.K.8.userL.L| +00003cc0 00 35 00 75 73 65 72 4d 00 4d 00 66 00 75 73 65 |.5.userM.M.f.use| +00003cd0 72 4e 00 4e 00 74 00 75 73 65 72 50 00 50 00 33 |rN.N.t.userP.P.3| +00003ce0 00 32 00 75 73 65 72 51 00 51 00 75 73 65 72 52 |.2.userQ.Q.userR| +00003cf0 00 52 00 31 00 75 73 65 72 53 00 53 00 31 33 00 |.R.1.userS.S.13.| +00003d00 75 73 65 72 54 00 54 00 36 00 77 00 75 73 65 72 |userT.T.6.w.user| +00003d10 55 00 55 00 57 00 75 73 65 72 56 00 56 00 6b 00 |U.U.W.userV.V.k.| +00003d20 0a 54 65 73 74 73 20 2d 20 72 75 6e 20 77 69 74 |.Tests - run wit| +00003d30 68 20 27 40 78 27 2c 20 77 68 65 72 65 20 27 78 |h '@x', where 'x| +00003d40 27 20 69 73 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 |' is one or more| +00003d50 20 6f 66 3a 0a 20 00 00 0a 4f 74 68 65 72 20 63 | of:. ...Other c| +00003d60 6f 6d 6d 61 6e 64 73 3a 20 40 2a 20 28 61 6c 6c |ommands: @* (all| +00003d70 29 2c 20 40 68 20 28 68 65 6c 70 29 2c 20 40 78 |), @h (help), @x| +00003d80 20 28 65 78 69 74 29 0a 00 73 68 65 6c 6c 3a 20 | (exit)..shell: | +00003d90 75 6e 6b 6e 6f 77 6e 20 63 6d 64 20 27 25 63 27 |unknown cmd '%c'| +00003da0 0a 00 53 68 65 6c 6c 20 69 73 20 72 65 61 64 79 |..Shell is ready| +00003db0 0a 00 0a 3e 20 00 00 00 2b 2b 2b 20 53 68 65 6c |...> ...+++ Shel| +00003dc0 6c 20 73 70 61 77 6e 20 25 63 20 66 61 69 6c 65 |l spawn %c faile| +00003dd0 64 2c 20 63 6f 64 65 20 25 64 0a 00 73 68 65 6c |d, code %d..shel| +00003de0 6c 3a 20 77 61 69 74 70 69 64 28 29 20 72 65 74 |l: waitpid() ret| +00003df0 75 72 6e 65 64 20 25 64 0a 00 73 68 65 6c 6c 3a |urned %d..shell:| +00003e00 20 50 49 44 20 25 64 20 65 78 69 74 20 73 74 61 | PID %d exit sta| +00003e10 74 75 73 20 25 64 0a 00 21 21 21 20 73 68 65 6c |tus %d..!!! shel| +00003e20 6c 20 65 78 69 74 65 64 20 6c 6f 6f 70 3f 3f 3f |l exited loop???| +00003e30 0a 00 43 68 69 6c 64 20 25 64 20 65 78 65 63 28 |..Child %d exec(| +00003e40 29 20 23 25 75 20 66 61 69 6c 65 64 0a 00 00 00 |) #%u failed....| +00003e50 60 16 00 00 9e 16 00 00 ea 17 00 00 ea 17 00 00 |`...............| +00003e60 ea 17 00 00 ea 17 00 00 ea 17 00 00 ea 17 00 00 |................| +* +00003e80 58 17 00 00 ea 17 00 00 ea 17 00 00 ea 17 00 00 |X...............| +00003e90 e2 16 00 00 ea 17 00 00 99 17 00 00 ea 17 00 00 |................| +00003ea0 ea 17 00 00 14 17 00 00 00 00 00 00 00 00 00 00 |................| +00003eb0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +000040e0 00 00 00 00 00 00 00 00 03 00 00 00 01 41 00 00 |.............A..| +000040f0 6c 1b 00 00 72 1b 00 00 74 1b 00 00 00 00 00 00 |l...r...t.......| +00004100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00004110 00 00 00 00 00 00 00 00 03 00 00 00 01 42 00 00 |.............B..| +00004120 77 1b 00 00 7d 1b 00 00 74 1b 00 00 00 00 00 00 |w...}...t.......| +00004130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00004140 00 00 00 00 00 00 00 00 03 00 00 00 01 43 00 00 |.............C..| +00004150 7f 1b 00 00 85 1b 00 00 74 1b 00 00 00 00 00 00 |........t.......| +00004160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00004170 00 00 00 00 00 00 00 00 04 00 00 00 01 44 00 00 |.............D..| +00004180 87 1b 00 00 8d 1b 00 00 8f 1b 00 00 00 00 00 00 |................| +00004190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +000041a0 00 00 00 00 00 00 00 00 04 00 00 00 01 45 00 00 |.............E..| +000041b0 92 1b 00 00 98 1b 00 00 8f 1b 00 00 00 00 00 00 |................| +000041c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +000041d0 00 00 00 00 00 00 00 00 05 00 00 00 01 46 00 00 |.............F..| +000041e0 9a 1b 00 00 a0 1b 00 00 8f 1b 00 00 00 00 00 00 |................| +000041f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00004200 00 00 00 00 00 00 00 00 05 00 00 00 01 47 00 00 |.............G..| +00004210 a2 1b 00 00 a8 1b 00 00 aa 1b 00 00 00 00 00 00 |................| +00004220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00004230 00 00 00 00 00 00 00 00 06 00 00 00 01 48 00 00 |.............H..| +00004240 ad 1b 00 00 b3 1b 00 00 b5 1b 00 00 00 00 00 00 |................| +00004250 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00004260 00 00 00 00 00 00 00 00 07 00 00 00 01 49 00 00 |.............I..| +00004270 b7 1b 00 00 bd 1b 00 00 00 00 00 00 00 00 00 00 |................| +00004280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00004290 00 00 00 00 00 00 00 00 08 00 00 00 01 4a 00 00 |.............J..| +000042a0 bf 1b 00 00 c5 1b 00 00 00 00 00 00 00 00 00 00 |................| +000042b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +000042c0 00 00 00 00 00 00 00 00 09 00 00 00 01 4b 00 00 |.............K..| +000042d0 c7 1b 00 00 cd 1b 00 00 cf 1b 00 00 00 00 00 00 |................| +000042e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +000042f0 00 00 00 00 00 00 00 00 09 00 00 00 01 4c 00 00 |.............L..| +00004300 d1 1b 00 00 d7 1b 00 00 d9 1b 00 00 00 00 00 00 |................| +00004310 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00004320 00 00 00 00 00 00 00 00 0a 00 00 00 01 4d 00 00 |.............M..| +00004330 db 1b 00 00 e1 1b 00 00 d9 1b 00 00 e3 1b 00 00 |................| +00004340 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00004350 00 00 00 00 00 00 00 00 0a 00 00 00 01 4e 00 00 |.............N..| +00004360 e5 1b 00 00 eb 1b 00 00 d9 1b 00 00 ed 1b 00 00 |................| +00004370 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00004380 00 00 00 00 00 00 00 00 0b 00 00 00 01 50 00 00 |.............P..| +00004390 ef 1b 00 00 f5 1b 00 00 f7 1b 00 00 f9 1b 00 00 |................| +000043a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +000043b0 00 00 00 00 00 00 00 00 0c 00 00 00 01 51 00 00 |.............Q..| +000043c0 fb 1b 00 00 01 1c 00 00 00 00 00 00 00 00 00 00 |................| +000043d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +000043e0 00 00 00 00 00 00 00 00 0d 00 00 00 01 52 00 00 |.............R..| +000043f0 03 1c 00 00 09 1c 00 00 8f 1b 00 00 0b 1c 00 00 |................| +00004400 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00004410 00 00 00 00 00 00 00 00 0e 00 00 00 01 53 00 00 |.............S..| +00004420 0d 1c 00 00 13 1c 00 00 15 1c 00 00 00 00 00 00 |................| +00004430 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00004440 00 00 00 00 00 00 00 00 0f 00 00 00 01 54 00 00 |.............T..| +00004450 18 1c 00 00 1e 1c 00 00 20 1c 00 00 22 1c 00 00 |........ ..."...| +00004460 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00004470 00 00 00 00 00 00 00 00 0f 00 00 00 01 55 00 00 |.............U..| +00004480 24 1c 00 00 2a 1c 00 00 20 1c 00 00 2c 1c 00 00 |$...*... ...,...| +00004490 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +000044a0 00 00 00 00 00 00 00 00 0f 00 00 00 01 56 00 00 |.............V..| +000044b0 2e 1c 00 00 34 1c 00 00 20 1c 00 00 36 1c 00 00 |....4... ...6...| +000044c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +000044d0 00 00 00 00 00 00 00 00 62 60 01 00 00 00 00 00 |........b`......| +000044e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00004510 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 |................| +00004520 00 00 00 00 03 00 01 00 00 00 00 00 6c 1b 00 00 |............l...| +00004530 00 00 00 00 03 00 02 00 00 00 00 00 00 20 00 00 |............. ..| +00004540 00 00 00 00 03 00 03 00 00 00 00 00 00 30 00 00 |.............0..| +00004550 00 00 00 00 03 00 04 00 01 00 00 00 00 00 00 00 |................| +00004560 00 00 00 00 04 00 f1 ff 09 00 00 00 00 30 00 00 |.............0..| +00004570 01 00 00 00 01 00 04 00 16 00 00 00 04 30 00 00 |.............0..| +00004580 04 00 00 00 01 00 04 00 1f 00 00 00 00 20 00 00 |............. ..| +00004590 20 04 00 00 01 00 03 00 2b 00 00 00 00 10 00 00 | .......+.......| +000045a0 61 00 00 00 02 00 01 00 31 00 00 00 61 10 00 00 |a.......1...a...| +000045b0 10 01 00 00 02 00 01 00 35 00 00 00 71 11 00 00 |........5...q...| +000045c0 4a 00 00 00 02 00 01 00 3a 00 00 00 00 00 00 00 |J.......:.......| +000045d0 00 00 00 00 04 00 f1 ff 42 00 00 00 00 00 00 00 |........B.......| +000045e0 00 00 00 00 04 00 f1 ff 4b 00 00 00 00 00 00 00 |........K.......| +000045f0 00 00 00 00 04 00 f1 ff 54 00 00 00 00 00 00 00 |........T.......| +00004600 00 00 00 00 04 00 f1 ff 5d 00 00 00 00 00 00 00 |........].......| +00004610 00 00 00 00 04 00 f1 ff 67 00 00 00 00 00 00 00 |........g.......| +00004620 00 00 00 00 04 00 f1 ff 70 00 00 00 00 00 00 00 |........p.......| +00004630 00 00 00 00 04 00 f1 ff 79 00 00 00 00 00 00 00 |........y.......| +00004640 00 00 00 00 04 00 f1 ff 82 00 00 00 00 00 00 00 |................| +00004650 00 00 00 00 04 00 f1 ff 8c 00 00 00 00 00 00 00 |................| +00004660 00 00 00 00 04 00 f1 ff 95 00 00 00 00 00 00 00 |................| +00004670 00 00 00 00 04 00 f1 ff 9b 00 00 00 a8 14 00 00 |................| +00004680 21 00 00 00 12 00 01 00 a4 00 00 00 19 15 00 00 |!...............| +00004690 00 00 00 00 10 00 01 00 ac 00 00 00 8d 14 00 00 |................| +000046a0 1b 00 00 00 12 00 01 00 b3 00 00 00 12 1a 00 00 |................| +000046b0 32 00 00 00 12 00 01 00 ba 00 00 00 41 15 00 00 |2...........A...| +000046c0 00 00 00 00 10 00 01 00 c1 00 00 00 71 15 00 00 |............q...| +000046d0 00 00 00 00 10 00 01 00 c7 00 00 00 f6 14 00 00 |................| +000046e0 1b 00 00 00 12 00 01 00 ce 00 00 00 47 1b 00 00 |............G...| +000046f0 22 00 00 00 12 00 01 00 d2 00 00 00 ca 13 00 00 |"...............| +00004700 75 00 00 00 12 00 01 00 d8 00 00 00 97 15 00 00 |u...............| +00004710 75 02 00 00 12 00 01 00 df 00 00 00 fe 18 00 00 |u...............| +00004720 8a 00 00 00 12 00 01 00 e6 00 00 00 44 1a 00 00 |............D...| +00004730 66 00 00 00 12 00 01 00 ad 00 00 00 39 15 00 00 |f...........9...| +00004740 00 00 00 00 10 00 01 00 ee 00 00 00 69 15 00 00 |............i...| +00004750 00 00 00 00 10 00 01 00 f3 00 00 00 60 14 00 00 |............`...| +00004760 2d 00 00 00 12 00 01 00 fb 00 00 00 29 15 00 00 |-...........)...| +00004770 00 00 00 00 10 00 01 00 00 01 00 00 b2 13 00 00 |................| +00004780 18 00 00 00 12 00 01 00 05 01 00 00 c9 14 00 00 |................| +00004790 2d 00 00 00 12 00 01 00 0d 01 00 00 87 15 00 00 |-...............| +000047a0 00 00 00 00 10 00 01 00 14 01 00 00 31 15 00 00 |............1...| +000047b0 00 00 00 00 10 00 01 00 19 01 00 00 59 15 00 00 |............Y...| +000047c0 00 00 00 00 10 00 01 00 21 01 00 00 75 18 00 00 |........!...u...| +000047d0 89 00 00 00 12 00 01 00 29 01 00 00 21 15 00 00 |........)...!...| +000047e0 00 00 00 00 10 00 01 00 2e 01 00 00 bb 11 00 00 |................| +000047f0 f7 01 00 00 12 00 01 00 33 01 00 00 49 15 00 00 |........3...I...| +00004800 00 00 00 00 10 00 01 00 3b 01 00 00 aa 1a 00 00 |........;.......| +00004810 9d 00 00 00 12 00 01 00 42 01 00 00 61 15 00 00 |........B...a...| +00004820 00 00 00 00 10 00 01 00 4a 01 00 00 88 19 00 00 |........J.......| +00004830 8a 00 00 00 12 00 01 00 51 01 00 00 3f 14 00 00 |........Q...?...| +00004840 21 00 00 00 12 00 01 00 5a 01 00 00 51 15 00 00 |!.......Z...Q...| +00004850 00 00 00 00 10 00 01 00 62 01 00 00 2e 18 00 00 |........b.......| +00004860 47 00 00 00 12 00 01 00 7b 01 00 00 11 15 00 00 |G.......{.......| +00004870 00 00 00 00 10 00 01 00 69 01 00 00 0c 18 00 00 |........i.......| +00004880 22 00 00 00 12 00 01 00 70 01 00 00 79 15 00 00 |".......p...y...| +00004890 00 00 00 00 10 00 01 00 76 01 00 00 81 15 00 00 |........v.......| +000048a0 00 00 00 00 10 00 01 00 00 73 68 65 6c 6c 2e 63 |.........shell.c| +000048b0 00 74 69 6d 65 5f 74 6f 5f 73 74 6f 70 00 63 68 |.time_to_stop.ch| +000048c0 69 6c 64 72 65 6e 00 73 70 61 77 6e 5f 74 61 62 |ildren.spawn_tab| +000048d0 6c 65 00 75 73 61 67 65 00 72 75 6e 00 65 64 69 |le.usage.run.edi| +000048e0 74 00 75 6c 69 62 63 2e 63 00 73 70 72 69 6e 74 |t.ulibc.c.sprint| +000048f0 2e 63 00 73 74 72 6c 65 6e 2e 63 00 63 76 74 64 |.c.strlen.c.cvtd| +00004900 65 63 2e 63 00 63 76 74 64 65 63 30 2e 63 00 63 |ec.c.cvtdec0.c.c| +00004910 76 74 68 65 78 2e 63 00 63 76 74 6f 63 74 2e 63 |vthex.c.cvtoct.c| +00004920 00 63 76 74 75 6e 73 2e 63 00 63 76 74 75 6e 73 |.cvtuns.c.cvtuns| +00004930 30 2e 63 00 70 61 64 73 74 72 2e 63 00 70 61 64 |0.c.padstr.c.pad| +00004940 2e 63 00 73 77 72 69 74 65 63 68 00 77 61 69 74 |.c.swritech.wait| +00004950 70 69 64 00 63 77 72 69 74 65 00 63 76 74 75 6e |pid.cwrite.cvtun| +00004960 73 00 67 65 74 70 69 64 00 73 6c 65 65 70 00 73 |s.getpid.sleep.s| +00004970 77 72 69 74 65 00 70 61 64 00 73 70 61 77 6e 00 |write.pad.spawn.| +00004980 73 70 72 69 6e 74 00 63 76 74 68 65 78 00 63 76 |sprint.cvthex.cv| +00004990 74 75 6e 73 30 00 6b 69 6c 6c 00 63 77 72 69 74 |tuns0.kill.cwrit| +000049a0 65 73 00 65 78 65 63 00 77 61 69 74 00 73 77 72 |es.exec.wait.swr| +000049b0 69 74 65 73 00 5f 73 74 61 72 74 00 72 65 61 64 |ites._start.read| +000049c0 00 67 65 74 70 72 69 6f 00 63 76 74 64 65 63 30 |.getprio.cvtdec0| +000049d0 00 66 6f 72 6b 00 6d 61 69 6e 00 67 65 74 70 70 |.fork.main.getpp| +000049e0 69 64 00 70 61 64 73 74 72 00 73 65 74 70 72 69 |id.padstr.setpri| +000049f0 6f 00 63 76 74 6f 63 74 00 63 77 72 69 74 65 63 |o.cvtoct.cwritec| +00004a00 68 00 67 65 74 74 69 6d 65 00 63 76 74 64 65 63 |h.gettime.cvtdec| +00004a10 00 73 74 72 6c 65 6e 00 62 6f 67 75 73 00 66 61 |.strlen.bogus.fa| +00004a20 6b 65 5f 65 78 69 74 00 00 2e 73 79 6d 74 61 62 |ke_exit...symtab| +00004a30 00 2e 73 74 72 74 61 62 00 2e 73 68 73 74 72 74 |..strtab..shstrt| +00004a40 61 62 00 2e 74 65 78 74 00 2e 72 6f 64 61 74 61 |ab..text..rodata| +00004a50 00 2e 64 61 74 61 00 2e 62 73 73 00 00 00 00 00 |..data..bss.....| +00004a60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00004a80 00 00 00 00 1b 00 00 00 01 00 00 00 06 00 00 00 |................| +00004a90 00 10 00 00 80 00 00 00 69 0b 00 00 00 00 00 00 |........i.......| +00004aa0 00 00 00 00 01 00 00 00 00 00 00 00 21 00 00 00 |............!...| +00004ab0 01 00 00 00 02 00 00 00 6c 1b 00 00 ec 0b 00 00 |........l.......| +00004ac0 54 02 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |T...............| +00004ad0 00 00 00 00 29 00 00 00 01 00 00 00 03 00 00 00 |....)...........| +00004ae0 00 20 00 00 80 10 00 00 20 04 00 00 00 00 00 00 |. ...... .......| +00004af0 00 00 00 00 20 00 00 00 00 00 00 00 2f 00 00 00 |.... ......./...| +00004b00 08 00 00 00 03 00 00 00 00 30 00 00 a0 14 00 00 |.........0......| +00004b10 08 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |................| +00004b20 00 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 |................| +00004b30 00 00 00 00 a0 14 00 00 a0 03 00 00 06 00 00 00 |................| +00004b40 17 00 00 00 04 00 00 00 10 00 00 00 09 00 00 00 |................| +00004b50 03 00 00 00 00 00 00 00 00 00 00 00 40 18 00 00 |............@...| +00004b60 80 01 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +00004b70 00 00 00 00 11 00 00 00 03 00 00 00 00 00 00 00 |................| +00004b80 00 00 00 00 c0 19 00 00 34 00 00 00 00 00 00 00 |........4.......| +00004b90 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +00004ba0 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| +00004bb0 02 00 03 00 01 00 00 00 0c 14 00 00 34 00 00 00 |............4...| +00004bc0 6c 15 00 00 00 00 00 00 34 00 20 00 02 00 28 00 |l.......4. ...(.| +00004bd0 08 00 07 00 01 00 00 00 74 00 00 00 00 10 00 00 |........t.......| +00004be0 00 10 00 00 00 10 00 00 00 10 00 00 07 00 00 00 |................| +00004bf0 04 00 00 00 51 e5 74 64 00 00 00 00 00 00 00 00 |....Q.td........| +00004c00 00 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 |................| +00004c10 10 00 00 00 8d 4c 24 04 83 e4 f0 ff 71 fc 55 89 |.....L$.....q.U.| +00004c20 e5 53 51 81 ec a0 00 00 00 89 cb c7 45 f4 1e 00 |.SQ.........E...| +00004c30 00 00 c6 45 f3 31 8b 03 83 f8 02 74 1e 83 f8 03 |...E.1.....t....| +00004c40 75 2c 8b 43 04 83 c0 08 8b 00 83 ec 08 6a 0a 50 |u,.C.........j.P| +00004c50 e8 50 06 00 00 83 c4 10 89 45 f4 8b 43 04 83 c0 |.P.......E..C...| +00004c60 04 8b 00 0f b6 00 88 45 f3 e9 a7 00 00 00 8b 43 |.......E.......C| +00004c70 04 8b 00 ff 33 50 68 60 1a 00 00 8d 85 60 ff ff |....3Ph`.....`..| +00004c80 ff 50 e8 a9 03 00 00 83 c4 10 83 ec 0c 8d 85 60 |.P.............`| +00004c90 ff ff ff 50 e8 60 02 00 00 83 c4 10 c7 45 ec 00 |...P.`.......E..| +00004ca0 00 00 00 eb 59 8b 03 8d 14 85 00 00 00 00 8b 43 |....Y..........C| +00004cb0 04 01 d0 8b 00 85 c0 74 12 8b 03 8d 14 85 00 00 |.......t........| +00004cc0 00 00 8b 43 04 01 d0 8b 00 eb 05 b8 74 1a 00 00 |...C........t...| +00004cd0 83 ec 04 50 68 7b 1a 00 00 8d 85 60 ff ff ff 50 |...Ph{.....`...P| +00004ce0 e8 4b 03 00 00 83 c4 10 83 ec 0c 8d 85 60 ff ff |.K...........`..| +00004cf0 ff 50 e8 02 02 00 00 83 c4 10 83 45 ec 01 8b 45 |.P.........E...E| +00004d00 ec 3b 03 7e a0 83 ec 0c 68 7f 1a 00 00 e8 e7 01 |.;.~....h.......| +00004d10 00 00 83 c4 10 0f be 45 f3 83 ec 0c 50 e8 1f 02 |.......E....P...| +00004d20 00 00 83 c4 10 89 45 e0 83 7d e0 01 74 2e 0f be |......E..}..t...| +00004d30 45 f3 ff 75 e0 50 68 81 1a 00 00 8d 85 60 ff ff |E..u.Ph......`..| +00004d40 ff 50 e8 e9 02 00 00 83 c4 10 83 ec 0c 8d 85 60 |.P.............`| +00004d50 ff ff ff 50 e8 a0 01 00 00 83 c4 10 c7 45 e8 00 |...P.........E..| +00004d60 00 00 00 eb 61 c7 45 e4 00 00 00 00 eb 04 83 45 |....a.E........E| +00004d70 e4 01 81 7d e4 9f 25 26 00 7e f3 0f be 45 f3 83 |...}..%&.~...E..| +00004d80 ec 0c 50 e8 b9 01 00 00 83 c4 10 89 45 e0 83 7d |..P.........E..}| +00004d90 e0 01 74 2e 0f be 45 f3 ff 75 e0 50 68 9e 1a 00 |..t...E..u.Ph...| +00004da0 00 8d 85 60 ff ff ff 50 e8 83 02 00 00 83 c4 10 |...`...P........| +00004db0 83 ec 0c 8d 85 60 ff ff ff 50 e8 3a 01 00 00 83 |.....`...P.:....| +00004dc0 c4 10 83 45 e8 01 8b 45 e8 3b 45 f4 7c 97 83 ec |...E...E.;E.|...| +00004dd0 0c 6a 00 e8 d2 01 00 00 83 c4 10 c7 85 5c ff ff |.j...........\..| +00004de0 ff 2a 31 2a 00 0f b6 45 f3 88 85 5d ff ff ff 83 |.*1*...E...]....| +00004df0 ec 04 6a 03 8d 85 5c ff ff ff 50 6a 01 e8 d0 01 |..j...\...Pj....| +00004e00 00 00 83 c4 10 89 45 e0 83 7d e0 03 74 2e 0f be |......E..}..t...| +00004e10 45 f3 ff 75 e0 50 68 bc 1a 00 00 8d 85 60 ff ff |E..u.Ph......`..| +00004e20 ff 50 e8 09 02 00 00 83 c4 10 83 ec 0c 8d 85 60 |.P.............`| +00004e30 ff ff ff 50 e8 c0 00 00 00 83 c4 10 b8 2a 00 00 |...P.........*..| +00004e40 00 8d 65 f8 59 5b 5d 8d 61 fc c3 55 89 e5 83 ec |..e.Y[].a..U....| +00004e50 08 83 ec 08 ff 75 08 6a 00 e8 54 01 00 00 83 c4 |.....u.j..T.....| +00004e60 10 c9 c3 55 89 e5 81 ec 18 01 00 00 e8 49 01 00 |...U.........I..| +00004e70 00 89 45 f4 83 7d f4 00 74 05 8b 45 f4 eb 57 e8 |..E..}..t..E..W.| +00004e80 56 01 00 00 89 45 f4 83 ec 08 ff 75 0c ff 75 08 |V....E.....u..u.| +00004e90 e8 2d 01 00 00 83 c4 10 ff 75 08 ff 75 f4 68 db |.-.......u..u.h.| +00004ea0 1a 00 00 8d 85 f4 fe ff ff 50 e8 81 01 00 00 83 |.........P......| +00004eb0 c4 10 83 ec 0c 8d 85 f4 fe ff ff 50 e8 38 00 00 |...........P.8..| +00004ec0 00 83 c4 10 83 ec 0c 6a ff e8 dc 00 00 00 83 c4 |.......j........| +00004ed0 10 b8 00 00 00 00 c9 c3 55 89 e5 83 ec 18 8b 45 |........U......E| +00004ee0 08 88 45 f4 83 ec 04 6a 01 8d 45 f4 50 6a 00 e8 |..E....j..E.Pj..| +00004ef0 de 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 83 |.........U......| +00004f00 ec 0c ff 75 08 e8 0d 04 00 00 83 c4 10 89 45 f4 |...u..........E.| +00004f10 8b 45 f4 83 ec 04 50 ff 75 08 6a 00 e8 b1 00 00 |.E....P.u.j.....| +00004f20 00 83 c4 10 c9 c3 55 89 e5 83 ec 08 83 ec 04 ff |......U.........| +00004f30 75 0c ff 75 08 6a 00 e8 96 00 00 00 83 c4 10 c9 |u..u.j..........| +00004f40 c3 55 89 e5 83 ec 18 8b 45 08 88 45 f4 83 ec 04 |.U......E..E....| +00004f50 6a 01 8d 45 f4 50 6a 01 e8 75 00 00 00 83 c4 10 |j..E.Pj..u......| +00004f60 c9 c3 55 89 e5 83 ec 18 83 ec 0c ff 75 08 e8 a4 |..U.........u...| +00004f70 03 00 00 83 c4 10 89 45 f4 8b 45 f4 83 ec 04 50 |.......E..E....P| +00004f80 ff 75 08 6a 01 e8 48 00 00 00 83 c4 10 c9 c3 55 |.u.j..H........U| +00004f90 89 e5 83 ec 08 83 ec 04 ff 75 0c ff 75 08 6a 01 |.........u..u.j.| +00004fa0 e8 2d 00 00 00 83 c4 10 c9 c3 b8 00 00 00 00 cd |.-..............| +00004fb0 80 c3 b8 01 00 00 00 cd 80 c3 b8 02 00 00 00 cd |................| +00004fc0 80 c3 b8 03 00 00 00 cd 80 c3 b8 04 00 00 00 cd |................| +00004fd0 80 c3 b8 05 00 00 00 cd 80 c3 b8 06 00 00 00 cd |................| +00004fe0 80 c3 b8 07 00 00 00 cd 80 c3 b8 08 00 00 00 cd |................| +00004ff0 80 c3 b8 09 00 00 00 cd 80 c3 b8 0a 00 00 00 cd |................| +00005000 80 c3 b8 0b 00 00 00 cd 80 c3 b8 0c 00 00 00 cd |................| +00005010 80 c3 b8 ad 0b 00 00 cd 80 c3 50 e8 8a ff ff ff |..........P.....| +00005020 e8 ef fb ff ff 83 ec 0c 50 e8 7c ff ff ff eb fe |........P.|.....| +00005030 55 89 e5 83 ec 38 8d 45 0c 83 c0 04 89 45 f4 e9 |U....8.E.....E..| +00005040 3f 02 00 00 80 7d f3 25 0f 85 26 02 00 00 c7 45 |?....}.%..&....E| +00005050 ec 00 00 00 00 c7 45 e4 20 00 00 00 c7 45 e8 00 |......E. ....E..| +00005060 00 00 00 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 |....E..P..U.....| +00005070 45 f3 80 7d f3 2d 75 16 c7 45 ec 01 00 00 00 8b |E..}.-u..E......| +00005080 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d |E..P..U.....E..}| +00005090 f3 30 75 40 c7 45 e4 30 00 00 00 8b 45 0c 8d 50 |.0u@.E.0....E..P| +000050a0 01 89 55 0c 0f b6 00 88 45 f3 eb 28 8b 55 e8 89 |..U.....E..(.U..| +000050b0 d0 c1 e0 02 01 d0 01 c0 89 45 e8 0f be 45 f3 83 |.........E...E..| +000050c0 e8 30 01 45 e8 8b 45 0c 8d 50 01 89 55 0c 0f b6 |.0.E..E..P..U...| +000050d0 00 88 45 f3 80 7d f3 2f 7e 06 80 7d f3 39 7e cc |..E..}./~..}.9~.| +000050e0 0f be 45 f3 83 e8 63 83 f8 15 0f 87 93 01 00 00 |..E...c.........| +000050f0 8b 04 85 f8 1a 00 00 ff e0 8b 45 f4 8d 50 04 89 |..........E..P..| +00005100 55 f4 8b 00 88 45 f3 0f b6 45 f3 88 45 d0 c6 45 |U....E...E..E..E| +00005110 d1 00 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 6a 01 |......u..u..u.j.| +00005120 8d 45 d0 50 ff 75 08 e8 89 04 00 00 83 c4 20 89 |.E.P.u........ .| +00005130 45 08 e9 4c 01 00 00 8b 45 f4 8d 50 04 89 55 f4 |E..L....E..P..U.| +00005140 8b 00 83 ec 08 50 8d 45 d0 50 e8 ea 01 00 00 83 |.....P.E.P......| +00005150 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 |...E.....u..u..u| +00005160 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 45 04 00 00 |..u..E.P.u..E...| +00005170 83 c4 20 89 45 08 e9 08 01 00 00 8b 45 f4 8d 50 |.. .E.......E..P| +00005180 04 89 55 f4 8b 00 89 45 dc 83 ec 08 ff 75 e4 ff |..U....E.....u..| +00005190 75 ec ff 75 e8 6a ff ff 75 dc ff 75 08 e8 13 04 |u..u.j..u..u....| +000051a0 00 00 83 c4 20 89 45 08 e9 d6 00 00 00 8b 45 f4 |.... .E.......E.| +000051b0 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 |.P..U......P.E.P| +000051c0 e8 44 02 00 00 83 c4 10 89 45 e0 83 ec 08 ff 75 |.D.......E.....u| +000051d0 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 |..u..u..u..E.P.u| +000051e0 08 e8 cf 03 00 00 83 c4 20 89 45 08 e9 92 00 00 |........ .E.....| +000051f0 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 |..E..P..U......P| +00005200 8d 45 d0 50 e8 8a 02 00 00 83 c4 10 89 45 e0 83 |.E.P.........E..| +00005210 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 |...u..u..u..u..E| +00005220 d0 50 ff 75 08 e8 8b 03 00 00 83 c4 20 89 45 08 |.P.u........ .E.| +00005230 eb 51 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 |.Q.E..P..U......| +00005240 50 8d 45 d0 50 e8 d3 02 00 00 83 c4 10 89 45 e0 |P.E.P.........E.| +00005250 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d |....u..u..u..u..| +00005260 45 d0 50 ff 75 08 e8 4a 03 00 00 83 c4 20 89 45 |E.P.u..J..... .E| +00005270 08 90 eb 0f 8b 45 08 8d 50 01 89 55 08 0f b6 55 |.....E..P..U...U| +00005280 f3 88 10 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 |....E..P..U.....| +00005290 45 f3 80 7d f3 00 0f 85 a8 fd ff ff 8b 45 08 c6 |E..}.........E..| +000052a0 00 00 90 c9 c3 55 89 e5 53 83 ec 14 8b 45 08 8b |.....U..S....E..| +000052b0 4d 0c bb 00 00 00 00 c6 45 eb 39 c7 45 f8 01 00 |M.......E.9.E...| +000052c0 00 00 0f b6 10 80 fa 2d 75 0a c7 45 f8 ff ff ff |.......-u..E....| +000052d0 ff 83 c0 01 83 f9 0a 74 2b 89 ca 83 c2 2f 88 55 |.......t+..../.U| +000052e0 eb eb 21 0f b6 10 80 fa 2f 7e 20 0f b6 10 38 55 |..!...../~ ...8U| +000052f0 eb 7c 18 0f af d9 0f b6 10 0f be d2 01 da 8d 5a |.|.............Z| +00005300 d0 83 c0 01 0f b6 10 84 d2 75 d8 89 d8 0f af 45 |.........u.....E| +00005310 f8 83 c4 14 5b 5d c3 55 89 e5 53 8b 55 08 bb 00 |....[].U..S.U...| +00005320 00 00 00 eb 03 83 c3 01 89 d0 8d 50 01 0f b6 00 |...........P....| +00005330 84 c0 75 f1 89 d8 5b 5d c3 55 89 e5 83 ec 18 8b |..u...[].U......| +00005340 45 08 89 45 f4 83 7d 0c 00 79 0f 8b 45 f4 8d 50 |E..E..}..y..E..P| +00005350 01 89 55 f4 c6 00 2d f7 5d 0c 83 ec 08 ff 75 0c |..U...-.].....u.| +00005360 ff 75 f4 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 |.u..........E..E| +00005370 f4 c6 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 |.....U..E.).....| +00005380 55 89 e5 83 ec 18 8b 4d 0c ba 67 66 66 66 89 c8 |U......M..gfff..| +00005390 f7 ea c1 fa 02 89 c8 c1 f8 1f 29 c2 89 d0 89 45 |..........)....E| +000053a0 f4 83 7d f4 00 79 0e c7 45 f4 cc cc cc 0c c7 45 |..}..y..E......E| +000053b0 0c 08 00 00 00 83 7d f4 00 74 14 83 ec 08 ff 75 |......}..t.....u| +000053c0 f4 ff 75 08 e8 b7 ff ff ff 83 c4 10 89 45 08 8b |..u..........E..| +000053d0 4d 0c ba 67 66 66 66 89 c8 f7 ea c1 fa 02 89 c8 |M..gfff.........| +000053e0 c1 f8 1f 29 c2 89 d0 c1 e0 02 01 d0 01 c0 29 c1 |...)..........).| +000053f0 89 ca 89 d0 8d 48 30 8b 45 08 8d 50 01 89 55 08 |.....H0.E..P..U.| +00005400 89 ca 88 10 8b 45 08 c9 c3 55 89 e5 83 ec 20 c7 |.....E...U.... .| +00005410 45 e3 30 31 32 33 c7 45 e7 34 35 36 37 c7 45 eb |E.0123.E.4567.E.| +00005420 38 39 41 42 c7 45 ef 43 44 45 46 c6 45 f3 00 c7 |89AB.E.CDEF.E...| +00005430 45 fc 00 00 00 00 c7 45 f8 00 00 00 00 eb 43 8b |E......E......C.| +00005440 45 0c 25 00 00 00 f0 89 45 f4 83 7d fc 00 75 0c |E.%.....E..}..u.| +00005450 83 7d f4 00 75 06 83 7d f8 07 75 1e 83 45 fc 01 |.}..u..}..u..E..| +00005460 c1 6d f4 1c 8b 45 08 8d 50 01 89 55 08 8d 4d e3 |.m...E..P..U..M.| +00005470 8b 55 f4 01 ca 0f b6 12 88 10 c1 65 0c 04 83 45 |.U.........e...E| +00005480 f8 01 83 7d f8 07 7e b7 8b 45 08 c6 00 00 8b 45 |...}..~..E.....E| +00005490 fc c9 c3 55 89 e5 83 ec 10 c7 45 f8 00 00 00 00 |...U......E.....| +000054a0 8b 45 08 89 45 f4 8b 45 0c 25 00 00 00 c0 89 45 |.E..E..E.%.....E| +000054b0 f0 c1 6d f0 1e c7 45 fc 00 00 00 00 eb 47 83 7d |..m...E......G.}| +000054c0 fc 0a 74 0c 83 7d f0 00 75 06 83 7d f8 00 74 1e |..t..}..u..}..t.| +000054d0 c7 45 f8 01 00 00 00 83 65 f0 07 8b 45 f0 8d 48 |.E......e...E..H| +000054e0 30 8b 45 f4 8d 50 01 89 55 f4 89 ca 88 10 c1 65 |0.E..P..U......e| +000054f0 0c 03 8b 45 0c 25 00 00 00 e0 89 45 f0 c1 6d f0 |...E.%.....E..m.| +00005500 1d 83 45 fc 01 83 7d fc 0a 7e b3 8b 45 f4 c6 00 |..E...}..~..E...| +00005510 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 |..U..E.).....U..| +00005520 83 ec 18 8b 45 08 89 45 f4 83 ec 08 ff 75 0c ff |....E..E.....u..| +00005530 75 f4 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 |u..........E..E.| +00005540 c6 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 |....U..E.).....U| +00005550 89 e5 83 ec 18 8b 45 0c ba cd cc cc cc f7 e2 89 |......E.........| +00005560 d0 c1 e8 03 89 45 f4 83 7d f4 00 74 15 8b 45 f4 |.....E..}..t..E.| +00005570 83 ec 08 50 ff 75 08 e8 04 fe ff ff 83 c4 10 89 |...P.u..........| +00005580 45 08 8b 4d 0c ba cd cc cc cc 89 c8 f7 e2 c1 ea |E..M............| +00005590 03 89 d0 c1 e0 02 01 d0 01 c0 29 c1 89 ca 89 d0 |..........).....| +000055a0 8d 48 30 8b 45 08 8d 50 01 89 55 08 89 ca 88 10 |.H0.E..P..U.....| +000055b0 8b 45 08 c9 c3 55 89 e5 83 ec 18 83 7d 10 00 79 |.E...U......}..y| +000055c0 11 83 ec 0c ff 75 0c e8 4b fd ff ff 83 c4 10 89 |.....u..K.......| +000055d0 45 10 8b 45 14 2b 45 10 89 45 f0 83 7d f0 00 7e |E..E.+E..E..}..~| +000055e0 1d 83 7d 18 00 75 17 83 ec 04 ff 75 1c ff 75 f0 |..}..u.....u..u.| +000055f0 ff 75 08 e8 5a 00 00 00 83 c4 10 89 45 08 c7 45 |.u..Z.......E..E| +00005600 f4 00 00 00 00 eb 1b 8b 55 f4 8b 45 0c 8d 0c 02 |........U..E....| +00005610 8b 45 08 8d 50 01 89 55 08 0f b6 11 88 10 83 45 |.E..P..U.......E| +00005620 f4 01 8b 45 f4 3b 45 10 7c dd 83 7d f0 00 7e 1d |...E.;E.|..}..~.| +00005630 83 7d 18 00 74 17 83 ec 04 ff 75 1c ff 75 f0 ff |.}..t.....u..u..| +00005640 75 08 e8 0b 00 00 00 83 c4 10 89 45 08 8b 45 08 |u..........E..E.| +00005650 c9 c3 55 89 e5 eb 12 8b 45 08 8d 50 01 89 55 08 |..U.....E..P..U.| +00005660 8b 55 10 88 10 83 6d 0c 01 83 7d 0c 00 7f e8 8b |.U....m...}.....| +00005670 45 08 5d c3 25 73 3a 20 61 72 67 63 20 25 64 2c |E.].%s: argc %d,| +00005680 20 61 72 67 73 3a 20 00 28 6e 75 6c 6c 29 00 20 | args: .(null). | +00005690 25 73 00 0a 00 3d 3d 20 25 63 2c 20 77 72 69 74 |%s...== %c, writ| +000056a0 65 20 23 31 20 72 65 74 75 72 6e 65 64 20 25 64 |e #1 returned %d| +000056b0 0a 00 3d 3d 20 25 63 2c 20 77 72 69 74 65 20 23 |..== %c, write #| +000056c0 32 20 72 65 74 75 72 6e 65 64 20 25 64 0a 00 00 |2 returned %d...| +000056d0 55 73 65 72 20 25 63 2c 20 77 72 69 74 65 20 23 |User %c, write #| +000056e0 33 20 72 65 74 75 72 6e 65 64 20 25 64 0a 00 43 |3 returned %d..C| +000056f0 68 69 6c 64 20 25 64 20 65 78 65 63 28 29 20 23 |hild %d exec() #| +00005700 25 75 20 66 61 69 6c 65 64 0a 00 00 e5 14 00 00 |%u failed.......| +00005710 23 15 00 00 6f 16 00 00 6f 16 00 00 6f 16 00 00 |#...o...o...o...| +00005720 6f 16 00 00 6f 16 00 00 6f 16 00 00 6f 16 00 00 |o...o...o...o...| +00005730 6f 16 00 00 6f 16 00 00 6f 16 00 00 dd 15 00 00 |o...o...o.......| +00005740 6f 16 00 00 6f 16 00 00 6f 16 00 00 67 15 00 00 |o...o...o...g...| +00005750 6f 16 00 00 1e 16 00 00 6f 16 00 00 6f 16 00 00 |o.......o...o...| +00005760 99 15 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00005770 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00005c20 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 |................| +00005c30 03 00 01 00 00 00 00 00 60 1a 00 00 00 00 00 00 |........`.......| +00005c40 03 00 02 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +00005c50 03 00 03 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +00005c60 03 00 04 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +00005c70 04 00 f1 ff 0b 00 00 00 00 00 00 00 00 00 00 00 |................| +00005c80 04 00 f1 ff 13 00 00 00 00 00 00 00 00 00 00 00 |................| +00005c90 04 00 f1 ff 1c 00 00 00 00 00 00 00 00 00 00 00 |................| +00005ca0 04 00 f1 ff 26 00 00 00 00 00 00 00 00 00 00 00 |....&...........| +00005cb0 04 00 f1 ff 2f 00 00 00 00 00 00 00 00 00 00 00 |..../...........| +00005cc0 04 00 f1 ff 38 00 00 00 00 00 00 00 00 00 00 00 |....8...........| +00005cd0 04 00 f1 ff 42 00 00 00 00 00 00 00 00 00 00 00 |....B...........| +00005ce0 04 00 f1 ff 4b 00 00 00 00 00 00 00 00 00 00 00 |....K...........| +00005cf0 04 00 f1 ff 54 00 00 00 00 00 00 00 00 00 00 00 |....T...........| +00005d00 04 00 f1 ff 5d 00 00 00 00 00 00 00 00 00 00 00 |....]...........| +00005d10 04 00 f1 ff 67 00 00 00 00 00 00 00 00 00 00 00 |....g...........| +00005d20 04 00 f1 ff 70 00 00 00 00 00 00 00 00 00 00 00 |....p...........| +00005d30 04 00 f1 ff 76 00 00 00 2d 13 00 00 21 00 00 00 |....v...-...!...| +00005d40 12 00 01 00 7f 00 00 00 9e 13 00 00 00 00 00 00 |................| +00005d50 10 00 01 00 87 00 00 00 12 13 00 00 1b 00 00 00 |................| +00005d60 12 00 01 00 8e 00 00 00 91 16 00 00 72 00 00 00 |............r...| +00005d70 12 00 01 00 96 00 00 00 09 19 00 00 32 00 00 00 |............2...| +00005d80 12 00 01 00 9d 00 00 00 c6 13 00 00 00 00 00 00 |................| +00005d90 10 00 01 00 a4 00 00 00 f6 13 00 00 00 00 00 00 |................| +00005da0 10 00 01 00 aa 00 00 00 7b 13 00 00 1b 00 00 00 |........{.......| +00005db0 12 00 01 00 b1 00 00 00 3e 1a 00 00 22 00 00 00 |........>..."...| +00005dc0 12 00 01 00 b5 00 00 00 4f 12 00 00 75 00 00 00 |........O...u...| +00005dd0 12 00 01 00 bb 00 00 00 1c 14 00 00 75 02 00 00 |............u...| +00005de0 12 00 01 00 c2 00 00 00 f5 17 00 00 8a 00 00 00 |................| +00005df0 12 00 01 00 c9 00 00 00 3b 19 00 00 66 00 00 00 |........;...f...| +00005e00 12 00 01 00 88 00 00 00 be 13 00 00 00 00 00 00 |................| +00005e10 10 00 01 00 d1 00 00 00 ee 13 00 00 00 00 00 00 |................| +00005e20 10 00 01 00 d6 00 00 00 e5 12 00 00 2d 00 00 00 |............-...| +00005e30 12 00 01 00 de 00 00 00 ae 13 00 00 00 00 00 00 |................| +00005e40 10 00 01 00 e3 00 00 00 37 12 00 00 18 00 00 00 |........7.......| +00005e50 12 00 01 00 e8 00 00 00 4e 13 00 00 2d 00 00 00 |........N...-...| +00005e60 12 00 01 00 f0 00 00 00 0c 14 00 00 00 00 00 00 |................| +00005e70 10 00 01 00 f7 00 00 00 b6 13 00 00 00 00 00 00 |................| +00005e80 10 00 01 00 fc 00 00 00 de 13 00 00 00 00 00 00 |................| +00005e90 10 00 01 00 04 01 00 00 6c 17 00 00 89 00 00 00 |........l.......| +00005ea0 12 00 01 00 0c 01 00 00 a6 13 00 00 00 00 00 00 |................| +00005eb0 10 00 01 00 11 01 00 00 00 10 00 00 37 02 00 00 |............7...| +00005ec0 12 00 01 00 16 01 00 00 ce 13 00 00 00 00 00 00 |................| +00005ed0 10 00 01 00 1e 01 00 00 a1 19 00 00 9d 00 00 00 |................| +00005ee0 12 00 01 00 25 01 00 00 e6 13 00 00 00 00 00 00 |....%...........| +00005ef0 10 00 01 00 2d 01 00 00 7f 18 00 00 8a 00 00 00 |....-...........| +00005f00 12 00 01 00 34 01 00 00 c4 12 00 00 21 00 00 00 |....4.......!...| +00005f10 12 00 01 00 3d 01 00 00 d6 13 00 00 00 00 00 00 |....=...........| +00005f20 10 00 01 00 45 01 00 00 25 17 00 00 47 00 00 00 |....E...%...G...| +00005f30 12 00 01 00 5e 01 00 00 96 13 00 00 00 00 00 00 |....^...........| +00005f40 10 00 01 00 4c 01 00 00 03 17 00 00 22 00 00 00 |....L......."...| +00005f50 12 00 01 00 53 01 00 00 fe 13 00 00 00 00 00 00 |....S...........| +00005f60 10 00 01 00 59 01 00 00 06 14 00 00 00 00 00 00 |....Y...........| +00005f70 10 00 01 00 00 70 72 6f 67 41 42 43 2e 63 00 75 |.....progABC.c.u| +00005f80 6c 69 62 63 2e 63 00 73 70 72 69 6e 74 2e 63 00 |libc.c.sprint.c.| +00005f90 73 74 72 32 69 6e 74 2e 63 00 73 74 72 6c 65 6e |str2int.c.strlen| +00005fa0 2e 63 00 63 76 74 64 65 63 2e 63 00 63 76 74 64 |.c.cvtdec.c.cvtd| +00005fb0 65 63 30 2e 63 00 63 76 74 68 65 78 2e 63 00 63 |ec0.c.cvthex.c.c| +00005fc0 76 74 6f 63 74 2e 63 00 63 76 74 75 6e 73 2e 63 |vtoct.c.cvtuns.c| +00005fd0 00 63 76 74 75 6e 73 30 2e 63 00 70 61 64 73 74 |.cvtuns0.c.padst| +00005fe0 72 2e 63 00 70 61 64 2e 63 00 73 77 72 69 74 65 |r.c.pad.c.swrite| +00005ff0 63 68 00 77 61 69 74 70 69 64 00 63 77 72 69 74 |ch.waitpid.cwrit| +00006000 65 00 73 74 72 32 69 6e 74 00 63 76 74 75 6e 73 |e.str2int.cvtuns| +00006010 00 67 65 74 70 69 64 00 73 6c 65 65 70 00 73 77 |.getpid.sleep.sw| +00006020 72 69 74 65 00 70 61 64 00 73 70 61 77 6e 00 73 |rite.pad.spawn.s| +00006030 70 72 69 6e 74 00 63 76 74 68 65 78 00 63 76 74 |print.cvthex.cvt| +00006040 75 6e 73 30 00 6b 69 6c 6c 00 63 77 72 69 74 65 |uns0.kill.cwrite| +00006050 73 00 65 78 65 63 00 77 61 69 74 00 73 77 72 69 |s.exec.wait.swri| +00006060 74 65 73 00 5f 73 74 61 72 74 00 72 65 61 64 00 |tes._start.read.| +00006070 67 65 74 70 72 69 6f 00 63 76 74 64 65 63 30 00 |getprio.cvtdec0.| +00006080 66 6f 72 6b 00 6d 61 69 6e 00 67 65 74 70 70 69 |fork.main.getppi| +00006090 64 00 70 61 64 73 74 72 00 73 65 74 70 72 69 6f |d.padstr.setprio| +000060a0 00 63 76 74 6f 63 74 00 63 77 72 69 74 65 63 68 |.cvtoct.cwritech| +000060b0 00 67 65 74 74 69 6d 65 00 63 76 74 64 65 63 00 |.gettime.cvtdec.| +000060c0 73 74 72 6c 65 6e 00 62 6f 67 75 73 00 66 61 6b |strlen.bogus.fak| +000060d0 65 5f 65 78 69 74 00 00 2e 73 79 6d 74 61 62 00 |e_exit...symtab.| +000060e0 2e 73 74 72 74 61 62 00 2e 73 68 73 74 72 74 61 |.strtab..shstrta| +000060f0 62 00 2e 74 65 78 74 00 2e 72 6f 64 61 74 61 00 |b..text..rodata.| +00006100 2e 64 61 74 61 00 2e 62 73 73 00 00 00 00 00 00 |.data..bss......| +00006110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00006130 00 00 00 00 1b 00 00 00 01 00 00 00 06 00 00 00 |................| +00006140 00 10 00 00 74 00 00 00 60 0a 00 00 00 00 00 00 |....t...`.......| +00006150 00 00 00 00 01 00 00 00 00 00 00 00 21 00 00 00 |............!...| +00006160 01 00 00 00 02 00 00 00 60 1a 00 00 d4 0a 00 00 |........`.......| +00006170 f0 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |................| +00006180 00 00 00 00 29 00 00 00 01 00 00 00 03 00 00 00 |....)...........| +00006190 00 20 00 00 74 10 00 00 00 00 00 00 00 00 00 00 |. ..t...........| +000061a0 00 00 00 00 01 00 00 00 00 00 00 00 2f 00 00 00 |............/...| +000061b0 08 00 00 00 03 00 00 00 00 20 00 00 74 10 00 00 |......... ..t...| +000061c0 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +000061d0 00 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 |................| +000061e0 00 00 00 00 74 10 00 00 60 03 00 00 06 00 00 00 |....t...`.......| +000061f0 12 00 00 00 04 00 00 00 10 00 00 00 09 00 00 00 |................| +00006200 03 00 00 00 00 00 00 00 00 00 00 00 d4 13 00 00 |................| +00006210 63 01 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |c...............| +00006220 00 00 00 00 11 00 00 00 03 00 00 00 00 00 00 00 |................| +00006230 00 00 00 00 37 15 00 00 34 00 00 00 00 00 00 00 |....7...4.......| +00006240 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +00006250 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| +00006260 02 00 03 00 01 00 00 00 9b 13 00 00 34 00 00 00 |............4...| +00006270 6c 15 00 00 00 00 00 00 34 00 20 00 02 00 28 00 |l.......4. ...(.| +00006280 08 00 07 00 01 00 00 00 74 00 00 00 00 10 00 00 |........t.......| +00006290 00 10 00 00 00 10 00 00 00 10 00 00 07 00 00 00 |................| +000062a0 04 00 00 00 51 e5 74 64 00 00 00 00 00 00 00 00 |....Q.td........| +000062b0 00 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 |................| +000062c0 10 00 00 00 8d 4c 24 04 83 e4 f0 ff 71 fc 55 89 |.....L$.....q.U.| +000062d0 e5 53 51 81 ec a0 00 00 00 89 cb c7 45 f4 1e 00 |.SQ.........E...| +000062e0 00 00 c6 45 f3 32 8b 03 83 f8 02 74 1e 83 f8 03 |...E.2.....t....| +000062f0 75 2c 8b 43 04 83 c0 08 8b 00 83 ec 08 6a 0a 50 |u,.C.........j.P| +00006300 e8 df 05 00 00 83 c4 10 89 45 f4 8b 43 04 83 c0 |.........E..C...| +00006310 04 8b 00 0f b6 00 88 45 f3 e9 a4 00 00 00 83 ec |.......E........| +00006320 04 ff 33 68 f0 19 00 00 8d 85 60 ff ff ff 50 e8 |..3h......`...P.| +00006330 3b 03 00 00 83 c4 10 83 ec 0c 8d 85 60 ff ff ff |;...........`...| +00006340 50 e8 f2 01 00 00 83 c4 10 c7 45 ec 00 00 00 00 |P.........E.....| +00006350 eb 59 8b 03 8d 14 85 00 00 00 00 8b 43 04 01 d0 |.Y..........C...| +00006360 8b 00 85 c0 74 12 8b 03 8d 14 85 00 00 00 00 8b |....t...........| +00006370 43 04 01 d0 8b 00 eb 05 b8 07 1a 00 00 83 ec 04 |C...............| +00006380 50 68 0e 1a 00 00 8d 85 60 ff ff ff 50 e8 dd 02 |Ph......`...P...| +00006390 00 00 83 c4 10 83 ec 0c 8d 85 60 ff ff ff 50 e8 |..........`...P.| +000063a0 94 01 00 00 83 c4 10 83 45 ec 01 8b 45 ec 3b 03 |........E...E.;.| +000063b0 7e a0 83 ec 0c 68 12 1a 00 00 e8 79 01 00 00 83 |~....h.....y....| +000063c0 c4 10 0f be 45 f3 83 ec 0c 50 e8 b1 01 00 00 83 |....E....P......| +000063d0 c4 10 89 45 e0 83 7d e0 01 74 2e 0f be 45 f3 ff |...E..}..t...E..| +000063e0 75 e0 50 68 14 1a 00 00 8d 85 60 ff ff ff 50 e8 |u.Ph......`...P.| +000063f0 7b 02 00 00 83 c4 10 83 ec 0c 8d 85 60 ff ff ff |{...........`...| +00006400 50 e8 32 01 00 00 83 c4 10 c7 45 e8 00 00 00 00 |P.2.......E.....| +00006410 eb 61 c7 45 e4 00 00 00 00 eb 04 83 45 e4 01 81 |.a.E........E...| +00006420 7d e4 9f 25 26 00 7e f3 0f be 45 f3 83 ec 0c 50 |}..%&.~...E....P| +00006430 e8 4b 01 00 00 83 c4 10 89 45 e0 83 7d e0 01 74 |.K.......E..}..t| +00006440 2e 0f be 45 f3 ff 75 e0 50 68 31 1a 00 00 8d 85 |...E..u.Ph1.....| +00006450 60 ff ff ff 50 e8 15 02 00 00 83 c4 10 83 ec 0c |`...P...........| +00006460 8d 85 60 ff ff ff 50 e8 cc 00 00 00 83 c4 10 83 |..`...P.........| +00006470 45 e8 01 8b 45 e8 3b 45 f4 7c 97 b8 00 00 00 00 |E...E.;E.|......| +00006480 8d 65 f8 59 5b 5d 8d 61 fc c3 55 89 e5 83 ec 08 |.e.Y[].a..U.....| +00006490 83 ec 08 ff 75 08 6a 00 e8 54 01 00 00 83 c4 10 |....u.j..T......| +000064a0 c9 c3 55 89 e5 81 ec 18 01 00 00 e8 49 01 00 00 |..U.........I...| +000064b0 89 45 f4 83 7d f4 00 74 05 8b 45 f4 eb 57 e8 56 |.E..}..t..E..W.V| +000064c0 01 00 00 89 45 f4 83 ec 08 ff 75 0c ff 75 08 e8 |....E.....u..u..| +000064d0 2d 01 00 00 83 c4 10 ff 75 08 ff 75 f4 68 4e 1a |-.......u..u.hN.| +000064e0 00 00 8d 85 f4 fe ff ff 50 e8 81 01 00 00 83 c4 |........P.......| +000064f0 10 83 ec 0c 8d 85 f4 fe ff ff 50 e8 38 00 00 00 |..........P.8...| +00006500 83 c4 10 83 ec 0c 6a ff e8 dc 00 00 00 83 c4 10 |......j.........| +00006510 b8 00 00 00 00 c9 c3 55 89 e5 83 ec 18 8b 45 08 |.......U......E.| +00006520 88 45 f4 83 ec 04 6a 01 8d 45 f4 50 6a 00 e8 de |.E....j..E.Pj...| +00006530 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 83 ec |........U.......| +00006540 0c ff 75 08 e8 0d 04 00 00 83 c4 10 89 45 f4 8b |..u..........E..| +00006550 45 f4 83 ec 04 50 ff 75 08 6a 00 e8 b1 00 00 00 |E....P.u.j......| +00006560 83 c4 10 c9 c3 55 89 e5 83 ec 08 83 ec 04 ff 75 |.....U.........u| +00006570 0c ff 75 08 6a 00 e8 96 00 00 00 83 c4 10 c9 c3 |..u.j...........| +00006580 55 89 e5 83 ec 18 8b 45 08 88 45 f4 83 ec 04 6a |U......E..E....j| +00006590 01 8d 45 f4 50 6a 01 e8 75 00 00 00 83 c4 10 c9 |..E.Pj..u.......| +000065a0 c3 55 89 e5 83 ec 18 83 ec 0c ff 75 08 e8 a4 03 |.U.........u....| +000065b0 00 00 83 c4 10 89 45 f4 8b 45 f4 83 ec 04 50 ff |......E..E....P.| +000065c0 75 08 6a 01 e8 48 00 00 00 83 c4 10 c9 c3 55 89 |u.j..H........U.| +000065d0 e5 83 ec 08 83 ec 04 ff 75 0c ff 75 08 6a 01 e8 |........u..u.j..| +000065e0 2d 00 00 00 83 c4 10 c9 c3 b8 00 00 00 00 cd 80 |-...............| +000065f0 c3 b8 01 00 00 00 cd 80 c3 b8 02 00 00 00 cd 80 |................| +00006600 c3 b8 03 00 00 00 cd 80 c3 b8 04 00 00 00 cd 80 |................| +00006610 c3 b8 05 00 00 00 cd 80 c3 b8 06 00 00 00 cd 80 |................| +00006620 c3 b8 07 00 00 00 cd 80 c3 b8 08 00 00 00 cd 80 |................| +00006630 c3 b8 09 00 00 00 cd 80 c3 b8 0a 00 00 00 cd 80 |................| +00006640 c3 b8 0b 00 00 00 cd 80 c3 b8 0c 00 00 00 cd 80 |................| +00006650 c3 b8 ad 0b 00 00 cd 80 c3 50 e8 8a ff ff ff e8 |.........P......| +00006660 60 fc ff ff 83 ec 0c 50 e8 7c ff ff ff eb fe 55 |`......P.|.....U| +00006670 89 e5 83 ec 38 8d 45 0c 83 c0 04 89 45 f4 e9 3f |....8.E.....E..?| +00006680 02 00 00 80 7d f3 25 0f 85 26 02 00 00 c7 45 ec |....}.%..&....E.| +00006690 00 00 00 00 c7 45 e4 20 00 00 00 c7 45 e8 00 00 |.....E. ....E...| +000066a0 00 00 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 |...E..P..U.....E| +000066b0 f3 80 7d f3 2d 75 16 c7 45 ec 01 00 00 00 8b 45 |..}.-u..E......E| +000066c0 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 |..P..U.....E..}.| +000066d0 30 75 40 c7 45 e4 30 00 00 00 8b 45 0c 8d 50 01 |0u@.E.0....E..P.| +000066e0 89 55 0c 0f b6 00 88 45 f3 eb 28 8b 55 e8 89 d0 |.U.....E..(.U...| +000066f0 c1 e0 02 01 d0 01 c0 89 45 e8 0f be 45 f3 83 e8 |........E...E...| +00006700 30 01 45 e8 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 |0.E..E..P..U....| +00006710 88 45 f3 80 7d f3 2f 7e 06 80 7d f3 39 7e cc 0f |.E..}./~..}.9~..| +00006720 be 45 f3 83 e8 63 83 f8 15 0f 87 93 01 00 00 8b |.E...c..........| +00006730 04 85 6c 1a 00 00 ff e0 8b 45 f4 8d 50 04 89 55 |..l......E..P..U| +00006740 f4 8b 00 88 45 f3 0f b6 45 f3 88 45 d0 c6 45 d1 |....E...E..E..E.| +00006750 00 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 6a 01 8d |.....u..u..u.j..| +00006760 45 d0 50 ff 75 08 e8 89 04 00 00 83 c4 20 89 45 |E.P.u........ .E| +00006770 08 e9 4c 01 00 00 8b 45 f4 8d 50 04 89 55 f4 8b |..L....E..P..U..| +00006780 00 83 ec 08 50 8d 45 d0 50 e8 ea 01 00 00 83 c4 |....P.E.P.......| +00006790 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 |..E.....u..u..u.| +000067a0 ff 75 e0 8d 45 d0 50 ff 75 08 e8 45 04 00 00 83 |.u..E.P.u..E....| +000067b0 c4 20 89 45 08 e9 08 01 00 00 8b 45 f4 8d 50 04 |. .E.......E..P.| +000067c0 89 55 f4 8b 00 89 45 dc 83 ec 08 ff 75 e4 ff 75 |.U....E.....u..u| +000067d0 ec ff 75 e8 6a ff ff 75 dc ff 75 08 e8 13 04 00 |..u.j..u..u.....| +000067e0 00 83 c4 20 89 45 08 e9 d6 00 00 00 8b 45 f4 8d |... .E.......E..| +000067f0 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 |P..U......P.E.P.| +00006800 44 02 00 00 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 |D.......E.....u.| +00006810 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 |.u..u..u..E.P.u.| +00006820 e8 cf 03 00 00 83 c4 20 89 45 08 e9 92 00 00 00 |....... .E......| +00006830 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d |.E..P..U......P.| +00006840 45 d0 50 e8 8a 02 00 00 83 c4 10 89 45 e0 83 ec |E.P.........E...| +00006850 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 |..u..u..u..u..E.| +00006860 50 ff 75 08 e8 8b 03 00 00 83 c4 20 89 45 08 eb |P.u........ .E..| +00006870 51 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 |Q.E..P..U......P| +00006880 8d 45 d0 50 e8 d3 02 00 00 83 c4 10 89 45 e0 83 |.E.P.........E..| +00006890 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 |...u..u..u..u..E| +000068a0 d0 50 ff 75 08 e8 4a 03 00 00 83 c4 20 89 45 08 |.P.u..J..... .E.| +000068b0 90 eb 0f 8b 45 08 8d 50 01 89 55 08 0f b6 55 f3 |....E..P..U...U.| +000068c0 88 10 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 |...E..P..U.....E| +000068d0 f3 80 7d f3 00 0f 85 a8 fd ff ff 8b 45 08 c6 00 |..}.........E...| +000068e0 00 90 c9 c3 55 89 e5 53 83 ec 14 8b 45 08 8b 4d |....U..S....E..M| +000068f0 0c bb 00 00 00 00 c6 45 eb 39 c7 45 f8 01 00 00 |.......E.9.E....| +00006900 00 0f b6 10 80 fa 2d 75 0a c7 45 f8 ff ff ff ff |......-u..E.....| +00006910 83 c0 01 83 f9 0a 74 2b 89 ca 83 c2 2f 88 55 eb |......t+..../.U.| +00006920 eb 21 0f b6 10 80 fa 2f 7e 20 0f b6 10 38 55 eb |.!...../~ ...8U.| +00006930 7c 18 0f af d9 0f b6 10 0f be d2 01 da 8d 5a d0 ||.............Z.| +00006940 83 c0 01 0f b6 10 84 d2 75 d8 89 d8 0f af 45 f8 |........u.....E.| +00006950 83 c4 14 5b 5d c3 55 89 e5 53 8b 55 08 bb 00 00 |...[].U..S.U....| +00006960 00 00 eb 03 83 c3 01 89 d0 8d 50 01 0f b6 00 84 |..........P.....| +00006970 c0 75 f1 89 d8 5b 5d c3 55 89 e5 83 ec 18 8b 45 |.u...[].U......E| +00006980 08 89 45 f4 83 7d 0c 00 79 0f 8b 45 f4 8d 50 01 |..E..}..y..E..P.| +00006990 89 55 f4 c6 00 2d f7 5d 0c 83 ec 08 ff 75 0c ff |.U...-.].....u..| +000069a0 75 f4 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 |u..........E..E.| +000069b0 c6 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 |....U..E.).....U| +000069c0 89 e5 83 ec 18 8b 4d 0c ba 67 66 66 66 89 c8 f7 |......M..gfff...| +000069d0 ea c1 fa 02 89 c8 c1 f8 1f 29 c2 89 d0 89 45 f4 |.........)....E.| +000069e0 83 7d f4 00 79 0e c7 45 f4 cc cc cc 0c c7 45 0c |.}..y..E......E.| +000069f0 08 00 00 00 83 7d f4 00 74 14 83 ec 08 ff 75 f4 |.....}..t.....u.| +00006a00 ff 75 08 e8 b7 ff ff ff 83 c4 10 89 45 08 8b 4d |.u..........E..M| +00006a10 0c ba 67 66 66 66 89 c8 f7 ea c1 fa 02 89 c8 c1 |..gfff..........| +00006a20 f8 1f 29 c2 89 d0 c1 e0 02 01 d0 01 c0 29 c1 89 |..)..........)..| +00006a30 ca 89 d0 8d 48 30 8b 45 08 8d 50 01 89 55 08 89 |....H0.E..P..U..| +00006a40 ca 88 10 8b 45 08 c9 c3 55 89 e5 83 ec 20 c7 45 |....E...U.... .E| +00006a50 e3 30 31 32 33 c7 45 e7 34 35 36 37 c7 45 eb 38 |.0123.E.4567.E.8| +00006a60 39 41 42 c7 45 ef 43 44 45 46 c6 45 f3 00 c7 45 |9AB.E.CDEF.E...E| +00006a70 fc 00 00 00 00 c7 45 f8 00 00 00 00 eb 43 8b 45 |......E......C.E| +00006a80 0c 25 00 00 00 f0 89 45 f4 83 7d fc 00 75 0c 83 |.%.....E..}..u..| +00006a90 7d f4 00 75 06 83 7d f8 07 75 1e 83 45 fc 01 c1 |}..u..}..u..E...| +00006aa0 6d f4 1c 8b 45 08 8d 50 01 89 55 08 8d 4d e3 8b |m...E..P..U..M..| +00006ab0 55 f4 01 ca 0f b6 12 88 10 c1 65 0c 04 83 45 f8 |U.........e...E.| +00006ac0 01 83 7d f8 07 7e b7 8b 45 08 c6 00 00 8b 45 fc |..}..~..E.....E.| +00006ad0 c9 c3 55 89 e5 83 ec 10 c7 45 f8 00 00 00 00 8b |..U......E......| +00006ae0 45 08 89 45 f4 8b 45 0c 25 00 00 00 c0 89 45 f0 |E..E..E.%.....E.| +00006af0 c1 6d f0 1e c7 45 fc 00 00 00 00 eb 47 83 7d fc |.m...E......G.}.| +00006b00 0a 74 0c 83 7d f0 00 75 06 83 7d f8 00 74 1e c7 |.t..}..u..}..t..| +00006b10 45 f8 01 00 00 00 83 65 f0 07 8b 45 f0 8d 48 30 |E......e...E..H0| +00006b20 8b 45 f4 8d 50 01 89 55 f4 89 ca 88 10 c1 65 0c |.E..P..U......e.| +00006b30 03 8b 45 0c 25 00 00 00 e0 89 45 f0 c1 6d f0 1d |..E.%.....E..m..| +00006b40 83 45 fc 01 83 7d fc 0a 7e b3 8b 45 f4 c6 00 00 |.E...}..~..E....| +00006b50 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 |.U..E.).....U...| +00006b60 ec 18 8b 45 08 89 45 f4 83 ec 08 ff 75 0c ff 75 |...E..E.....u..u| +00006b70 f4 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 c6 |..........E..E..| +00006b80 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 |...U..E.).....U.| +00006b90 e5 83 ec 18 8b 45 0c ba cd cc cc cc f7 e2 89 d0 |.....E..........| +00006ba0 c1 e8 03 89 45 f4 83 7d f4 00 74 15 8b 45 f4 83 |....E..}..t..E..| +00006bb0 ec 08 50 ff 75 08 e8 04 fe ff ff 83 c4 10 89 45 |..P.u..........E| +00006bc0 08 8b 4d 0c ba cd cc cc cc 89 c8 f7 e2 c1 ea 03 |..M.............| +00006bd0 89 d0 c1 e0 02 01 d0 01 c0 29 c1 89 ca 89 d0 8d |.........)......| +00006be0 48 30 8b 45 08 8d 50 01 89 55 08 89 ca 88 10 8b |H0.E..P..U......| +00006bf0 45 08 c9 c3 55 89 e5 83 ec 18 83 7d 10 00 79 11 |E...U......}..y.| +00006c00 83 ec 0c ff 75 0c e8 4b fd ff ff 83 c4 10 89 45 |....u..K.......E| +00006c10 10 8b 45 14 2b 45 10 89 45 f0 83 7d f0 00 7e 1d |..E.+E..E..}..~.| +00006c20 83 7d 18 00 75 17 83 ec 04 ff 75 1c ff 75 f0 ff |.}..u.....u..u..| +00006c30 75 08 e8 5a 00 00 00 83 c4 10 89 45 08 c7 45 f4 |u..Z.......E..E.| +00006c40 00 00 00 00 eb 1b 8b 55 f4 8b 45 0c 8d 0c 02 8b |.......U..E.....| +00006c50 45 08 8d 50 01 89 55 08 0f b6 11 88 10 83 45 f4 |E..P..U.......E.| +00006c60 01 8b 45 f4 3b 45 10 7c dd 83 7d f0 00 7e 1d 83 |..E.;E.|..}..~..| +00006c70 7d 18 00 74 17 83 ec 04 ff 75 1c ff 75 f0 ff 75 |}..t.....u..u..u| +00006c80 08 e8 0b 00 00 00 83 c4 10 89 45 08 8b 45 08 c9 |..........E..E..| +00006c90 c3 55 89 e5 eb 12 8b 45 08 8d 50 01 89 55 08 8b |.U.....E..P..U..| +00006ca0 55 10 88 10 83 6d 0c 01 83 7d 0c 00 7f e8 8b 45 |U....m...}.....E| +00006cb0 08 5d c3 00 6d 61 69 6e 32 3a 20 61 72 67 63 20 |.]..main2: argc | +00006cc0 25 64 2c 20 61 72 67 73 3a 20 00 28 6e 75 6c 6c |%d, args: .(null| +00006cd0 29 00 20 25 73 00 0a 00 3d 3d 20 25 63 2c 20 77 |). %s...== %c, w| +00006ce0 72 69 74 65 20 23 31 20 72 65 74 75 72 6e 65 64 |rite #1 returned| +00006cf0 20 25 64 0a 00 3d 3d 20 25 63 2c 20 77 72 69 74 | %d..== %c, writ| +00006d00 65 20 23 32 20 72 65 74 75 72 6e 65 64 20 25 64 |e #2 returned %d| +00006d10 0a 00 43 68 69 6c 64 20 25 64 20 65 78 65 63 28 |..Child %d exec(| +00006d20 29 20 23 25 75 20 66 61 69 6c 65 64 0a 00 00 00 |) #%u failed....| +00006d30 74 14 00 00 b2 14 00 00 fe 15 00 00 fe 15 00 00 |t...............| +00006d40 fe 15 00 00 fe 15 00 00 fe 15 00 00 fe 15 00 00 |................| +* +00006d60 6c 15 00 00 fe 15 00 00 fe 15 00 00 fe 15 00 00 |l...............| +00006d70 f6 14 00 00 fe 15 00 00 ad 15 00 00 fe 15 00 00 |................| +00006d80 fe 15 00 00 28 15 00 00 00 00 00 00 00 00 00 00 |....(...........| +00006d90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +000072d0 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 |................| +000072e0 03 00 01 00 00 00 00 00 f0 19 00 00 00 00 00 00 |................| +000072f0 03 00 02 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +00007300 03 00 03 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +00007310 03 00 04 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +00007320 04 00 f1 ff 0a 00 00 00 00 00 00 00 00 00 00 00 |................| +00007330 04 00 f1 ff 12 00 00 00 00 00 00 00 00 00 00 00 |................| +00007340 04 00 f1 ff 1b 00 00 00 00 00 00 00 00 00 00 00 |................| +00007350 04 00 f1 ff 25 00 00 00 00 00 00 00 00 00 00 00 |....%...........| +00007360 04 00 f1 ff 2e 00 00 00 00 00 00 00 00 00 00 00 |................| +00007370 04 00 f1 ff 37 00 00 00 00 00 00 00 00 00 00 00 |....7...........| +00007380 04 00 f1 ff 41 00 00 00 00 00 00 00 00 00 00 00 |....A...........| +00007390 04 00 f1 ff 4a 00 00 00 00 00 00 00 00 00 00 00 |....J...........| +000073a0 04 00 f1 ff 53 00 00 00 00 00 00 00 00 00 00 00 |....S...........| +000073b0 04 00 f1 ff 5c 00 00 00 00 00 00 00 00 00 00 00 |....\...........| +000073c0 04 00 f1 ff 66 00 00 00 00 00 00 00 00 00 00 00 |....f...........| +000073d0 04 00 f1 ff 6f 00 00 00 00 00 00 00 00 00 00 00 |....o...........| +000073e0 04 00 f1 ff 75 00 00 00 bc 12 00 00 21 00 00 00 |....u.......!...| +000073f0 12 00 01 00 7e 00 00 00 2d 13 00 00 00 00 00 00 |....~...-.......| +00007400 10 00 01 00 86 00 00 00 a1 12 00 00 1b 00 00 00 |................| +00007410 12 00 01 00 8d 00 00 00 20 16 00 00 72 00 00 00 |........ ...r...| +00007420 12 00 01 00 95 00 00 00 98 18 00 00 32 00 00 00 |............2...| +00007430 12 00 01 00 9c 00 00 00 55 13 00 00 00 00 00 00 |........U.......| +00007440 10 00 01 00 a3 00 00 00 85 13 00 00 00 00 00 00 |................| +00007450 10 00 01 00 a9 00 00 00 0a 13 00 00 1b 00 00 00 |................| +00007460 12 00 01 00 b0 00 00 00 cd 19 00 00 22 00 00 00 |............"...| +00007470 12 00 01 00 b4 00 00 00 de 11 00 00 75 00 00 00 |............u...| +00007480 12 00 01 00 ba 00 00 00 ab 13 00 00 75 02 00 00 |............u...| +00007490 12 00 01 00 c1 00 00 00 84 17 00 00 8a 00 00 00 |................| +000074a0 12 00 01 00 c8 00 00 00 ca 18 00 00 66 00 00 00 |............f...| +000074b0 12 00 01 00 87 00 00 00 4d 13 00 00 00 00 00 00 |........M.......| +000074c0 10 00 01 00 d0 00 00 00 7d 13 00 00 00 00 00 00 |........}.......| +000074d0 10 00 01 00 d5 00 00 00 74 12 00 00 2d 00 00 00 |........t...-...| +000074e0 12 00 01 00 dd 00 00 00 3d 13 00 00 00 00 00 00 |........=.......| +000074f0 10 00 01 00 e2 00 00 00 c6 11 00 00 18 00 00 00 |................| +00007500 12 00 01 00 e7 00 00 00 dd 12 00 00 2d 00 00 00 |............-...| +00007510 12 00 01 00 ef 00 00 00 9b 13 00 00 00 00 00 00 |................| +00007520 10 00 01 00 f6 00 00 00 45 13 00 00 00 00 00 00 |........E.......| +00007530 10 00 01 00 fb 00 00 00 6d 13 00 00 00 00 00 00 |........m.......| +00007540 10 00 01 00 03 01 00 00 fb 16 00 00 89 00 00 00 |................| +00007550 12 00 01 00 0b 01 00 00 35 13 00 00 00 00 00 00 |........5.......| +00007560 10 00 01 00 10 01 00 00 00 10 00 00 c6 01 00 00 |................| +00007570 12 00 01 00 15 01 00 00 5d 13 00 00 00 00 00 00 |........].......| +00007580 10 00 01 00 1d 01 00 00 30 19 00 00 9d 00 00 00 |........0.......| +00007590 12 00 01 00 24 01 00 00 75 13 00 00 00 00 00 00 |....$...u.......| +000075a0 10 00 01 00 2c 01 00 00 0e 18 00 00 8a 00 00 00 |....,...........| +000075b0 12 00 01 00 33 01 00 00 53 12 00 00 21 00 00 00 |....3...S...!...| +000075c0 12 00 01 00 3c 01 00 00 65 13 00 00 00 00 00 00 |....<...e.......| +000075d0 10 00 01 00 44 01 00 00 b4 16 00 00 47 00 00 00 |....D.......G...| +000075e0 12 00 01 00 5d 01 00 00 25 13 00 00 00 00 00 00 |....]...%.......| +000075f0 10 00 01 00 4b 01 00 00 92 16 00 00 22 00 00 00 |....K......."...| +00007600 12 00 01 00 52 01 00 00 8d 13 00 00 00 00 00 00 |....R...........| +00007610 10 00 01 00 58 01 00 00 95 13 00 00 00 00 00 00 |....X...........| +00007620 10 00 01 00 00 70 72 6f 67 44 45 2e 63 00 75 6c |.....progDE.c.ul| +00007630 69 62 63 2e 63 00 73 70 72 69 6e 74 2e 63 00 73 |ibc.c.sprint.c.s| +00007640 74 72 32 69 6e 74 2e 63 00 73 74 72 6c 65 6e 2e |tr2int.c.strlen.| +00007650 63 00 63 76 74 64 65 63 2e 63 00 63 76 74 64 65 |c.cvtdec.c.cvtde| +00007660 63 30 2e 63 00 63 76 74 68 65 78 2e 63 00 63 76 |c0.c.cvthex.c.cv| +00007670 74 6f 63 74 2e 63 00 63 76 74 75 6e 73 2e 63 00 |toct.c.cvtuns.c.| +00007680 63 76 74 75 6e 73 30 2e 63 00 70 61 64 73 74 72 |cvtuns0.c.padstr| +00007690 2e 63 00 70 61 64 2e 63 00 73 77 72 69 74 65 63 |.c.pad.c.swritec| +000076a0 68 00 77 61 69 74 70 69 64 00 63 77 72 69 74 65 |h.waitpid.cwrite| +000076b0 00 73 74 72 32 69 6e 74 00 63 76 74 75 6e 73 00 |.str2int.cvtuns.| +000076c0 67 65 74 70 69 64 00 73 6c 65 65 70 00 73 77 72 |getpid.sleep.swr| +000076d0 69 74 65 00 70 61 64 00 73 70 61 77 6e 00 73 70 |ite.pad.spawn.sp| +000076e0 72 69 6e 74 00 63 76 74 68 65 78 00 63 76 74 75 |rint.cvthex.cvtu| +000076f0 6e 73 30 00 6b 69 6c 6c 00 63 77 72 69 74 65 73 |ns0.kill.cwrites| +00007700 00 65 78 65 63 00 77 61 69 74 00 73 77 72 69 74 |.exec.wait.swrit| +00007710 65 73 00 5f 73 74 61 72 74 00 72 65 61 64 00 67 |es._start.read.g| +00007720 65 74 70 72 69 6f 00 63 76 74 64 65 63 30 00 66 |etprio.cvtdec0.f| +00007730 6f 72 6b 00 6d 61 69 6e 00 67 65 74 70 70 69 64 |ork.main.getppid| +00007740 00 70 61 64 73 74 72 00 73 65 74 70 72 69 6f 00 |.padstr.setprio.| +00007750 63 76 74 6f 63 74 00 63 77 72 69 74 65 63 68 00 |cvtoct.cwritech.| +00007760 67 65 74 74 69 6d 65 00 63 76 74 64 65 63 00 73 |gettime.cvtdec.s| +00007770 74 72 6c 65 6e 00 62 6f 67 75 73 00 66 61 6b 65 |trlen.bogus.fake| +00007780 5f 65 78 69 74 00 00 2e 73 79 6d 74 61 62 00 2e |_exit...symtab..| +00007790 73 74 72 74 61 62 00 2e 73 68 73 74 72 74 61 62 |strtab..shstrtab| +000077a0 00 2e 74 65 78 74 00 2e 72 6f 64 61 74 61 00 2e |..text..rodata..| +000077b0 64 61 74 61 00 2e 62 73 73 00 00 00 00 00 00 00 |data..bss.......| +000077c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +000077e0 00 00 00 00 1b 00 00 00 01 00 00 00 06 00 00 00 |................| +000077f0 00 10 00 00 74 00 00 00 ef 09 00 00 00 00 00 00 |....t...........| +00007800 00 00 00 00 01 00 00 00 00 00 00 00 21 00 00 00 |............!...| +00007810 01 00 00 00 02 00 00 00 f0 19 00 00 64 0a 00 00 |............d...| +00007820 d4 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |................| +00007830 00 00 00 00 29 00 00 00 01 00 00 00 03 00 00 00 |....)...........| +00007840 00 20 00 00 74 10 00 00 00 00 00 00 00 00 00 00 |. ..t...........| +00007850 00 00 00 00 01 00 00 00 00 00 00 00 2f 00 00 00 |............/...| +00007860 08 00 00 00 03 00 00 00 00 20 00 00 74 10 00 00 |......... ..t...| +00007870 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +00007880 00 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 |................| +00007890 00 00 00 00 74 10 00 00 60 03 00 00 06 00 00 00 |....t...`.......| +000078a0 12 00 00 00 04 00 00 00 10 00 00 00 09 00 00 00 |................| +000078b0 03 00 00 00 00 00 00 00 00 00 00 00 d4 13 00 00 |................| +000078c0 62 01 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |b...............| +000078d0 00 00 00 00 11 00 00 00 03 00 00 00 00 00 00 00 |................| +000078e0 00 00 00 00 36 15 00 00 34 00 00 00 00 00 00 00 |....6...4.......| +000078f0 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +00007900 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| +00007910 02 00 03 00 01 00 00 00 b3 13 00 00 34 00 00 00 |............4...| +00007920 6c 15 00 00 00 00 00 00 34 00 20 00 02 00 28 00 |l.......4. ...(.| +00007930 08 00 07 00 01 00 00 00 74 00 00 00 00 10 00 00 |........t.......| +00007940 00 10 00 00 00 10 00 00 00 10 00 00 07 00 00 00 |................| +00007950 04 00 00 00 51 e5 74 64 00 00 00 00 00 00 00 00 |....Q.td........| +00007960 00 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 |................| +00007970 10 00 00 00 8d 4c 24 04 83 e4 f0 ff 71 fc 55 89 |.....L$.....q.U.| +00007980 e5 53 51 81 ec a0 00 00 00 89 cb c6 45 e3 33 c7 |.SQ.........E.3.| +00007990 45 f4 0a 00 00 00 c7 45 f0 1e 00 00 00 8b 03 83 |E......E........| +000079a0 f8 03 74 25 83 f8 04 74 07 83 f8 02 74 34 eb 45 |..t%...t....t4.E| +000079b0 8b 43 04 83 c0 0c 8b 00 83 ec 08 6a 0a 50 e8 e9 |.C.........j.P..| +000079c0 05 00 00 83 c4 10 89 45 f4 8b 43 04 83 c0 08 8b |.......E..C.....| +000079d0 00 83 ec 08 6a 0a 50 e8 d0 05 00 00 83 c4 10 89 |....j.P.........| +000079e0 45 f0 8b 43 04 83 c0 04 8b 00 0f b6 00 88 45 e3 |E..C..........E.| +000079f0 e9 a4 00 00 00 83 ec 04 ff 33 68 08 1a 00 00 8d |.........3h.....| +00007a00 85 63 ff ff ff 50 e8 2c 03 00 00 83 c4 10 83 ec |.c...P.,........| +00007a10 0c 8d 85 63 ff ff ff 50 e8 e3 01 00 00 83 c4 10 |...c...P........| +00007a20 c7 45 ec 00 00 00 00 eb 59 8b 03 8d 14 85 00 00 |.E......Y.......| +00007a30 00 00 8b 43 04 01 d0 8b 00 85 c0 74 12 8b 03 8d |...C.......t....| +00007a40 14 85 00 00 00 00 8b 43 04 01 d0 8b 00 eb 05 b8 |.......C........| +00007a50 1f 1a 00 00 83 ec 04 50 68 26 1a 00 00 8d 85 63 |.......Ph&.....c| +00007a60 ff ff ff 50 e8 ce 02 00 00 83 c4 10 83 ec 0c 8d |...P............| +00007a70 85 63 ff ff ff 50 e8 85 01 00 00 83 c4 10 83 45 |.c...P.........E| +00007a80 ec 01 8b 45 ec 3b 03 7e a0 83 ec 0c 68 2a 1a 00 |...E.;.~....h*..| +00007a90 00 e8 6a 01 00 00 83 c4 10 0f b6 45 e3 0f be c0 |..j........E....| +00007aa0 83 ec 0c 50 e8 9f 01 00 00 83 c4 10 89 45 e4 83 |...P.........E..| +00007ab0 7d e4 01 74 31 0f b6 45 e3 0f be c0 ff 75 e4 50 |}..t1..E.....u.P| +00007ac0 68 2c 1a 00 00 8d 85 63 ff ff ff 50 e8 66 02 00 |h,.....c...P.f..| +00007ad0 00 83 c4 10 83 ec 0c 8d 85 63 ff ff ff 50 e8 1d |.........c...P..| +00007ae0 01 00 00 83 c4 10 83 ec 04 6a 01 8d 45 e3 50 6a |.........j..E.Pj| +00007af0 01 e8 e3 01 00 00 83 c4 10 c7 45 e8 00 00 00 00 |..........E.....| +00007b00 eb 2c 8b 45 f4 69 c0 e8 03 00 00 83 ec 0c 50 e8 |.,.E.i........P.| +00007b10 fd 01 00 00 83 c4 10 83 ec 04 6a 01 8d 45 e3 50 |..........j..E.P| +00007b20 6a 01 e8 b2 01 00 00 83 c4 10 83 45 e8 01 8b 45 |j..........E...E| +00007b30 e8 3b 45 f0 7c cc 83 ec 0c 6a 00 e8 71 01 00 00 |.;E.|....j..q...| +00007b40 83 c4 10 b8 2a 00 00 00 8d 65 f8 59 5b 5d 8d 61 |....*....e.Y[].a| +00007b50 fc c3 55 89 e5 83 ec 08 83 ec 08 ff 75 08 6a 00 |..U.........u.j.| +00007b60 e8 54 01 00 00 83 c4 10 c9 c3 55 89 e5 81 ec 18 |.T........U.....| +00007b70 01 00 00 e8 49 01 00 00 89 45 f4 83 7d f4 00 74 |....I....E..}..t| +00007b80 05 8b 45 f4 eb 57 e8 56 01 00 00 89 45 f4 83 ec |..E..W.V....E...| +00007b90 08 ff 75 0c ff 75 08 e8 2d 01 00 00 83 c4 10 ff |..u..u..-.......| +00007ba0 75 08 ff 75 f4 68 4a 1a 00 00 8d 85 f4 fe ff ff |u..u.hJ.........| +00007bb0 50 e8 81 01 00 00 83 c4 10 83 ec 0c 8d 85 f4 fe |P...............| +00007bc0 ff ff 50 e8 38 00 00 00 83 c4 10 83 ec 0c 6a ff |..P.8.........j.| +00007bd0 e8 dc 00 00 00 83 c4 10 b8 00 00 00 00 c9 c3 55 |...............U| +00007be0 89 e5 83 ec 18 8b 45 08 88 45 f4 83 ec 04 6a 01 |......E..E....j.| +00007bf0 8d 45 f4 50 6a 00 e8 de 00 00 00 83 c4 10 c9 c3 |.E.Pj...........| +00007c00 55 89 e5 83 ec 18 83 ec 0c ff 75 08 e8 0d 04 00 |U.........u.....| +00007c10 00 83 c4 10 89 45 f4 8b 45 f4 83 ec 04 50 ff 75 |.....E..E....P.u| +00007c20 08 6a 00 e8 b1 00 00 00 83 c4 10 c9 c3 55 89 e5 |.j...........U..| +00007c30 83 ec 08 83 ec 04 ff 75 0c ff 75 08 6a 00 e8 96 |.......u..u.j...| +00007c40 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 8b 45 |........U......E| +00007c50 08 88 45 f4 83 ec 04 6a 01 8d 45 f4 50 6a 01 e8 |..E....j..E.Pj..| +00007c60 75 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 83 |u........U......| +00007c70 ec 0c ff 75 08 e8 a4 03 00 00 83 c4 10 89 45 f4 |...u..........E.| +00007c80 8b 45 f4 83 ec 04 50 ff 75 08 6a 01 e8 48 00 00 |.E....P.u.j..H..| +00007c90 00 83 c4 10 c9 c3 55 89 e5 83 ec 08 83 ec 04 ff |......U.........| +00007ca0 75 0c ff 75 08 6a 01 e8 2d 00 00 00 83 c4 10 c9 |u..u.j..-.......| +00007cb0 c3 b8 00 00 00 00 cd 80 c3 b8 01 00 00 00 cd 80 |................| +00007cc0 c3 b8 02 00 00 00 cd 80 c3 b8 03 00 00 00 cd 80 |................| +00007cd0 c3 b8 04 00 00 00 cd 80 c3 b8 05 00 00 00 cd 80 |................| +00007ce0 c3 b8 06 00 00 00 cd 80 c3 b8 07 00 00 00 cd 80 |................| +00007cf0 c3 b8 08 00 00 00 cd 80 c3 b8 09 00 00 00 cd 80 |................| +00007d00 c3 b8 0a 00 00 00 cd 80 c3 b8 0b 00 00 00 cd 80 |................| +00007d10 c3 b8 0c 00 00 00 cd 80 c3 b8 ad 0b 00 00 cd 80 |................| +00007d20 c3 50 e8 8a ff ff ff e8 48 fc ff ff 83 ec 0c 50 |.P......H......P| +00007d30 e8 7c ff ff ff eb fe 55 89 e5 83 ec 38 8d 45 0c |.|.....U....8.E.| +00007d40 83 c0 04 89 45 f4 e9 3f 02 00 00 80 7d f3 25 0f |....E..?....}.%.| +00007d50 85 26 02 00 00 c7 45 ec 00 00 00 00 c7 45 e4 20 |.&....E......E. | +00007d60 00 00 00 c7 45 e8 00 00 00 00 8b 45 0c 8d 50 01 |....E......E..P.| +00007d70 89 55 0c 0f b6 00 88 45 f3 80 7d f3 2d 75 16 c7 |.U.....E..}.-u..| +00007d80 45 ec 01 00 00 00 8b 45 0c 8d 50 01 89 55 0c 0f |E......E..P..U..| +00007d90 b6 00 88 45 f3 80 7d f3 30 75 40 c7 45 e4 30 00 |...E..}.0u@.E.0.| +00007da0 00 00 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 |...E..P..U.....E| +00007db0 f3 eb 28 8b 55 e8 89 d0 c1 e0 02 01 d0 01 c0 89 |..(.U...........| +00007dc0 45 e8 0f be 45 f3 83 e8 30 01 45 e8 8b 45 0c 8d |E...E...0.E..E..| +00007dd0 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 2f 7e |P..U.....E..}./~| +00007de0 06 80 7d f3 39 7e cc 0f be 45 f3 83 e8 63 83 f8 |..}.9~...E...c..| +00007df0 15 0f 87 93 01 00 00 8b 04 85 68 1a 00 00 ff e0 |..........h.....| +00007e00 8b 45 f4 8d 50 04 89 55 f4 8b 00 88 45 f3 0f b6 |.E..P..U....E...| +00007e10 45 f3 88 45 d0 c6 45 d1 00 83 ec 08 ff 75 e4 ff |E..E..E......u..| +00007e20 75 ec ff 75 e8 6a 01 8d 45 d0 50 ff 75 08 e8 89 |u..u.j..E.P.u...| +00007e30 04 00 00 83 c4 20 89 45 08 e9 4c 01 00 00 8b 45 |..... .E..L....E| +00007e40 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 |..P..U......P.E.| +00007e50 50 e8 ea 01 00 00 83 c4 10 89 45 e0 83 ec 08 ff |P.........E.....| +00007e60 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff |u..u..u..u..E.P.| +00007e70 75 08 e8 45 04 00 00 83 c4 20 89 45 08 e9 08 01 |u..E..... .E....| +00007e80 00 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 89 45 dc |...E..P..U....E.| +00007e90 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 6a ff ff 75 |....u..u..u.j..u| +00007ea0 dc ff 75 08 e8 13 04 00 00 83 c4 20 89 45 08 e9 |..u........ .E..| +00007eb0 d6 00 00 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 |.....E..P..U....| +00007ec0 ec 08 50 8d 45 d0 50 e8 44 02 00 00 83 c4 10 89 |..P.E.P.D.......| +00007ed0 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 |E.....u..u..u..u| +00007ee0 e0 8d 45 d0 50 ff 75 08 e8 cf 03 00 00 83 c4 20 |..E.P.u........ | +00007ef0 89 45 08 e9 92 00 00 00 8b 45 f4 8d 50 04 89 55 |.E.......E..P..U| +00007f00 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 8a 02 00 00 |......P.E.P.....| +00007f10 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff |....E.....u..u..| +00007f20 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 8b 03 00 |u..u..E.P.u.....| +00007f30 00 83 c4 20 89 45 08 eb 51 8b 45 f4 8d 50 04 89 |... .E..Q.E..P..| +00007f40 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 d3 02 00 |U......P.E.P....| +00007f50 00 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec |.....E.....u..u.| +00007f60 ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 4a 03 |.u..u..E.P.u..J.| +00007f70 00 00 83 c4 20 89 45 08 90 eb 0f 8b 45 08 8d 50 |.... .E.....E..P| +00007f80 01 89 55 08 0f b6 55 f3 88 10 8b 45 0c 8d 50 01 |..U...U....E..P.| +00007f90 89 55 0c 0f b6 00 88 45 f3 80 7d f3 00 0f 85 a8 |.U.....E..}.....| +00007fa0 fd ff ff 8b 45 08 c6 00 00 90 c9 c3 55 89 e5 53 |....E.......U..S| +00007fb0 83 ec 14 8b 45 08 8b 4d 0c bb 00 00 00 00 c6 45 |....E..M.......E| +00007fc0 eb 39 c7 45 f8 01 00 00 00 0f b6 10 80 fa 2d 75 |.9.E..........-u| +00007fd0 0a c7 45 f8 ff ff ff ff 83 c0 01 83 f9 0a 74 2b |..E...........t+| +00007fe0 89 ca 83 c2 2f 88 55 eb eb 21 0f b6 10 80 fa 2f |..../.U..!...../| +00007ff0 7e 20 0f b6 10 38 55 eb 7c 18 0f af d9 0f b6 10 |~ ...8U.|.......| +00008000 0f be d2 01 da 8d 5a d0 83 c0 01 0f b6 10 84 d2 |......Z.........| +00008010 75 d8 89 d8 0f af 45 f8 83 c4 14 5b 5d c3 55 89 |u.....E....[].U.| +00008020 e5 53 8b 55 08 bb 00 00 00 00 eb 03 83 c3 01 89 |.S.U............| +00008030 d0 8d 50 01 0f b6 00 84 c0 75 f1 89 d8 5b 5d c3 |..P......u...[].| +00008040 55 89 e5 83 ec 18 8b 45 08 89 45 f4 83 7d 0c 00 |U......E..E..}..| +00008050 79 0f 8b 45 f4 8d 50 01 89 55 f4 c6 00 2d f7 5d |y..E..P..U...-.]| +00008060 0c 83 ec 08 ff 75 0c ff 75 f4 e8 18 00 00 00 83 |.....u..u.......| +00008070 c4 10 89 45 f4 8b 45 f4 c6 00 00 8b 55 f4 8b 45 |...E..E.....U..E| +00008080 08 29 c2 89 d0 c9 c3 55 89 e5 83 ec 18 8b 4d 0c |.).....U......M.| +00008090 ba 67 66 66 66 89 c8 f7 ea c1 fa 02 89 c8 c1 f8 |.gfff...........| +000080a0 1f 29 c2 89 d0 89 45 f4 83 7d f4 00 79 0e c7 45 |.)....E..}..y..E| +000080b0 f4 cc cc cc 0c c7 45 0c 08 00 00 00 83 7d f4 00 |......E......}..| +000080c0 74 14 83 ec 08 ff 75 f4 ff 75 08 e8 b7 ff ff ff |t.....u..u......| +000080d0 83 c4 10 89 45 08 8b 4d 0c ba 67 66 66 66 89 c8 |....E..M..gfff..| +000080e0 f7 ea c1 fa 02 89 c8 c1 f8 1f 29 c2 89 d0 c1 e0 |..........).....| +000080f0 02 01 d0 01 c0 29 c1 89 ca 89 d0 8d 48 30 8b 45 |.....)......H0.E| +00008100 08 8d 50 01 89 55 08 89 ca 88 10 8b 45 08 c9 c3 |..P..U......E...| +00008110 55 89 e5 83 ec 20 c7 45 e3 30 31 32 33 c7 45 e7 |U.... .E.0123.E.| +00008120 34 35 36 37 c7 45 eb 38 39 41 42 c7 45 ef 43 44 |4567.E.89AB.E.CD| +00008130 45 46 c6 45 f3 00 c7 45 fc 00 00 00 00 c7 45 f8 |EF.E...E......E.| +00008140 00 00 00 00 eb 43 8b 45 0c 25 00 00 00 f0 89 45 |.....C.E.%.....E| +00008150 f4 83 7d fc 00 75 0c 83 7d f4 00 75 06 83 7d f8 |..}..u..}..u..}.| +00008160 07 75 1e 83 45 fc 01 c1 6d f4 1c 8b 45 08 8d 50 |.u..E...m...E..P| +00008170 01 89 55 08 8d 4d e3 8b 55 f4 01 ca 0f b6 12 88 |..U..M..U.......| +00008180 10 c1 65 0c 04 83 45 f8 01 83 7d f8 07 7e b7 8b |..e...E...}..~..| +00008190 45 08 c6 00 00 8b 45 fc c9 c3 55 89 e5 83 ec 10 |E.....E...U.....| +000081a0 c7 45 f8 00 00 00 00 8b 45 08 89 45 f4 8b 45 0c |.E......E..E..E.| +000081b0 25 00 00 00 c0 89 45 f0 c1 6d f0 1e c7 45 fc 00 |%.....E..m...E..| +000081c0 00 00 00 eb 47 83 7d fc 0a 74 0c 83 7d f0 00 75 |....G.}..t..}..u| +000081d0 06 83 7d f8 00 74 1e c7 45 f8 01 00 00 00 83 65 |..}..t..E......e| +000081e0 f0 07 8b 45 f0 8d 48 30 8b 45 f4 8d 50 01 89 55 |...E..H0.E..P..U| +000081f0 f4 89 ca 88 10 c1 65 0c 03 8b 45 0c 25 00 00 00 |......e...E.%...| +00008200 e0 89 45 f0 c1 6d f0 1d 83 45 fc 01 83 7d fc 0a |..E..m...E...}..| +00008210 7e b3 8b 45 f4 c6 00 00 8b 55 f4 8b 45 08 29 c2 |~..E.....U..E.).| +00008220 89 d0 c9 c3 55 89 e5 83 ec 18 8b 45 08 89 45 f4 |....U......E..E.| +00008230 83 ec 08 ff 75 0c ff 75 f4 e8 18 00 00 00 83 c4 |....u..u........| +00008240 10 89 45 f4 8b 45 f4 c6 00 00 8b 55 f4 8b 45 08 |..E..E.....U..E.| +00008250 29 c2 89 d0 c9 c3 55 89 e5 83 ec 18 8b 45 0c ba |).....U......E..| +00008260 cd cc cc cc f7 e2 89 d0 c1 e8 03 89 45 f4 83 7d |............E..}| +00008270 f4 00 74 15 8b 45 f4 83 ec 08 50 ff 75 08 e8 04 |..t..E....P.u...| +00008280 fe ff ff 83 c4 10 89 45 08 8b 4d 0c ba cd cc cc |.......E..M.....| +00008290 cc 89 c8 f7 e2 c1 ea 03 89 d0 c1 e0 02 01 d0 01 |................| +000082a0 c0 29 c1 89 ca 89 d0 8d 48 30 8b 45 08 8d 50 01 |.)......H0.E..P.| +000082b0 89 55 08 89 ca 88 10 8b 45 08 c9 c3 55 89 e5 83 |.U......E...U...| +000082c0 ec 18 83 7d 10 00 79 11 83 ec 0c ff 75 0c e8 4b |...}..y.....u..K| +000082d0 fd ff ff 83 c4 10 89 45 10 8b 45 14 2b 45 10 89 |.......E..E.+E..| +000082e0 45 f0 83 7d f0 00 7e 1d 83 7d 18 00 75 17 83 ec |E..}..~..}..u...| +000082f0 04 ff 75 1c ff 75 f0 ff 75 08 e8 5a 00 00 00 83 |..u..u..u..Z....| +00008300 c4 10 89 45 08 c7 45 f4 00 00 00 00 eb 1b 8b 55 |...E..E........U| +00008310 f4 8b 45 0c 8d 0c 02 8b 45 08 8d 50 01 89 55 08 |..E.....E..P..U.| +00008320 0f b6 11 88 10 83 45 f4 01 8b 45 f4 3b 45 10 7c |......E...E.;E.|| +00008330 dd 83 7d f0 00 7e 1d 83 7d 18 00 74 17 83 ec 04 |..}..~..}..t....| +00008340 ff 75 1c ff 75 f0 ff 75 08 e8 0b 00 00 00 83 c4 |.u..u..u........| +00008350 10 89 45 08 8b 45 08 c9 c3 55 89 e5 eb 12 8b 45 |..E..E...U.....E| +00008360 08 8d 50 01 89 55 08 8b 55 10 88 10 83 6d 0c 01 |..P..U..U....m..| +00008370 83 7d 0c 00 7f e8 8b 45 08 5d c3 00 6d 61 69 6e |.}.....E.]..main| +00008380 33 3a 20 61 72 67 63 20 25 64 2c 20 61 72 67 73 |3: argc %d, args| +00008390 3a 20 00 28 6e 75 6c 6c 29 00 20 25 73 00 0a 00 |: .(null). %s...| +000083a0 3d 3d 3d 20 25 63 2c 20 77 72 69 74 65 20 23 31 |=== %c, write #1| +000083b0 20 72 65 74 75 72 6e 65 64 20 25 64 0a 00 43 68 | returned %d..Ch| +000083c0 69 6c 64 20 25 64 20 65 78 65 63 28 29 20 23 25 |ild %d exec() #%| +000083d0 75 20 66 61 69 6c 65 64 0a 00 00 00 8c 14 00 00 |u failed........| +000083e0 ca 14 00 00 16 16 00 00 16 16 00 00 16 16 00 00 |................| +000083f0 16 16 00 00 16 16 00 00 16 16 00 00 16 16 00 00 |................| +00008400 16 16 00 00 16 16 00 00 16 16 00 00 84 15 00 00 |................| +00008410 16 16 00 00 16 16 00 00 16 16 00 00 0e 15 00 00 |................| +00008420 16 16 00 00 c5 15 00 00 16 16 00 00 16 16 00 00 |................| +00008430 40 15 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |@...............| +00008440 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00008980 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 |................| +00008990 03 00 01 00 00 00 00 00 08 1a 00 00 00 00 00 00 |................| +000089a0 03 00 02 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +000089b0 03 00 03 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +000089c0 03 00 04 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +000089d0 04 00 f1 ff 0a 00 00 00 00 00 00 00 00 00 00 00 |................| +000089e0 04 00 f1 ff 12 00 00 00 00 00 00 00 00 00 00 00 |................| +000089f0 04 00 f1 ff 1b 00 00 00 00 00 00 00 00 00 00 00 |................| +00008a00 04 00 f1 ff 25 00 00 00 00 00 00 00 00 00 00 00 |....%...........| +00008a10 04 00 f1 ff 2e 00 00 00 00 00 00 00 00 00 00 00 |................| +00008a20 04 00 f1 ff 37 00 00 00 00 00 00 00 00 00 00 00 |....7...........| +00008a30 04 00 f1 ff 41 00 00 00 00 00 00 00 00 00 00 00 |....A...........| +00008a40 04 00 f1 ff 4a 00 00 00 00 00 00 00 00 00 00 00 |....J...........| +00008a50 04 00 f1 ff 53 00 00 00 00 00 00 00 00 00 00 00 |....S...........| +00008a60 04 00 f1 ff 5c 00 00 00 00 00 00 00 00 00 00 00 |....\...........| +00008a70 04 00 f1 ff 66 00 00 00 00 00 00 00 00 00 00 00 |....f...........| +00008a80 04 00 f1 ff 6f 00 00 00 00 00 00 00 00 00 00 00 |....o...........| +00008a90 04 00 f1 ff 75 00 00 00 d4 12 00 00 21 00 00 00 |....u.......!...| +00008aa0 12 00 01 00 7e 00 00 00 45 13 00 00 00 00 00 00 |....~...E.......| +00008ab0 10 00 01 00 86 00 00 00 b9 12 00 00 1b 00 00 00 |................| +00008ac0 12 00 01 00 8d 00 00 00 38 16 00 00 72 00 00 00 |........8...r...| +00008ad0 12 00 01 00 95 00 00 00 b0 18 00 00 32 00 00 00 |............2...| +00008ae0 12 00 01 00 9c 00 00 00 6d 13 00 00 00 00 00 00 |........m.......| +00008af0 10 00 01 00 a3 00 00 00 9d 13 00 00 00 00 00 00 |................| +00008b00 10 00 01 00 a9 00 00 00 22 13 00 00 1b 00 00 00 |........".......| +00008b10 12 00 01 00 b0 00 00 00 e5 19 00 00 22 00 00 00 |............"...| +00008b20 12 00 01 00 b4 00 00 00 f6 11 00 00 75 00 00 00 |............u...| +00008b30 12 00 01 00 ba 00 00 00 c3 13 00 00 75 02 00 00 |............u...| +00008b40 12 00 01 00 c1 00 00 00 9c 17 00 00 8a 00 00 00 |................| +00008b50 12 00 01 00 c8 00 00 00 e2 18 00 00 66 00 00 00 |............f...| +00008b60 12 00 01 00 87 00 00 00 65 13 00 00 00 00 00 00 |........e.......| +00008b70 10 00 01 00 d0 00 00 00 95 13 00 00 00 00 00 00 |................| +00008b80 10 00 01 00 d5 00 00 00 8c 12 00 00 2d 00 00 00 |............-...| +00008b90 12 00 01 00 dd 00 00 00 55 13 00 00 00 00 00 00 |........U.......| +00008ba0 10 00 01 00 e2 00 00 00 de 11 00 00 18 00 00 00 |................| +00008bb0 12 00 01 00 e7 00 00 00 f5 12 00 00 2d 00 00 00 |............-...| +00008bc0 12 00 01 00 ef 00 00 00 b3 13 00 00 00 00 00 00 |................| +00008bd0 10 00 01 00 f6 00 00 00 5d 13 00 00 00 00 00 00 |........].......| +00008be0 10 00 01 00 fb 00 00 00 85 13 00 00 00 00 00 00 |................| +00008bf0 10 00 01 00 03 01 00 00 13 17 00 00 89 00 00 00 |................| +00008c00 12 00 01 00 0b 01 00 00 4d 13 00 00 00 00 00 00 |........M.......| +00008c10 10 00 01 00 10 01 00 00 00 10 00 00 de 01 00 00 |................| +00008c20 12 00 01 00 15 01 00 00 75 13 00 00 00 00 00 00 |........u.......| +00008c30 10 00 01 00 1d 01 00 00 48 19 00 00 9d 00 00 00 |........H.......| +00008c40 12 00 01 00 24 01 00 00 8d 13 00 00 00 00 00 00 |....$...........| +00008c50 10 00 01 00 2c 01 00 00 26 18 00 00 8a 00 00 00 |....,...&.......| +00008c60 12 00 01 00 33 01 00 00 6b 12 00 00 21 00 00 00 |....3...k...!...| +00008c70 12 00 01 00 3c 01 00 00 7d 13 00 00 00 00 00 00 |....<...}.......| +00008c80 10 00 01 00 44 01 00 00 cc 16 00 00 47 00 00 00 |....D.......G...| +00008c90 12 00 01 00 5d 01 00 00 3d 13 00 00 00 00 00 00 |....]...=.......| +00008ca0 10 00 01 00 4b 01 00 00 aa 16 00 00 22 00 00 00 |....K......."...| +00008cb0 12 00 01 00 52 01 00 00 a5 13 00 00 00 00 00 00 |....R...........| +00008cc0 10 00 01 00 58 01 00 00 ad 13 00 00 00 00 00 00 |....X...........| +00008cd0 10 00 01 00 00 70 72 6f 67 46 47 2e 63 00 75 6c |.....progFG.c.ul| +00008ce0 69 62 63 2e 63 00 73 70 72 69 6e 74 2e 63 00 73 |ibc.c.sprint.c.s| +00008cf0 74 72 32 69 6e 74 2e 63 00 73 74 72 6c 65 6e 2e |tr2int.c.strlen.| +00008d00 63 00 63 76 74 64 65 63 2e 63 00 63 76 74 64 65 |c.cvtdec.c.cvtde| +00008d10 63 30 2e 63 00 63 76 74 68 65 78 2e 63 00 63 76 |c0.c.cvthex.c.cv| +00008d20 74 6f 63 74 2e 63 00 63 76 74 75 6e 73 2e 63 00 |toct.c.cvtuns.c.| +00008d30 63 76 74 75 6e 73 30 2e 63 00 70 61 64 73 74 72 |cvtuns0.c.padstr| +00008d40 2e 63 00 70 61 64 2e 63 00 73 77 72 69 74 65 63 |.c.pad.c.swritec| +00008d50 68 00 77 61 69 74 70 69 64 00 63 77 72 69 74 65 |h.waitpid.cwrite| +00008d60 00 73 74 72 32 69 6e 74 00 63 76 74 75 6e 73 00 |.str2int.cvtuns.| +00008d70 67 65 74 70 69 64 00 73 6c 65 65 70 00 73 77 72 |getpid.sleep.swr| +00008d80 69 74 65 00 70 61 64 00 73 70 61 77 6e 00 73 70 |ite.pad.spawn.sp| +00008d90 72 69 6e 74 00 63 76 74 68 65 78 00 63 76 74 75 |rint.cvthex.cvtu| +00008da0 6e 73 30 00 6b 69 6c 6c 00 63 77 72 69 74 65 73 |ns0.kill.cwrites| +00008db0 00 65 78 65 63 00 77 61 69 74 00 73 77 72 69 74 |.exec.wait.swrit| +00008dc0 65 73 00 5f 73 74 61 72 74 00 72 65 61 64 00 67 |es._start.read.g| +00008dd0 65 74 70 72 69 6f 00 63 76 74 64 65 63 30 00 66 |etprio.cvtdec0.f| +00008de0 6f 72 6b 00 6d 61 69 6e 00 67 65 74 70 70 69 64 |ork.main.getppid| +00008df0 00 70 61 64 73 74 72 00 73 65 74 70 72 69 6f 00 |.padstr.setprio.| +00008e00 63 76 74 6f 63 74 00 63 77 72 69 74 65 63 68 00 |cvtoct.cwritech.| +00008e10 67 65 74 74 69 6d 65 00 63 76 74 64 65 63 00 73 |gettime.cvtdec.s| +00008e20 74 72 6c 65 6e 00 62 6f 67 75 73 00 66 61 6b 65 |trlen.bogus.fake| +00008e30 5f 65 78 69 74 00 00 2e 73 79 6d 74 61 62 00 2e |_exit...symtab..| +00008e40 73 74 72 74 61 62 00 2e 73 68 73 74 72 74 61 62 |strtab..shstrtab| +00008e50 00 2e 74 65 78 74 00 2e 72 6f 64 61 74 61 00 2e |..text..rodata..| +00008e60 64 61 74 61 00 2e 62 73 73 00 00 00 00 00 00 00 |data..bss.......| +00008e70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00008e90 00 00 00 00 1b 00 00 00 01 00 00 00 06 00 00 00 |................| +00008ea0 00 10 00 00 74 00 00 00 07 0a 00 00 00 00 00 00 |....t...........| +00008eb0 00 00 00 00 01 00 00 00 00 00 00 00 21 00 00 00 |............!...| +00008ec0 01 00 00 00 02 00 00 00 08 1a 00 00 7c 0a 00 00 |............|...| +00008ed0 b8 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |................| +00008ee0 00 00 00 00 29 00 00 00 01 00 00 00 03 00 00 00 |....)...........| +00008ef0 00 20 00 00 74 10 00 00 00 00 00 00 00 00 00 00 |. ..t...........| +00008f00 00 00 00 00 01 00 00 00 00 00 00 00 2f 00 00 00 |............/...| +00008f10 08 00 00 00 03 00 00 00 00 20 00 00 74 10 00 00 |......... ..t...| +00008f20 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +00008f30 00 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 |................| +00008f40 00 00 00 00 74 10 00 00 60 03 00 00 06 00 00 00 |....t...`.......| +00008f50 12 00 00 00 04 00 00 00 10 00 00 00 09 00 00 00 |................| +00008f60 03 00 00 00 00 00 00 00 00 00 00 00 d4 13 00 00 |................| +00008f70 62 01 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |b...............| +00008f80 00 00 00 00 11 00 00 00 03 00 00 00 00 00 00 00 |................| +00008f90 00 00 00 00 36 15 00 00 34 00 00 00 00 00 00 00 |....6...4.......| +00008fa0 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +00008fb0 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| +00008fc0 02 00 03 00 01 00 00 00 b0 13 00 00 34 00 00 00 |............4...| +00008fd0 6c 15 00 00 00 00 00 00 34 00 20 00 02 00 28 00 |l.......4. ...(.| +00008fe0 08 00 07 00 01 00 00 00 74 00 00 00 00 10 00 00 |........t.......| +00008ff0 00 10 00 00 00 10 00 00 00 10 00 00 07 00 00 00 |................| +00009000 04 00 00 00 51 e5 74 64 00 00 00 00 00 00 00 00 |....Q.td........| +00009010 00 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 |................| +00009020 10 00 00 00 8d 4c 24 04 83 e4 f0 ff 71 fc 55 89 |.....L$.....q.U.| +00009030 e5 53 51 81 ec b0 00 00 00 89 cb c7 45 f4 00 00 |.SQ.........E...| +00009040 00 00 c7 45 f0 05 00 00 00 c6 45 ef 68 8b 03 83 |...E......E.h...| +00009050 f8 02 74 1e 83 f8 03 75 2c 8b 43 04 83 c0 08 8b |..t....u,.C.....| +00009060 00 83 ec 08 6a 0a 50 e8 ed 05 00 00 83 c4 10 89 |....j.P.........| +00009070 45 f0 8b 43 04 83 c0 04 8b 00 0f b6 00 88 45 ef |E..C..........E.| +00009080 e9 a4 00 00 00 83 ec 04 ff 33 68 04 1a 00 00 8d |.........3h.....| +00009090 85 60 ff ff ff 50 e8 49 03 00 00 83 c4 10 83 ec |.`...P.I........| +000090a0 0c 8d 85 60 ff ff ff 50 e8 00 02 00 00 83 c4 10 |...`...P........| +000090b0 c7 45 e8 00 00 00 00 eb 59 8b 03 8d 14 85 00 00 |.E......Y.......| +000090c0 00 00 8b 43 04 01 d0 8b 00 85 c0 74 12 8b 03 8d |...C.......t....| +000090d0 14 85 00 00 00 00 8b 43 04 01 d0 8b 00 eb 05 b8 |.......C........| +000090e0 1b 1a 00 00 83 ec 04 50 68 22 1a 00 00 8d 85 60 |.......Ph".....`| +000090f0 ff ff ff 50 e8 eb 02 00 00 83 c4 10 83 ec 0c 8d |...P............| +00009100 85 60 ff ff ff 50 e8 a2 01 00 00 83 c4 10 83 45 |.`...P.........E| +00009110 e8 01 8b 45 e8 3b 03 7e a0 83 ec 0c 68 26 1a 00 |...E.;.~....h&..| +00009120 00 e8 87 01 00 00 83 c4 10 0f be 45 ef 83 ec 0c |...........E....| +00009130 50 e8 bf 01 00 00 83 c4 10 c7 85 50 ff ff ff 28 |P..........P...(| +00009140 1a 00 00 c7 85 54 ff ff ff 2e 1a 00 00 c7 85 58 |.....T.........X| +00009150 ff ff ff 30 1a 00 00 c7 85 5c ff ff ff 00 00 00 |...0.....\......| +00009160 00 c7 45 e4 00 00 00 00 eb 53 83 ec 08 8d 85 50 |..E......S.....P| +00009170 ff ff ff 50 6a 13 e8 9c 00 00 00 83 c4 10 89 45 |...Pj..........E| +00009180 e0 83 7d e0 00 79 32 0f be 45 ef ff 75 e0 50 68 |..}..y2..E..u.Ph| +00009190 34 1a 00 00 8d 85 60 ff ff ff 50 e8 44 02 00 00 |4.....`...P.D...| +000091a0 83 c4 10 83 ec 0c 8d 85 60 ff ff ff 50 e8 fb 00 |........`...P...| +000091b0 00 00 83 c4 10 83 45 f4 01 83 45 e4 01 8b 45 e4 |......E...E...E.| +000091c0 3b 45 f0 7c a5 83 ec 0c 6a 00 e8 ef 01 00 00 83 |;E.|....j.......| +000091d0 c4 10 0f be 45 ef 83 ec 0c 50 e8 16 01 00 00 83 |....E....P......| +000091e0 c4 10 83 ec 0c ff 75 f4 e8 71 01 00 00 83 c4 10 |......u..q......| +000091f0 b8 2a 00 00 00 8d 65 f8 59 5b 5d 8d 61 fc c3 55 |.*....e.Y[].a..U| +00009200 89 e5 83 ec 08 83 ec 08 ff 75 08 6a 00 e8 54 01 |.........u.j..T.| +00009210 00 00 83 c4 10 c9 c3 55 89 e5 81 ec 18 01 00 00 |.......U........| +00009220 e8 49 01 00 00 89 45 f4 83 7d f4 00 74 05 8b 45 |.I....E..}..t..E| +00009230 f4 eb 57 e8 56 01 00 00 89 45 f4 83 ec 08 ff 75 |..W.V....E.....u| +00009240 0c ff 75 08 e8 2d 01 00 00 83 c4 10 ff 75 08 ff |..u..-.......u..| +00009250 75 f4 68 57 1a 00 00 8d 85 f4 fe ff ff 50 e8 81 |u.hW.........P..| +00009260 01 00 00 83 c4 10 83 ec 0c 8d 85 f4 fe ff ff 50 |...............P| +00009270 e8 38 00 00 00 83 c4 10 83 ec 0c 6a ff e8 dc 00 |.8.........j....| +00009280 00 00 83 c4 10 b8 00 00 00 00 c9 c3 55 89 e5 83 |............U...| +00009290 ec 18 8b 45 08 88 45 f4 83 ec 04 6a 01 8d 45 f4 |...E..E....j..E.| +000092a0 50 6a 00 e8 de 00 00 00 83 c4 10 c9 c3 55 89 e5 |Pj...........U..| +000092b0 83 ec 18 83 ec 0c ff 75 08 e8 0d 04 00 00 83 c4 |.......u........| +000092c0 10 89 45 f4 8b 45 f4 83 ec 04 50 ff 75 08 6a 00 |..E..E....P.u.j.| +000092d0 e8 b1 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 08 |..........U.....| +000092e0 83 ec 04 ff 75 0c ff 75 08 6a 00 e8 96 00 00 00 |....u..u.j......| +000092f0 83 c4 10 c9 c3 55 89 e5 83 ec 18 8b 45 08 88 45 |.....U......E..E| +00009300 f4 83 ec 04 6a 01 8d 45 f4 50 6a 01 e8 75 00 00 |....j..E.Pj..u..| +00009310 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 83 ec 0c ff |......U.........| +00009320 75 08 e8 a4 03 00 00 83 c4 10 89 45 f4 8b 45 f4 |u..........E..E.| +00009330 83 ec 04 50 ff 75 08 6a 01 e8 48 00 00 00 83 c4 |...P.u.j..H.....| +00009340 10 c9 c3 55 89 e5 83 ec 08 83 ec 04 ff 75 0c ff |...U.........u..| +00009350 75 08 6a 01 e8 2d 00 00 00 83 c4 10 c9 c3 b8 00 |u.j..-..........| +00009360 00 00 00 cd 80 c3 b8 01 00 00 00 cd 80 c3 b8 02 |................| +00009370 00 00 00 cd 80 c3 b8 03 00 00 00 cd 80 c3 b8 04 |................| +00009380 00 00 00 cd 80 c3 b8 05 00 00 00 cd 80 c3 b8 06 |................| +00009390 00 00 00 cd 80 c3 b8 07 00 00 00 cd 80 c3 b8 08 |................| +000093a0 00 00 00 cd 80 c3 b8 09 00 00 00 cd 80 c3 b8 0a |................| +000093b0 00 00 00 cd 80 c3 b8 0b 00 00 00 cd 80 c3 b8 0c |................| +000093c0 00 00 00 cd 80 c3 b8 ad 0b 00 00 cd 80 c3 50 e8 |..............P.| +000093d0 8a ff ff ff e8 4b fc ff ff 83 ec 0c 50 e8 7c ff |.....K......P.|.| +000093e0 ff ff eb fe 55 89 e5 83 ec 38 8d 45 0c 83 c0 04 |....U....8.E....| +000093f0 89 45 f4 e9 3f 02 00 00 80 7d f3 25 0f 85 26 02 |.E..?....}.%..&.| +00009400 00 00 c7 45 ec 00 00 00 00 c7 45 e4 20 00 00 00 |...E......E. ...| +00009410 c7 45 e8 00 00 00 00 8b 45 0c 8d 50 01 89 55 0c |.E......E..P..U.| +00009420 0f b6 00 88 45 f3 80 7d f3 2d 75 16 c7 45 ec 01 |....E..}.-u..E..| +00009430 00 00 00 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 |....E..P..U.....| +00009440 45 f3 80 7d f3 30 75 40 c7 45 e4 30 00 00 00 8b |E..}.0u@.E.0....| +00009450 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 eb 28 |E..P..U.....E..(| +00009460 8b 55 e8 89 d0 c1 e0 02 01 d0 01 c0 89 45 e8 0f |.U...........E..| +00009470 be 45 f3 83 e8 30 01 45 e8 8b 45 0c 8d 50 01 89 |.E...0.E..E..P..| +00009480 55 0c 0f b6 00 88 45 f3 80 7d f3 2f 7e 06 80 7d |U.....E..}./~..}| +00009490 f3 39 7e cc 0f be 45 f3 83 e8 63 83 f8 15 0f 87 |.9~...E...c.....| +000094a0 93 01 00 00 8b 04 85 74 1a 00 00 ff e0 8b 45 f4 |.......t......E.| +000094b0 8d 50 04 89 55 f4 8b 00 88 45 f3 0f b6 45 f3 88 |.P..U....E...E..| +000094c0 45 d0 c6 45 d1 00 83 ec 08 ff 75 e4 ff 75 ec ff |E..E......u..u..| +000094d0 75 e8 6a 01 8d 45 d0 50 ff 75 08 e8 89 04 00 00 |u.j..E.P.u......| +000094e0 83 c4 20 89 45 08 e9 4c 01 00 00 8b 45 f4 8d 50 |.. .E..L....E..P| +000094f0 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 ea |..U......P.E.P..| +00009500 01 00 00 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff |.......E.....u..| +00009510 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 |u..u..u..E.P.u..| +00009520 45 04 00 00 83 c4 20 89 45 08 e9 08 01 00 00 8b |E..... .E.......| +00009530 45 f4 8d 50 04 89 55 f4 8b 00 89 45 dc 83 ec 08 |E..P..U....E....| +00009540 ff 75 e4 ff 75 ec ff 75 e8 6a ff ff 75 dc ff 75 |.u..u..u.j..u..u| +00009550 08 e8 13 04 00 00 83 c4 20 89 45 08 e9 d6 00 00 |........ .E.....| +00009560 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 |..E..P..U......P| +00009570 8d 45 d0 50 e8 44 02 00 00 83 c4 10 89 45 e0 83 |.E.P.D.......E..| +00009580 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 |...u..u..u..u..E| +00009590 d0 50 ff 75 08 e8 cf 03 00 00 83 c4 20 89 45 08 |.P.u........ .E.| +000095a0 e9 92 00 00 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 |......E..P..U...| +000095b0 83 ec 08 50 8d 45 d0 50 e8 8a 02 00 00 83 c4 10 |...P.E.P........| +000095c0 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff |.E.....u..u..u..| +000095d0 75 e0 8d 45 d0 50 ff 75 08 e8 8b 03 00 00 83 c4 |u..E.P.u........| +000095e0 20 89 45 08 eb 51 8b 45 f4 8d 50 04 89 55 f4 8b | .E..Q.E..P..U..| +000095f0 00 83 ec 08 50 8d 45 d0 50 e8 d3 02 00 00 83 c4 |....P.E.P.......| +00009600 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 |..E.....u..u..u.| +00009610 ff 75 e0 8d 45 d0 50 ff 75 08 e8 4a 03 00 00 83 |.u..E.P.u..J....| +00009620 c4 20 89 45 08 90 eb 0f 8b 45 08 8d 50 01 89 55 |. .E.....E..P..U| +00009630 08 0f b6 55 f3 88 10 8b 45 0c 8d 50 01 89 55 0c |...U....E..P..U.| +00009640 0f b6 00 88 45 f3 80 7d f3 00 0f 85 a8 fd ff ff |....E..}........| +00009650 8b 45 08 c6 00 00 90 c9 c3 55 89 e5 53 83 ec 14 |.E.......U..S...| +00009660 8b 45 08 8b 4d 0c bb 00 00 00 00 c6 45 eb 39 c7 |.E..M.......E.9.| +00009670 45 f8 01 00 00 00 0f b6 10 80 fa 2d 75 0a c7 45 |E..........-u..E| +00009680 f8 ff ff ff ff 83 c0 01 83 f9 0a 74 2b 89 ca 83 |...........t+...| +00009690 c2 2f 88 55 eb eb 21 0f b6 10 80 fa 2f 7e 20 0f |./.U..!...../~ .| +000096a0 b6 10 38 55 eb 7c 18 0f af d9 0f b6 10 0f be d2 |..8U.|..........| +000096b0 01 da 8d 5a d0 83 c0 01 0f b6 10 84 d2 75 d8 89 |...Z.........u..| +000096c0 d8 0f af 45 f8 83 c4 14 5b 5d c3 55 89 e5 53 8b |...E....[].U..S.| +000096d0 55 08 bb 00 00 00 00 eb 03 83 c3 01 89 d0 8d 50 |U..............P| +000096e0 01 0f b6 00 84 c0 75 f1 89 d8 5b 5d c3 55 89 e5 |......u...[].U..| +000096f0 83 ec 18 8b 45 08 89 45 f4 83 7d 0c 00 79 0f 8b |....E..E..}..y..| +00009700 45 f4 8d 50 01 89 55 f4 c6 00 2d f7 5d 0c 83 ec |E..P..U...-.]...| +00009710 08 ff 75 0c ff 75 f4 e8 18 00 00 00 83 c4 10 89 |..u..u..........| +00009720 45 f4 8b 45 f4 c6 00 00 8b 55 f4 8b 45 08 29 c2 |E..E.....U..E.).| +00009730 89 d0 c9 c3 55 89 e5 83 ec 18 8b 4d 0c ba 67 66 |....U......M..gf| +00009740 66 66 89 c8 f7 ea c1 fa 02 89 c8 c1 f8 1f 29 c2 |ff............).| +00009750 89 d0 89 45 f4 83 7d f4 00 79 0e c7 45 f4 cc cc |...E..}..y..E...| +00009760 cc 0c c7 45 0c 08 00 00 00 83 7d f4 00 74 14 83 |...E......}..t..| +00009770 ec 08 ff 75 f4 ff 75 08 e8 b7 ff ff ff 83 c4 10 |...u..u.........| +00009780 89 45 08 8b 4d 0c ba 67 66 66 66 89 c8 f7 ea c1 |.E..M..gfff.....| +00009790 fa 02 89 c8 c1 f8 1f 29 c2 89 d0 c1 e0 02 01 d0 |.......)........| +000097a0 01 c0 29 c1 89 ca 89 d0 8d 48 30 8b 45 08 8d 50 |..)......H0.E..P| +000097b0 01 89 55 08 89 ca 88 10 8b 45 08 c9 c3 55 89 e5 |..U......E...U..| +000097c0 83 ec 20 c7 45 e3 30 31 32 33 c7 45 e7 34 35 36 |.. .E.0123.E.456| +000097d0 37 c7 45 eb 38 39 41 42 c7 45 ef 43 44 45 46 c6 |7.E.89AB.E.CDEF.| +000097e0 45 f3 00 c7 45 fc 00 00 00 00 c7 45 f8 00 00 00 |E...E......E....| +000097f0 00 eb 43 8b 45 0c 25 00 00 00 f0 89 45 f4 83 7d |..C.E.%.....E..}| +00009800 fc 00 75 0c 83 7d f4 00 75 06 83 7d f8 07 75 1e |..u..}..u..}..u.| +00009810 83 45 fc 01 c1 6d f4 1c 8b 45 08 8d 50 01 89 55 |.E...m...E..P..U| +00009820 08 8d 4d e3 8b 55 f4 01 ca 0f b6 12 88 10 c1 65 |..M..U.........e| +00009830 0c 04 83 45 f8 01 83 7d f8 07 7e b7 8b 45 08 c6 |...E...}..~..E..| +00009840 00 00 8b 45 fc c9 c3 55 89 e5 83 ec 10 c7 45 f8 |...E...U......E.| +00009850 00 00 00 00 8b 45 08 89 45 f4 8b 45 0c 25 00 00 |.....E..E..E.%..| +00009860 00 c0 89 45 f0 c1 6d f0 1e c7 45 fc 00 00 00 00 |...E..m...E.....| +00009870 eb 47 83 7d fc 0a 74 0c 83 7d f0 00 75 06 83 7d |.G.}..t..}..u..}| +00009880 f8 00 74 1e c7 45 f8 01 00 00 00 83 65 f0 07 8b |..t..E......e...| +00009890 45 f0 8d 48 30 8b 45 f4 8d 50 01 89 55 f4 89 ca |E..H0.E..P..U...| +000098a0 88 10 c1 65 0c 03 8b 45 0c 25 00 00 00 e0 89 45 |...e...E.%.....E| +000098b0 f0 c1 6d f0 1d 83 45 fc 01 83 7d fc 0a 7e b3 8b |..m...E...}..~..| +000098c0 45 f4 c6 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 |E.....U..E.)....| +000098d0 c3 55 89 e5 83 ec 18 8b 45 08 89 45 f4 83 ec 08 |.U......E..E....| +000098e0 ff 75 0c ff 75 f4 e8 18 00 00 00 83 c4 10 89 45 |.u..u..........E| +000098f0 f4 8b 45 f4 c6 00 00 8b 55 f4 8b 45 08 29 c2 89 |..E.....U..E.)..| +00009900 d0 c9 c3 55 89 e5 83 ec 18 8b 45 0c ba cd cc cc |...U......E.....| +00009910 cc f7 e2 89 d0 c1 e8 03 89 45 f4 83 7d f4 00 74 |.........E..}..t| +00009920 15 8b 45 f4 83 ec 08 50 ff 75 08 e8 04 fe ff ff |..E....P.u......| +00009930 83 c4 10 89 45 08 8b 4d 0c ba cd cc cc cc 89 c8 |....E..M........| +00009940 f7 e2 c1 ea 03 89 d0 c1 e0 02 01 d0 01 c0 29 c1 |..............).| +00009950 89 ca 89 d0 8d 48 30 8b 45 08 8d 50 01 89 55 08 |.....H0.E..P..U.| +00009960 89 ca 88 10 8b 45 08 c9 c3 55 89 e5 83 ec 18 83 |.....E...U......| +00009970 7d 10 00 79 11 83 ec 0c ff 75 0c e8 4b fd ff ff |}..y.....u..K...| +00009980 83 c4 10 89 45 10 8b 45 14 2b 45 10 89 45 f0 83 |....E..E.+E..E..| +00009990 7d f0 00 7e 1d 83 7d 18 00 75 17 83 ec 04 ff 75 |}..~..}..u.....u| +000099a0 1c ff 75 f0 ff 75 08 e8 5a 00 00 00 83 c4 10 89 |..u..u..Z.......| +000099b0 45 08 c7 45 f4 00 00 00 00 eb 1b 8b 55 f4 8b 45 |E..E........U..E| +000099c0 0c 8d 0c 02 8b 45 08 8d 50 01 89 55 08 0f b6 11 |.....E..P..U....| +000099d0 88 10 83 45 f4 01 8b 45 f4 3b 45 10 7c dd 83 7d |...E...E.;E.|..}| +000099e0 f0 00 7e 1d 83 7d 18 00 74 17 83 ec 04 ff 75 1c |..~..}..t.....u.| +000099f0 ff 75 f0 ff 75 08 e8 0b 00 00 00 83 c4 10 89 45 |.u..u..........E| +00009a00 08 8b 45 08 c9 c3 55 89 e5 eb 12 8b 45 08 8d 50 |..E...U.....E..P| +00009a10 01 89 55 08 8b 55 10 88 10 83 6d 0c 01 83 7d 0c |..U..U....m...}.| +00009a20 00 7f e8 8b 45 08 5d c3 75 73 65 72 48 3a 20 61 |....E.].userH: a| +00009a30 72 67 63 20 25 64 2c 20 61 72 67 73 3a 20 00 28 |rgc %d, args: .(| +00009a40 6e 75 6c 6c 29 00 20 25 73 00 0a 00 75 73 65 72 |null). %s...user| +00009a50 5a 00 5a 00 31 30 00 00 21 21 20 25 63 20 73 70 |Z.Z.10..!! %c sp| +00009a60 61 77 6e 28 29 20 66 61 69 6c 65 64 2c 20 72 65 |awn() failed, re| +00009a70 74 75 72 6e 65 64 20 25 64 0a 00 43 68 69 6c 64 |turned %d..Child| +00009a80 20 25 64 20 65 78 65 63 28 29 20 23 25 75 20 66 | %d exec() #%u f| +00009a90 61 69 6c 65 64 0a 00 00 89 14 00 00 c7 14 00 00 |ailed...........| +00009aa0 13 16 00 00 13 16 00 00 13 16 00 00 13 16 00 00 |................| +* +00009ac0 13 16 00 00 13 16 00 00 81 15 00 00 13 16 00 00 |................| +00009ad0 13 16 00 00 13 16 00 00 0b 15 00 00 13 16 00 00 |................| +00009ae0 c2 15 00 00 13 16 00 00 13 16 00 00 3d 15 00 00 |............=...| +00009af0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +0000a030 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 |................| +0000a040 03 00 01 00 00 00 00 00 04 1a 00 00 00 00 00 00 |................| +0000a050 03 00 02 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +0000a060 03 00 03 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +0000a070 03 00 04 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +0000a080 04 00 f1 ff 09 00 00 00 00 00 00 00 00 00 00 00 |................| +0000a090 04 00 f1 ff 11 00 00 00 00 00 00 00 00 00 00 00 |................| +0000a0a0 04 00 f1 ff 1a 00 00 00 00 00 00 00 00 00 00 00 |................| +0000a0b0 04 00 f1 ff 24 00 00 00 00 00 00 00 00 00 00 00 |....$...........| +0000a0c0 04 00 f1 ff 2d 00 00 00 00 00 00 00 00 00 00 00 |....-...........| +0000a0d0 04 00 f1 ff 36 00 00 00 00 00 00 00 00 00 00 00 |....6...........| +0000a0e0 04 00 f1 ff 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........| +0000a0f0 04 00 f1 ff 49 00 00 00 00 00 00 00 00 00 00 00 |....I...........| +0000a100 04 00 f1 ff 52 00 00 00 00 00 00 00 00 00 00 00 |....R...........| +0000a110 04 00 f1 ff 5b 00 00 00 00 00 00 00 00 00 00 00 |....[...........| +0000a120 04 00 f1 ff 65 00 00 00 00 00 00 00 00 00 00 00 |....e...........| +0000a130 04 00 f1 ff 6e 00 00 00 00 00 00 00 00 00 00 00 |....n...........| +0000a140 04 00 f1 ff 74 00 00 00 d1 12 00 00 21 00 00 00 |....t.......!...| +0000a150 12 00 01 00 7d 00 00 00 42 13 00 00 00 00 00 00 |....}...B.......| +0000a160 10 00 01 00 85 00 00 00 b6 12 00 00 1b 00 00 00 |................| +0000a170 12 00 01 00 8c 00 00 00 35 16 00 00 72 00 00 00 |........5...r...| +0000a180 12 00 01 00 94 00 00 00 ad 18 00 00 32 00 00 00 |............2...| +0000a190 12 00 01 00 9b 00 00 00 6a 13 00 00 00 00 00 00 |........j.......| +0000a1a0 10 00 01 00 a2 00 00 00 9a 13 00 00 00 00 00 00 |................| +0000a1b0 10 00 01 00 a8 00 00 00 1f 13 00 00 1b 00 00 00 |................| +0000a1c0 12 00 01 00 af 00 00 00 e2 19 00 00 22 00 00 00 |............"...| +0000a1d0 12 00 01 00 b3 00 00 00 f3 11 00 00 75 00 00 00 |............u...| +0000a1e0 12 00 01 00 b9 00 00 00 c0 13 00 00 75 02 00 00 |............u...| +0000a1f0 12 00 01 00 c0 00 00 00 99 17 00 00 8a 00 00 00 |................| +0000a200 12 00 01 00 c7 00 00 00 df 18 00 00 66 00 00 00 |............f...| +0000a210 12 00 01 00 86 00 00 00 62 13 00 00 00 00 00 00 |........b.......| +0000a220 10 00 01 00 cf 00 00 00 92 13 00 00 00 00 00 00 |................| +0000a230 10 00 01 00 d4 00 00 00 89 12 00 00 2d 00 00 00 |............-...| +0000a240 12 00 01 00 dc 00 00 00 52 13 00 00 00 00 00 00 |........R.......| +0000a250 10 00 01 00 e1 00 00 00 db 11 00 00 18 00 00 00 |................| +0000a260 12 00 01 00 e6 00 00 00 f2 12 00 00 2d 00 00 00 |............-...| +0000a270 12 00 01 00 ee 00 00 00 b0 13 00 00 00 00 00 00 |................| +0000a280 10 00 01 00 f5 00 00 00 5a 13 00 00 00 00 00 00 |........Z.......| +0000a290 10 00 01 00 fa 00 00 00 82 13 00 00 00 00 00 00 |................| +0000a2a0 10 00 01 00 02 01 00 00 10 17 00 00 89 00 00 00 |................| +0000a2b0 12 00 01 00 0a 01 00 00 4a 13 00 00 00 00 00 00 |........J.......| +0000a2c0 10 00 01 00 0f 01 00 00 00 10 00 00 db 01 00 00 |................| +0000a2d0 12 00 01 00 14 01 00 00 72 13 00 00 00 00 00 00 |........r.......| +0000a2e0 10 00 01 00 1c 01 00 00 45 19 00 00 9d 00 00 00 |........E.......| +0000a2f0 12 00 01 00 23 01 00 00 8a 13 00 00 00 00 00 00 |....#...........| +0000a300 10 00 01 00 2b 01 00 00 23 18 00 00 8a 00 00 00 |....+...#.......| +0000a310 12 00 01 00 32 01 00 00 68 12 00 00 21 00 00 00 |....2...h...!...| +0000a320 12 00 01 00 3b 01 00 00 7a 13 00 00 00 00 00 00 |....;...z.......| +0000a330 10 00 01 00 43 01 00 00 c9 16 00 00 47 00 00 00 |....C.......G...| +0000a340 12 00 01 00 5c 01 00 00 3a 13 00 00 00 00 00 00 |....\...:.......| +0000a350 10 00 01 00 4a 01 00 00 a7 16 00 00 22 00 00 00 |....J......."...| +0000a360 12 00 01 00 51 01 00 00 a2 13 00 00 00 00 00 00 |....Q...........| +0000a370 10 00 01 00 57 01 00 00 aa 13 00 00 00 00 00 00 |....W...........| +0000a380 10 00 01 00 00 70 72 6f 67 48 2e 63 00 75 6c 69 |.....progH.c.uli| +0000a390 62 63 2e 63 00 73 70 72 69 6e 74 2e 63 00 73 74 |bc.c.sprint.c.st| +0000a3a0 72 32 69 6e 74 2e 63 00 73 74 72 6c 65 6e 2e 63 |r2int.c.strlen.c| +0000a3b0 00 63 76 74 64 65 63 2e 63 00 63 76 74 64 65 63 |.cvtdec.c.cvtdec| +0000a3c0 30 2e 63 00 63 76 74 68 65 78 2e 63 00 63 76 74 |0.c.cvthex.c.cvt| +0000a3d0 6f 63 74 2e 63 00 63 76 74 75 6e 73 2e 63 00 63 |oct.c.cvtuns.c.c| +0000a3e0 76 74 75 6e 73 30 2e 63 00 70 61 64 73 74 72 2e |vtuns0.c.padstr.| +0000a3f0 63 00 70 61 64 2e 63 00 73 77 72 69 74 65 63 68 |c.pad.c.swritech| +0000a400 00 77 61 69 74 70 69 64 00 63 77 72 69 74 65 00 |.waitpid.cwrite.| +0000a410 73 74 72 32 69 6e 74 00 63 76 74 75 6e 73 00 67 |str2int.cvtuns.g| +0000a420 65 74 70 69 64 00 73 6c 65 65 70 00 73 77 72 69 |etpid.sleep.swri| +0000a430 74 65 00 70 61 64 00 73 70 61 77 6e 00 73 70 72 |te.pad.spawn.spr| +0000a440 69 6e 74 00 63 76 74 68 65 78 00 63 76 74 75 6e |int.cvthex.cvtun| +0000a450 73 30 00 6b 69 6c 6c 00 63 77 72 69 74 65 73 00 |s0.kill.cwrites.| +0000a460 65 78 65 63 00 77 61 69 74 00 73 77 72 69 74 65 |exec.wait.swrite| +0000a470 73 00 5f 73 74 61 72 74 00 72 65 61 64 00 67 65 |s._start.read.ge| +0000a480 74 70 72 69 6f 00 63 76 74 64 65 63 30 00 66 6f |tprio.cvtdec0.fo| +0000a490 72 6b 00 6d 61 69 6e 00 67 65 74 70 70 69 64 00 |rk.main.getppid.| +0000a4a0 70 61 64 73 74 72 00 73 65 74 70 72 69 6f 00 63 |padstr.setprio.c| +0000a4b0 76 74 6f 63 74 00 63 77 72 69 74 65 63 68 00 67 |vtoct.cwritech.g| +0000a4c0 65 74 74 69 6d 65 00 63 76 74 64 65 63 00 73 74 |ettime.cvtdec.st| +0000a4d0 72 6c 65 6e 00 62 6f 67 75 73 00 66 61 6b 65 5f |rlen.bogus.fake_| +0000a4e0 65 78 69 74 00 00 2e 73 79 6d 74 61 62 00 2e 73 |exit...symtab..s| +0000a4f0 74 72 74 61 62 00 2e 73 68 73 74 72 74 61 62 00 |trtab..shstrtab.| +0000a500 2e 74 65 78 74 00 2e 72 6f 64 61 74 61 00 2e 64 |.text..rodata..d| +0000a510 61 74 61 00 2e 62 73 73 00 00 00 00 00 00 00 00 |ata..bss........| +0000a520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +0000a540 00 00 00 00 1b 00 00 00 01 00 00 00 06 00 00 00 |................| +0000a550 00 10 00 00 74 00 00 00 04 0a 00 00 00 00 00 00 |....t...........| +0000a560 00 00 00 00 01 00 00 00 00 00 00 00 21 00 00 00 |............!...| +0000a570 01 00 00 00 02 00 00 00 04 1a 00 00 78 0a 00 00 |............x...| +0000a580 c8 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |................| +0000a590 00 00 00 00 29 00 00 00 01 00 00 00 03 00 00 00 |....)...........| +0000a5a0 00 20 00 00 74 10 00 00 00 00 00 00 00 00 00 00 |. ..t...........| +0000a5b0 00 00 00 00 01 00 00 00 00 00 00 00 2f 00 00 00 |............/...| +0000a5c0 08 00 00 00 03 00 00 00 00 20 00 00 74 10 00 00 |......... ..t...| +0000a5d0 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +0000a5e0 00 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 |................| +0000a5f0 00 00 00 00 74 10 00 00 60 03 00 00 06 00 00 00 |....t...`.......| +0000a600 12 00 00 00 04 00 00 00 10 00 00 00 09 00 00 00 |................| +0000a610 03 00 00 00 00 00 00 00 00 00 00 00 d4 13 00 00 |................| +0000a620 61 01 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |a...............| +0000a630 00 00 00 00 11 00 00 00 03 00 00 00 00 00 00 00 |................| +0000a640 00 00 00 00 35 15 00 00 34 00 00 00 00 00 00 00 |....5...4.......| +0000a650 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +0000a660 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| +0000a670 02 00 03 00 01 00 00 00 3d 15 00 00 34 00 00 00 |........=...4...| +0000a680 6c 15 00 00 00 00 00 00 34 00 20 00 02 00 28 00 |l.......4. ...(.| +0000a690 08 00 07 00 01 00 00 00 74 00 00 00 00 10 00 00 |........t.......| +0000a6a0 00 10 00 00 00 10 00 00 00 10 00 00 07 00 00 00 |................| +0000a6b0 04 00 00 00 51 e5 74 64 00 00 00 00 00 00 00 00 |....Q.td........| +0000a6c0 00 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 |................| +0000a6d0 10 00 00 00 8d 4c 24 04 83 e4 f0 ff 71 fc 55 89 |.....L$.....q.U.| +0000a6e0 e5 53 51 81 ec 90 01 00 00 89 cb c7 45 f4 05 00 |.SQ.........E...| +0000a6f0 00 00 c6 45 d3 69 c7 45 e0 05 00 00 00 c7 85 4f |...E.i.E.......O| +0000a700 ff ff ff 2a 3f 2a 00 c7 45 f0 00 00 00 00 8b 03 |...*?*..E.......| +0000a710 83 f8 02 74 29 83 f8 03 74 0b 83 f8 01 0f 84 d4 |...t)...t.......| +0000a720 00 00 00 eb 2c 8b 43 04 83 c0 08 8b 00 83 ec 08 |....,.C.........| +0000a730 6a 0a 50 e8 5e 07 00 00 83 c4 10 89 45 f4 8b 43 |j.P.^.......E..C| +0000a740 04 83 c0 04 8b 00 0f b6 00 88 45 d3 e9 a7 00 00 |..........E.....| +0000a750 00 83 ec 04 ff 33 68 94 1b 00 00 8d 85 53 ff ff |.....3h......S..| +0000a760 ff 50 e8 ba 04 00 00 83 c4 10 83 ec 0c 8d 85 53 |.P.............S| +0000a770 ff ff ff 50 e8 71 03 00 00 83 c4 10 c7 45 ec 00 |...P.q.......E..| +0000a780 00 00 00 eb 59 8b 03 8d 14 85 00 00 00 00 8b 43 |....Y..........C| +0000a790 04 01 d0 8b 00 85 c0 74 12 8b 03 8d 14 85 00 00 |.......t........| +0000a7a0 00 00 8b 43 04 01 d0 8b 00 eb 05 b8 ab 1b 00 00 |...C............| +0000a7b0 83 ec 04 50 68 b2 1b 00 00 8d 85 53 ff ff ff 50 |...Ph......S...P| +0000a7c0 e8 5c 04 00 00 83 c4 10 83 ec 0c 8d 85 53 ff ff |.\...........S..| +0000a7d0 ff 50 e8 13 03 00 00 83 c4 10 83 45 ec 01 8b 45 |.P.........E...E| +0000a7e0 ec 3b 03 7e a0 83 ec 0c 68 b6 1b 00 00 e8 f8 02 |.;.~....h.......| +0000a7f0 00 00 83 c4 10 eb 01 90 0f b6 45 d3 88 85 50 ff |..........E...P.| +0000a800 ff ff 83 ec 04 6a 01 8d 45 d3 50 6a 01 e8 b1 03 |.....j..E.Pj....| +0000a810 00 00 83 c4 10 c7 85 70 fe ff ff b8 1b 00 00 c7 |.......p........| +0000a820 85 74 fe ff ff be 1b 00 00 c7 85 78 fe ff ff c0 |.t.........x....| +0000a830 1b 00 00 c7 85 7c fe ff ff c3 1b 00 00 c7 85 80 |.....|..........| +0000a840 fe ff ff 00 00 00 00 c7 45 e8 00 00 00 00 eb 5b |........E......[| +0000a850 83 ec 08 8d 85 70 fe ff ff 50 6a 10 e8 f3 01 00 |.....p...Pj.....| +0000a860 00 83 c4 10 89 45 d4 83 7d d4 00 79 14 83 ec 0c |.....E..}..y....| +0000a870 8d 85 4f ff ff ff 50 e8 d7 02 00 00 83 c4 10 eb |..O...P.........| +0000a880 26 0f b6 45 d3 0f be c0 83 ec 0c 50 e8 a1 02 00 |&..E.......P....| +0000a890 00 83 c4 10 8b 45 f0 8d 50 01 89 55 f0 8b 55 d4 |.....E..P..U..U.| +0000a8a0 89 94 85 84 fe ff ff 83 45 e8 01 8b 45 e8 3b 45 |........E...E.;E| +0000a8b0 f4 7c 9d 8b 45 e0 69 c0 e8 03 00 00 83 ec 0c 50 |.|..E.i........P| +0000a8c0 e8 36 03 00 00 83 c4 10 8b 85 88 fe ff ff 83 ec |.6..............| +0000a8d0 0c 50 e8 1c 03 00 00 83 c4 10 89 45 dc 83 7d dc |.P.........E..}.| +0000a8e0 00 74 45 8b 95 88 fe ff ff 0f b6 45 d3 0f be c0 |.tE........E....| +0000a8f0 83 ec 0c ff 75 dc 52 50 68 c5 1b 00 00 8d 85 53 |....u.RPh......S| +0000a900 ff ff ff 50 e8 18 03 00 00 83 c4 20 83 ec 0c 8d |...P....... ....| +0000a910 85 53 ff ff ff 50 e8 cf 01 00 00 83 c4 10 c7 85 |.S...P..........| +0000a920 88 fe ff ff d6 ff ff ff 8b 85 90 fe ff ff 83 ec |................| +0000a930 0c 50 e8 bc 02 00 00 83 c4 10 89 45 dc 83 7d dc |.P.........E..}.| +0000a940 00 74 45 8b 95 90 fe ff ff 0f b6 45 d3 0f be c0 |.tE........E....| +0000a950 83 ec 0c ff 75 dc 52 50 68 c5 1b 00 00 8d 85 53 |....u.RPh......S| +0000a960 ff ff ff 50 e8 b8 02 00 00 83 c4 20 83 ec 0c 8d |...P....... ....| +0000a970 85 53 ff ff ff 50 e8 6f 01 00 00 83 c4 10 c7 85 |.S...P.o........| +0000a980 90 fe ff ff d6 ff ff ff 83 ec 08 6a 00 6a 00 e8 |...........j.j..| +0000a990 0f 02 00 00 83 c4 10 89 45 d8 83 7d d8 fc 74 7f |........E..}..t.| +0000a9a0 c7 45 e4 00 00 00 00 eb 54 8b 45 e4 8b 94 85 84 |.E......T.E.....| +0000a9b0 fe ff ff 8b 45 d8 39 c2 75 3f 8b 45 e4 8b 94 85 |....E.9.u?.E....| +0000a9c0 84 fe ff ff 0f b6 45 d3 0f be c0 83 ec 0c 52 ff |......E.......R.| +0000a9d0 75 e4 50 68 e0 1b 00 00 8d 85 53 ff ff ff 50 e8 |u.Ph......S...P.| +0000a9e0 3d 02 00 00 83 c4 20 83 ec 0c 8d 85 53 ff ff ff |=..... .....S...| +0000a9f0 50 e8 f4 00 00 00 83 c4 10 83 45 e4 01 8b 45 e4 |P.........E...E.| +0000aa00 3b 45 f4 7c a4 8b 45 e0 69 c0 e8 03 00 00 83 ec |;E.|..E.i.......| +0000aa10 0c 50 e8 e4 01 00 00 83 c4 10 e9 69 ff ff ff 90 |.P.........i....| +0000aa20 83 ec 0c 6a 00 e8 71 01 00 00 83 c4 10 b8 2a 00 |...j..q.......*.| +0000aa30 00 00 8d 65 f8 59 5b 5d 8d 61 fc c3 55 89 e5 83 |...e.Y[].a..U...| +0000aa40 ec 08 83 ec 08 ff 75 08 6a 00 e8 54 01 00 00 83 |......u.j..T....| +0000aa50 c4 10 c9 c3 55 89 e5 81 ec 18 01 00 00 e8 49 01 |....U.........I.| +0000aa60 00 00 89 45 f4 83 7d f4 00 74 05 8b 45 f4 eb 57 |...E..}..t..E..W| +0000aa70 e8 56 01 00 00 89 45 f4 83 ec 08 ff 75 0c ff 75 |.V....E.....u..u| +0000aa80 08 e8 2d 01 00 00 83 c4 10 ff 75 08 ff 75 f4 68 |..-.......u..u.h| +0000aa90 f6 1b 00 00 8d 85 f4 fe ff ff 50 e8 81 01 00 00 |..........P.....| +0000aaa0 83 c4 10 83 ec 0c 8d 85 f4 fe ff ff 50 e8 38 00 |............P.8.| +0000aab0 00 00 83 c4 10 83 ec 0c 6a ff e8 dc 00 00 00 83 |........j.......| +0000aac0 c4 10 b8 00 00 00 00 c9 c3 55 89 e5 83 ec 18 8b |.........U......| +0000aad0 45 08 88 45 f4 83 ec 04 6a 01 8d 45 f4 50 6a 00 |E..E....j..E.Pj.| +0000aae0 e8 de 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 |..........U.....| +0000aaf0 83 ec 0c ff 75 08 e8 0d 04 00 00 83 c4 10 89 45 |....u..........E| +0000ab00 f4 8b 45 f4 83 ec 04 50 ff 75 08 6a 00 e8 b1 00 |..E....P.u.j....| +0000ab10 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 08 83 ec 04 |.......U........| +0000ab20 ff 75 0c ff 75 08 6a 00 e8 96 00 00 00 83 c4 10 |.u..u.j.........| +0000ab30 c9 c3 55 89 e5 83 ec 18 8b 45 08 88 45 f4 83 ec |..U......E..E...| +0000ab40 04 6a 01 8d 45 f4 50 6a 01 e8 75 00 00 00 83 c4 |.j..E.Pj..u.....| +0000ab50 10 c9 c3 55 89 e5 83 ec 18 83 ec 0c ff 75 08 e8 |...U.........u..| +0000ab60 a4 03 00 00 83 c4 10 89 45 f4 8b 45 f4 83 ec 04 |........E..E....| +0000ab70 50 ff 75 08 6a 01 e8 48 00 00 00 83 c4 10 c9 c3 |P.u.j..H........| +0000ab80 55 89 e5 83 ec 08 83 ec 04 ff 75 0c ff 75 08 6a |U.........u..u.j| +0000ab90 01 e8 2d 00 00 00 83 c4 10 c9 c3 b8 00 00 00 00 |..-.............| +0000aba0 cd 80 c3 b8 01 00 00 00 cd 80 c3 b8 02 00 00 00 |................| +0000abb0 cd 80 c3 b8 03 00 00 00 cd 80 c3 b8 04 00 00 00 |................| +0000abc0 cd 80 c3 b8 05 00 00 00 cd 80 c3 b8 06 00 00 00 |................| +0000abd0 cd 80 c3 b8 07 00 00 00 cd 80 c3 b8 08 00 00 00 |................| +0000abe0 cd 80 c3 b8 09 00 00 00 cd 80 c3 b8 0a 00 00 00 |................| +0000abf0 cd 80 c3 b8 0b 00 00 00 cd 80 c3 b8 0c 00 00 00 |................| +0000ac00 cd 80 c3 b8 ad 0b 00 00 cd 80 c3 50 e8 8a ff ff |...........P....| +0000ac10 ff e8 be fa ff ff 83 ec 0c 50 e8 7c ff ff ff eb |.........P.|....| +0000ac20 fe 55 89 e5 83 ec 38 8d 45 0c 83 c0 04 89 45 f4 |.U....8.E.....E.| +0000ac30 e9 3f 02 00 00 80 7d f3 25 0f 85 26 02 00 00 c7 |.?....}.%..&....| +0000ac40 45 ec 00 00 00 00 c7 45 e4 20 00 00 00 c7 45 e8 |E......E. ....E.| +0000ac50 00 00 00 00 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 |.....E..P..U....| +0000ac60 88 45 f3 80 7d f3 2d 75 16 c7 45 ec 01 00 00 00 |.E..}.-u..E.....| +0000ac70 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 |.E..P..U.....E..| +0000ac80 7d f3 30 75 40 c7 45 e4 30 00 00 00 8b 45 0c 8d |}.0u@.E.0....E..| +0000ac90 50 01 89 55 0c 0f b6 00 88 45 f3 eb 28 8b 55 e8 |P..U.....E..(.U.| +0000aca0 89 d0 c1 e0 02 01 d0 01 c0 89 45 e8 0f be 45 f3 |..........E...E.| +0000acb0 83 e8 30 01 45 e8 8b 45 0c 8d 50 01 89 55 0c 0f |..0.E..E..P..U..| +0000acc0 b6 00 88 45 f3 80 7d f3 2f 7e 06 80 7d f3 39 7e |...E..}./~..}.9~| +0000acd0 cc 0f be 45 f3 83 e8 63 83 f8 15 0f 87 93 01 00 |...E...c........| +0000ace0 00 8b 04 85 14 1c 00 00 ff e0 8b 45 f4 8d 50 04 |...........E..P.| +0000acf0 89 55 f4 8b 00 88 45 f3 0f b6 45 f3 88 45 d0 c6 |.U....E...E..E..| +0000ad00 45 d1 00 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 6a |E......u..u..u.j| +0000ad10 01 8d 45 d0 50 ff 75 08 e8 89 04 00 00 83 c4 20 |..E.P.u........ | +0000ad20 89 45 08 e9 4c 01 00 00 8b 45 f4 8d 50 04 89 55 |.E..L....E..P..U| +0000ad30 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 ea 01 00 00 |......P.E.P.....| +0000ad40 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff |....E.....u..u..| +0000ad50 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 45 04 00 |u..u..E.P.u..E..| +0000ad60 00 83 c4 20 89 45 08 e9 08 01 00 00 8b 45 f4 8d |... .E.......E..| +0000ad70 50 04 89 55 f4 8b 00 89 45 dc 83 ec 08 ff 75 e4 |P..U....E.....u.| +0000ad80 ff 75 ec ff 75 e8 6a ff ff 75 dc ff 75 08 e8 13 |.u..u.j..u..u...| +0000ad90 04 00 00 83 c4 20 89 45 08 e9 d6 00 00 00 8b 45 |..... .E.......E| +0000ada0 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 |..P..U......P.E.| +0000adb0 50 e8 44 02 00 00 83 c4 10 89 45 e0 83 ec 08 ff |P.D.......E.....| +0000adc0 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff |u..u..u..u..E.P.| +0000add0 75 08 e8 cf 03 00 00 83 c4 20 89 45 08 e9 92 00 |u........ .E....| +0000ade0 00 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 |...E..P..U......| +0000adf0 50 8d 45 d0 50 e8 8a 02 00 00 83 c4 10 89 45 e0 |P.E.P.........E.| +0000ae00 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d |....u..u..u..u..| +0000ae10 45 d0 50 ff 75 08 e8 8b 03 00 00 83 c4 20 89 45 |E.P.u........ .E| +0000ae20 08 eb 51 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec |..Q.E..P..U.....| +0000ae30 08 50 8d 45 d0 50 e8 d3 02 00 00 83 c4 10 89 45 |.P.E.P.........E| +0000ae40 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 |.....u..u..u..u.| +0000ae50 8d 45 d0 50 ff 75 08 e8 4a 03 00 00 83 c4 20 89 |.E.P.u..J..... .| +0000ae60 45 08 90 eb 0f 8b 45 08 8d 50 01 89 55 08 0f b6 |E.....E..P..U...| +0000ae70 55 f3 88 10 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 |U....E..P..U....| +0000ae80 88 45 f3 80 7d f3 00 0f 85 a8 fd ff ff 8b 45 08 |.E..}.........E.| +0000ae90 c6 00 00 90 c9 c3 55 89 e5 53 83 ec 14 8b 45 08 |......U..S....E.| +0000aea0 8b 4d 0c bb 00 00 00 00 c6 45 eb 39 c7 45 f8 01 |.M.......E.9.E..| +0000aeb0 00 00 00 0f b6 10 80 fa 2d 75 0a c7 45 f8 ff ff |........-u..E...| +0000aec0 ff ff 83 c0 01 83 f9 0a 74 2b 89 ca 83 c2 2f 88 |........t+..../.| +0000aed0 55 eb eb 21 0f b6 10 80 fa 2f 7e 20 0f b6 10 38 |U..!...../~ ...8| +0000aee0 55 eb 7c 18 0f af d9 0f b6 10 0f be d2 01 da 8d |U.|.............| +0000aef0 5a d0 83 c0 01 0f b6 10 84 d2 75 d8 89 d8 0f af |Z.........u.....| +0000af00 45 f8 83 c4 14 5b 5d c3 55 89 e5 53 8b 55 08 bb |E....[].U..S.U..| +0000af10 00 00 00 00 eb 03 83 c3 01 89 d0 8d 50 01 0f b6 |............P...| +0000af20 00 84 c0 75 f1 89 d8 5b 5d c3 55 89 e5 83 ec 18 |...u...[].U.....| +0000af30 8b 45 08 89 45 f4 83 7d 0c 00 79 0f 8b 45 f4 8d |.E..E..}..y..E..| +0000af40 50 01 89 55 f4 c6 00 2d f7 5d 0c 83 ec 08 ff 75 |P..U...-.].....u| +0000af50 0c ff 75 f4 e8 18 00 00 00 83 c4 10 89 45 f4 8b |..u..........E..| +0000af60 45 f4 c6 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 |E.....U..E.)....| +0000af70 c3 55 89 e5 83 ec 18 8b 4d 0c ba 67 66 66 66 89 |.U......M..gfff.| +0000af80 c8 f7 ea c1 fa 02 89 c8 c1 f8 1f 29 c2 89 d0 89 |...........)....| +0000af90 45 f4 83 7d f4 00 79 0e c7 45 f4 cc cc cc 0c c7 |E..}..y..E......| +0000afa0 45 0c 08 00 00 00 83 7d f4 00 74 14 83 ec 08 ff |E......}..t.....| +0000afb0 75 f4 ff 75 08 e8 b7 ff ff ff 83 c4 10 89 45 08 |u..u..........E.| +0000afc0 8b 4d 0c ba 67 66 66 66 89 c8 f7 ea c1 fa 02 89 |.M..gfff........| +0000afd0 c8 c1 f8 1f 29 c2 89 d0 c1 e0 02 01 d0 01 c0 29 |....)..........)| +0000afe0 c1 89 ca 89 d0 8d 48 30 8b 45 08 8d 50 01 89 55 |......H0.E..P..U| +0000aff0 08 89 ca 88 10 8b 45 08 c9 c3 55 89 e5 83 ec 20 |......E...U.... | +0000b000 c7 45 e3 30 31 32 33 c7 45 e7 34 35 36 37 c7 45 |.E.0123.E.4567.E| +0000b010 eb 38 39 41 42 c7 45 ef 43 44 45 46 c6 45 f3 00 |.89AB.E.CDEF.E..| +0000b020 c7 45 fc 00 00 00 00 c7 45 f8 00 00 00 00 eb 43 |.E......E......C| +0000b030 8b 45 0c 25 00 00 00 f0 89 45 f4 83 7d fc 00 75 |.E.%.....E..}..u| +0000b040 0c 83 7d f4 00 75 06 83 7d f8 07 75 1e 83 45 fc |..}..u..}..u..E.| +0000b050 01 c1 6d f4 1c 8b 45 08 8d 50 01 89 55 08 8d 4d |..m...E..P..U..M| +0000b060 e3 8b 55 f4 01 ca 0f b6 12 88 10 c1 65 0c 04 83 |..U.........e...| +0000b070 45 f8 01 83 7d f8 07 7e b7 8b 45 08 c6 00 00 8b |E...}..~..E.....| +0000b080 45 fc c9 c3 55 89 e5 83 ec 10 c7 45 f8 00 00 00 |E...U......E....| +0000b090 00 8b 45 08 89 45 f4 8b 45 0c 25 00 00 00 c0 89 |..E..E..E.%.....| +0000b0a0 45 f0 c1 6d f0 1e c7 45 fc 00 00 00 00 eb 47 83 |E..m...E......G.| +0000b0b0 7d fc 0a 74 0c 83 7d f0 00 75 06 83 7d f8 00 74 |}..t..}..u..}..t| +0000b0c0 1e c7 45 f8 01 00 00 00 83 65 f0 07 8b 45 f0 8d |..E......e...E..| +0000b0d0 48 30 8b 45 f4 8d 50 01 89 55 f4 89 ca 88 10 c1 |H0.E..P..U......| +0000b0e0 65 0c 03 8b 45 0c 25 00 00 00 e0 89 45 f0 c1 6d |e...E.%.....E..m| +0000b0f0 f0 1d 83 45 fc 01 83 7d fc 0a 7e b3 8b 45 f4 c6 |...E...}..~..E..| +0000b100 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 |...U..E.).....U.| +0000b110 e5 83 ec 18 8b 45 08 89 45 f4 83 ec 08 ff 75 0c |.....E..E.....u.| +0000b120 ff 75 f4 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 |.u..........E..E| +0000b130 f4 c6 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 |.....U..E.).....| +0000b140 55 89 e5 83 ec 18 8b 45 0c ba cd cc cc cc f7 e2 |U......E........| +0000b150 89 d0 c1 e8 03 89 45 f4 83 7d f4 00 74 15 8b 45 |......E..}..t..E| +0000b160 f4 83 ec 08 50 ff 75 08 e8 04 fe ff ff 83 c4 10 |....P.u.........| +0000b170 89 45 08 8b 4d 0c ba cd cc cc cc 89 c8 f7 e2 c1 |.E..M...........| +0000b180 ea 03 89 d0 c1 e0 02 01 d0 01 c0 29 c1 89 ca 89 |...........)....| +0000b190 d0 8d 48 30 8b 45 08 8d 50 01 89 55 08 89 ca 88 |..H0.E..P..U....| +0000b1a0 10 8b 45 08 c9 c3 55 89 e5 83 ec 18 83 7d 10 00 |..E...U......}..| +0000b1b0 79 11 83 ec 0c ff 75 0c e8 4b fd ff ff 83 c4 10 |y.....u..K......| +0000b1c0 89 45 10 8b 45 14 2b 45 10 89 45 f0 83 7d f0 00 |.E..E.+E..E..}..| +0000b1d0 7e 1d 83 7d 18 00 75 17 83 ec 04 ff 75 1c ff 75 |~..}..u.....u..u| +0000b1e0 f0 ff 75 08 e8 5a 00 00 00 83 c4 10 89 45 08 c7 |..u..Z.......E..| +0000b1f0 45 f4 00 00 00 00 eb 1b 8b 55 f4 8b 45 0c 8d 0c |E........U..E...| +0000b200 02 8b 45 08 8d 50 01 89 55 08 0f b6 11 88 10 83 |..E..P..U.......| +0000b210 45 f4 01 8b 45 f4 3b 45 10 7c dd 83 7d f0 00 7e |E...E.;E.|..}..~| +0000b220 1d 83 7d 18 00 74 17 83 ec 04 ff 75 1c ff 75 f0 |..}..t.....u..u.| +0000b230 ff 75 08 e8 0b 00 00 00 83 c4 10 89 45 08 8b 45 |.u..........E..E| +0000b240 08 c9 c3 55 89 e5 eb 12 8b 45 08 8d 50 01 89 55 |...U.....E..P..U| +0000b250 08 8b 55 10 88 10 83 6d 0c 01 83 7d 0c 00 7f e8 |..U....m...}....| +0000b260 8b 45 08 5d c3 00 00 00 75 73 65 72 49 3a 20 61 |.E.]....userI: a| +0000b270 72 67 63 20 25 64 2c 20 61 72 67 73 3a 20 00 28 |rgc %d, args: .(| +0000b280 6e 75 6c 6c 29 00 20 25 73 00 0a 00 75 73 65 72 |null). %s...user| +0000b290 57 00 57 00 31 30 00 35 00 21 21 20 25 63 3a 20 |W.W.10.5.!! %c: | +0000b2a0 6b 69 6c 6c 28 25 64 29 20 73 74 61 74 75 73 20 |kill(%d) status | +0000b2b0 25 64 0a 00 3d 3d 20 25 63 3a 20 63 68 69 6c 64 |%d..== %c: child| +0000b2c0 20 25 64 20 28 25 64 29 0a 00 43 68 69 6c 64 20 | %d (%d)..Child | +0000b2d0 25 64 20 65 78 65 63 28 29 20 23 25 75 20 66 61 |%d exec() #%u fa| +0000b2e0 69 6c 65 64 0a 00 00 00 16 16 00 00 54 16 00 00 |iled........T...| +0000b2f0 a0 17 00 00 a0 17 00 00 a0 17 00 00 a0 17 00 00 |................| +* +0000b310 a0 17 00 00 a0 17 00 00 0e 17 00 00 a0 17 00 00 |................| +0000b320 a0 17 00 00 a0 17 00 00 98 16 00 00 a0 17 00 00 |................| +0000b330 4f 17 00 00 a0 17 00 00 a0 17 00 00 ca 16 00 00 |O...............| +0000b340 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +0000b6e0 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 |................| +0000b6f0 03 00 01 00 00 00 00 00 94 1b 00 00 00 00 00 00 |................| +0000b700 03 00 02 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +0000b710 03 00 03 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +0000b720 03 00 04 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +0000b730 04 00 f1 ff 09 00 00 00 00 00 00 00 00 00 00 00 |................| +0000b740 04 00 f1 ff 11 00 00 00 00 00 00 00 00 00 00 00 |................| +0000b750 04 00 f1 ff 1a 00 00 00 00 00 00 00 00 00 00 00 |................| +0000b760 04 00 f1 ff 24 00 00 00 00 00 00 00 00 00 00 00 |....$...........| +0000b770 04 00 f1 ff 2d 00 00 00 00 00 00 00 00 00 00 00 |....-...........| +0000b780 04 00 f1 ff 36 00 00 00 00 00 00 00 00 00 00 00 |....6...........| +0000b790 04 00 f1 ff 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........| +0000b7a0 04 00 f1 ff 49 00 00 00 00 00 00 00 00 00 00 00 |....I...........| +0000b7b0 04 00 f1 ff 52 00 00 00 00 00 00 00 00 00 00 00 |....R...........| +0000b7c0 04 00 f1 ff 5b 00 00 00 00 00 00 00 00 00 00 00 |....[...........| +0000b7d0 04 00 f1 ff 65 00 00 00 00 00 00 00 00 00 00 00 |....e...........| +0000b7e0 04 00 f1 ff 6e 00 00 00 00 00 00 00 00 00 00 00 |....n...........| +0000b7f0 04 00 f1 ff 74 00 00 00 5e 14 00 00 21 00 00 00 |....t...^...!...| +0000b800 12 00 01 00 7d 00 00 00 cf 14 00 00 00 00 00 00 |....}...........| +0000b810 10 00 01 00 85 00 00 00 43 14 00 00 1b 00 00 00 |........C.......| +0000b820 12 00 01 00 8c 00 00 00 c2 17 00 00 72 00 00 00 |............r...| +0000b830 12 00 01 00 94 00 00 00 3a 1a 00 00 32 00 00 00 |........:...2...| +0000b840 12 00 01 00 9b 00 00 00 f7 14 00 00 00 00 00 00 |................| +0000b850 10 00 01 00 a2 00 00 00 27 15 00 00 00 00 00 00 |........'.......| +0000b860 10 00 01 00 a8 00 00 00 ac 14 00 00 1b 00 00 00 |................| +0000b870 12 00 01 00 af 00 00 00 6f 1b 00 00 22 00 00 00 |........o..."...| +0000b880 12 00 01 00 b3 00 00 00 80 13 00 00 75 00 00 00 |............u...| +0000b890 12 00 01 00 b9 00 00 00 4d 15 00 00 75 02 00 00 |........M...u...| +0000b8a0 12 00 01 00 c0 00 00 00 26 19 00 00 8a 00 00 00 |........&.......| +0000b8b0 12 00 01 00 c7 00 00 00 6c 1a 00 00 66 00 00 00 |........l...f...| +0000b8c0 12 00 01 00 86 00 00 00 ef 14 00 00 00 00 00 00 |................| +0000b8d0 10 00 01 00 cf 00 00 00 1f 15 00 00 00 00 00 00 |................| +0000b8e0 10 00 01 00 d4 00 00 00 16 14 00 00 2d 00 00 00 |............-...| +0000b8f0 12 00 01 00 dc 00 00 00 df 14 00 00 00 00 00 00 |................| +0000b900 10 00 01 00 e1 00 00 00 68 13 00 00 18 00 00 00 |........h.......| +0000b910 12 00 01 00 e6 00 00 00 7f 14 00 00 2d 00 00 00 |............-...| +0000b920 12 00 01 00 ee 00 00 00 3d 15 00 00 00 00 00 00 |........=.......| +0000b930 10 00 01 00 f5 00 00 00 e7 14 00 00 00 00 00 00 |................| +0000b940 10 00 01 00 fa 00 00 00 0f 15 00 00 00 00 00 00 |................| +0000b950 10 00 01 00 02 01 00 00 9d 18 00 00 89 00 00 00 |................| +0000b960 12 00 01 00 0a 01 00 00 d7 14 00 00 00 00 00 00 |................| +0000b970 10 00 01 00 0f 01 00 00 00 10 00 00 68 03 00 00 |............h...| +0000b980 12 00 01 00 14 01 00 00 ff 14 00 00 00 00 00 00 |................| +0000b990 10 00 01 00 1c 01 00 00 d2 1a 00 00 9d 00 00 00 |................| +0000b9a0 12 00 01 00 23 01 00 00 17 15 00 00 00 00 00 00 |....#...........| +0000b9b0 10 00 01 00 2b 01 00 00 b0 19 00 00 8a 00 00 00 |....+...........| +0000b9c0 12 00 01 00 32 01 00 00 f5 13 00 00 21 00 00 00 |....2.......!...| +0000b9d0 12 00 01 00 3b 01 00 00 07 15 00 00 00 00 00 00 |....;...........| +0000b9e0 10 00 01 00 43 01 00 00 56 18 00 00 47 00 00 00 |....C...V...G...| +0000b9f0 12 00 01 00 5c 01 00 00 c7 14 00 00 00 00 00 00 |....\...........| +0000ba00 10 00 01 00 4a 01 00 00 34 18 00 00 22 00 00 00 |....J...4..."...| +0000ba10 12 00 01 00 51 01 00 00 2f 15 00 00 00 00 00 00 |....Q.../.......| +0000ba20 10 00 01 00 57 01 00 00 37 15 00 00 00 00 00 00 |....W...7.......| +0000ba30 10 00 01 00 00 70 72 6f 67 49 2e 63 00 75 6c 69 |.....progI.c.uli| +0000ba40 62 63 2e 63 00 73 70 72 69 6e 74 2e 63 00 73 74 |bc.c.sprint.c.st| +0000ba50 72 32 69 6e 74 2e 63 00 73 74 72 6c 65 6e 2e 63 |r2int.c.strlen.c| +0000ba60 00 63 76 74 64 65 63 2e 63 00 63 76 74 64 65 63 |.cvtdec.c.cvtdec| +0000ba70 30 2e 63 00 63 76 74 68 65 78 2e 63 00 63 76 74 |0.c.cvthex.c.cvt| +0000ba80 6f 63 74 2e 63 00 63 76 74 75 6e 73 2e 63 00 63 |oct.c.cvtuns.c.c| +0000ba90 76 74 75 6e 73 30 2e 63 00 70 61 64 73 74 72 2e |vtuns0.c.padstr.| +0000baa0 63 00 70 61 64 2e 63 00 73 77 72 69 74 65 63 68 |c.pad.c.swritech| +0000bab0 00 77 61 69 74 70 69 64 00 63 77 72 69 74 65 00 |.waitpid.cwrite.| +0000bac0 73 74 72 32 69 6e 74 00 63 76 74 75 6e 73 00 67 |str2int.cvtuns.g| +0000bad0 65 74 70 69 64 00 73 6c 65 65 70 00 73 77 72 69 |etpid.sleep.swri| +0000bae0 74 65 00 70 61 64 00 73 70 61 77 6e 00 73 70 72 |te.pad.spawn.spr| +0000baf0 69 6e 74 00 63 76 74 68 65 78 00 63 76 74 75 6e |int.cvthex.cvtun| +0000bb00 73 30 00 6b 69 6c 6c 00 63 77 72 69 74 65 73 00 |s0.kill.cwrites.| +0000bb10 65 78 65 63 00 77 61 69 74 00 73 77 72 69 74 65 |exec.wait.swrite| +0000bb20 73 00 5f 73 74 61 72 74 00 72 65 61 64 00 67 65 |s._start.read.ge| +0000bb30 74 70 72 69 6f 00 63 76 74 64 65 63 30 00 66 6f |tprio.cvtdec0.fo| +0000bb40 72 6b 00 6d 61 69 6e 00 67 65 74 70 70 69 64 00 |rk.main.getppid.| +0000bb50 70 61 64 73 74 72 00 73 65 74 70 72 69 6f 00 63 |padstr.setprio.c| +0000bb60 76 74 6f 63 74 00 63 77 72 69 74 65 63 68 00 67 |vtoct.cwritech.g| +0000bb70 65 74 74 69 6d 65 00 63 76 74 64 65 63 00 73 74 |ettime.cvtdec.st| +0000bb80 72 6c 65 6e 00 62 6f 67 75 73 00 66 61 6b 65 5f |rlen.bogus.fake_| +0000bb90 65 78 69 74 00 00 2e 73 79 6d 74 61 62 00 2e 73 |exit...symtab..s| +0000bba0 74 72 74 61 62 00 2e 73 68 73 74 72 74 61 62 00 |trtab..shstrtab.| +0000bbb0 2e 74 65 78 74 00 2e 72 6f 64 61 74 61 00 2e 64 |.text..rodata..d| +0000bbc0 61 74 61 00 2e 62 73 73 00 00 00 00 00 00 00 00 |ata..bss........| +0000bbd0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +0000bbf0 00 00 00 00 1b 00 00 00 01 00 00 00 06 00 00 00 |................| +0000bc00 00 10 00 00 74 00 00 00 91 0b 00 00 00 00 00 00 |....t...........| +0000bc10 00 00 00 00 01 00 00 00 00 00 00 00 21 00 00 00 |............!...| +0000bc20 01 00 00 00 02 00 00 00 94 1b 00 00 08 0c 00 00 |................| +0000bc30 d8 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |................| +0000bc40 00 00 00 00 29 00 00 00 01 00 00 00 03 00 00 00 |....)...........| +0000bc50 00 20 00 00 74 10 00 00 00 00 00 00 00 00 00 00 |. ..t...........| +0000bc60 00 00 00 00 01 00 00 00 00 00 00 00 2f 00 00 00 |............/...| +0000bc70 08 00 00 00 03 00 00 00 00 20 00 00 74 10 00 00 |......... ..t...| +0000bc80 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +0000bc90 00 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 |................| +0000bca0 00 00 00 00 74 10 00 00 60 03 00 00 06 00 00 00 |....t...`.......| +0000bcb0 12 00 00 00 04 00 00 00 10 00 00 00 09 00 00 00 |................| +0000bcc0 03 00 00 00 00 00 00 00 00 00 00 00 d4 13 00 00 |................| +0000bcd0 61 01 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |a...............| +0000bce0 00 00 00 00 11 00 00 00 03 00 00 00 00 00 00 00 |................| +0000bcf0 00 00 00 00 35 15 00 00 34 00 00 00 00 00 00 00 |....5...4.......| +0000bd00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +0000bd10 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| +0000bd20 02 00 03 00 01 00 00 00 85 13 00 00 34 00 00 00 |............4...| +0000bd30 6c 15 00 00 00 00 00 00 34 00 20 00 02 00 28 00 |l.......4. ...(.| +0000bd40 08 00 07 00 01 00 00 00 74 00 00 00 00 10 00 00 |........t.......| +0000bd50 00 10 00 00 00 10 00 00 00 10 00 00 07 00 00 00 |................| +0000bd60 04 00 00 00 51 e5 74 64 00 00 00 00 00 00 00 00 |....Q.td........| +0000bd70 00 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 |................| +0000bd80 10 00 00 00 8d 4c 24 04 83 e4 f0 ff 71 fc 55 89 |.....L$.....q.U.| +0000bd90 e5 53 51 81 ec b0 00 00 00 89 cb c7 45 f4 32 00 |.SQ.........E.2.| +0000bda0 00 00 c6 45 e7 6a 8b 03 83 f8 02 74 1e 83 f8 03 |...E.j.....t....| +0000bdb0 75 2c 8b 43 04 83 c0 08 8b 00 83 ec 08 6a 0a 50 |u,.C.........j.P| +0000bdc0 e8 c9 05 00 00 83 c4 10 89 45 f4 8b 43 04 83 c0 |.........E..C...| +0000bdd0 04 8b 00 0f b6 00 88 45 e7 e9 a4 00 00 00 83 ec |.......E........| +0000bde0 04 ff 33 68 dc 19 00 00 8d 85 67 ff ff ff 50 e8 |..3h......g...P.| +0000bdf0 25 03 00 00 83 c4 10 83 ec 0c 8d 85 67 ff ff ff |%...........g...| +0000be00 50 e8 dc 01 00 00 83 c4 10 c7 45 f0 00 00 00 00 |P.........E.....| +0000be10 eb 59 8b 03 8d 14 85 00 00 00 00 8b 43 04 01 d0 |.Y..........C...| +0000be20 8b 00 85 c0 74 12 8b 03 8d 14 85 00 00 00 00 8b |....t...........| +0000be30 43 04 01 d0 8b 00 eb 05 b8 f3 19 00 00 83 ec 04 |C...............| +0000be40 50 68 fa 19 00 00 8d 85 67 ff ff ff 50 e8 c7 02 |Ph......g...P...| +0000be50 00 00 83 c4 10 83 ec 0c 8d 85 67 ff ff ff 50 e8 |..........g...P.| +0000be60 7e 01 00 00 83 c4 10 83 45 f0 01 8b 45 f0 3b 03 |~.......E...E.;.| +0000be70 7e a0 83 ec 0c 68 fe 19 00 00 e8 63 01 00 00 83 |~....h.....c....| +0000be80 c4 10 83 ec 04 6a 01 8d 45 e7 50 6a 01 e8 29 02 |.....j..E.Pj..).| +0000be90 00 00 83 c4 10 c7 85 54 ff ff ff 00 1a 00 00 c7 |.......T........| +0000bea0 85 58 ff ff ff 06 1a 00 00 c7 85 5c ff ff ff 08 |.X.........\....| +0000beb0 1a 00 00 c7 85 60 ff ff ff 00 00 00 00 c7 45 ec |.....`........E.| +0000bec0 00 00 00 00 eb 4a 83 ec 08 8d 85 54 ff ff ff 50 |.....J.....T...P| +0000bed0 6a 12 e8 75 00 00 00 83 c4 10 89 45 e8 83 7d e8 |j..u.......E..}.| +0000bee0 00 79 16 83 ec 04 6a 03 68 0b 1a 00 00 6a 01 e8 |.y....j.h....j..| +0000bef0 c7 01 00 00 83 c4 10 eb 13 83 ec 04 6a 01 8d 45 |............j..E| +0000bf00 e7 50 6a 01 e8 b2 01 00 00 83 c4 10 83 45 ec 01 |.Pj..........E..| +0000bf10 8b 45 ec 3b 45 f4 7c ae 83 ec 0c 6a 00 e8 71 01 |.E.;E.|....j..q.| +0000bf20 00 00 83 c4 10 b8 2a 00 00 00 8d 65 f8 59 5b 5d |......*....e.Y[]| +0000bf30 8d 61 fc c3 55 89 e5 83 ec 08 83 ec 08 ff 75 08 |.a..U.........u.| +0000bf40 6a 00 e8 54 01 00 00 83 c4 10 c9 c3 55 89 e5 81 |j..T........U...| +0000bf50 ec 18 01 00 00 e8 49 01 00 00 89 45 f4 83 7d f4 |......I....E..}.| +0000bf60 00 74 05 8b 45 f4 eb 57 e8 56 01 00 00 89 45 f4 |.t..E..W.V....E.| +0000bf70 83 ec 08 ff 75 0c ff 75 08 e8 2d 01 00 00 83 c4 |....u..u..-.....| +0000bf80 10 ff 75 08 ff 75 f4 68 0f 1a 00 00 8d 85 f4 fe |..u..u.h........| +0000bf90 ff ff 50 e8 81 01 00 00 83 c4 10 83 ec 0c 8d 85 |..P.............| +0000bfa0 f4 fe ff ff 50 e8 38 00 00 00 83 c4 10 83 ec 0c |....P.8.........| +0000bfb0 6a ff e8 dc 00 00 00 83 c4 10 b8 00 00 00 00 c9 |j...............| +0000bfc0 c3 55 89 e5 83 ec 18 8b 45 08 88 45 f4 83 ec 04 |.U......E..E....| +0000bfd0 6a 01 8d 45 f4 50 6a 00 e8 de 00 00 00 83 c4 10 |j..E.Pj.........| +0000bfe0 c9 c3 55 89 e5 83 ec 18 83 ec 0c ff 75 08 e8 0d |..U.........u...| +0000bff0 04 00 00 83 c4 10 89 45 f4 8b 45 f4 83 ec 04 50 |.......E..E....P| +0000c000 ff 75 08 6a 00 e8 b1 00 00 00 83 c4 10 c9 c3 55 |.u.j...........U| +0000c010 89 e5 83 ec 08 83 ec 04 ff 75 0c ff 75 08 6a 00 |.........u..u.j.| +0000c020 e8 96 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 |..........U.....| +0000c030 8b 45 08 88 45 f4 83 ec 04 6a 01 8d 45 f4 50 6a |.E..E....j..E.Pj| +0000c040 01 e8 75 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec |..u........U....| +0000c050 18 83 ec 0c ff 75 08 e8 a4 03 00 00 83 c4 10 89 |.....u..........| +0000c060 45 f4 8b 45 f4 83 ec 04 50 ff 75 08 6a 01 e8 48 |E..E....P.u.j..H| +0000c070 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 08 83 ec |........U.......| +0000c080 04 ff 75 0c ff 75 08 6a 01 e8 2d 00 00 00 83 c4 |..u..u.j..-.....| +0000c090 10 c9 c3 b8 00 00 00 00 cd 80 c3 b8 01 00 00 00 |................| +0000c0a0 cd 80 c3 b8 02 00 00 00 cd 80 c3 b8 03 00 00 00 |................| +0000c0b0 cd 80 c3 b8 04 00 00 00 cd 80 c3 b8 05 00 00 00 |................| +0000c0c0 cd 80 c3 b8 06 00 00 00 cd 80 c3 b8 07 00 00 00 |................| +0000c0d0 cd 80 c3 b8 08 00 00 00 cd 80 c3 b8 09 00 00 00 |................| +0000c0e0 cd 80 c3 b8 0a 00 00 00 cd 80 c3 b8 0b 00 00 00 |................| +0000c0f0 cd 80 c3 b8 0c 00 00 00 cd 80 c3 b8 ad 0b 00 00 |................| +0000c100 cd 80 c3 50 e8 8a ff ff ff e8 76 fc ff ff 83 ec |...P......v.....| +0000c110 0c 50 e8 7c ff ff ff eb fe 55 89 e5 83 ec 38 8d |.P.|.....U....8.| +0000c120 45 0c 83 c0 04 89 45 f4 e9 3f 02 00 00 80 7d f3 |E.....E..?....}.| +0000c130 25 0f 85 26 02 00 00 c7 45 ec 00 00 00 00 c7 45 |%..&....E......E| +0000c140 e4 20 00 00 00 c7 45 e8 00 00 00 00 8b 45 0c 8d |. ....E......E..| +0000c150 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 2d 75 |P..U.....E..}.-u| +0000c160 16 c7 45 ec 01 00 00 00 8b 45 0c 8d 50 01 89 55 |..E......E..P..U| +0000c170 0c 0f b6 00 88 45 f3 80 7d f3 30 75 40 c7 45 e4 |.....E..}.0u@.E.| +0000c180 30 00 00 00 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 |0....E..P..U....| +0000c190 88 45 f3 eb 28 8b 55 e8 89 d0 c1 e0 02 01 d0 01 |.E..(.U.........| +0000c1a0 c0 89 45 e8 0f be 45 f3 83 e8 30 01 45 e8 8b 45 |..E...E...0.E..E| +0000c1b0 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 |..P..U.....E..}.| +0000c1c0 2f 7e 06 80 7d f3 39 7e cc 0f be 45 f3 83 e8 63 |/~..}.9~...E...c| +0000c1d0 83 f8 15 0f 87 93 01 00 00 8b 04 85 2c 1a 00 00 |............,...| +0000c1e0 ff e0 8b 45 f4 8d 50 04 89 55 f4 8b 00 88 45 f3 |...E..P..U....E.| +0000c1f0 0f b6 45 f3 88 45 d0 c6 45 d1 00 83 ec 08 ff 75 |..E..E..E......u| +0000c200 e4 ff 75 ec ff 75 e8 6a 01 8d 45 d0 50 ff 75 08 |..u..u.j..E.P.u.| +0000c210 e8 89 04 00 00 83 c4 20 89 45 08 e9 4c 01 00 00 |....... .E..L...| +0000c220 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d |.E..P..U......P.| +0000c230 45 d0 50 e8 ea 01 00 00 83 c4 10 89 45 e0 83 ec |E.P.........E...| +0000c240 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 |..u..u..u..u..E.| +0000c250 50 ff 75 08 e8 45 04 00 00 83 c4 20 89 45 08 e9 |P.u..E..... .E..| +0000c260 08 01 00 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 89 |.....E..P..U....| +0000c270 45 dc 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 6a ff |E.....u..u..u.j.| +0000c280 ff 75 dc ff 75 08 e8 13 04 00 00 83 c4 20 89 45 |.u..u........ .E| +0000c290 08 e9 d6 00 00 00 8b 45 f4 8d 50 04 89 55 f4 8b |.......E..P..U..| +0000c2a0 00 83 ec 08 50 8d 45 d0 50 e8 44 02 00 00 83 c4 |....P.E.P.D.....| +0000c2b0 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 |..E.....u..u..u.| +0000c2c0 ff 75 e0 8d 45 d0 50 ff 75 08 e8 cf 03 00 00 83 |.u..E.P.u.......| +0000c2d0 c4 20 89 45 08 e9 92 00 00 00 8b 45 f4 8d 50 04 |. .E.......E..P.| +0000c2e0 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 8a 02 |.U......P.E.P...| +0000c2f0 00 00 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 |......E.....u..u| +0000c300 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 8b |..u..u..E.P.u...| +0000c310 03 00 00 83 c4 20 89 45 08 eb 51 8b 45 f4 8d 50 |..... .E..Q.E..P| +0000c320 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 d3 |..U......P.E.P..| +0000c330 02 00 00 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff |.......E.....u..| +0000c340 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 |u..u..u..E.P.u..| +0000c350 4a 03 00 00 83 c4 20 89 45 08 90 eb 0f 8b 45 08 |J..... .E.....E.| +0000c360 8d 50 01 89 55 08 0f b6 55 f3 88 10 8b 45 0c 8d |.P..U...U....E..| +0000c370 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 00 0f |P..U.....E..}...| +0000c380 85 a8 fd ff ff 8b 45 08 c6 00 00 90 c9 c3 55 89 |......E.......U.| +0000c390 e5 53 83 ec 14 8b 45 08 8b 4d 0c bb 00 00 00 00 |.S....E..M......| +0000c3a0 c6 45 eb 39 c7 45 f8 01 00 00 00 0f b6 10 80 fa |.E.9.E..........| +0000c3b0 2d 75 0a c7 45 f8 ff ff ff ff 83 c0 01 83 f9 0a |-u..E...........| +0000c3c0 74 2b 89 ca 83 c2 2f 88 55 eb eb 21 0f b6 10 80 |t+..../.U..!....| +0000c3d0 fa 2f 7e 20 0f b6 10 38 55 eb 7c 18 0f af d9 0f |./~ ...8U.|.....| +0000c3e0 b6 10 0f be d2 01 da 8d 5a d0 83 c0 01 0f b6 10 |........Z.......| +0000c3f0 84 d2 75 d8 89 d8 0f af 45 f8 83 c4 14 5b 5d c3 |..u.....E....[].| +0000c400 55 89 e5 53 8b 55 08 bb 00 00 00 00 eb 03 83 c3 |U..S.U..........| +0000c410 01 89 d0 8d 50 01 0f b6 00 84 c0 75 f1 89 d8 5b |....P......u...[| +0000c420 5d c3 55 89 e5 83 ec 18 8b 45 08 89 45 f4 83 7d |].U......E..E..}| +0000c430 0c 00 79 0f 8b 45 f4 8d 50 01 89 55 f4 c6 00 2d |..y..E..P..U...-| +0000c440 f7 5d 0c 83 ec 08 ff 75 0c ff 75 f4 e8 18 00 00 |.].....u..u.....| +0000c450 00 83 c4 10 89 45 f4 8b 45 f4 c6 00 00 8b 55 f4 |.....E..E.....U.| +0000c460 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 ec 18 8b |.E.).....U......| +0000c470 4d 0c ba 67 66 66 66 89 c8 f7 ea c1 fa 02 89 c8 |M..gfff.........| +0000c480 c1 f8 1f 29 c2 89 d0 89 45 f4 83 7d f4 00 79 0e |...)....E..}..y.| +0000c490 c7 45 f4 cc cc cc 0c c7 45 0c 08 00 00 00 83 7d |.E......E......}| +0000c4a0 f4 00 74 14 83 ec 08 ff 75 f4 ff 75 08 e8 b7 ff |..t.....u..u....| +0000c4b0 ff ff 83 c4 10 89 45 08 8b 4d 0c ba 67 66 66 66 |......E..M..gfff| +0000c4c0 89 c8 f7 ea c1 fa 02 89 c8 c1 f8 1f 29 c2 89 d0 |............)...| +0000c4d0 c1 e0 02 01 d0 01 c0 29 c1 89 ca 89 d0 8d 48 30 |.......)......H0| +0000c4e0 8b 45 08 8d 50 01 89 55 08 89 ca 88 10 8b 45 08 |.E..P..U......E.| +0000c4f0 c9 c3 55 89 e5 83 ec 20 c7 45 e3 30 31 32 33 c7 |..U.... .E.0123.| +0000c500 45 e7 34 35 36 37 c7 45 eb 38 39 41 42 c7 45 ef |E.4567.E.89AB.E.| +0000c510 43 44 45 46 c6 45 f3 00 c7 45 fc 00 00 00 00 c7 |CDEF.E...E......| +0000c520 45 f8 00 00 00 00 eb 43 8b 45 0c 25 00 00 00 f0 |E......C.E.%....| +0000c530 89 45 f4 83 7d fc 00 75 0c 83 7d f4 00 75 06 83 |.E..}..u..}..u..| +0000c540 7d f8 07 75 1e 83 45 fc 01 c1 6d f4 1c 8b 45 08 |}..u..E...m...E.| +0000c550 8d 50 01 89 55 08 8d 4d e3 8b 55 f4 01 ca 0f b6 |.P..U..M..U.....| +0000c560 12 88 10 c1 65 0c 04 83 45 f8 01 83 7d f8 07 7e |....e...E...}..~| +0000c570 b7 8b 45 08 c6 00 00 8b 45 fc c9 c3 55 89 e5 83 |..E.....E...U...| +0000c580 ec 10 c7 45 f8 00 00 00 00 8b 45 08 89 45 f4 8b |...E......E..E..| +0000c590 45 0c 25 00 00 00 c0 89 45 f0 c1 6d f0 1e c7 45 |E.%.....E..m...E| +0000c5a0 fc 00 00 00 00 eb 47 83 7d fc 0a 74 0c 83 7d f0 |......G.}..t..}.| +0000c5b0 00 75 06 83 7d f8 00 74 1e c7 45 f8 01 00 00 00 |.u..}..t..E.....| +0000c5c0 83 65 f0 07 8b 45 f0 8d 48 30 8b 45 f4 8d 50 01 |.e...E..H0.E..P.| +0000c5d0 89 55 f4 89 ca 88 10 c1 65 0c 03 8b 45 0c 25 00 |.U......e...E.%.| +0000c5e0 00 00 e0 89 45 f0 c1 6d f0 1d 83 45 fc 01 83 7d |....E..m...E...}| +0000c5f0 fc 0a 7e b3 8b 45 f4 c6 00 00 8b 55 f4 8b 45 08 |..~..E.....U..E.| +0000c600 29 c2 89 d0 c9 c3 55 89 e5 83 ec 18 8b 45 08 89 |).....U......E..| +0000c610 45 f4 83 ec 08 ff 75 0c ff 75 f4 e8 18 00 00 00 |E.....u..u......| +0000c620 83 c4 10 89 45 f4 8b 45 f4 c6 00 00 8b 55 f4 8b |....E..E.....U..| +0000c630 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 ec 18 8b 45 |E.).....U......E| +0000c640 0c ba cd cc cc cc f7 e2 89 d0 c1 e8 03 89 45 f4 |..............E.| +0000c650 83 7d f4 00 74 15 8b 45 f4 83 ec 08 50 ff 75 08 |.}..t..E....P.u.| +0000c660 e8 04 fe ff ff 83 c4 10 89 45 08 8b 4d 0c ba cd |.........E..M...| +0000c670 cc cc cc 89 c8 f7 e2 c1 ea 03 89 d0 c1 e0 02 01 |................| +0000c680 d0 01 c0 29 c1 89 ca 89 d0 8d 48 30 8b 45 08 8d |...)......H0.E..| +0000c690 50 01 89 55 08 89 ca 88 10 8b 45 08 c9 c3 55 89 |P..U......E...U.| +0000c6a0 e5 83 ec 18 83 7d 10 00 79 11 83 ec 0c ff 75 0c |.....}..y.....u.| +0000c6b0 e8 4b fd ff ff 83 c4 10 89 45 10 8b 45 14 2b 45 |.K.......E..E.+E| +0000c6c0 10 89 45 f0 83 7d f0 00 7e 1d 83 7d 18 00 75 17 |..E..}..~..}..u.| +0000c6d0 83 ec 04 ff 75 1c ff 75 f0 ff 75 08 e8 5a 00 00 |....u..u..u..Z..| +0000c6e0 00 83 c4 10 89 45 08 c7 45 f4 00 00 00 00 eb 1b |.....E..E.......| +0000c6f0 8b 55 f4 8b 45 0c 8d 0c 02 8b 45 08 8d 50 01 89 |.U..E.....E..P..| +0000c700 55 08 0f b6 11 88 10 83 45 f4 01 8b 45 f4 3b 45 |U.......E...E.;E| +0000c710 10 7c dd 83 7d f0 00 7e 1d 83 7d 18 00 74 17 83 |.|..}..~..}..t..| +0000c720 ec 04 ff 75 1c ff 75 f0 ff 75 08 e8 0b 00 00 00 |...u..u..u......| +0000c730 83 c4 10 89 45 08 8b 45 08 c9 c3 55 89 e5 eb 12 |....E..E...U....| +0000c740 8b 45 08 8d 50 01 89 55 08 8b 55 10 88 10 83 6d |.E..P..U..U....m| +0000c750 0c 01 83 7d 0c 00 7f e8 8b 45 08 5d c3 00 00 00 |...}.....E.]....| +0000c760 75 73 65 72 4a 3a 20 61 72 67 63 20 25 64 2c 20 |userJ: argc %d, | +0000c770 61 72 67 73 3a 20 00 28 6e 75 6c 6c 29 00 20 25 |args: .(null). %| +0000c780 73 00 0a 00 75 73 65 72 59 00 59 00 31 30 00 21 |s...userY.Y.10.!| +0000c790 6a 21 00 43 68 69 6c 64 20 25 64 20 65 78 65 63 |j!.Child %d exec| +0000c7a0 28 29 20 23 25 75 20 66 61 69 6c 65 64 0a 00 00 |() #%u failed...| +0000c7b0 5e 14 00 00 9c 14 00 00 e8 15 00 00 e8 15 00 00 |^...............| +0000c7c0 e8 15 00 00 e8 15 00 00 e8 15 00 00 e8 15 00 00 |................| +* +0000c7e0 56 15 00 00 e8 15 00 00 e8 15 00 00 e8 15 00 00 |V...............| +0000c7f0 e0 14 00 00 e8 15 00 00 97 15 00 00 e8 15 00 00 |................| +0000c800 e8 15 00 00 12 15 00 00 00 00 00 00 00 00 00 00 |................| +0000c810 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +0000cd90 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 |................| +0000cda0 03 00 01 00 00 00 00 00 dc 19 00 00 00 00 00 00 |................| +0000cdb0 03 00 02 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +0000cdc0 03 00 03 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +0000cdd0 03 00 04 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +0000cde0 04 00 f1 ff 09 00 00 00 00 00 00 00 00 00 00 00 |................| +0000cdf0 04 00 f1 ff 11 00 00 00 00 00 00 00 00 00 00 00 |................| +0000ce00 04 00 f1 ff 1a 00 00 00 00 00 00 00 00 00 00 00 |................| +0000ce10 04 00 f1 ff 24 00 00 00 00 00 00 00 00 00 00 00 |....$...........| +0000ce20 04 00 f1 ff 2d 00 00 00 00 00 00 00 00 00 00 00 |....-...........| +0000ce30 04 00 f1 ff 36 00 00 00 00 00 00 00 00 00 00 00 |....6...........| +0000ce40 04 00 f1 ff 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........| +0000ce50 04 00 f1 ff 49 00 00 00 00 00 00 00 00 00 00 00 |....I...........| +0000ce60 04 00 f1 ff 52 00 00 00 00 00 00 00 00 00 00 00 |....R...........| +0000ce70 04 00 f1 ff 5b 00 00 00 00 00 00 00 00 00 00 00 |....[...........| +0000ce80 04 00 f1 ff 65 00 00 00 00 00 00 00 00 00 00 00 |....e...........| +0000ce90 04 00 f1 ff 6e 00 00 00 00 00 00 00 00 00 00 00 |....n...........| +0000cea0 04 00 f1 ff 74 00 00 00 a6 12 00 00 21 00 00 00 |....t.......!...| +0000ceb0 12 00 01 00 7d 00 00 00 17 13 00 00 00 00 00 00 |....}...........| +0000cec0 10 00 01 00 85 00 00 00 8b 12 00 00 1b 00 00 00 |................| +0000ced0 12 00 01 00 8c 00 00 00 0a 16 00 00 72 00 00 00 |............r...| +0000cee0 12 00 01 00 94 00 00 00 82 18 00 00 32 00 00 00 |............2...| +0000cef0 12 00 01 00 9b 00 00 00 3f 13 00 00 00 00 00 00 |........?.......| +0000cf00 10 00 01 00 a2 00 00 00 6f 13 00 00 00 00 00 00 |........o.......| +0000cf10 10 00 01 00 a8 00 00 00 f4 12 00 00 1b 00 00 00 |................| +0000cf20 12 00 01 00 af 00 00 00 b7 19 00 00 22 00 00 00 |............"...| +0000cf30 12 00 01 00 b3 00 00 00 c8 11 00 00 75 00 00 00 |............u...| +0000cf40 12 00 01 00 b9 00 00 00 95 13 00 00 75 02 00 00 |............u...| +0000cf50 12 00 01 00 c0 00 00 00 6e 17 00 00 8a 00 00 00 |........n.......| +0000cf60 12 00 01 00 c7 00 00 00 b4 18 00 00 66 00 00 00 |............f...| +0000cf70 12 00 01 00 86 00 00 00 37 13 00 00 00 00 00 00 |........7.......| +0000cf80 10 00 01 00 cf 00 00 00 67 13 00 00 00 00 00 00 |........g.......| +0000cf90 10 00 01 00 d4 00 00 00 5e 12 00 00 2d 00 00 00 |........^...-...| +0000cfa0 12 00 01 00 dc 00 00 00 27 13 00 00 00 00 00 00 |........'.......| +0000cfb0 10 00 01 00 e1 00 00 00 b0 11 00 00 18 00 00 00 |................| +0000cfc0 12 00 01 00 e6 00 00 00 c7 12 00 00 2d 00 00 00 |............-...| +0000cfd0 12 00 01 00 ee 00 00 00 85 13 00 00 00 00 00 00 |................| +0000cfe0 10 00 01 00 f5 00 00 00 2f 13 00 00 00 00 00 00 |......../.......| +0000cff0 10 00 01 00 fa 00 00 00 57 13 00 00 00 00 00 00 |........W.......| +0000d000 10 00 01 00 02 01 00 00 e5 16 00 00 89 00 00 00 |................| +0000d010 12 00 01 00 0a 01 00 00 1f 13 00 00 00 00 00 00 |................| +0000d020 10 00 01 00 0f 01 00 00 00 10 00 00 b0 01 00 00 |................| +0000d030 12 00 01 00 14 01 00 00 47 13 00 00 00 00 00 00 |........G.......| +0000d040 10 00 01 00 1c 01 00 00 1a 19 00 00 9d 00 00 00 |................| +0000d050 12 00 01 00 23 01 00 00 5f 13 00 00 00 00 00 00 |....#..._.......| +0000d060 10 00 01 00 2b 01 00 00 f8 17 00 00 8a 00 00 00 |....+...........| +0000d070 12 00 01 00 32 01 00 00 3d 12 00 00 21 00 00 00 |....2...=...!...| +0000d080 12 00 01 00 3b 01 00 00 4f 13 00 00 00 00 00 00 |....;...O.......| +0000d090 10 00 01 00 43 01 00 00 9e 16 00 00 47 00 00 00 |....C.......G...| +0000d0a0 12 00 01 00 5c 01 00 00 0f 13 00 00 00 00 00 00 |....\...........| +0000d0b0 10 00 01 00 4a 01 00 00 7c 16 00 00 22 00 00 00 |....J...|..."...| +0000d0c0 12 00 01 00 51 01 00 00 77 13 00 00 00 00 00 00 |....Q...w.......| +0000d0d0 10 00 01 00 57 01 00 00 7f 13 00 00 00 00 00 00 |....W...........| +0000d0e0 10 00 01 00 00 70 72 6f 67 4a 2e 63 00 75 6c 69 |.....progJ.c.uli| +0000d0f0 62 63 2e 63 00 73 70 72 69 6e 74 2e 63 00 73 74 |bc.c.sprint.c.st| +0000d100 72 32 69 6e 74 2e 63 00 73 74 72 6c 65 6e 2e 63 |r2int.c.strlen.c| +0000d110 00 63 76 74 64 65 63 2e 63 00 63 76 74 64 65 63 |.cvtdec.c.cvtdec| +0000d120 30 2e 63 00 63 76 74 68 65 78 2e 63 00 63 76 74 |0.c.cvthex.c.cvt| +0000d130 6f 63 74 2e 63 00 63 76 74 75 6e 73 2e 63 00 63 |oct.c.cvtuns.c.c| +0000d140 76 74 75 6e 73 30 2e 63 00 70 61 64 73 74 72 2e |vtuns0.c.padstr.| +0000d150 63 00 70 61 64 2e 63 00 73 77 72 69 74 65 63 68 |c.pad.c.swritech| +0000d160 00 77 61 69 74 70 69 64 00 63 77 72 69 74 65 00 |.waitpid.cwrite.| +0000d170 73 74 72 32 69 6e 74 00 63 76 74 75 6e 73 00 67 |str2int.cvtuns.g| +0000d180 65 74 70 69 64 00 73 6c 65 65 70 00 73 77 72 69 |etpid.sleep.swri| +0000d190 74 65 00 70 61 64 00 73 70 61 77 6e 00 73 70 72 |te.pad.spawn.spr| +0000d1a0 69 6e 74 00 63 76 74 68 65 78 00 63 76 74 75 6e |int.cvthex.cvtun| +0000d1b0 73 30 00 6b 69 6c 6c 00 63 77 72 69 74 65 73 00 |s0.kill.cwrites.| +0000d1c0 65 78 65 63 00 77 61 69 74 00 73 77 72 69 74 65 |exec.wait.swrite| +0000d1d0 73 00 5f 73 74 61 72 74 00 72 65 61 64 00 67 65 |s._start.read.ge| +0000d1e0 74 70 72 69 6f 00 63 76 74 64 65 63 30 00 66 6f |tprio.cvtdec0.fo| +0000d1f0 72 6b 00 6d 61 69 6e 00 67 65 74 70 70 69 64 00 |rk.main.getppid.| +0000d200 70 61 64 73 74 72 00 73 65 74 70 72 69 6f 00 63 |padstr.setprio.c| +0000d210 76 74 6f 63 74 00 63 77 72 69 74 65 63 68 00 67 |vtoct.cwritech.g| +0000d220 65 74 74 69 6d 65 00 63 76 74 64 65 63 00 73 74 |ettime.cvtdec.st| +0000d230 72 6c 65 6e 00 62 6f 67 75 73 00 66 61 6b 65 5f |rlen.bogus.fake_| +0000d240 65 78 69 74 00 00 2e 73 79 6d 74 61 62 00 2e 73 |exit...symtab..s| +0000d250 74 72 74 61 62 00 2e 73 68 73 74 72 74 61 62 00 |trtab..shstrtab.| +0000d260 2e 74 65 78 74 00 2e 72 6f 64 61 74 61 00 2e 64 |.text..rodata..d| +0000d270 61 74 61 00 2e 62 73 73 00 00 00 00 00 00 00 00 |ata..bss........| +0000d280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +0000d2a0 00 00 00 00 1b 00 00 00 01 00 00 00 06 00 00 00 |................| +0000d2b0 00 10 00 00 74 00 00 00 d9 09 00 00 00 00 00 00 |....t...........| +0000d2c0 00 00 00 00 01 00 00 00 00 00 00 00 21 00 00 00 |............!...| +0000d2d0 01 00 00 00 02 00 00 00 dc 19 00 00 50 0a 00 00 |............P...| +0000d2e0 a8 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |................| +0000d2f0 00 00 00 00 29 00 00 00 01 00 00 00 03 00 00 00 |....)...........| +0000d300 00 20 00 00 74 10 00 00 00 00 00 00 00 00 00 00 |. ..t...........| +0000d310 00 00 00 00 01 00 00 00 00 00 00 00 2f 00 00 00 |............/...| +0000d320 08 00 00 00 03 00 00 00 00 20 00 00 74 10 00 00 |......... ..t...| +0000d330 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +0000d340 00 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 |................| +0000d350 00 00 00 00 74 10 00 00 60 03 00 00 06 00 00 00 |....t...`.......| +0000d360 12 00 00 00 04 00 00 00 10 00 00 00 09 00 00 00 |................| +0000d370 03 00 00 00 00 00 00 00 00 00 00 00 d4 13 00 00 |................| +0000d380 61 01 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |a...............| +0000d390 00 00 00 00 11 00 00 00 03 00 00 00 00 00 00 00 |................| +0000d3a0 00 00 00 00 35 15 00 00 34 00 00 00 00 00 00 00 |....5...4.......| +0000d3b0 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +0000d3c0 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| +0000d3d0 02 00 03 00 01 00 00 00 b9 13 00 00 34 00 00 00 |............4...| +0000d3e0 6c 15 00 00 00 00 00 00 34 00 20 00 02 00 28 00 |l.......4. ...(.| +0000d3f0 08 00 07 00 01 00 00 00 74 00 00 00 00 10 00 00 |........t.......| +0000d400 00 10 00 00 00 10 00 00 00 10 00 00 07 00 00 00 |................| +0000d410 04 00 00 00 51 e5 74 64 00 00 00 00 00 00 00 00 |....Q.td........| +0000d420 00 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 |................| +0000d430 10 00 00 00 8d 4c 24 04 83 e4 f0 ff 71 fc 55 89 |.....L$.....q.U.| +0000d440 e5 53 51 83 ec 50 89 cb c7 45 f4 05 00 00 00 c6 |.SQ..P...E......| +0000d450 45 e3 34 c7 45 e8 1e 00 00 00 c7 45 df 2a 34 2a |E.4.E......E.*4*| +0000d460 00 8b 03 83 f8 02 74 1e 83 f8 03 75 2c 8b 43 04 |......t....u,.C.| +0000d470 83 c0 08 8b 00 83 ec 08 6a 0a 50 e8 f2 05 00 00 |........j.P.....| +0000d480 83 c4 10 89 45 f4 8b 43 04 83 c0 04 8b 00 0f b6 |....E..C........| +0000d490 00 88 45 e3 e9 98 00 00 00 83 ec 04 ff 33 68 10 |..E..........3h.| +0000d4a0 1a 00 00 8d 45 bf 50 e8 51 03 00 00 83 c4 10 83 |....E.P.Q.......| +0000d4b0 ec 0c 8d 45 bf 50 e8 0b 02 00 00 83 c4 10 c7 45 |...E.P.........E| +0000d4c0 f0 00 00 00 00 eb 53 8b 03 8d 14 85 00 00 00 00 |......S.........| +0000d4d0 8b 43 04 01 d0 8b 00 85 c0 74 12 8b 03 8d 14 85 |.C.......t......| +0000d4e0 00 00 00 00 8b 43 04 01 d0 8b 00 eb 05 b8 27 1a |.....C........'.| +0000d4f0 00 00 83 ec 04 50 68 2e 1a 00 00 8d 45 bf 50 e8 |.....Ph.....E.P.| +0000d500 f9 02 00 00 83 c4 10 83 ec 0c 8d 45 bf 50 e8 b3 |...........E.P..| +0000d510 01 00 00 83 c4 10 83 45 f0 01 8b 45 f0 3b 03 7e |.......E...E.;.~| +0000d520 a6 83 ec 0c 68 32 1a 00 00 e8 98 01 00 00 83 c4 |....h2..........| +0000d530 10 83 ec 04 6a 01 8d 45 e3 50 6a 01 e8 5e 02 00 |....j..E.Pj..^..| +0000d540 00 83 c4 10 c7 45 ac 34 1a 00 00 c7 45 b0 3a 1a |.....E.4....E.:.| +0000d550 00 00 8d 45 bf 89 45 b4 c7 45 b8 00 00 00 00 c7 |...E..E..E......| +0000d560 45 ec 00 00 00 00 e9 85 00 00 00 83 ec 04 6a 01 |E.............j.| +0000d570 8d 45 e3 50 6a 01 e8 24 02 00 00 83 c4 10 8b 45 |.E.Pj..$.......E| +0000d580 ec 83 c0 64 83 ec 04 50 68 3c 1a 00 00 8d 45 bf |...d...Ph<....E.| +0000d590 50 e8 67 02 00 00 83 c4 10 83 ec 08 8d 45 ac 50 |P.g..........E.P| +0000d5a0 6a 11 e8 89 00 00 00 83 c4 10 89 45 e4 83 7d e4 |j..........E..}.| +0000d5b0 00 79 11 83 ec 0c 8d 45 df 50 e8 70 01 00 00 83 |.y.....E.P.p....| +0000d5c0 c4 10 eb 13 83 ec 04 6a 01 8d 45 e3 50 6a 01 e8 |.......j..E.Pj..| +0000d5d0 cb 01 00 00 83 c4 10 8b 45 e8 69 c0 e8 03 00 00 |........E.i.....| +0000d5e0 83 ec 0c 50 e8 ee 01 00 00 83 c4 10 83 45 ec 01 |...P.........E..| +0000d5f0 8b 45 ec 3b 45 f4 0f 8c 6f ff ff ff 83 ec 0c 6a |.E.;E...o......j| +0000d600 00 e8 71 01 00 00 83 c4 10 b8 2a 00 00 00 8d 65 |..q.......*....e| +0000d610 f8 59 5b 5d 8d 61 fc c3 55 89 e5 83 ec 08 83 ec |.Y[].a..U.......| +0000d620 08 ff 75 08 6a 00 e8 54 01 00 00 83 c4 10 c9 c3 |..u.j..T........| +0000d630 55 89 e5 81 ec 18 01 00 00 e8 49 01 00 00 89 45 |U.........I....E| +0000d640 f4 83 7d f4 00 74 05 8b 45 f4 eb 57 e8 56 01 00 |..}..t..E..W.V..| +0000d650 00 89 45 f4 83 ec 08 ff 75 0c ff 75 08 e8 2d 01 |..E.....u..u..-.| +0000d660 00 00 83 c4 10 ff 75 08 ff 75 f4 68 3f 1a 00 00 |......u..u.h?...| +0000d670 8d 85 f4 fe ff ff 50 e8 81 01 00 00 83 c4 10 83 |......P.........| +0000d680 ec 0c 8d 85 f4 fe ff ff 50 e8 38 00 00 00 83 c4 |........P.8.....| +0000d690 10 83 ec 0c 6a ff e8 dc 00 00 00 83 c4 10 b8 00 |....j...........| +0000d6a0 00 00 00 c9 c3 55 89 e5 83 ec 18 8b 45 08 88 45 |.....U......E..E| +0000d6b0 f4 83 ec 04 6a 01 8d 45 f4 50 6a 00 e8 de 00 00 |....j..E.Pj.....| +0000d6c0 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 83 ec 0c ff |......U.........| +0000d6d0 75 08 e8 0d 04 00 00 83 c4 10 89 45 f4 8b 45 f4 |u..........E..E.| +0000d6e0 83 ec 04 50 ff 75 08 6a 00 e8 b1 00 00 00 83 c4 |...P.u.j........| +0000d6f0 10 c9 c3 55 89 e5 83 ec 08 83 ec 04 ff 75 0c ff |...U.........u..| +0000d700 75 08 6a 00 e8 96 00 00 00 83 c4 10 c9 c3 55 89 |u.j...........U.| +0000d710 e5 83 ec 18 8b 45 08 88 45 f4 83 ec 04 6a 01 8d |.....E..E....j..| +0000d720 45 f4 50 6a 01 e8 75 00 00 00 83 c4 10 c9 c3 55 |E.Pj..u........U| +0000d730 89 e5 83 ec 18 83 ec 0c ff 75 08 e8 a4 03 00 00 |.........u......| +0000d740 83 c4 10 89 45 f4 8b 45 f4 83 ec 04 50 ff 75 08 |....E..E....P.u.| +0000d750 6a 01 e8 48 00 00 00 83 c4 10 c9 c3 55 89 e5 83 |j..H........U...| +0000d760 ec 08 83 ec 04 ff 75 0c ff 75 08 6a 01 e8 2d 00 |......u..u.j..-.| +0000d770 00 00 83 c4 10 c9 c3 b8 00 00 00 00 cd 80 c3 b8 |................| +0000d780 01 00 00 00 cd 80 c3 b8 02 00 00 00 cd 80 c3 b8 |................| +0000d790 03 00 00 00 cd 80 c3 b8 04 00 00 00 cd 80 c3 b8 |................| +0000d7a0 05 00 00 00 cd 80 c3 b8 06 00 00 00 cd 80 c3 b8 |................| +0000d7b0 07 00 00 00 cd 80 c3 b8 08 00 00 00 cd 80 c3 b8 |................| +0000d7c0 09 00 00 00 cd 80 c3 b8 0a 00 00 00 cd 80 c3 b8 |................| +0000d7d0 0b 00 00 00 cd 80 c3 b8 0c 00 00 00 cd 80 c3 b8 |................| +0000d7e0 ad 0b 00 00 cd 80 c3 50 e8 8a ff ff ff e8 42 fc |.......P......B.| +0000d7f0 ff ff 83 ec 0c 50 e8 7c ff ff ff eb fe 55 89 e5 |.....P.|.....U..| +0000d800 83 ec 38 8d 45 0c 83 c0 04 89 45 f4 e9 3f 02 00 |..8.E.....E..?..| +0000d810 00 80 7d f3 25 0f 85 26 02 00 00 c7 45 ec 00 00 |..}.%..&....E...| +0000d820 00 00 c7 45 e4 20 00 00 00 c7 45 e8 00 00 00 00 |...E. ....E.....| +0000d830 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 |.E..P..U.....E..| +0000d840 7d f3 2d 75 16 c7 45 ec 01 00 00 00 8b 45 0c 8d |}.-u..E......E..| +0000d850 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 30 75 |P..U.....E..}.0u| +0000d860 40 c7 45 e4 30 00 00 00 8b 45 0c 8d 50 01 89 55 |@.E.0....E..P..U| +0000d870 0c 0f b6 00 88 45 f3 eb 28 8b 55 e8 89 d0 c1 e0 |.....E..(.U.....| +0000d880 02 01 d0 01 c0 89 45 e8 0f be 45 f3 83 e8 30 01 |......E...E...0.| +0000d890 45 e8 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 |E..E..P..U.....E| +0000d8a0 f3 80 7d f3 2f 7e 06 80 7d f3 39 7e cc 0f be 45 |..}./~..}.9~...E| +0000d8b0 f3 83 e8 63 83 f8 15 0f 87 93 01 00 00 8b 04 85 |...c............| +0000d8c0 5c 1a 00 00 ff e0 8b 45 f4 8d 50 04 89 55 f4 8b |\......E..P..U..| +0000d8d0 00 88 45 f3 0f b6 45 f3 88 45 d0 c6 45 d1 00 83 |..E...E..E..E...| +0000d8e0 ec 08 ff 75 e4 ff 75 ec ff 75 e8 6a 01 8d 45 d0 |...u..u..u.j..E.| +0000d8f0 50 ff 75 08 e8 89 04 00 00 83 c4 20 89 45 08 e9 |P.u........ .E..| +0000d900 4c 01 00 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 |L....E..P..U....| +0000d910 ec 08 50 8d 45 d0 50 e8 ea 01 00 00 83 c4 10 89 |..P.E.P.........| +0000d920 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 |E.....u..u..u..u| +0000d930 e0 8d 45 d0 50 ff 75 08 e8 45 04 00 00 83 c4 20 |..E.P.u..E..... | +0000d940 89 45 08 e9 08 01 00 00 8b 45 f4 8d 50 04 89 55 |.E.......E..P..U| +0000d950 f4 8b 00 89 45 dc 83 ec 08 ff 75 e4 ff 75 ec ff |....E.....u..u..| +0000d960 75 e8 6a ff ff 75 dc ff 75 08 e8 13 04 00 00 83 |u.j..u..u.......| +0000d970 c4 20 89 45 08 e9 d6 00 00 00 8b 45 f4 8d 50 04 |. .E.......E..P.| +0000d980 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 44 02 |.U......P.E.P.D.| +0000d990 00 00 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 |......E.....u..u| +0000d9a0 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 cf |..u..u..E.P.u...| +0000d9b0 03 00 00 83 c4 20 89 45 08 e9 92 00 00 00 8b 45 |..... .E.......E| +0000d9c0 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 |..P..U......P.E.| +0000d9d0 50 e8 8a 02 00 00 83 c4 10 89 45 e0 83 ec 08 ff |P.........E.....| +0000d9e0 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff |u..u..u..u..E.P.| +0000d9f0 75 08 e8 8b 03 00 00 83 c4 20 89 45 08 eb 51 8b |u........ .E..Q.| +0000da00 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 |E..P..U......P.E| +0000da10 d0 50 e8 d3 02 00 00 83 c4 10 89 45 e0 83 ec 08 |.P.........E....| +0000da20 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 |.u..u..u..u..E.P| +0000da30 ff 75 08 e8 4a 03 00 00 83 c4 20 89 45 08 90 eb |.u..J..... .E...| +0000da40 0f 8b 45 08 8d 50 01 89 55 08 0f b6 55 f3 88 10 |..E..P..U...U...| +0000da50 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 |.E..P..U.....E..| +0000da60 7d f3 00 0f 85 a8 fd ff ff 8b 45 08 c6 00 00 90 |}.........E.....| +0000da70 c9 c3 55 89 e5 53 83 ec 14 8b 45 08 8b 4d 0c bb |..U..S....E..M..| +0000da80 00 00 00 00 c6 45 eb 39 c7 45 f8 01 00 00 00 0f |.....E.9.E......| +0000da90 b6 10 80 fa 2d 75 0a c7 45 f8 ff ff ff ff 83 c0 |....-u..E.......| +0000daa0 01 83 f9 0a 74 2b 89 ca 83 c2 2f 88 55 eb eb 21 |....t+..../.U..!| +0000dab0 0f b6 10 80 fa 2f 7e 20 0f b6 10 38 55 eb 7c 18 |...../~ ...8U.|.| +0000dac0 0f af d9 0f b6 10 0f be d2 01 da 8d 5a d0 83 c0 |............Z...| +0000dad0 01 0f b6 10 84 d2 75 d8 89 d8 0f af 45 f8 83 c4 |......u.....E...| +0000dae0 14 5b 5d c3 55 89 e5 53 8b 55 08 bb 00 00 00 00 |.[].U..S.U......| +0000daf0 eb 03 83 c3 01 89 d0 8d 50 01 0f b6 00 84 c0 75 |........P......u| +0000db00 f1 89 d8 5b 5d c3 55 89 e5 83 ec 18 8b 45 08 89 |...[].U......E..| +0000db10 45 f4 83 7d 0c 00 79 0f 8b 45 f4 8d 50 01 89 55 |E..}..y..E..P..U| +0000db20 f4 c6 00 2d f7 5d 0c 83 ec 08 ff 75 0c ff 75 f4 |...-.].....u..u.| +0000db30 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 c6 00 |.........E..E...| +0000db40 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 |..U..E.).....U..| +0000db50 83 ec 18 8b 4d 0c ba 67 66 66 66 89 c8 f7 ea c1 |....M..gfff.....| +0000db60 fa 02 89 c8 c1 f8 1f 29 c2 89 d0 89 45 f4 83 7d |.......)....E..}| +0000db70 f4 00 79 0e c7 45 f4 cc cc cc 0c c7 45 0c 08 00 |..y..E......E...| +0000db80 00 00 83 7d f4 00 74 14 83 ec 08 ff 75 f4 ff 75 |...}..t.....u..u| +0000db90 08 e8 b7 ff ff ff 83 c4 10 89 45 08 8b 4d 0c ba |..........E..M..| +0000dba0 67 66 66 66 89 c8 f7 ea c1 fa 02 89 c8 c1 f8 1f |gfff............| +0000dbb0 29 c2 89 d0 c1 e0 02 01 d0 01 c0 29 c1 89 ca 89 |)..........)....| +0000dbc0 d0 8d 48 30 8b 45 08 8d 50 01 89 55 08 89 ca 88 |..H0.E..P..U....| +0000dbd0 10 8b 45 08 c9 c3 55 89 e5 83 ec 20 c7 45 e3 30 |..E...U.... .E.0| +0000dbe0 31 32 33 c7 45 e7 34 35 36 37 c7 45 eb 38 39 41 |123.E.4567.E.89A| +0000dbf0 42 c7 45 ef 43 44 45 46 c6 45 f3 00 c7 45 fc 00 |B.E.CDEF.E...E..| +0000dc00 00 00 00 c7 45 f8 00 00 00 00 eb 43 8b 45 0c 25 |....E......C.E.%| +0000dc10 00 00 00 f0 89 45 f4 83 7d fc 00 75 0c 83 7d f4 |.....E..}..u..}.| +0000dc20 00 75 06 83 7d f8 07 75 1e 83 45 fc 01 c1 6d f4 |.u..}..u..E...m.| +0000dc30 1c 8b 45 08 8d 50 01 89 55 08 8d 4d e3 8b 55 f4 |..E..P..U..M..U.| +0000dc40 01 ca 0f b6 12 88 10 c1 65 0c 04 83 45 f8 01 83 |........e...E...| +0000dc50 7d f8 07 7e b7 8b 45 08 c6 00 00 8b 45 fc c9 c3 |}..~..E.....E...| +0000dc60 55 89 e5 83 ec 10 c7 45 f8 00 00 00 00 8b 45 08 |U......E......E.| +0000dc70 89 45 f4 8b 45 0c 25 00 00 00 c0 89 45 f0 c1 6d |.E..E.%.....E..m| +0000dc80 f0 1e c7 45 fc 00 00 00 00 eb 47 83 7d fc 0a 74 |...E......G.}..t| +0000dc90 0c 83 7d f0 00 75 06 83 7d f8 00 74 1e c7 45 f8 |..}..u..}..t..E.| +0000dca0 01 00 00 00 83 65 f0 07 8b 45 f0 8d 48 30 8b 45 |.....e...E..H0.E| +0000dcb0 f4 8d 50 01 89 55 f4 89 ca 88 10 c1 65 0c 03 8b |..P..U......e...| +0000dcc0 45 0c 25 00 00 00 e0 89 45 f0 c1 6d f0 1d 83 45 |E.%.....E..m...E| +0000dcd0 fc 01 83 7d fc 0a 7e b3 8b 45 f4 c6 00 00 8b 55 |...}..~..E.....U| +0000dce0 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 ec 18 |..E.).....U.....| +0000dcf0 8b 45 08 89 45 f4 83 ec 08 ff 75 0c ff 75 f4 e8 |.E..E.....u..u..| +0000dd00 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 c6 00 00 |........E..E....| +0000dd10 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 |.U..E.).....U...| +0000dd20 ec 18 8b 45 0c ba cd cc cc cc f7 e2 89 d0 c1 e8 |...E............| +0000dd30 03 89 45 f4 83 7d f4 00 74 15 8b 45 f4 83 ec 08 |..E..}..t..E....| +0000dd40 50 ff 75 08 e8 04 fe ff ff 83 c4 10 89 45 08 8b |P.u..........E..| +0000dd50 4d 0c ba cd cc cc cc 89 c8 f7 e2 c1 ea 03 89 d0 |M...............| +0000dd60 c1 e0 02 01 d0 01 c0 29 c1 89 ca 89 d0 8d 48 30 |.......)......H0| +0000dd70 8b 45 08 8d 50 01 89 55 08 89 ca 88 10 8b 45 08 |.E..P..U......E.| +0000dd80 c9 c3 55 89 e5 83 ec 18 83 7d 10 00 79 11 83 ec |..U......}..y...| +0000dd90 0c ff 75 0c e8 4b fd ff ff 83 c4 10 89 45 10 8b |..u..K.......E..| +0000dda0 45 14 2b 45 10 89 45 f0 83 7d f0 00 7e 1d 83 7d |E.+E..E..}..~..}| +0000ddb0 18 00 75 17 83 ec 04 ff 75 1c ff 75 f0 ff 75 08 |..u.....u..u..u.| +0000ddc0 e8 5a 00 00 00 83 c4 10 89 45 08 c7 45 f4 00 00 |.Z.......E..E...| +0000ddd0 00 00 eb 1b 8b 55 f4 8b 45 0c 8d 0c 02 8b 45 08 |.....U..E.....E.| +0000dde0 8d 50 01 89 55 08 0f b6 11 88 10 83 45 f4 01 8b |.P..U.......E...| +0000ddf0 45 f4 3b 45 10 7c dd 83 7d f0 00 7e 1d 83 7d 18 |E.;E.|..}..~..}.| +0000de00 00 74 17 83 ec 04 ff 75 1c ff 75 f0 ff 75 08 e8 |.t.....u..u..u..| +0000de10 0b 00 00 00 83 c4 10 89 45 08 8b 45 08 c9 c3 55 |........E..E...U| +0000de20 89 e5 eb 12 8b 45 08 8d 50 01 89 55 08 8b 55 10 |.....E..P..U..U.| +0000de30 88 10 83 6d 0c 01 83 7d 0c 00 7f e8 8b 45 08 5d |...m...}.....E.]| +0000de40 c3 00 00 00 6d 61 69 6e 34 3a 20 61 72 67 63 20 |....main4: argc | +0000de50 25 64 2c 20 61 72 67 73 3a 20 00 28 6e 75 6c 6c |%d, args: .(null| +0000de60 29 00 20 25 73 00 0a 00 75 73 65 72 58 00 58 00 |). %s...userX.X.| +0000de70 25 64 00 43 68 69 6c 64 20 25 64 20 65 78 65 63 |%d.Child %d exec| +0000de80 28 29 20 23 25 75 20 66 61 69 6c 65 64 0a 00 00 |() #%u failed...| +0000de90 92 14 00 00 d0 14 00 00 1c 16 00 00 1c 16 00 00 |................| +0000dea0 1c 16 00 00 1c 16 00 00 1c 16 00 00 1c 16 00 00 |................| +* +0000dec0 8a 15 00 00 1c 16 00 00 1c 16 00 00 1c 16 00 00 |................| +0000ded0 14 15 00 00 1c 16 00 00 cb 15 00 00 1c 16 00 00 |................| +0000dee0 1c 16 00 00 46 15 00 00 00 00 00 00 00 00 00 00 |....F...........| +0000def0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +0000e440 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 |................| +0000e450 03 00 01 00 00 00 00 00 10 1a 00 00 00 00 00 00 |................| +0000e460 03 00 02 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +0000e470 03 00 03 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +0000e480 03 00 04 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +0000e490 04 00 f1 ff 0a 00 00 00 00 00 00 00 00 00 00 00 |................| +0000e4a0 04 00 f1 ff 12 00 00 00 00 00 00 00 00 00 00 00 |................| +0000e4b0 04 00 f1 ff 1b 00 00 00 00 00 00 00 00 00 00 00 |................| +0000e4c0 04 00 f1 ff 25 00 00 00 00 00 00 00 00 00 00 00 |....%...........| +0000e4d0 04 00 f1 ff 2e 00 00 00 00 00 00 00 00 00 00 00 |................| +0000e4e0 04 00 f1 ff 37 00 00 00 00 00 00 00 00 00 00 00 |....7...........| +0000e4f0 04 00 f1 ff 41 00 00 00 00 00 00 00 00 00 00 00 |....A...........| +0000e500 04 00 f1 ff 4a 00 00 00 00 00 00 00 00 00 00 00 |....J...........| +0000e510 04 00 f1 ff 53 00 00 00 00 00 00 00 00 00 00 00 |....S...........| +0000e520 04 00 f1 ff 5c 00 00 00 00 00 00 00 00 00 00 00 |....\...........| +0000e530 04 00 f1 ff 66 00 00 00 00 00 00 00 00 00 00 00 |....f...........| +0000e540 04 00 f1 ff 6f 00 00 00 00 00 00 00 00 00 00 00 |....o...........| +0000e550 04 00 f1 ff 75 00 00 00 da 12 00 00 21 00 00 00 |....u.......!...| +0000e560 12 00 01 00 7e 00 00 00 4b 13 00 00 00 00 00 00 |....~...K.......| +0000e570 10 00 01 00 86 00 00 00 bf 12 00 00 1b 00 00 00 |................| +0000e580 12 00 01 00 8d 00 00 00 3e 16 00 00 72 00 00 00 |........>...r...| +0000e590 12 00 01 00 95 00 00 00 b6 18 00 00 32 00 00 00 |............2...| +0000e5a0 12 00 01 00 9c 00 00 00 73 13 00 00 00 00 00 00 |........s.......| +0000e5b0 10 00 01 00 a3 00 00 00 a3 13 00 00 00 00 00 00 |................| +0000e5c0 10 00 01 00 a9 00 00 00 28 13 00 00 1b 00 00 00 |........(.......| +0000e5d0 12 00 01 00 b0 00 00 00 eb 19 00 00 22 00 00 00 |............"...| +0000e5e0 12 00 01 00 b4 00 00 00 fc 11 00 00 75 00 00 00 |............u...| +0000e5f0 12 00 01 00 ba 00 00 00 c9 13 00 00 75 02 00 00 |............u...| +0000e600 12 00 01 00 c1 00 00 00 a2 17 00 00 8a 00 00 00 |................| +0000e610 12 00 01 00 c8 00 00 00 e8 18 00 00 66 00 00 00 |............f...| +0000e620 12 00 01 00 87 00 00 00 6b 13 00 00 00 00 00 00 |........k.......| +0000e630 10 00 01 00 d0 00 00 00 9b 13 00 00 00 00 00 00 |................| +0000e640 10 00 01 00 d5 00 00 00 92 12 00 00 2d 00 00 00 |............-...| +0000e650 12 00 01 00 dd 00 00 00 5b 13 00 00 00 00 00 00 |........[.......| +0000e660 10 00 01 00 e2 00 00 00 e4 11 00 00 18 00 00 00 |................| +0000e670 12 00 01 00 e7 00 00 00 fb 12 00 00 2d 00 00 00 |............-...| +0000e680 12 00 01 00 ef 00 00 00 b9 13 00 00 00 00 00 00 |................| +0000e690 10 00 01 00 f6 00 00 00 63 13 00 00 00 00 00 00 |........c.......| +0000e6a0 10 00 01 00 fb 00 00 00 8b 13 00 00 00 00 00 00 |................| +0000e6b0 10 00 01 00 03 01 00 00 19 17 00 00 89 00 00 00 |................| +0000e6c0 12 00 01 00 0b 01 00 00 53 13 00 00 00 00 00 00 |........S.......| +0000e6d0 10 00 01 00 10 01 00 00 00 10 00 00 e4 01 00 00 |................| +0000e6e0 12 00 01 00 15 01 00 00 7b 13 00 00 00 00 00 00 |........{.......| +0000e6f0 10 00 01 00 1d 01 00 00 4e 19 00 00 9d 00 00 00 |........N.......| +0000e700 12 00 01 00 24 01 00 00 93 13 00 00 00 00 00 00 |....$...........| +0000e710 10 00 01 00 2c 01 00 00 2c 18 00 00 8a 00 00 00 |....,...,.......| +0000e720 12 00 01 00 33 01 00 00 71 12 00 00 21 00 00 00 |....3...q...!...| +0000e730 12 00 01 00 3c 01 00 00 83 13 00 00 00 00 00 00 |....<...........| +0000e740 10 00 01 00 44 01 00 00 d2 16 00 00 47 00 00 00 |....D.......G...| +0000e750 12 00 01 00 5d 01 00 00 43 13 00 00 00 00 00 00 |....]...C.......| +0000e760 10 00 01 00 4b 01 00 00 b0 16 00 00 22 00 00 00 |....K......."...| +0000e770 12 00 01 00 52 01 00 00 ab 13 00 00 00 00 00 00 |....R...........| +0000e780 10 00 01 00 58 01 00 00 b3 13 00 00 00 00 00 00 |....X...........| +0000e790 10 00 01 00 00 70 72 6f 67 4b 4c 2e 63 00 75 6c |.....progKL.c.ul| +0000e7a0 69 62 63 2e 63 00 73 70 72 69 6e 74 2e 63 00 73 |ibc.c.sprint.c.s| +0000e7b0 74 72 32 69 6e 74 2e 63 00 73 74 72 6c 65 6e 2e |tr2int.c.strlen.| +0000e7c0 63 00 63 76 74 64 65 63 2e 63 00 63 76 74 64 65 |c.cvtdec.c.cvtde| +0000e7d0 63 30 2e 63 00 63 76 74 68 65 78 2e 63 00 63 76 |c0.c.cvthex.c.cv| +0000e7e0 74 6f 63 74 2e 63 00 63 76 74 75 6e 73 2e 63 00 |toct.c.cvtuns.c.| +0000e7f0 63 76 74 75 6e 73 30 2e 63 00 70 61 64 73 74 72 |cvtuns0.c.padstr| +0000e800 2e 63 00 70 61 64 2e 63 00 73 77 72 69 74 65 63 |.c.pad.c.swritec| +0000e810 68 00 77 61 69 74 70 69 64 00 63 77 72 69 74 65 |h.waitpid.cwrite| +0000e820 00 73 74 72 32 69 6e 74 00 63 76 74 75 6e 73 00 |.str2int.cvtuns.| +0000e830 67 65 74 70 69 64 00 73 6c 65 65 70 00 73 77 72 |getpid.sleep.swr| +0000e840 69 74 65 00 70 61 64 00 73 70 61 77 6e 00 73 70 |ite.pad.spawn.sp| +0000e850 72 69 6e 74 00 63 76 74 68 65 78 00 63 76 74 75 |rint.cvthex.cvtu| +0000e860 6e 73 30 00 6b 69 6c 6c 00 63 77 72 69 74 65 73 |ns0.kill.cwrites| +0000e870 00 65 78 65 63 00 77 61 69 74 00 73 77 72 69 74 |.exec.wait.swrit| +0000e880 65 73 00 5f 73 74 61 72 74 00 72 65 61 64 00 67 |es._start.read.g| +0000e890 65 74 70 72 69 6f 00 63 76 74 64 65 63 30 00 66 |etprio.cvtdec0.f| +0000e8a0 6f 72 6b 00 6d 61 69 6e 00 67 65 74 70 70 69 64 |ork.main.getppid| +0000e8b0 00 70 61 64 73 74 72 00 73 65 74 70 72 69 6f 00 |.padstr.setprio.| +0000e8c0 63 76 74 6f 63 74 00 63 77 72 69 74 65 63 68 00 |cvtoct.cwritech.| +0000e8d0 67 65 74 74 69 6d 65 00 63 76 74 64 65 63 00 73 |gettime.cvtdec.s| +0000e8e0 74 72 6c 65 6e 00 62 6f 67 75 73 00 66 61 6b 65 |trlen.bogus.fake| +0000e8f0 5f 65 78 69 74 00 00 2e 73 79 6d 74 61 62 00 2e |_exit...symtab..| +0000e900 73 74 72 74 61 62 00 2e 73 68 73 74 72 74 61 62 |strtab..shstrtab| +0000e910 00 2e 74 65 78 74 00 2e 72 6f 64 61 74 61 00 2e |..text..rodata..| +0000e920 64 61 74 61 00 2e 62 73 73 00 00 00 00 00 00 00 |data..bss.......| +0000e930 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +0000e950 00 00 00 00 1b 00 00 00 01 00 00 00 06 00 00 00 |................| +0000e960 00 10 00 00 74 00 00 00 0d 0a 00 00 00 00 00 00 |....t...........| +0000e970 00 00 00 00 01 00 00 00 00 00 00 00 21 00 00 00 |............!...| +0000e980 01 00 00 00 02 00 00 00 10 1a 00 00 84 0a 00 00 |................| +0000e990 a4 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |................| +0000e9a0 00 00 00 00 29 00 00 00 01 00 00 00 03 00 00 00 |....)...........| +0000e9b0 00 20 00 00 74 10 00 00 00 00 00 00 00 00 00 00 |. ..t...........| +0000e9c0 00 00 00 00 01 00 00 00 00 00 00 00 2f 00 00 00 |............/...| +0000e9d0 08 00 00 00 03 00 00 00 00 20 00 00 74 10 00 00 |......... ..t...| +0000e9e0 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +0000e9f0 00 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 |................| +0000ea00 00 00 00 00 74 10 00 00 60 03 00 00 06 00 00 00 |....t...`.......| +0000ea10 12 00 00 00 04 00 00 00 10 00 00 00 09 00 00 00 |................| +0000ea20 03 00 00 00 00 00 00 00 00 00 00 00 d4 13 00 00 |................| +0000ea30 62 01 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |b...............| +0000ea40 00 00 00 00 11 00 00 00 03 00 00 00 00 00 00 00 |................| +0000ea50 00 00 00 00 36 15 00 00 34 00 00 00 00 00 00 00 |....6...4.......| +0000ea60 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +0000ea70 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| +0000ea80 02 00 03 00 01 00 00 00 2a 14 00 00 34 00 00 00 |........*...4...| +0000ea90 6c 15 00 00 00 00 00 00 34 00 20 00 02 00 28 00 |l.......4. ...(.| +0000eaa0 08 00 07 00 01 00 00 00 74 00 00 00 00 10 00 00 |........t.......| +0000eab0 00 10 00 00 00 10 00 00 00 10 00 00 07 00 00 00 |................| +0000eac0 04 00 00 00 51 e5 74 64 00 00 00 00 00 00 00 00 |....Q.td........| +0000ead0 00 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 |................| +0000eae0 10 00 00 00 8d 4c 24 04 83 e4 f0 ff 71 fc 55 89 |.....L$.....q.U.| +0000eaf0 e5 53 51 81 ec d0 00 00 00 89 cb c7 45 f4 05 00 |.SQ.........E...| +0000eb00 00 00 c6 45 e3 35 c7 45 f0 00 00 00 00 c7 45 de |...E.5.E......E.| +0000eb10 2a 35 77 2a c6 45 e2 00 c7 45 d9 2a 35 7a 2a c6 |*5w*.E...E.*5z*.| +0000eb20 45 dd 00 8b 03 83 f8 03 74 22 83 f8 04 74 07 83 |E.......t"...t..| +0000eb30 f8 02 74 31 eb 42 8b 43 04 83 c0 0c 8b 00 0f b6 |..t1.B.C........| +0000eb40 00 3c 74 0f 94 c0 0f b6 c0 89 45 f0 8b 43 04 83 |.<t.......E..C..| +0000eb50 c0 08 8b 00 83 ec 08 6a 0a 50 e8 34 06 00 00 83 |.......j.P.4....| +0000eb60 c4 10 89 45 f4 8b 43 04 83 c0 04 8b 00 0f b6 00 |...E..C.........| +0000eb70 88 45 e3 e9 a4 00 00 00 83 ec 04 ff 33 68 80 1a |.E..........3h..| +0000eb80 00 00 8d 85 59 ff ff ff 50 e8 90 03 00 00 83 c4 |....Y...P.......| +0000eb90 10 83 ec 0c 8d 85 59 ff ff ff 50 e8 47 02 00 00 |......Y...P.G...| +0000eba0 83 c4 10 c7 45 ec 00 00 00 00 eb 59 8b 03 8d 14 |....E......Y....| +0000ebb0 85 00 00 00 00 8b 43 04 01 d0 8b 00 85 c0 74 12 |......C.......t.| +0000ebc0 8b 03 8d 14 85 00 00 00 00 8b 43 04 01 d0 8b 00 |..........C.....| +0000ebd0 eb 05 b8 97 1a 00 00 83 ec 04 50 68 9e 1a 00 00 |..........Ph....| +0000ebe0 8d 85 59 ff ff ff 50 e8 32 03 00 00 83 c4 10 83 |..Y...P.2.......| +0000ebf0 ec 0c 8d 85 59 ff ff ff 50 e8 e9 01 00 00 83 c4 |....Y...P.......| +0000ec00 10 83 45 ec 01 8b 45 ec 3b 03 7e a0 83 ec 0c 68 |..E...E.;.~....h| +0000ec10 a2 1a 00 00 e8 ce 01 00 00 83 c4 10 0f b6 45 e3 |..............E.| +0000ec20 88 45 da 0f b6 45 da 88 45 df 83 ec 04 6a 01 8d |.E...E..E....j..| +0000ec30 45 e3 50 6a 01 e8 86 02 00 00 83 c4 10 c7 85 44 |E.Pj...........D| +0000ec40 ff ff ff a4 1a 00 00 c7 85 48 ff ff ff aa 1a 00 |.........H......| +0000ec50 00 c7 85 4c ff ff ff ac 1a 00 00 c7 85 50 ff ff |...L.........P..| +0000ec60 ff af 1a 00 00 c7 85 54 ff ff ff 00 00 00 00 c7 |.......T........| +0000ec70 85 34 ff ff ff b1 1a 00 00 c7 85 38 ff ff ff b7 |.4.........8....| +0000ec80 1a 00 00 c7 85 3c ff ff ff ac 1a 00 00 c7 85 40 |.....<.........@| +0000ec90 ff ff ff 00 00 00 00 c7 45 e8 00 00 00 00 eb 75 |........E......u| +0000eca0 83 ec 04 6a 01 8d 45 e3 50 6a 01 e8 10 02 00 00 |...j..E.Pj......| +0000ecb0 83 c4 10 83 ec 08 8d 85 44 ff ff ff 50 6a 10 e8 |........D...Pj..| +0000ecc0 8d 00 00 00 83 c4 10 89 45 e4 83 7d e4 00 7f 0f |........E..}....| +0000ecd0 83 ec 0c 8d 45 de 50 e8 74 01 00 00 83 c4 10 83 |....E.P.t.......| +0000ece0 7d f0 00 74 2c 83 ec 08 8d 85 34 ff ff ff 50 6a |}..t,.....4...Pj| +0000ecf0 13 e8 5b 00 00 00 83 c4 10 89 45 e4 83 7d e4 00 |..[.......E..}..| +0000ed00 7f 0f 83 ec 0c 8d 45 d9 50 e8 42 01 00 00 83 c4 |......E.P.B.....| +0000ed10 10 83 45 e8 01 8b 45 e8 3b 45 f4 7c 83 83 ec 0c |..E...E.;E.|....| +0000ed20 6a 00 e8 71 01 00 00 83 c4 10 b8 2a 00 00 00 8d |j..q.......*....| +0000ed30 65 f8 59 5b 5d 8d 61 fc c3 55 89 e5 83 ec 08 83 |e.Y[].a..U......| +0000ed40 ec 08 ff 75 08 6a 00 e8 54 01 00 00 83 c4 10 c9 |...u.j..T.......| +0000ed50 c3 55 89 e5 81 ec 18 01 00 00 e8 49 01 00 00 89 |.U.........I....| +0000ed60 45 f4 83 7d f4 00 74 05 8b 45 f4 eb 57 e8 56 01 |E..}..t..E..W.V.| +0000ed70 00 00 89 45 f4 83 ec 08 ff 75 0c ff 75 08 e8 2d |...E.....u..u..-| +0000ed80 01 00 00 83 c4 10 ff 75 08 ff 75 f4 68 b9 1a 00 |.......u..u.h...| +0000ed90 00 8d 85 f4 fe ff ff 50 e8 81 01 00 00 83 c4 10 |.......P........| +0000eda0 83 ec 0c 8d 85 f4 fe ff ff 50 e8 38 00 00 00 83 |.........P.8....| +0000edb0 c4 10 83 ec 0c 6a ff e8 dc 00 00 00 83 c4 10 b8 |.....j..........| +0000edc0 00 00 00 00 c9 c3 55 89 e5 83 ec 18 8b 45 08 88 |......U......E..| +0000edd0 45 f4 83 ec 04 6a 01 8d 45 f4 50 6a 00 e8 de 00 |E....j..E.Pj....| +0000ede0 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 83 ec 0c |.......U........| +0000edf0 ff 75 08 e8 0d 04 00 00 83 c4 10 89 45 f4 8b 45 |.u..........E..E| +0000ee00 f4 83 ec 04 50 ff 75 08 6a 00 e8 b1 00 00 00 83 |....P.u.j.......| +0000ee10 c4 10 c9 c3 55 89 e5 83 ec 08 83 ec 04 ff 75 0c |....U.........u.| +0000ee20 ff 75 08 6a 00 e8 96 00 00 00 83 c4 10 c9 c3 55 |.u.j...........U| +0000ee30 89 e5 83 ec 18 8b 45 08 88 45 f4 83 ec 04 6a 01 |......E..E....j.| +0000ee40 8d 45 f4 50 6a 01 e8 75 00 00 00 83 c4 10 c9 c3 |.E.Pj..u........| +0000ee50 55 89 e5 83 ec 18 83 ec 0c ff 75 08 e8 a4 03 00 |U.........u.....| +0000ee60 00 83 c4 10 89 45 f4 8b 45 f4 83 ec 04 50 ff 75 |.....E..E....P.u| +0000ee70 08 6a 01 e8 48 00 00 00 83 c4 10 c9 c3 55 89 e5 |.j..H........U..| +0000ee80 83 ec 08 83 ec 04 ff 75 0c ff 75 08 6a 01 e8 2d |.......u..u.j..-| +0000ee90 00 00 00 83 c4 10 c9 c3 b8 00 00 00 00 cd 80 c3 |................| +0000eea0 b8 01 00 00 00 cd 80 c3 b8 02 00 00 00 cd 80 c3 |................| +0000eeb0 b8 03 00 00 00 cd 80 c3 b8 04 00 00 00 cd 80 c3 |................| +0000eec0 b8 05 00 00 00 cd 80 c3 b8 06 00 00 00 cd 80 c3 |................| +0000eed0 b8 07 00 00 00 cd 80 c3 b8 08 00 00 00 cd 80 c3 |................| +0000eee0 b8 09 00 00 00 cd 80 c3 b8 0a 00 00 00 cd 80 c3 |................| +0000eef0 b8 0b 00 00 00 cd 80 c3 b8 0c 00 00 00 cd 80 c3 |................| +0000ef00 b8 ad 0b 00 00 cd 80 c3 50 e8 8a ff ff ff e8 d1 |........P.......| +0000ef10 fb ff ff 83 ec 0c 50 e8 7c ff ff ff eb fe 55 89 |......P.|.....U.| +0000ef20 e5 83 ec 38 8d 45 0c 83 c0 04 89 45 f4 e9 3f 02 |...8.E.....E..?.| +0000ef30 00 00 80 7d f3 25 0f 85 26 02 00 00 c7 45 ec 00 |...}.%..&....E..| +0000ef40 00 00 00 c7 45 e4 20 00 00 00 c7 45 e8 00 00 00 |....E. ....E....| +0000ef50 00 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 |..E..P..U.....E.| +0000ef60 80 7d f3 2d 75 16 c7 45 ec 01 00 00 00 8b 45 0c |.}.-u..E......E.| +0000ef70 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 30 |.P..U.....E..}.0| +0000ef80 75 40 c7 45 e4 30 00 00 00 8b 45 0c 8d 50 01 89 |u@.E.0....E..P..| +0000ef90 55 0c 0f b6 00 88 45 f3 eb 28 8b 55 e8 89 d0 c1 |U.....E..(.U....| +0000efa0 e0 02 01 d0 01 c0 89 45 e8 0f be 45 f3 83 e8 30 |.......E...E...0| +0000efb0 01 45 e8 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 |.E..E..P..U.....| +0000efc0 45 f3 80 7d f3 2f 7e 06 80 7d f3 39 7e cc 0f be |E..}./~..}.9~...| +0000efd0 45 f3 83 e8 63 83 f8 15 0f 87 93 01 00 00 8b 04 |E...c...........| +0000efe0 85 d8 1a 00 00 ff e0 8b 45 f4 8d 50 04 89 55 f4 |........E..P..U.| +0000eff0 8b 00 88 45 f3 0f b6 45 f3 88 45 d0 c6 45 d1 00 |...E...E..E..E..| +0000f000 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 6a 01 8d 45 |....u..u..u.j..E| +0000f010 d0 50 ff 75 08 e8 89 04 00 00 83 c4 20 89 45 08 |.P.u........ .E.| +0000f020 e9 4c 01 00 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 |.L....E..P..U...| +0000f030 83 ec 08 50 8d 45 d0 50 e8 ea 01 00 00 83 c4 10 |...P.E.P........| +0000f040 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff |.E.....u..u..u..| +0000f050 75 e0 8d 45 d0 50 ff 75 08 e8 45 04 00 00 83 c4 |u..E.P.u..E.....| +0000f060 20 89 45 08 e9 08 01 00 00 8b 45 f4 8d 50 04 89 | .E.......E..P..| +0000f070 55 f4 8b 00 89 45 dc 83 ec 08 ff 75 e4 ff 75 ec |U....E.....u..u.| +0000f080 ff 75 e8 6a ff ff 75 dc ff 75 08 e8 13 04 00 00 |.u.j..u..u......| +0000f090 83 c4 20 89 45 08 e9 d6 00 00 00 8b 45 f4 8d 50 |.. .E.......E..P| +0000f0a0 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 44 |..U......P.E.P.D| +0000f0b0 02 00 00 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff |.......E.....u..| +0000f0c0 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 |u..u..u..E.P.u..| +0000f0d0 cf 03 00 00 83 c4 20 89 45 08 e9 92 00 00 00 8b |...... .E.......| +0000f0e0 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 |E..P..U......P.E| +0000f0f0 d0 50 e8 8a 02 00 00 83 c4 10 89 45 e0 83 ec 08 |.P.........E....| +0000f100 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 |.u..u..u..u..E.P| +0000f110 ff 75 08 e8 8b 03 00 00 83 c4 20 89 45 08 eb 51 |.u........ .E..Q| +0000f120 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d |.E..P..U......P.| +0000f130 45 d0 50 e8 d3 02 00 00 83 c4 10 89 45 e0 83 ec |E.P.........E...| +0000f140 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 |..u..u..u..u..E.| +0000f150 50 ff 75 08 e8 4a 03 00 00 83 c4 20 89 45 08 90 |P.u..J..... .E..| +0000f160 eb 0f 8b 45 08 8d 50 01 89 55 08 0f b6 55 f3 88 |...E..P..U...U..| +0000f170 10 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 |..E..P..U.....E.| +0000f180 80 7d f3 00 0f 85 a8 fd ff ff 8b 45 08 c6 00 00 |.}.........E....| +0000f190 90 c9 c3 55 89 e5 53 83 ec 14 8b 45 08 8b 4d 0c |...U..S....E..M.| +0000f1a0 bb 00 00 00 00 c6 45 eb 39 c7 45 f8 01 00 00 00 |......E.9.E.....| +0000f1b0 0f b6 10 80 fa 2d 75 0a c7 45 f8 ff ff ff ff 83 |.....-u..E......| +0000f1c0 c0 01 83 f9 0a 74 2b 89 ca 83 c2 2f 88 55 eb eb |.....t+..../.U..| +0000f1d0 21 0f b6 10 80 fa 2f 7e 20 0f b6 10 38 55 eb 7c |!...../~ ...8U.|| +0000f1e0 18 0f af d9 0f b6 10 0f be d2 01 da 8d 5a d0 83 |.............Z..| +0000f1f0 c0 01 0f b6 10 84 d2 75 d8 89 d8 0f af 45 f8 83 |.......u.....E..| +0000f200 c4 14 5b 5d c3 55 89 e5 53 8b 55 08 bb 00 00 00 |..[].U..S.U.....| +0000f210 00 eb 03 83 c3 01 89 d0 8d 50 01 0f b6 00 84 c0 |.........P......| +0000f220 75 f1 89 d8 5b 5d c3 55 89 e5 83 ec 18 8b 45 08 |u...[].U......E.| +0000f230 89 45 f4 83 7d 0c 00 79 0f 8b 45 f4 8d 50 01 89 |.E..}..y..E..P..| +0000f240 55 f4 c6 00 2d f7 5d 0c 83 ec 08 ff 75 0c ff 75 |U...-.].....u..u| +0000f250 f4 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 c6 |..........E..E..| +0000f260 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 |...U..E.).....U.| +0000f270 e5 83 ec 18 8b 4d 0c ba 67 66 66 66 89 c8 f7 ea |.....M..gfff....| +0000f280 c1 fa 02 89 c8 c1 f8 1f 29 c2 89 d0 89 45 f4 83 |........)....E..| +0000f290 7d f4 00 79 0e c7 45 f4 cc cc cc 0c c7 45 0c 08 |}..y..E......E..| +0000f2a0 00 00 00 83 7d f4 00 74 14 83 ec 08 ff 75 f4 ff |....}..t.....u..| +0000f2b0 75 08 e8 b7 ff ff ff 83 c4 10 89 45 08 8b 4d 0c |u..........E..M.| +0000f2c0 ba 67 66 66 66 89 c8 f7 ea c1 fa 02 89 c8 c1 f8 |.gfff...........| +0000f2d0 1f 29 c2 89 d0 c1 e0 02 01 d0 01 c0 29 c1 89 ca |.)..........)...| +0000f2e0 89 d0 8d 48 30 8b 45 08 8d 50 01 89 55 08 89 ca |...H0.E..P..U...| +0000f2f0 88 10 8b 45 08 c9 c3 55 89 e5 83 ec 20 c7 45 e3 |...E...U.... .E.| +0000f300 30 31 32 33 c7 45 e7 34 35 36 37 c7 45 eb 38 39 |0123.E.4567.E.89| +0000f310 41 42 c7 45 ef 43 44 45 46 c6 45 f3 00 c7 45 fc |AB.E.CDEF.E...E.| +0000f320 00 00 00 00 c7 45 f8 00 00 00 00 eb 43 8b 45 0c |.....E......C.E.| +0000f330 25 00 00 00 f0 89 45 f4 83 7d fc 00 75 0c 83 7d |%.....E..}..u..}| +0000f340 f4 00 75 06 83 7d f8 07 75 1e 83 45 fc 01 c1 6d |..u..}..u..E...m| +0000f350 f4 1c 8b 45 08 8d 50 01 89 55 08 8d 4d e3 8b 55 |...E..P..U..M..U| +0000f360 f4 01 ca 0f b6 12 88 10 c1 65 0c 04 83 45 f8 01 |.........e...E..| +0000f370 83 7d f8 07 7e b7 8b 45 08 c6 00 00 8b 45 fc c9 |.}..~..E.....E..| +0000f380 c3 55 89 e5 83 ec 10 c7 45 f8 00 00 00 00 8b 45 |.U......E......E| +0000f390 08 89 45 f4 8b 45 0c 25 00 00 00 c0 89 45 f0 c1 |..E..E.%.....E..| +0000f3a0 6d f0 1e c7 45 fc 00 00 00 00 eb 47 83 7d fc 0a |m...E......G.}..| +0000f3b0 74 0c 83 7d f0 00 75 06 83 7d f8 00 74 1e c7 45 |t..}..u..}..t..E| +0000f3c0 f8 01 00 00 00 83 65 f0 07 8b 45 f0 8d 48 30 8b |......e...E..H0.| +0000f3d0 45 f4 8d 50 01 89 55 f4 89 ca 88 10 c1 65 0c 03 |E..P..U......e..| +0000f3e0 8b 45 0c 25 00 00 00 e0 89 45 f0 c1 6d f0 1d 83 |.E.%.....E..m...| +0000f3f0 45 fc 01 83 7d fc 0a 7e b3 8b 45 f4 c6 00 00 8b |E...}..~..E.....| +0000f400 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 ec |U..E.).....U....| +0000f410 18 8b 45 08 89 45 f4 83 ec 08 ff 75 0c ff 75 f4 |..E..E.....u..u.| +0000f420 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 c6 00 |.........E..E...| +0000f430 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 |..U..E.).....U..| +0000f440 83 ec 18 8b 45 0c ba cd cc cc cc f7 e2 89 d0 c1 |....E...........| +0000f450 e8 03 89 45 f4 83 7d f4 00 74 15 8b 45 f4 83 ec |...E..}..t..E...| +0000f460 08 50 ff 75 08 e8 04 fe ff ff 83 c4 10 89 45 08 |.P.u..........E.| +0000f470 8b 4d 0c ba cd cc cc cc 89 c8 f7 e2 c1 ea 03 89 |.M..............| +0000f480 d0 c1 e0 02 01 d0 01 c0 29 c1 89 ca 89 d0 8d 48 |........)......H| +0000f490 30 8b 45 08 8d 50 01 89 55 08 89 ca 88 10 8b 45 |0.E..P..U......E| +0000f4a0 08 c9 c3 55 89 e5 83 ec 18 83 7d 10 00 79 11 83 |...U......}..y..| +0000f4b0 ec 0c ff 75 0c e8 4b fd ff ff 83 c4 10 89 45 10 |...u..K.......E.| +0000f4c0 8b 45 14 2b 45 10 89 45 f0 83 7d f0 00 7e 1d 83 |.E.+E..E..}..~..| +0000f4d0 7d 18 00 75 17 83 ec 04 ff 75 1c ff 75 f0 ff 75 |}..u.....u..u..u| +0000f4e0 08 e8 5a 00 00 00 83 c4 10 89 45 08 c7 45 f4 00 |..Z.......E..E..| +0000f4f0 00 00 00 eb 1b 8b 55 f4 8b 45 0c 8d 0c 02 8b 45 |......U..E.....E| +0000f500 08 8d 50 01 89 55 08 0f b6 11 88 10 83 45 f4 01 |..P..U.......E..| +0000f510 8b 45 f4 3b 45 10 7c dd 83 7d f0 00 7e 1d 83 7d |.E.;E.|..}..~..}| +0000f520 18 00 74 17 83 ec 04 ff 75 1c ff 75 f0 ff 75 08 |..t.....u..u..u.| +0000f530 e8 0b 00 00 00 83 c4 10 89 45 08 8b 45 08 c9 c3 |.........E..E...| +0000f540 55 89 e5 eb 12 8b 45 08 8d 50 01 89 55 08 8b 55 |U.....E..P..U..U| +0000f550 10 88 10 83 6d 0c 01 83 7d 0c 00 7f e8 8b 45 08 |....m...}.....E.| +0000f560 5d c3 00 00 6d 61 69 6e 35 3a 20 61 72 67 63 20 |]...main5: argc | +0000f570 25 64 2c 20 61 72 67 73 3a 20 00 28 6e 75 6c 6c |%d, args: .(null| +0000f580 29 00 20 25 73 00 0a 00 75 73 65 72 57 00 57 00 |). %s...userW.W.| +0000f590 31 35 00 35 00 75 73 65 72 5a 00 5a 00 43 68 69 |15.5.userZ.Z.Chi| +0000f5a0 6c 64 20 25 64 20 65 78 65 63 28 29 20 23 25 75 |ld %d exec() #%u| +0000f5b0 20 66 61 69 6c 65 64 0a 00 00 00 00 03 15 00 00 | failed.........| +0000f5c0 41 15 00 00 8d 16 00 00 8d 16 00 00 8d 16 00 00 |A...............| +0000f5d0 8d 16 00 00 8d 16 00 00 8d 16 00 00 8d 16 00 00 |................| +0000f5e0 8d 16 00 00 8d 16 00 00 8d 16 00 00 fb 15 00 00 |................| +0000f5f0 8d 16 00 00 8d 16 00 00 8d 16 00 00 85 15 00 00 |................| +0000f600 8d 16 00 00 3c 16 00 00 8d 16 00 00 8d 16 00 00 |....<...........| +0000f610 b7 15 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +0000f620 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +0000faf0 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 |................| +0000fb00 03 00 01 00 00 00 00 00 80 1a 00 00 00 00 00 00 |................| +0000fb10 03 00 02 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +0000fb20 03 00 03 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +0000fb30 03 00 04 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +0000fb40 04 00 f1 ff 0a 00 00 00 00 00 00 00 00 00 00 00 |................| +0000fb50 04 00 f1 ff 12 00 00 00 00 00 00 00 00 00 00 00 |................| +0000fb60 04 00 f1 ff 1b 00 00 00 00 00 00 00 00 00 00 00 |................| +0000fb70 04 00 f1 ff 25 00 00 00 00 00 00 00 00 00 00 00 |....%...........| +0000fb80 04 00 f1 ff 2e 00 00 00 00 00 00 00 00 00 00 00 |................| +0000fb90 04 00 f1 ff 37 00 00 00 00 00 00 00 00 00 00 00 |....7...........| +0000fba0 04 00 f1 ff 41 00 00 00 00 00 00 00 00 00 00 00 |....A...........| +0000fbb0 04 00 f1 ff 4a 00 00 00 00 00 00 00 00 00 00 00 |....J...........| +0000fbc0 04 00 f1 ff 53 00 00 00 00 00 00 00 00 00 00 00 |....S...........| +0000fbd0 04 00 f1 ff 5c 00 00 00 00 00 00 00 00 00 00 00 |....\...........| +0000fbe0 04 00 f1 ff 66 00 00 00 00 00 00 00 00 00 00 00 |....f...........| +0000fbf0 04 00 f1 ff 6f 00 00 00 00 00 00 00 00 00 00 00 |....o...........| +0000fc00 04 00 f1 ff 75 00 00 00 4b 13 00 00 21 00 00 00 |....u...K...!...| +0000fc10 12 00 01 00 7e 00 00 00 bc 13 00 00 00 00 00 00 |....~...........| +0000fc20 10 00 01 00 86 00 00 00 30 13 00 00 1b 00 00 00 |........0.......| +0000fc30 12 00 01 00 8d 00 00 00 af 16 00 00 72 00 00 00 |............r...| +0000fc40 12 00 01 00 95 00 00 00 27 19 00 00 32 00 00 00 |........'...2...| +0000fc50 12 00 01 00 9c 00 00 00 e4 13 00 00 00 00 00 00 |................| +0000fc60 10 00 01 00 a3 00 00 00 14 14 00 00 00 00 00 00 |................| +0000fc70 10 00 01 00 a9 00 00 00 99 13 00 00 1b 00 00 00 |................| +0000fc80 12 00 01 00 b0 00 00 00 5c 1a 00 00 22 00 00 00 |........\..."...| +0000fc90 12 00 01 00 b4 00 00 00 6d 12 00 00 75 00 00 00 |........m...u...| +0000fca0 12 00 01 00 ba 00 00 00 3a 14 00 00 75 02 00 00 |........:...u...| +0000fcb0 12 00 01 00 c1 00 00 00 13 18 00 00 8a 00 00 00 |................| +0000fcc0 12 00 01 00 c8 00 00 00 59 19 00 00 66 00 00 00 |........Y...f...| +0000fcd0 12 00 01 00 87 00 00 00 dc 13 00 00 00 00 00 00 |................| +0000fce0 10 00 01 00 d0 00 00 00 0c 14 00 00 00 00 00 00 |................| +0000fcf0 10 00 01 00 d5 00 00 00 03 13 00 00 2d 00 00 00 |............-...| +0000fd00 12 00 01 00 dd 00 00 00 cc 13 00 00 00 00 00 00 |................| +0000fd10 10 00 01 00 e2 00 00 00 55 12 00 00 18 00 00 00 |........U.......| +0000fd20 12 00 01 00 e7 00 00 00 6c 13 00 00 2d 00 00 00 |........l...-...| +0000fd30 12 00 01 00 ef 00 00 00 2a 14 00 00 00 00 00 00 |........*.......| +0000fd40 10 00 01 00 f6 00 00 00 d4 13 00 00 00 00 00 00 |................| +0000fd50 10 00 01 00 fb 00 00 00 fc 13 00 00 00 00 00 00 |................| +0000fd60 10 00 01 00 03 01 00 00 8a 17 00 00 89 00 00 00 |................| +0000fd70 12 00 01 00 0b 01 00 00 c4 13 00 00 00 00 00 00 |................| +0000fd80 10 00 01 00 10 01 00 00 00 10 00 00 55 02 00 00 |............U...| +0000fd90 12 00 01 00 15 01 00 00 ec 13 00 00 00 00 00 00 |................| +0000fda0 10 00 01 00 1d 01 00 00 bf 19 00 00 9d 00 00 00 |................| +0000fdb0 12 00 01 00 24 01 00 00 04 14 00 00 00 00 00 00 |....$...........| +0000fdc0 10 00 01 00 2c 01 00 00 9d 18 00 00 8a 00 00 00 |....,...........| +0000fdd0 12 00 01 00 33 01 00 00 e2 12 00 00 21 00 00 00 |....3.......!...| +0000fde0 12 00 01 00 3c 01 00 00 f4 13 00 00 00 00 00 00 |....<...........| +0000fdf0 10 00 01 00 44 01 00 00 43 17 00 00 47 00 00 00 |....D...C...G...| +0000fe00 12 00 01 00 5d 01 00 00 b4 13 00 00 00 00 00 00 |....]...........| +0000fe10 10 00 01 00 4b 01 00 00 21 17 00 00 22 00 00 00 |....K...!..."...| +0000fe20 12 00 01 00 52 01 00 00 1c 14 00 00 00 00 00 00 |....R...........| +0000fe30 10 00 01 00 58 01 00 00 24 14 00 00 00 00 00 00 |....X...$.......| +0000fe40 10 00 01 00 00 70 72 6f 67 4d 4e 2e 63 00 75 6c |.....progMN.c.ul| +0000fe50 69 62 63 2e 63 00 73 70 72 69 6e 74 2e 63 00 73 |ibc.c.sprint.c.s| +0000fe60 74 72 32 69 6e 74 2e 63 00 73 74 72 6c 65 6e 2e |tr2int.c.strlen.| +0000fe70 63 00 63 76 74 64 65 63 2e 63 00 63 76 74 64 65 |c.cvtdec.c.cvtde| +0000fe80 63 30 2e 63 00 63 76 74 68 65 78 2e 63 00 63 76 |c0.c.cvthex.c.cv| +0000fe90 74 6f 63 74 2e 63 00 63 76 74 75 6e 73 2e 63 00 |toct.c.cvtuns.c.| +0000fea0 63 76 74 75 6e 73 30 2e 63 00 70 61 64 73 74 72 |cvtuns0.c.padstr| +0000feb0 2e 63 00 70 61 64 2e 63 00 73 77 72 69 74 65 63 |.c.pad.c.swritec| +0000fec0 68 00 77 61 69 74 70 69 64 00 63 77 72 69 74 65 |h.waitpid.cwrite| +0000fed0 00 73 74 72 32 69 6e 74 00 63 76 74 75 6e 73 00 |.str2int.cvtuns.| +0000fee0 67 65 74 70 69 64 00 73 6c 65 65 70 00 73 77 72 |getpid.sleep.swr| +0000fef0 69 74 65 00 70 61 64 00 73 70 61 77 6e 00 73 70 |ite.pad.spawn.sp| +0000ff00 72 69 6e 74 00 63 76 74 68 65 78 00 63 76 74 75 |rint.cvthex.cvtu| +0000ff10 6e 73 30 00 6b 69 6c 6c 00 63 77 72 69 74 65 73 |ns0.kill.cwrites| +0000ff20 00 65 78 65 63 00 77 61 69 74 00 73 77 72 69 74 |.exec.wait.swrit| +0000ff30 65 73 00 5f 73 74 61 72 74 00 72 65 61 64 00 67 |es._start.read.g| +0000ff40 65 74 70 72 69 6f 00 63 76 74 64 65 63 30 00 66 |etprio.cvtdec0.f| +0000ff50 6f 72 6b 00 6d 61 69 6e 00 67 65 74 70 70 69 64 |ork.main.getppid| +0000ff60 00 70 61 64 73 74 72 00 73 65 74 70 72 69 6f 00 |.padstr.setprio.| +0000ff70 63 76 74 6f 63 74 00 63 77 72 69 74 65 63 68 00 |cvtoct.cwritech.| +0000ff80 67 65 74 74 69 6d 65 00 63 76 74 64 65 63 00 73 |gettime.cvtdec.s| +0000ff90 74 72 6c 65 6e 00 62 6f 67 75 73 00 66 61 6b 65 |trlen.bogus.fake| +0000ffa0 5f 65 78 69 74 00 00 2e 73 79 6d 74 61 62 00 2e |_exit...symtab..| +0000ffb0 73 74 72 74 61 62 00 2e 73 68 73 74 72 74 61 62 |strtab..shstrtab| +0000ffc0 00 2e 74 65 78 74 00 2e 72 6f 64 61 74 61 00 2e |..text..rodata..| +0000ffd0 64 61 74 61 00 2e 62 73 73 00 00 00 00 00 00 00 |data..bss.......| +0000ffe0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00010000 00 00 00 00 1b 00 00 00 01 00 00 00 06 00 00 00 |................| +00010010 00 10 00 00 74 00 00 00 7e 0a 00 00 00 00 00 00 |....t...~.......| +00010020 00 00 00 00 01 00 00 00 00 00 00 00 21 00 00 00 |............!...| +00010030 01 00 00 00 02 00 00 00 80 1a 00 00 f4 0a 00 00 |................| +00010040 b0 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |................| +00010050 00 00 00 00 29 00 00 00 01 00 00 00 03 00 00 00 |....)...........| +00010060 00 20 00 00 74 10 00 00 00 00 00 00 00 00 00 00 |. ..t...........| +00010070 00 00 00 00 01 00 00 00 00 00 00 00 2f 00 00 00 |............/...| +00010080 08 00 00 00 03 00 00 00 00 20 00 00 74 10 00 00 |......... ..t...| +00010090 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +000100a0 00 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 |................| +000100b0 00 00 00 00 74 10 00 00 60 03 00 00 06 00 00 00 |....t...`.......| +000100c0 12 00 00 00 04 00 00 00 10 00 00 00 09 00 00 00 |................| +000100d0 03 00 00 00 00 00 00 00 00 00 00 00 d4 13 00 00 |................| +000100e0 62 01 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |b...............| +000100f0 00 00 00 00 11 00 00 00 03 00 00 00 00 00 00 00 |................| +00010100 00 00 00 00 36 15 00 00 34 00 00 00 00 00 00 00 |....6...4.......| +00010110 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +00010120 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| +00010130 02 00 03 00 01 00 00 00 87 13 00 00 34 00 00 00 |............4...| +00010140 6c 15 00 00 00 00 00 00 34 00 20 00 02 00 28 00 |l.......4. ...(.| +00010150 08 00 07 00 01 00 00 00 74 00 00 00 00 10 00 00 |........t.......| +00010160 00 10 00 00 00 10 00 00 00 10 00 00 07 00 00 00 |................| +00010170 04 00 00 00 51 e5 74 64 00 00 00 00 00 00 00 00 |....Q.td........| +00010180 00 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 |................| +00010190 10 00 00 00 8d 4c 24 04 83 e4 f0 ff 71 fc 55 89 |.....L$.....q.U.| +000101a0 e5 53 51 81 ec a0 00 00 00 89 cb c7 45 f4 03 00 |.SQ.........E...| +000101b0 00 00 c6 45 e3 70 c7 45 f0 02 00 00 00 8b 03 83 |...E.p.E........| +000101c0 f8 03 74 25 83 f8 04 74 07 83 f8 02 74 34 eb 45 |..t%...t....t4.E| +000101d0 8b 43 04 83 c0 0c 8b 00 83 ec 08 6a 0a 50 e8 bd |.C.........j.P..| +000101e0 05 00 00 83 c4 10 89 45 f0 8b 43 04 83 c0 08 8b |.......E..C.....| +000101f0 00 83 ec 08 6a 0a 50 e8 a4 05 00 00 83 c4 10 89 |....j.P.........| +00010200 45 f4 8b 43 04 83 c0 04 8b 00 0f b6 00 88 45 e3 |E..C..........E.| +00010210 e9 a4 00 00 00 83 ec 04 ff 33 68 dc 19 00 00 8d |.........3h.....| +00010220 85 63 ff ff ff 50 e8 00 03 00 00 83 c4 10 83 ec |.c...P..........| +00010230 0c 8d 85 63 ff ff ff 50 e8 b7 01 00 00 83 c4 10 |...c...P........| +00010240 c7 45 ec 00 00 00 00 eb 59 8b 03 8d 14 85 00 00 |.E......Y.......| +00010250 00 00 8b 43 04 01 d0 8b 00 85 c0 74 12 8b 03 8d |...C.......t....| +00010260 14 85 00 00 00 00 8b 43 04 01 d0 8b 00 eb 05 b8 |.......C........| +00010270 f3 19 00 00 83 ec 04 50 68 fa 19 00 00 8d 85 63 |.......Ph......c| +00010280 ff ff ff 50 e8 a2 02 00 00 83 c4 10 83 ec 0c 8d |...P............| +00010290 85 63 ff ff ff 50 e8 59 01 00 00 83 c4 10 83 45 |.c...P.Y.......E| +000102a0 ec 01 8b 45 ec 3b 03 7e a0 83 ec 0c 68 fe 19 00 |...E.;.~....h...| +000102b0 00 e8 3e 01 00 00 83 c4 10 e8 27 02 00 00 89 45 |..>.......'....E| +000102c0 e4 83 ec 04 ff 75 e4 68 00 1a 00 00 8d 85 63 ff |.....u.h......c.| +000102d0 ff ff 50 e8 53 02 00 00 83 c4 10 83 ec 0c 8d 85 |..P.S...........| +000102e0 63 ff ff ff 50 e8 73 01 00 00 83 c4 10 c7 45 e8 |c...P.s.......E.| +000102f0 00 00 00 00 eb 2c 8b 45 f0 69 c0 e8 03 00 00 83 |.....,.E.i......| +00010300 ec 0c 50 e8 fd 01 00 00 83 c4 10 83 ec 04 6a 01 |..P...........j.| +00010310 8d 45 e3 50 6a 01 e8 b2 01 00 00 83 c4 10 83 45 |.E.Pj..........E| +00010320 e8 01 8b 45 e8 3b 45 f4 7c cc 83 ec 0c 6a 00 e8 |...E.;E.|....j..| +00010330 71 01 00 00 83 c4 10 b8 2a 00 00 00 8d 65 f8 59 |q.......*....e.Y| +00010340 5b 5d 8d 61 fc c3 55 89 e5 83 ec 08 83 ec 08 ff |[].a..U.........| +00010350 75 08 6a 00 e8 54 01 00 00 83 c4 10 c9 c3 55 89 |u.j..T........U.| +00010360 e5 81 ec 18 01 00 00 e8 49 01 00 00 89 45 f4 83 |........I....E..| +00010370 7d f4 00 74 05 8b 45 f4 eb 57 e8 56 01 00 00 89 |}..t..E..W.V....| +00010380 45 f4 83 ec 08 ff 75 0c ff 75 08 e8 2d 01 00 00 |E.....u..u..-...| +00010390 83 c4 10 ff 75 08 ff 75 f4 68 06 1a 00 00 8d 85 |....u..u.h......| +000103a0 f4 fe ff ff 50 e8 81 01 00 00 83 c4 10 83 ec 0c |....P...........| +000103b0 8d 85 f4 fe ff ff 50 e8 38 00 00 00 83 c4 10 83 |......P.8.......| +000103c0 ec 0c 6a ff e8 dc 00 00 00 83 c4 10 b8 00 00 00 |..j.............| +000103d0 00 c9 c3 55 89 e5 83 ec 18 8b 45 08 88 45 f4 83 |...U......E..E..| +000103e0 ec 04 6a 01 8d 45 f4 50 6a 00 e8 de 00 00 00 83 |..j..E.Pj.......| +000103f0 c4 10 c9 c3 55 89 e5 83 ec 18 83 ec 0c ff 75 08 |....U.........u.| +00010400 e8 0d 04 00 00 83 c4 10 89 45 f4 8b 45 f4 83 ec |.........E..E...| +00010410 04 50 ff 75 08 6a 00 e8 b1 00 00 00 83 c4 10 c9 |.P.u.j..........| +00010420 c3 55 89 e5 83 ec 08 83 ec 04 ff 75 0c ff 75 08 |.U.........u..u.| +00010430 6a 00 e8 96 00 00 00 83 c4 10 c9 c3 55 89 e5 83 |j...........U...| +00010440 ec 18 8b 45 08 88 45 f4 83 ec 04 6a 01 8d 45 f4 |...E..E....j..E.| +00010450 50 6a 01 e8 75 00 00 00 83 c4 10 c9 c3 55 89 e5 |Pj..u........U..| +00010460 83 ec 18 83 ec 0c ff 75 08 e8 a4 03 00 00 83 c4 |.......u........| +00010470 10 89 45 f4 8b 45 f4 83 ec 04 50 ff 75 08 6a 01 |..E..E....P.u.j.| +00010480 e8 48 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 08 |.H........U.....| +00010490 83 ec 04 ff 75 0c ff 75 08 6a 01 e8 2d 00 00 00 |....u..u.j..-...| +000104a0 83 c4 10 c9 c3 b8 00 00 00 00 cd 80 c3 b8 01 00 |................| +000104b0 00 00 cd 80 c3 b8 02 00 00 00 cd 80 c3 b8 03 00 |................| +000104c0 00 00 cd 80 c3 b8 04 00 00 00 cd 80 c3 b8 05 00 |................| +000104d0 00 00 cd 80 c3 b8 06 00 00 00 cd 80 c3 b8 07 00 |................| +000104e0 00 00 cd 80 c3 b8 08 00 00 00 cd 80 c3 b8 09 00 |................| +000104f0 00 00 cd 80 c3 b8 0a 00 00 00 cd 80 c3 b8 0b 00 |................| +00010500 00 00 cd 80 c3 b8 0c 00 00 00 cd 80 c3 b8 ad 0b |................| +00010510 00 00 cd 80 c3 50 e8 8a ff ff ff e8 74 fc ff ff |.....P......t...| +00010520 83 ec 0c 50 e8 7c ff ff ff eb fe 55 89 e5 83 ec |...P.|.....U....| +00010530 38 8d 45 0c 83 c0 04 89 45 f4 e9 3f 02 00 00 80 |8.E.....E..?....| +00010540 7d f3 25 0f 85 26 02 00 00 c7 45 ec 00 00 00 00 |}.%..&....E.....| +00010550 c7 45 e4 20 00 00 00 c7 45 e8 00 00 00 00 8b 45 |.E. ....E......E| +00010560 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 |..P..U.....E..}.| +00010570 2d 75 16 c7 45 ec 01 00 00 00 8b 45 0c 8d 50 01 |-u..E......E..P.| +00010580 89 55 0c 0f b6 00 88 45 f3 80 7d f3 30 75 40 c7 |.U.....E..}.0u@.| +00010590 45 e4 30 00 00 00 8b 45 0c 8d 50 01 89 55 0c 0f |E.0....E..P..U..| +000105a0 b6 00 88 45 f3 eb 28 8b 55 e8 89 d0 c1 e0 02 01 |...E..(.U.......| +000105b0 d0 01 c0 89 45 e8 0f be 45 f3 83 e8 30 01 45 e8 |....E...E...0.E.| +000105c0 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 |.E..P..U.....E..| +000105d0 7d f3 2f 7e 06 80 7d f3 39 7e cc 0f be 45 f3 83 |}./~..}.9~...E..| +000105e0 e8 63 83 f8 15 0f 87 93 01 00 00 8b 04 85 24 1a |.c............$.| +000105f0 00 00 ff e0 8b 45 f4 8d 50 04 89 55 f4 8b 00 88 |.....E..P..U....| +00010600 45 f3 0f b6 45 f3 88 45 d0 c6 45 d1 00 83 ec 08 |E...E..E..E.....| +00010610 ff 75 e4 ff 75 ec ff 75 e8 6a 01 8d 45 d0 50 ff |.u..u..u.j..E.P.| +00010620 75 08 e8 89 04 00 00 83 c4 20 89 45 08 e9 4c 01 |u........ .E..L.| +00010630 00 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 |...E..P..U......| +00010640 50 8d 45 d0 50 e8 ea 01 00 00 83 c4 10 89 45 e0 |P.E.P.........E.| +00010650 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d |....u..u..u..u..| +00010660 45 d0 50 ff 75 08 e8 45 04 00 00 83 c4 20 89 45 |E.P.u..E..... .E| +00010670 08 e9 08 01 00 00 8b 45 f4 8d 50 04 89 55 f4 8b |.......E..P..U..| +00010680 00 89 45 dc 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 |..E.....u..u..u.| +00010690 6a ff ff 75 dc ff 75 08 e8 13 04 00 00 83 c4 20 |j..u..u........ | +000106a0 89 45 08 e9 d6 00 00 00 8b 45 f4 8d 50 04 89 55 |.E.......E..P..U| +000106b0 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 44 02 00 00 |......P.E.P.D...| +000106c0 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff |....E.....u..u..| +000106d0 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 cf 03 00 |u..u..E.P.u.....| +000106e0 00 83 c4 20 89 45 08 e9 92 00 00 00 8b 45 f4 8d |... .E.......E..| +000106f0 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 |P..U......P.E.P.| +00010700 8a 02 00 00 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 |........E.....u.| +00010710 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 |.u..u..u..E.P.u.| +00010720 e8 8b 03 00 00 83 c4 20 89 45 08 eb 51 8b 45 f4 |....... .E..Q.E.| +00010730 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 |.P..U......P.E.P| +00010740 e8 d3 02 00 00 83 c4 10 89 45 e0 83 ec 08 ff 75 |.........E.....u| +00010750 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 |..u..u..u..E.P.u| +00010760 08 e8 4a 03 00 00 83 c4 20 89 45 08 90 eb 0f 8b |..J..... .E.....| +00010770 45 08 8d 50 01 89 55 08 0f b6 55 f3 88 10 8b 45 |E..P..U...U....E| +00010780 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 |..P..U.....E..}.| +00010790 00 0f 85 a8 fd ff ff 8b 45 08 c6 00 00 90 c9 c3 |........E.......| +000107a0 55 89 e5 53 83 ec 14 8b 45 08 8b 4d 0c bb 00 00 |U..S....E..M....| +000107b0 00 00 c6 45 eb 39 c7 45 f8 01 00 00 00 0f b6 10 |...E.9.E........| +000107c0 80 fa 2d 75 0a c7 45 f8 ff ff ff ff 83 c0 01 83 |..-u..E.........| +000107d0 f9 0a 74 2b 89 ca 83 c2 2f 88 55 eb eb 21 0f b6 |..t+..../.U..!..| +000107e0 10 80 fa 2f 7e 20 0f b6 10 38 55 eb 7c 18 0f af |.../~ ...8U.|...| +000107f0 d9 0f b6 10 0f be d2 01 da 8d 5a d0 83 c0 01 0f |..........Z.....| +00010800 b6 10 84 d2 75 d8 89 d8 0f af 45 f8 83 c4 14 5b |....u.....E....[| +00010810 5d c3 55 89 e5 53 8b 55 08 bb 00 00 00 00 eb 03 |].U..S.U........| +00010820 83 c3 01 89 d0 8d 50 01 0f b6 00 84 c0 75 f1 89 |......P......u..| +00010830 d8 5b 5d c3 55 89 e5 83 ec 18 8b 45 08 89 45 f4 |.[].U......E..E.| +00010840 83 7d 0c 00 79 0f 8b 45 f4 8d 50 01 89 55 f4 c6 |.}..y..E..P..U..| +00010850 00 2d f7 5d 0c 83 ec 08 ff 75 0c ff 75 f4 e8 18 |.-.].....u..u...| +00010860 00 00 00 83 c4 10 89 45 f4 8b 45 f4 c6 00 00 8b |.......E..E.....| +00010870 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 ec |U..E.).....U....| +00010880 18 8b 4d 0c ba 67 66 66 66 89 c8 f7 ea c1 fa 02 |..M..gfff.......| +00010890 89 c8 c1 f8 1f 29 c2 89 d0 89 45 f4 83 7d f4 00 |.....)....E..}..| +000108a0 79 0e c7 45 f4 cc cc cc 0c c7 45 0c 08 00 00 00 |y..E......E.....| +000108b0 83 7d f4 00 74 14 83 ec 08 ff 75 f4 ff 75 08 e8 |.}..t.....u..u..| +000108c0 b7 ff ff ff 83 c4 10 89 45 08 8b 4d 0c ba 67 66 |........E..M..gf| +000108d0 66 66 89 c8 f7 ea c1 fa 02 89 c8 c1 f8 1f 29 c2 |ff............).| +000108e0 89 d0 c1 e0 02 01 d0 01 c0 29 c1 89 ca 89 d0 8d |.........)......| +000108f0 48 30 8b 45 08 8d 50 01 89 55 08 89 ca 88 10 8b |H0.E..P..U......| +00010900 45 08 c9 c3 55 89 e5 83 ec 20 c7 45 e3 30 31 32 |E...U.... .E.012| +00010910 33 c7 45 e7 34 35 36 37 c7 45 eb 38 39 41 42 c7 |3.E.4567.E.89AB.| +00010920 45 ef 43 44 45 46 c6 45 f3 00 c7 45 fc 00 00 00 |E.CDEF.E...E....| +00010930 00 c7 45 f8 00 00 00 00 eb 43 8b 45 0c 25 00 00 |..E......C.E.%..| +00010940 00 f0 89 45 f4 83 7d fc 00 75 0c 83 7d f4 00 75 |...E..}..u..}..u| +00010950 06 83 7d f8 07 75 1e 83 45 fc 01 c1 6d f4 1c 8b |..}..u..E...m...| +00010960 45 08 8d 50 01 89 55 08 8d 4d e3 8b 55 f4 01 ca |E..P..U..M..U...| +00010970 0f b6 12 88 10 c1 65 0c 04 83 45 f8 01 83 7d f8 |......e...E...}.| +00010980 07 7e b7 8b 45 08 c6 00 00 8b 45 fc c9 c3 55 89 |.~..E.....E...U.| +00010990 e5 83 ec 10 c7 45 f8 00 00 00 00 8b 45 08 89 45 |.....E......E..E| +000109a0 f4 8b 45 0c 25 00 00 00 c0 89 45 f0 c1 6d f0 1e |..E.%.....E..m..| +000109b0 c7 45 fc 00 00 00 00 eb 47 83 7d fc 0a 74 0c 83 |.E......G.}..t..| +000109c0 7d f0 00 75 06 83 7d f8 00 74 1e c7 45 f8 01 00 |}..u..}..t..E...| +000109d0 00 00 83 65 f0 07 8b 45 f0 8d 48 30 8b 45 f4 8d |...e...E..H0.E..| +000109e0 50 01 89 55 f4 89 ca 88 10 c1 65 0c 03 8b 45 0c |P..U......e...E.| +000109f0 25 00 00 00 e0 89 45 f0 c1 6d f0 1d 83 45 fc 01 |%.....E..m...E..| +00010a00 83 7d fc 0a 7e b3 8b 45 f4 c6 00 00 8b 55 f4 8b |.}..~..E.....U..| +00010a10 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 ec 18 8b 45 |E.).....U......E| +00010a20 08 89 45 f4 83 ec 08 ff 75 0c ff 75 f4 e8 18 00 |..E.....u..u....| +00010a30 00 00 83 c4 10 89 45 f4 8b 45 f4 c6 00 00 8b 55 |......E..E.....U| +00010a40 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 ec 18 |..E.).....U.....| +00010a50 8b 45 0c ba cd cc cc cc f7 e2 89 d0 c1 e8 03 89 |.E..............| +00010a60 45 f4 83 7d f4 00 74 15 8b 45 f4 83 ec 08 50 ff |E..}..t..E....P.| +00010a70 75 08 e8 04 fe ff ff 83 c4 10 89 45 08 8b 4d 0c |u..........E..M.| +00010a80 ba cd cc cc cc 89 c8 f7 e2 c1 ea 03 89 d0 c1 e0 |................| +00010a90 02 01 d0 01 c0 29 c1 89 ca 89 d0 8d 48 30 8b 45 |.....)......H0.E| +00010aa0 08 8d 50 01 89 55 08 89 ca 88 10 8b 45 08 c9 c3 |..P..U......E...| +00010ab0 55 89 e5 83 ec 18 83 7d 10 00 79 11 83 ec 0c ff |U......}..y.....| +00010ac0 75 0c e8 4b fd ff ff 83 c4 10 89 45 10 8b 45 14 |u..K.......E..E.| +00010ad0 2b 45 10 89 45 f0 83 7d f0 00 7e 1d 83 7d 18 00 |+E..E..}..~..}..| +00010ae0 75 17 83 ec 04 ff 75 1c ff 75 f0 ff 75 08 e8 5a |u.....u..u..u..Z| +00010af0 00 00 00 83 c4 10 89 45 08 c7 45 f4 00 00 00 00 |.......E..E.....| +00010b00 eb 1b 8b 55 f4 8b 45 0c 8d 0c 02 8b 45 08 8d 50 |...U..E.....E..P| +00010b10 01 89 55 08 0f b6 11 88 10 83 45 f4 01 8b 45 f4 |..U.......E...E.| +00010b20 3b 45 10 7c dd 83 7d f0 00 7e 1d 83 7d 18 00 74 |;E.|..}..~..}..t| +00010b30 17 83 ec 04 ff 75 1c ff 75 f0 ff 75 08 e8 0b 00 |.....u..u..u....| +00010b40 00 00 83 c4 10 89 45 08 8b 45 08 c9 c3 55 89 e5 |......E..E...U..| +00010b50 eb 12 8b 45 08 8d 50 01 89 55 08 8b 55 10 88 10 |...E..P..U..U...| +00010b60 83 6d 0c 01 83 7d 0c 00 7f e8 8b 45 08 5d c3 00 |.m...}.....E.]..| +00010b70 75 73 65 72 50 3a 20 61 72 67 63 20 25 64 2c 20 |userP: argc %d, | +00010b80 61 72 67 73 3a 20 00 28 6e 75 6c 6c 29 00 20 25 |args: .(null). %| +00010b90 73 00 0a 00 20 50 40 25 75 00 43 68 69 6c 64 20 |s... P@%u.Child | +00010ba0 25 64 20 65 78 65 63 28 29 20 23 25 75 20 66 61 |%d exec() #%u fa| +00010bb0 69 6c 65 64 0a 00 00 00 60 14 00 00 9e 14 00 00 |iled....`.......| +00010bc0 ea 15 00 00 ea 15 00 00 ea 15 00 00 ea 15 00 00 |................| +* +00010be0 ea 15 00 00 ea 15 00 00 58 15 00 00 ea 15 00 00 |........X.......| +00010bf0 ea 15 00 00 ea 15 00 00 e2 14 00 00 ea 15 00 00 |................| +00010c00 99 15 00 00 ea 15 00 00 ea 15 00 00 14 15 00 00 |................| +00010c10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +000111a0 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 |................| +000111b0 03 00 01 00 00 00 00 00 dc 19 00 00 00 00 00 00 |................| +000111c0 03 00 02 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +000111d0 03 00 03 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +000111e0 03 00 04 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +000111f0 04 00 f1 ff 09 00 00 00 00 00 00 00 00 00 00 00 |................| +00011200 04 00 f1 ff 11 00 00 00 00 00 00 00 00 00 00 00 |................| +00011210 04 00 f1 ff 1a 00 00 00 00 00 00 00 00 00 00 00 |................| +00011220 04 00 f1 ff 24 00 00 00 00 00 00 00 00 00 00 00 |....$...........| +00011230 04 00 f1 ff 2d 00 00 00 00 00 00 00 00 00 00 00 |....-...........| +00011240 04 00 f1 ff 36 00 00 00 00 00 00 00 00 00 00 00 |....6...........| +00011250 04 00 f1 ff 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........| +00011260 04 00 f1 ff 49 00 00 00 00 00 00 00 00 00 00 00 |....I...........| +00011270 04 00 f1 ff 52 00 00 00 00 00 00 00 00 00 00 00 |....R...........| +00011280 04 00 f1 ff 5b 00 00 00 00 00 00 00 00 00 00 00 |....[...........| +00011290 04 00 f1 ff 65 00 00 00 00 00 00 00 00 00 00 00 |....e...........| +000112a0 04 00 f1 ff 6e 00 00 00 00 00 00 00 00 00 00 00 |....n...........| +000112b0 04 00 f1 ff 74 00 00 00 a8 12 00 00 21 00 00 00 |....t.......!...| +000112c0 12 00 01 00 7d 00 00 00 19 13 00 00 00 00 00 00 |....}...........| +000112d0 10 00 01 00 85 00 00 00 8d 12 00 00 1b 00 00 00 |................| +000112e0 12 00 01 00 8c 00 00 00 0c 16 00 00 72 00 00 00 |............r...| +000112f0 12 00 01 00 94 00 00 00 84 18 00 00 32 00 00 00 |............2...| +00011300 12 00 01 00 9b 00 00 00 41 13 00 00 00 00 00 00 |........A.......| +00011310 10 00 01 00 a2 00 00 00 71 13 00 00 00 00 00 00 |........q.......| +00011320 10 00 01 00 a8 00 00 00 f6 12 00 00 1b 00 00 00 |................| +00011330 12 00 01 00 af 00 00 00 b9 19 00 00 22 00 00 00 |............"...| +00011340 12 00 01 00 b3 00 00 00 ca 11 00 00 75 00 00 00 |............u...| +00011350 12 00 01 00 b9 00 00 00 97 13 00 00 75 02 00 00 |............u...| +00011360 12 00 01 00 c0 00 00 00 70 17 00 00 8a 00 00 00 |........p.......| +00011370 12 00 01 00 c7 00 00 00 b6 18 00 00 66 00 00 00 |............f...| +00011380 12 00 01 00 86 00 00 00 39 13 00 00 00 00 00 00 |........9.......| +00011390 10 00 01 00 cf 00 00 00 69 13 00 00 00 00 00 00 |........i.......| +000113a0 10 00 01 00 d4 00 00 00 60 12 00 00 2d 00 00 00 |........`...-...| +000113b0 12 00 01 00 dc 00 00 00 29 13 00 00 00 00 00 00 |........).......| +000113c0 10 00 01 00 e1 00 00 00 b2 11 00 00 18 00 00 00 |................| +000113d0 12 00 01 00 e6 00 00 00 c9 12 00 00 2d 00 00 00 |............-...| +000113e0 12 00 01 00 ee 00 00 00 87 13 00 00 00 00 00 00 |................| +000113f0 10 00 01 00 f5 00 00 00 31 13 00 00 00 00 00 00 |........1.......| +00011400 10 00 01 00 fa 00 00 00 59 13 00 00 00 00 00 00 |........Y.......| +00011410 10 00 01 00 02 01 00 00 e7 16 00 00 89 00 00 00 |................| +00011420 12 00 01 00 0a 01 00 00 21 13 00 00 00 00 00 00 |........!.......| +00011430 10 00 01 00 0f 01 00 00 00 10 00 00 b2 01 00 00 |................| +00011440 12 00 01 00 14 01 00 00 49 13 00 00 00 00 00 00 |........I.......| +00011450 10 00 01 00 1c 01 00 00 1c 19 00 00 9d 00 00 00 |................| +00011460 12 00 01 00 23 01 00 00 61 13 00 00 00 00 00 00 |....#...a.......| +00011470 10 00 01 00 2b 01 00 00 fa 17 00 00 8a 00 00 00 |....+...........| +00011480 12 00 01 00 32 01 00 00 3f 12 00 00 21 00 00 00 |....2...?...!...| +00011490 12 00 01 00 3b 01 00 00 51 13 00 00 00 00 00 00 |....;...Q.......| +000114a0 10 00 01 00 43 01 00 00 a0 16 00 00 47 00 00 00 |....C.......G...| +000114b0 12 00 01 00 5c 01 00 00 11 13 00 00 00 00 00 00 |....\...........| +000114c0 10 00 01 00 4a 01 00 00 7e 16 00 00 22 00 00 00 |....J...~..."...| +000114d0 12 00 01 00 51 01 00 00 79 13 00 00 00 00 00 00 |....Q...y.......| +000114e0 10 00 01 00 57 01 00 00 81 13 00 00 00 00 00 00 |....W...........| +000114f0 10 00 01 00 00 70 72 6f 67 50 2e 63 00 75 6c 69 |.....progP.c.uli| +00011500 62 63 2e 63 00 73 70 72 69 6e 74 2e 63 00 73 74 |bc.c.sprint.c.st| +00011510 72 32 69 6e 74 2e 63 00 73 74 72 6c 65 6e 2e 63 |r2int.c.strlen.c| +00011520 00 63 76 74 64 65 63 2e 63 00 63 76 74 64 65 63 |.cvtdec.c.cvtdec| +00011530 30 2e 63 00 63 76 74 68 65 78 2e 63 00 63 76 74 |0.c.cvthex.c.cvt| +00011540 6f 63 74 2e 63 00 63 76 74 75 6e 73 2e 63 00 63 |oct.c.cvtuns.c.c| +00011550 76 74 75 6e 73 30 2e 63 00 70 61 64 73 74 72 2e |vtuns0.c.padstr.| +00011560 63 00 70 61 64 2e 63 00 73 77 72 69 74 65 63 68 |c.pad.c.swritech| +00011570 00 77 61 69 74 70 69 64 00 63 77 72 69 74 65 00 |.waitpid.cwrite.| +00011580 73 74 72 32 69 6e 74 00 63 76 74 75 6e 73 00 67 |str2int.cvtuns.g| +00011590 65 74 70 69 64 00 73 6c 65 65 70 00 73 77 72 69 |etpid.sleep.swri| +000115a0 74 65 00 70 61 64 00 73 70 61 77 6e 00 73 70 72 |te.pad.spawn.spr| +000115b0 69 6e 74 00 63 76 74 68 65 78 00 63 76 74 75 6e |int.cvthex.cvtun| +000115c0 73 30 00 6b 69 6c 6c 00 63 77 72 69 74 65 73 00 |s0.kill.cwrites.| +000115d0 65 78 65 63 00 77 61 69 74 00 73 77 72 69 74 65 |exec.wait.swrite| +000115e0 73 00 5f 73 74 61 72 74 00 72 65 61 64 00 67 65 |s._start.read.ge| +000115f0 74 70 72 69 6f 00 63 76 74 64 65 63 30 00 66 6f |tprio.cvtdec0.fo| +00011600 72 6b 00 6d 61 69 6e 00 67 65 74 70 70 69 64 00 |rk.main.getppid.| +00011610 70 61 64 73 74 72 00 73 65 74 70 72 69 6f 00 63 |padstr.setprio.c| +00011620 76 74 6f 63 74 00 63 77 72 69 74 65 63 68 00 67 |vtoct.cwritech.g| +00011630 65 74 74 69 6d 65 00 63 76 74 64 65 63 00 73 74 |ettime.cvtdec.st| +00011640 72 6c 65 6e 00 62 6f 67 75 73 00 66 61 6b 65 5f |rlen.bogus.fake_| +00011650 65 78 69 74 00 00 2e 73 79 6d 74 61 62 00 2e 73 |exit...symtab..s| +00011660 74 72 74 61 62 00 2e 73 68 73 74 72 74 61 62 00 |trtab..shstrtab.| +00011670 2e 74 65 78 74 00 2e 72 6f 64 61 74 61 00 2e 64 |.text..rodata..d| +00011680 61 74 61 00 2e 62 73 73 00 00 00 00 00 00 00 00 |ata..bss........| +00011690 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +000116b0 00 00 00 00 1b 00 00 00 01 00 00 00 06 00 00 00 |................| +000116c0 00 10 00 00 74 00 00 00 db 09 00 00 00 00 00 00 |....t...........| +000116d0 00 00 00 00 01 00 00 00 00 00 00 00 21 00 00 00 |............!...| +000116e0 01 00 00 00 02 00 00 00 dc 19 00 00 50 0a 00 00 |............P...| +000116f0 a0 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |................| +00011700 00 00 00 00 29 00 00 00 01 00 00 00 03 00 00 00 |....)...........| +00011710 00 20 00 00 74 10 00 00 00 00 00 00 00 00 00 00 |. ..t...........| +00011720 00 00 00 00 01 00 00 00 00 00 00 00 2f 00 00 00 |............/...| +00011730 08 00 00 00 03 00 00 00 00 20 00 00 74 10 00 00 |......... ..t...| +00011740 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +00011750 00 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 |................| +00011760 00 00 00 00 74 10 00 00 60 03 00 00 06 00 00 00 |....t...`.......| +00011770 12 00 00 00 04 00 00 00 10 00 00 00 09 00 00 00 |................| +00011780 03 00 00 00 00 00 00 00 00 00 00 00 d4 13 00 00 |................| +00011790 61 01 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |a...............| +000117a0 00 00 00 00 11 00 00 00 03 00 00 00 00 00 00 00 |................| +000117b0 00 00 00 00 35 15 00 00 34 00 00 00 00 00 00 00 |....5...4.......| +000117c0 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +000117d0 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| +000117e0 02 00 03 00 01 00 00 00 13 13 00 00 34 00 00 00 |............4...| +000117f0 38 15 00 00 00 00 00 00 34 00 20 00 02 00 28 00 |8.......4. ...(.| +00011800 08 00 07 00 01 00 00 00 74 00 00 00 00 10 00 00 |........t.......| +00011810 00 10 00 00 00 10 00 00 00 10 00 00 07 00 00 00 |................| +00011820 04 00 00 00 51 e5 74 64 00 00 00 00 00 00 00 00 |....Q.td........| +00011830 00 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 |................| +00011840 10 00 00 00 8d 4c 24 04 83 e4 f0 ff 71 fc 55 89 |.....L$.....q.U.| +00011850 e5 53 51 81 ec 90 00 00 00 89 cb c6 45 f3 71 8b |.SQ.........E.q.| +00011860 03 83 f8 02 75 13 8b 43 04 83 c0 04 8b 00 0f b6 |....u..C........| +00011870 00 88 45 f3 e9 a4 00 00 00 83 ec 04 ff 33 68 f8 |..E..........3h.| +00011880 18 00 00 8d 85 73 ff ff ff 50 e8 d8 02 00 00 83 |.....s...P......| +00011890 c4 10 83 ec 0c 8d 85 73 ff ff ff 50 e8 8f 01 00 |.......s...P....| +000118a0 00 83 c4 10 c7 45 f4 00 00 00 00 eb 59 8b 03 8d |.....E......Y...| +000118b0 14 85 00 00 00 00 8b 43 04 01 d0 8b 00 85 c0 74 |.......C.......t| +000118c0 12 8b 03 8d 14 85 00 00 00 00 8b 43 04 01 d0 8b |...........C....| +000118d0 00 eb 05 b8 0f 19 00 00 83 ec 04 50 68 16 19 00 |...........Ph...| +000118e0 00 8d 85 73 ff ff ff 50 e8 7a 02 00 00 83 c4 10 |...s...P.z......| +000118f0 83 ec 0c 8d 85 73 ff ff ff 50 e8 31 01 00 00 83 |.....s...P.1....| +00011900 c4 10 83 45 f4 01 8b 45 f4 3b 03 7e a0 83 ec 0c |...E...E.;.~....| +00011910 68 1a 19 00 00 e8 16 01 00 00 83 c4 10 83 ec 04 |h...............| +00011920 6a 01 8d 45 f3 50 6a 01 e8 dc 01 00 00 83 c4 10 |j..E.Pj.........| +00011930 e8 14 02 00 00 0f b6 45 f3 0f be c0 83 ec 04 50 |.......E.......P| +00011940 68 1c 19 00 00 8d 85 73 ff ff ff 50 e8 16 02 00 |h......s...P....| +00011950 00 83 c4 10 83 ec 0c 8d 85 73 ff ff ff 50 e8 cd |.........s...P..| +00011960 00 00 00 83 c4 10 83 ec 0c 6a 01 e8 71 01 00 00 |.........j..q...| +00011970 83 c4 10 b8 2a 00 00 00 8d 65 f8 59 5b 5d 8d 61 |....*....e.Y[].a| +00011980 fc c3 55 89 e5 83 ec 08 83 ec 08 ff 75 08 6a 00 |..U.........u.j.| +00011990 e8 54 01 00 00 83 c4 10 c9 c3 55 89 e5 81 ec 18 |.T........U.....| +000119a0 01 00 00 e8 49 01 00 00 89 45 f4 83 7d f4 00 74 |....I....E..}..t| +000119b0 05 8b 45 f4 eb 57 e8 56 01 00 00 89 45 f4 83 ec |..E..W.V....E...| +000119c0 08 ff 75 0c ff 75 08 e8 2d 01 00 00 83 c4 10 ff |..u..u..-.......| +000119d0 75 08 ff 75 f4 68 47 19 00 00 8d 85 f4 fe ff ff |u..u.hG.........| +000119e0 50 e8 81 01 00 00 83 c4 10 83 ec 0c 8d 85 f4 fe |P...............| +000119f0 ff ff 50 e8 38 00 00 00 83 c4 10 83 ec 0c 6a ff |..P.8.........j.| +00011a00 e8 dc 00 00 00 83 c4 10 b8 00 00 00 00 c9 c3 55 |...............U| +00011a10 89 e5 83 ec 18 8b 45 08 88 45 f4 83 ec 04 6a 01 |......E..E....j.| +00011a20 8d 45 f4 50 6a 00 e8 de 00 00 00 83 c4 10 c9 c3 |.E.Pj...........| +00011a30 55 89 e5 83 ec 18 83 ec 0c ff 75 08 e8 9b 03 00 |U.........u.....| +00011a40 00 83 c4 10 89 45 f4 8b 45 f4 83 ec 04 50 ff 75 |.....E..E....P.u| +00011a50 08 6a 00 e8 b1 00 00 00 83 c4 10 c9 c3 55 89 e5 |.j...........U..| +00011a60 83 ec 08 83 ec 04 ff 75 0c ff 75 08 6a 00 e8 96 |.......u..u.j...| +00011a70 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 8b 45 |........U......E| +00011a80 08 88 45 f4 83 ec 04 6a 01 8d 45 f4 50 6a 01 e8 |..E....j..E.Pj..| +00011a90 75 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 83 |u........U......| +00011aa0 ec 0c ff 75 08 e8 32 03 00 00 83 c4 10 89 45 f4 |...u..2.......E.| +00011ab0 8b 45 f4 83 ec 04 50 ff 75 08 6a 01 e8 48 00 00 |.E....P.u.j..H..| +00011ac0 00 83 c4 10 c9 c3 55 89 e5 83 ec 08 83 ec 04 ff |......U.........| +00011ad0 75 0c ff 75 08 6a 01 e8 2d 00 00 00 83 c4 10 c9 |u..u.j..-.......| +00011ae0 c3 b8 00 00 00 00 cd 80 c3 b8 01 00 00 00 cd 80 |................| +00011af0 c3 b8 02 00 00 00 cd 80 c3 b8 03 00 00 00 cd 80 |................| +00011b00 c3 b8 04 00 00 00 cd 80 c3 b8 05 00 00 00 cd 80 |................| +00011b10 c3 b8 06 00 00 00 cd 80 c3 b8 07 00 00 00 cd 80 |................| +00011b20 c3 b8 08 00 00 00 cd 80 c3 b8 09 00 00 00 cd 80 |................| +00011b30 c3 b8 0a 00 00 00 cd 80 c3 b8 0b 00 00 00 cd 80 |................| +00011b40 c3 b8 0c 00 00 00 cd 80 c3 b8 ad 0b 00 00 cd 80 |................| +00011b50 c3 50 e8 8a ff ff ff e8 e8 fc ff ff 83 ec 0c 50 |.P.............P| +00011b60 e8 7c ff ff ff eb fe 55 89 e5 83 ec 38 8d 45 0c |.|.....U....8.E.| +00011b70 83 c0 04 89 45 f4 e9 3f 02 00 00 80 7d f3 25 0f |....E..?....}.%.| +00011b80 85 26 02 00 00 c7 45 ec 00 00 00 00 c7 45 e4 20 |.&....E......E. | +00011b90 00 00 00 c7 45 e8 00 00 00 00 8b 45 0c 8d 50 01 |....E......E..P.| +00011ba0 89 55 0c 0f b6 00 88 45 f3 80 7d f3 2d 75 16 c7 |.U.....E..}.-u..| +00011bb0 45 ec 01 00 00 00 8b 45 0c 8d 50 01 89 55 0c 0f |E......E..P..U..| +00011bc0 b6 00 88 45 f3 80 7d f3 30 75 40 c7 45 e4 30 00 |...E..}.0u@.E.0.| +00011bd0 00 00 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 |...E..P..U.....E| +00011be0 f3 eb 28 8b 55 e8 89 d0 c1 e0 02 01 d0 01 c0 89 |..(.U...........| +00011bf0 45 e8 0f be 45 f3 83 e8 30 01 45 e8 8b 45 0c 8d |E...E...0.E..E..| +00011c00 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 2f 7e |P..U.....E..}./~| +00011c10 06 80 7d f3 39 7e cc 0f be 45 f3 83 e8 63 83 f8 |..}.9~...E...c..| +00011c20 15 0f 87 93 01 00 00 8b 04 85 64 19 00 00 ff e0 |..........d.....| +00011c30 8b 45 f4 8d 50 04 89 55 f4 8b 00 88 45 f3 0f b6 |.E..P..U....E...| +00011c40 45 f3 88 45 d0 c6 45 d1 00 83 ec 08 ff 75 e4 ff |E..E..E......u..| +00011c50 75 ec ff 75 e8 6a 01 8d 45 d0 50 ff 75 08 e8 17 |u..u.j..E.P.u...| +00011c60 04 00 00 83 c4 20 89 45 08 e9 4c 01 00 00 8b 45 |..... .E..L....E| +00011c70 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 |..P..U......P.E.| +00011c80 50 e8 78 01 00 00 83 c4 10 89 45 e0 83 ec 08 ff |P.x.......E.....| +00011c90 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff |u..u..u..u..E.P.| +00011ca0 75 08 e8 d3 03 00 00 83 c4 20 89 45 08 e9 08 01 |u........ .E....| +00011cb0 00 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 89 45 dc |...E..P..U....E.| +00011cc0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 6a ff ff 75 |....u..u..u.j..u| +00011cd0 dc ff 75 08 e8 a1 03 00 00 83 c4 20 89 45 08 e9 |..u........ .E..| +00011ce0 d6 00 00 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 |.....E..P..U....| +00011cf0 ec 08 50 8d 45 d0 50 e8 d2 01 00 00 83 c4 10 89 |..P.E.P.........| +00011d00 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 |E.....u..u..u..u| +00011d10 e0 8d 45 d0 50 ff 75 08 e8 5d 03 00 00 83 c4 20 |..E.P.u..]..... | +00011d20 89 45 08 e9 92 00 00 00 8b 45 f4 8d 50 04 89 55 |.E.......E..P..U| +00011d30 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 18 02 00 00 |......P.E.P.....| +00011d40 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff |....E.....u..u..| +00011d50 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 19 03 00 |u..u..E.P.u.....| +00011d60 00 83 c4 20 89 45 08 eb 51 8b 45 f4 8d 50 04 89 |... .E..Q.E..P..| +00011d70 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 61 02 00 |U......P.E.P.a..| +00011d80 00 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec |.....E.....u..u.| +00011d90 ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 d8 02 |.u..u..E.P.u....| +00011da0 00 00 83 c4 20 89 45 08 90 eb 0f 8b 45 08 8d 50 |.... .E.....E..P| +00011db0 01 89 55 08 0f b6 55 f3 88 10 8b 45 0c 8d 50 01 |..U...U....E..P.| +00011dc0 89 55 0c 0f b6 00 88 45 f3 80 7d f3 00 0f 85 a8 |.U.....E..}.....| +00011dd0 fd ff ff 8b 45 08 c6 00 00 90 c9 c3 55 89 e5 53 |....E.......U..S| +00011de0 8b 55 08 bb 00 00 00 00 eb 03 83 c3 01 89 d0 8d |.U..............| +00011df0 50 01 0f b6 00 84 c0 75 f1 89 d8 5b 5d c3 55 89 |P......u...[].U.| +00011e00 e5 83 ec 18 8b 45 08 89 45 f4 83 7d 0c 00 79 0f |.....E..E..}..y.| +00011e10 8b 45 f4 8d 50 01 89 55 f4 c6 00 2d f7 5d 0c 83 |.E..P..U...-.]..| +00011e20 ec 08 ff 75 0c ff 75 f4 e8 18 00 00 00 83 c4 10 |...u..u.........| +00011e30 89 45 f4 8b 45 f4 c6 00 00 8b 55 f4 8b 45 08 29 |.E..E.....U..E.)| +00011e40 c2 89 d0 c9 c3 55 89 e5 83 ec 18 8b 4d 0c ba 67 |.....U......M..g| +00011e50 66 66 66 89 c8 f7 ea c1 fa 02 89 c8 c1 f8 1f 29 |fff............)| +00011e60 c2 89 d0 89 45 f4 83 7d f4 00 79 0e c7 45 f4 cc |....E..}..y..E..| +00011e70 cc cc 0c c7 45 0c 08 00 00 00 83 7d f4 00 74 14 |....E......}..t.| +00011e80 83 ec 08 ff 75 f4 ff 75 08 e8 b7 ff ff ff 83 c4 |....u..u........| +00011e90 10 89 45 08 8b 4d 0c ba 67 66 66 66 89 c8 f7 ea |..E..M..gfff....| +00011ea0 c1 fa 02 89 c8 c1 f8 1f 29 c2 89 d0 c1 e0 02 01 |........).......| +00011eb0 d0 01 c0 29 c1 89 ca 89 d0 8d 48 30 8b 45 08 8d |...)......H0.E..| +00011ec0 50 01 89 55 08 89 ca 88 10 8b 45 08 c9 c3 55 89 |P..U......E...U.| +00011ed0 e5 83 ec 20 c7 45 e3 30 31 32 33 c7 45 e7 34 35 |... .E.0123.E.45| +00011ee0 36 37 c7 45 eb 38 39 41 42 c7 45 ef 43 44 45 46 |67.E.89AB.E.CDEF| +00011ef0 c6 45 f3 00 c7 45 fc 00 00 00 00 c7 45 f8 00 00 |.E...E......E...| +00011f00 00 00 eb 43 8b 45 0c 25 00 00 00 f0 89 45 f4 83 |...C.E.%.....E..| +00011f10 7d fc 00 75 0c 83 7d f4 00 75 06 83 7d f8 07 75 |}..u..}..u..}..u| +00011f20 1e 83 45 fc 01 c1 6d f4 1c 8b 45 08 8d 50 01 89 |..E...m...E..P..| +00011f30 55 08 8d 4d e3 8b 55 f4 01 ca 0f b6 12 88 10 c1 |U..M..U.........| +00011f40 65 0c 04 83 45 f8 01 83 7d f8 07 7e b7 8b 45 08 |e...E...}..~..E.| +00011f50 c6 00 00 8b 45 fc c9 c3 55 89 e5 83 ec 10 c7 45 |....E...U......E| +00011f60 f8 00 00 00 00 8b 45 08 89 45 f4 8b 45 0c 25 00 |......E..E..E.%.| +00011f70 00 00 c0 89 45 f0 c1 6d f0 1e c7 45 fc 00 00 00 |....E..m...E....| +00011f80 00 eb 47 83 7d fc 0a 74 0c 83 7d f0 00 75 06 83 |..G.}..t..}..u..| +00011f90 7d f8 00 74 1e c7 45 f8 01 00 00 00 83 65 f0 07 |}..t..E......e..| +00011fa0 8b 45 f0 8d 48 30 8b 45 f4 8d 50 01 89 55 f4 89 |.E..H0.E..P..U..| +00011fb0 ca 88 10 c1 65 0c 03 8b 45 0c 25 00 00 00 e0 89 |....e...E.%.....| +00011fc0 45 f0 c1 6d f0 1d 83 45 fc 01 83 7d fc 0a 7e b3 |E..m...E...}..~.| +00011fd0 8b 45 f4 c6 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 |.E.....U..E.)...| +00011fe0 c9 c3 55 89 e5 83 ec 18 8b 45 08 89 45 f4 83 ec |..U......E..E...| +00011ff0 08 ff 75 0c ff 75 f4 e8 18 00 00 00 83 c4 10 89 |..u..u..........| +00012000 45 f4 8b 45 f4 c6 00 00 8b 55 f4 8b 45 08 29 c2 |E..E.....U..E.).| +00012010 89 d0 c9 c3 55 89 e5 83 ec 18 8b 45 0c ba cd cc |....U......E....| +00012020 cc cc f7 e2 89 d0 c1 e8 03 89 45 f4 83 7d f4 00 |..........E..}..| +00012030 74 15 8b 45 f4 83 ec 08 50 ff 75 08 e8 04 fe ff |t..E....P.u.....| +00012040 ff 83 c4 10 89 45 08 8b 4d 0c ba cd cc cc cc 89 |.....E..M.......| +00012050 c8 f7 e2 c1 ea 03 89 d0 c1 e0 02 01 d0 01 c0 29 |...............)| +00012060 c1 89 ca 89 d0 8d 48 30 8b 45 08 8d 50 01 89 55 |......H0.E..P..U| +00012070 08 89 ca 88 10 8b 45 08 c9 c3 55 89 e5 83 ec 18 |......E...U.....| +00012080 83 7d 10 00 79 11 83 ec 0c ff 75 0c e8 4b fd ff |.}..y.....u..K..| +00012090 ff 83 c4 10 89 45 10 8b 45 14 2b 45 10 89 45 f0 |.....E..E.+E..E.| +000120a0 83 7d f0 00 7e 1d 83 7d 18 00 75 17 83 ec 04 ff |.}..~..}..u.....| +000120b0 75 1c ff 75 f0 ff 75 08 e8 5a 00 00 00 83 c4 10 |u..u..u..Z......| +000120c0 89 45 08 c7 45 f4 00 00 00 00 eb 1b 8b 55 f4 8b |.E..E........U..| +000120d0 45 0c 8d 0c 02 8b 45 08 8d 50 01 89 55 08 0f b6 |E.....E..P..U...| +000120e0 11 88 10 83 45 f4 01 8b 45 f4 3b 45 10 7c dd 83 |....E...E.;E.|..| +000120f0 7d f0 00 7e 1d 83 7d 18 00 74 17 83 ec 04 ff 75 |}..~..}..t.....u| +00012100 1c ff 75 f0 ff 75 08 e8 0b 00 00 00 83 c4 10 89 |..u..u..........| +00012110 45 08 8b 45 08 c9 c3 55 89 e5 eb 12 8b 45 08 8d |E..E...U.....E..| +00012120 50 01 89 55 08 8b 55 10 88 10 83 6d 0c 01 83 7d |P..U..U....m...}| +00012130 0c 00 7f e8 8b 45 08 5d c3 00 00 00 75 73 65 72 |.....E.]....user| +00012140 51 3a 20 61 72 67 63 20 25 64 2c 20 61 72 67 73 |Q: argc %d, args| +00012150 3a 20 00 28 6e 75 6c 6c 29 00 20 25 73 00 0a 00 |: .(null). %s...| +00012160 21 21 21 21 21 20 25 63 20 72 65 74 75 72 6e 65 |!!!!! %c returne| +00012170 64 20 66 72 6f 6d 20 62 6f 67 75 73 20 73 79 73 |d from bogus sys| +00012180 63 61 6c 6c 21 3f 21 3f 21 0a 00 43 68 69 6c 64 |call!?!?!..Child| +00012190 20 25 64 20 65 78 65 63 28 29 20 23 25 75 20 66 | %d exec() #%u f| +000121a0 61 69 6c 65 64 0a 00 00 ec 13 00 00 2a 14 00 00 |ailed.......*...| +000121b0 76 15 00 00 76 15 00 00 76 15 00 00 76 15 00 00 |v...v...v...v...| +* +000121d0 76 15 00 00 76 15 00 00 e4 14 00 00 76 15 00 00 |v...v.......v...| +000121e0 76 15 00 00 76 15 00 00 6e 14 00 00 76 15 00 00 |v...v...n...v...| +000121f0 25 15 00 00 76 15 00 00 76 15 00 00 a0 14 00 00 |%...v...v.......| +00012200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00012850 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 |................| +00012860 03 00 01 00 00 00 00 00 f8 18 00 00 00 00 00 00 |................| +00012870 03 00 02 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +00012880 03 00 03 00 00 00 00 00 00 20 00 00 00 00 00 00 |......... ......| +00012890 03 00 04 00 01 00 00 00 00 00 00 00 00 00 00 00 |................| +000128a0 04 00 f1 ff 09 00 00 00 00 00 00 00 00 00 00 00 |................| +000128b0 04 00 f1 ff 11 00 00 00 00 00 00 00 00 00 00 00 |................| +000128c0 04 00 f1 ff 1a 00 00 00 00 00 00 00 00 00 00 00 |................| +000128d0 04 00 f1 ff 23 00 00 00 00 00 00 00 00 00 00 00 |....#...........| +000128e0 04 00 f1 ff 2c 00 00 00 00 00 00 00 00 00 00 00 |....,...........| +000128f0 04 00 f1 ff 36 00 00 00 00 00 00 00 00 00 00 00 |....6...........| +00012900 04 00 f1 ff 3f 00 00 00 00 00 00 00 00 00 00 00 |....?...........| +00012910 04 00 f1 ff 48 00 00 00 00 00 00 00 00 00 00 00 |....H...........| +00012920 04 00 f1 ff 51 00 00 00 00 00 00 00 00 00 00 00 |....Q...........| +00012930 04 00 f1 ff 5b 00 00 00 00 00 00 00 00 00 00 00 |....[...........| +00012940 04 00 f1 ff 64 00 00 00 00 00 00 00 00 00 00 00 |....d...........| +00012950 04 00 f1 ff 6a 00 00 00 34 12 00 00 21 00 00 00 |....j...4...!...| +00012960 12 00 01 00 73 00 00 00 a5 12 00 00 00 00 00 00 |....s...........| +00012970 10 00 01 00 7b 00 00 00 19 12 00 00 1b 00 00 00 |....{...........| +00012980 12 00 01 00 82 00 00 00 9e 17 00 00 32 00 00 00 |............2...| +00012990 12 00 01 00 89 00 00 00 cd 12 00 00 00 00 00 00 |................| +000129a0 10 00 01 00 90 00 00 00 fd 12 00 00 00 00 00 00 |................| +000129b0 10 00 01 00 96 00 00 00 82 12 00 00 1b 00 00 00 |................| +000129c0 12 00 01 00 9d 00 00 00 d3 18 00 00 22 00 00 00 |............"...| +000129d0 12 00 01 00 a1 00 00 00 56 11 00 00 75 00 00 00 |........V...u...| +000129e0 12 00 01 00 a7 00 00 00 23 13 00 00 75 02 00 00 |........#...u...| +000129f0 12 00 01 00 ae 00 00 00 8a 16 00 00 8a 00 00 00 |................| +00012a00 12 00 01 00 b5 00 00 00 d0 17 00 00 66 00 00 00 |............f...| +00012a10 12 00 01 00 7c 00 00 00 c5 12 00 00 00 00 00 00 |....|...........| +00012a20 10 00 01 00 bd 00 00 00 f5 12 00 00 00 00 00 00 |................| +00012a30 10 00 01 00 c2 00 00 00 ec 11 00 00 2d 00 00 00 |............-...| +00012a40 12 00 01 00 ca 00 00 00 b5 12 00 00 00 00 00 00 |................| +00012a50 10 00 01 00 cf 00 00 00 3e 11 00 00 18 00 00 00 |........>.......| +00012a60 12 00 01 00 d4 00 00 00 55 12 00 00 2d 00 00 00 |........U...-...| +00012a70 12 00 01 00 dc 00 00 00 13 13 00 00 00 00 00 00 |................| +00012a80 10 00 01 00 e3 00 00 00 bd 12 00 00 00 00 00 00 |................| +00012a90 10 00 01 00 e8 00 00 00 e5 12 00 00 00 00 00 00 |................| +00012aa0 10 00 01 00 f0 00 00 00 01 16 00 00 89 00 00 00 |................| +00012ab0 12 00 01 00 f8 00 00 00 ad 12 00 00 00 00 00 00 |................| +00012ac0 10 00 01 00 fd 00 00 00 00 10 00 00 3e 01 00 00 |............>...| +00012ad0 12 00 01 00 02 01 00 00 d5 12 00 00 00 00 00 00 |................| +00012ae0 10 00 01 00 0a 01 00 00 36 18 00 00 9d 00 00 00 |........6.......| +00012af0 12 00 01 00 11 01 00 00 ed 12 00 00 00 00 00 00 |................| +00012b00 10 00 01 00 19 01 00 00 14 17 00 00 8a 00 00 00 |................| +00012b10 12 00 01 00 20 01 00 00 cb 11 00 00 21 00 00 00 |.... .......!...| +00012b20 12 00 01 00 29 01 00 00 dd 12 00 00 00 00 00 00 |....)...........| +00012b30 10 00 01 00 31 01 00 00 ba 15 00 00 47 00 00 00 |....1.......G...| +00012b40 12 00 01 00 4a 01 00 00 9d 12 00 00 00 00 00 00 |....J...........| +00012b50 10 00 01 00 38 01 00 00 98 15 00 00 22 00 00 00 |....8......."...| +00012b60 12 00 01 00 3f 01 00 00 05 13 00 00 00 00 00 00 |....?...........| +00012b70 10 00 01 00 45 01 00 00 0d 13 00 00 00 00 00 00 |....E...........| +00012b80 10 00 01 00 00 70 72 6f 67 51 2e 63 00 75 6c 69 |.....progQ.c.uli| +00012b90 62 63 2e 63 00 73 70 72 69 6e 74 2e 63 00 73 74 |bc.c.sprint.c.st| +00012ba0 72 6c 65 6e 2e 63 00 63 76 74 64 65 63 2e 63 00 |rlen.c.cvtdec.c.| +00012bb0 63 76 74 64 65 63 30 2e 63 00 63 76 74 68 65 78 |cvtdec0.c.cvthex| +00012bc0 2e 63 00 63 76 74 6f 63 74 2e 63 00 63 76 74 75 |.c.cvtoct.c.cvtu| +00012bd0 6e 73 2e 63 00 63 76 74 75 6e 73 30 2e 63 00 70 |ns.c.cvtuns0.c.p| +00012be0 61 64 73 74 72 2e 63 00 70 61 64 2e 63 00 73 77 |adstr.c.pad.c.sw| +00012bf0 72 69 74 65 63 68 00 77 61 69 74 70 69 64 00 63 |ritech.waitpid.c| +00012c00 77 72 69 74 65 00 63 76 74 75 6e 73 00 67 65 74 |write.cvtuns.get| +00012c10 70 69 64 00 73 6c 65 65 70 00 73 77 72 69 74 65 |pid.sleep.swrite| +00012c20 00 70 61 64 00 73 70 61 77 6e 00 73 70 72 69 6e |.pad.spawn.sprin| +00012c30 74 00 63 76 74 68 65 78 00 63 76 74 75 6e 73 30 |t.cvthex.cvtuns0| +00012c40 00 6b 69 6c 6c 00 63 77 72 69 74 65 73 00 65 78 |.kill.cwrites.ex| +00012c50 65 63 00 77 61 69 74 00 73 77 72 69 74 65 73 00 |ec.wait.swrites.| +00012c60 5f 73 74 61 72 74 00 72 65 61 64 00 67 65 74 70 |_start.read.getp| +00012c70 72 69 6f 00 63 76 74 64 65 63 30 00 66 6f 72 6b |rio.cvtdec0.fork| +00012c80 00 6d 61 69 6e 00 67 65 74 70 70 69 64 00 70 61 |.main.getppid.pa| +00012c90 64 73 74 72 00 73 65 74 70 72 69 6f 00 63 76 74 |dstr.setprio.cvt| +00012ca0 6f 63 74 00 63 77 72 69 74 65 63 68 00 67 65 74 |oct.cwritech.get| +00012cb0 74 69 6d 65 00 63 76 74 64 65 63 00 73 74 72 6c |time.cvtdec.strl| +00012cc0 65 6e 00 62 6f 67 75 73 00 66 61 6b 65 5f 65 78 |en.bogus.fake_ex| +00012cd0 69 74 00 00 2e 73 79 6d 74 61 62 00 2e 73 74 72 |it...symtab..str| +00012ce0 74 61 62 00 2e 73 68 73 74 72 74 61 62 00 2e 74 |tab..shstrtab..t| +00012cf0 65 78 74 00 2e 72 6f 64 61 74 61 00 2e 64 61 74 |ext..rodata..dat| +00012d00 61 00 2e 62 73 73 00 00 00 00 00 00 00 00 00 00 |a..bss..........| +00012d10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00012d30 1b 00 00 00 01 00 00 00 06 00 00 00 00 10 00 00 |................| +00012d40 74 00 00 00 f5 08 00 00 00 00 00 00 00 00 00 00 |t...............| +00012d50 01 00 00 00 00 00 00 00 21 00 00 00 01 00 00 00 |........!.......| +00012d60 02 00 00 00 f8 18 00 00 6c 09 00 00 c4 00 00 00 |........l.......| +00012d70 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 |................| +00012d80 29 00 00 00 01 00 00 00 03 00 00 00 00 20 00 00 |)............ ..| +00012d90 74 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |t...............| +00012da0 01 00 00 00 00 00 00 00 2f 00 00 00 08 00 00 00 |......../.......| +00012db0 03 00 00 00 00 20 00 00 74 10 00 00 00 00 00 00 |..... ..t.......| +00012dc0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 |................| +00012dd0 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 |................| +00012de0 74 10 00 00 40 03 00 00 06 00 00 00 11 00 00 00 |t...@...........| +00012df0 04 00 00 00 10 00 00 00 09 00 00 00 03 00 00 00 |................| +00012e00 00 00 00 00 00 00 00 00 b4 13 00 00 4f 01 00 00 |............O...| +00012e10 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 |................| +00012e20 11 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 |................| +00012e30 03 15 00 00 34 00 00 00 00 00 00 00 00 00 00 00 |....4...........| +00012e40 01 00 00 00 00 00 00 00 7f 45 4c 46 01 01 01 00 |.........ELF....| +00012e50 00 00 00 00 00 00 00 00 02 00 03 00 01 00 00 00 |................| +00012e60 23 14 00 00 34 00 00 00 6c 15 00 00 00 00 00 00 |#...4...l.......| +00012e70 34 00 20 00 02 00 28 00 08 00 07 00 01 00 00 00 |4. ...(.........| +00012e80 74 00 00 00 00 10 00 00 00 10 00 00 00 10 00 00 |t...............| +00012e90 00 10 00 00 07 00 00 00 04 00 00 00 51 e5 74 64 |............Q.td| +00012ea0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00012eb0 00 00 00 00 07 00 00 00 10 00 00 00 8d 4c 24 04 |.............L$.| +00012ec0 83 e4 f0 ff 71 fc 55 89 e5 53 51 81 ec a0 00 00 |....q.U..SQ.....| +00012ed0 00 89 cb c6 45 f7 72 c7 45 f0 0a 00 00 00 c7 45 |....E.r.E......E| +00012ee0 ec 63 00 00 00 8b 03 83 f8 03 74 25 83 f8 04 74 |.c........t%...t| +00012ef0 07 83 f8 02 74 34 eb 45 8b 43 04 83 c0 0c 8b 00 |....t4.E.C......| +00012f00 83 ec 08 6a 0a 50 e8 59 06 00 00 83 c4 10 89 45 |...j.P.Y.......E| +00012f10 f0 8b 43 04 83 c0 08 8b 00 83 ec 08 6a 0a 50 e8 |..C.........j.P.| +00012f20 40 06 00 00 83 c4 10 89 45 ec 8b 43 04 83 c0 04 |@.......E..C....| +00012f30 8b 00 0f b6 00 88 45 f7 e9 a4 00 00 00 83 ec 04 |......E.........| +00012f40 ff 33 68 78 1a 00 00 8d 85 5c ff ff ff 50 e8 9c |.3hx.....\...P..| +00012f50 03 00 00 83 c4 10 83 ec 0c 8d 85 5c ff ff ff 50 |...........\...P| +00012f60 e8 53 02 00 00 83 c4 10 c7 45 e8 00 00 00 00 eb |.S.......E......| +00012f70 59 8b 03 8d 14 85 00 00 00 00 8b 43 04 01 d0 8b |Y..........C....| +00012f80 00 85 c0 74 12 8b 03 8d 14 85 00 00 00 00 8b 43 |...t...........C| +00012f90 04 01 d0 8b 00 eb 05 b8 8f 1a 00 00 83 ec 04 50 |...............P| +00012fa0 68 96 1a 00 00 8d 85 5c ff ff ff 50 e8 3e 03 00 |h......\...P.>..| +00012fb0 00 83 c4 10 83 ec 0c 8d 85 5c ff ff ff 50 e8 f5 |.........\...P..| +00012fc0 01 00 00 83 c4 10 83 45 e8 01 8b 45 e8 3b 03 7e |.......E...E.;.~| +00012fd0 a0 83 ec 0c 68 9a 1a 00 00 e8 da 01 00 00 83 c4 |....h...........| +00012fe0 10 e8 b3 02 00 00 89 45 e4 e8 b3 02 00 00 89 45 |.......E.......E| +00012ff0 e0 0f be 45 f7 83 ec 08 ff 75 e0 ff 75 e4 ff 75 |...E.....u..u..u| +00013000 ec 50 68 9c 1a 00 00 8d 85 5c ff ff ff 50 e8 dc |.Ph......\...P..| +00013010 02 00 00 83 c4 20 83 ec 0c 8d 85 5c ff ff ff 50 |..... .....\...P| +00013020 e8 fc 01 00 00 83 c4 10 8b 45 f0 69 c0 e8 03 00 |.........E.i....| +00013030 00 83 ec 0c 50 e8 8f 02 00 00 83 c4 10 83 7d ec |....P.........}.| +00013040 04 7f 63 83 45 ec 01 e8 2d 02 00 00 89 45 dc 8b |..c.E...-....E..| +00013050 45 dc 83 f8 ff 74 06 85 c0 74 86 eb 2e ff 75 dc |E....t...t....u.| +00013060 ff 75 e4 68 aa 1a 00 00 8d 85 5c ff ff ff 50 e8 |.u.h......\...P.| +00013070 7b 02 00 00 83 c4 10 83 ec 0c 8d 85 5c ff ff ff |{...........\...| +00013080 50 e8 32 01 00 00 83 c4 10 eb 1c 83 6d ec 01 8b |P.2.........m...| +00013090 45 f0 69 c0 e8 03 00 00 83 ec 0c 50 e8 28 02 00 |E.i........P.(..| +000130a0 00 83 c4 10 eb 01 90 e8 ed 01 00 00 89 45 e4 e8 |.............E..| +000130b0 ed 01 00 00 89 45 e0 0f be 45 f7 83 ec 08 ff 75 |.....E...E.....u| +000130c0 e0 ff 75 e4 ff 75 ec 50 68 9c 1a 00 00 8d 85 5c |..u..u.Ph......\| +000130d0 ff ff ff 50 e8 16 02 00 00 83 c4 20 83 ec 0c 8d |...P....... ....| +000130e0 85 5c ff ff ff 50 e8 36 01 00 00 83 c4 10 83 ec |.\...P.6........| +000130f0 0c 6a 00 e8 71 01 00 00 83 c4 10 b8 2a 00 00 00 |.j..q.......*...| +00013100 8d 65 f8 59 5b 5d 8d 61 fc c3 55 89 e5 83 ec 08 |.e.Y[].a..U.....| +00013110 83 ec 08 ff 75 08 6a 00 e8 54 01 00 00 83 c4 10 |....u.j..T......| +00013120 c9 c3 55 89 e5 81 ec 18 01 00 00 e8 49 01 00 00 |..U.........I...| +00013130 89 45 f4 83 7d f4 00 74 05 8b 45 f4 eb 57 e8 56 |.E..}..t..E..W.V| +00013140 01 00 00 89 45 f4 83 ec 08 ff 75 0c ff 75 08 e8 |....E.....u..u..| +00013150 2d 01 00 00 83 c4 10 ff 75 08 ff 75 f4 68 c1 1a |-.......u..u.h..| +00013160 00 00 8d 85 f4 fe ff ff 50 e8 81 01 00 00 83 c4 |........P.......| +00013170 10 83 ec 0c 8d 85 f4 fe ff ff 50 e8 38 00 00 00 |..........P.8...| +00013180 83 c4 10 83 ec 0c 6a ff e8 dc 00 00 00 83 c4 10 |......j.........| +00013190 b8 00 00 00 00 c9 c3 55 89 e5 83 ec 18 8b 45 08 |.......U......E.| +000131a0 88 45 f4 83 ec 04 6a 01 8d 45 f4 50 6a 00 e8 de |.E....j..E.Pj...| +000131b0 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 83 ec |........U.......| +000131c0 0c ff 75 08 e8 0d 04 00 00 83 c4 10 89 45 f4 8b |..u..........E..| +000131d0 45 f4 83 ec 04 50 ff 75 08 6a 00 e8 b1 00 00 00 |E....P.u.j......| +000131e0 83 c4 10 c9 c3 55 89 e5 83 ec 08 83 ec 04 ff 75 |.....U.........u| +000131f0 0c ff 75 08 6a 00 e8 96 00 00 00 83 c4 10 c9 c3 |..u.j...........| +00013200 55 89 e5 83 ec 18 8b 45 08 88 45 f4 83 ec 04 6a |U......E..E....j| +00013210 01 8d 45 f4 50 6a 01 e8 75 00 00 00 83 c4 10 c9 |..E.Pj..u.......| +00013220 c3 55 89 e5 83 ec 18 83 ec 0c ff 75 08 e8 a4 03 |.U.........u....| +00013230 00 00 83 c4 10 89 45 f4 8b 45 f4 83 ec 04 50 ff |......E..E....P.| +00013240 75 08 6a 01 e8 48 00 00 00 83 c4 10 c9 c3 55 89 |u.j..H........U.| +00013250 e5 83 ec 08 83 ec 04 ff 75 0c ff 75 08 6a 01 e8 |........u..u.j..| +00013260 2d 00 00 00 83 c4 10 c9 c3 b8 00 00 00 00 cd 80 |-...............| +00013270 c3 b8 01 00 00 00 cd 80 c3 b8 02 00 00 00 cd 80 |................| +00013280 c3 b8 03 00 00 00 cd 80 c3 b8 04 00 00 00 cd 80 |................| +00013290 c3 b8 05 00 00 00 cd 80 c3 b8 06 00 00 00 cd 80 |................| +000132a0 c3 b8 07 00 00 00 cd 80 c3 b8 08 00 00 00 cd 80 |................| +000132b0 c3 b8 09 00 00 00 cd 80 c3 b8 0a 00 00 00 cd 80 |................| +000132c0 c3 b8 0b 00 00 00 cd 80 c3 b8 0c 00 00 00 cd 80 |................| +000132d0 c3 b8 ad 0b 00 00 cd 80 c3 50 e8 8a ff ff ff e8 |.........P......| +000132e0 d8 fb ff ff 83 ec 0c 50 e8 7c ff ff ff eb fe 55 |.......P.|.....U| +000132f0 89 e5 83 ec 38 8d 45 0c 83 c0 04 89 45 f4 e9 3f |....8.E.....E..?| +00013300 02 00 00 80 7d f3 25 0f 85 26 02 00 00 c7 45 ec |....}.%..&....E.| +00013310 00 00 00 00 c7 45 e4 20 00 00 00 c7 45 e8 00 00 |.....E. ....E...| +00013320 00 00 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 |...E..P..U.....E| +00013330 f3 80 7d f3 2d 75 16 c7 45 ec 01 00 00 00 8b 45 |..}.-u..E......E| +00013340 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 |..P..U.....E..}.| +00013350 30 75 40 c7 45 e4 30 00 00 00 8b 45 0c 8d 50 01 |0u@.E.0....E..P.| +00013360 89 55 0c 0f b6 00 88 45 f3 eb 28 8b 55 e8 89 d0 |.U.....E..(.U...| +00013370 c1 e0 02 01 d0 01 c0 89 45 e8 0f be 45 f3 83 e8 |........E...E...| +00013380 30 01 45 e8 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 |0.E..E..P..U....| +00013390 88 45 f3 80 7d f3 2f 7e 06 80 7d f3 39 7e cc 0f |.E..}./~..}.9~..| +000133a0 be 45 f3 83 e8 63 83 f8 15 0f 87 93 01 00 00 8b |.E...c..........| +000133b0 04 85 e0 1a 00 00 ff e0 8b 45 f4 8d 50 04 89 55 |.........E..P..U| +000133c0 f4 8b 00 88 45 f3 0f b6 45 f3 88 45 d0 c6 45 d1 |....E...E..E..E.| +000133d0 00 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 6a 01 8d |.....u..u..u.j..| +000133e0 45 d0 50 ff 75 08 e8 89 04 00 00 83 c4 20 89 45 |E.P.u........ .E| +000133f0 08 e9 4c 01 00 00 8b 45 f4 8d 50 04 89 55 f4 8b |..L....E..P..U..| +00013400 00 83 ec 08 50 8d 45 d0 50 e8 ea 01 00 00 83 c4 |....P.E.P.......| +00013410 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 |..E.....u..u..u.| +00013420 ff 75 e0 8d 45 d0 50 ff 75 08 e8 45 04 00 00 83 |.u..E.P.u..E....| +00013430 c4 20 89 45 08 e9 08 01 00 00 8b 45 f4 8d 50 04 |. .E.......E..P.| +00013440 89 55 f4 8b 00 89 45 dc 83 ec 08 ff 75 e4 ff 75 |.U....E.....u..u| +00013450 ec ff 75 e8 6a ff ff 75 dc ff 75 08 e8 13 04 00 |..u.j..u..u.....| +00013460 00 83 c4 20 89 45 08 e9 d6 00 00 00 8b 45 f4 8d |... .E.......E..| +00013470 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 |P..U......P.E.P.| +00013480 44 02 00 00 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 |D.......E.....u.| +00013490 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 |.u..u..u..E.P.u.| +000134a0 e8 cf 03 00 00 83 c4 20 89 45 08 e9 92 00 00 00 |....... .E......| +000134b0 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d |.E..P..U......P.| +000134c0 45 d0 50 e8 8a 02 00 00 83 c4 10 89 45 e0 83 ec |E.P.........E...| +000134d0 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 |..u..u..u..u..E.| +000134e0 50 ff 75 08 e8 8b 03 00 00 83 c4 20 89 45 08 eb |P.u........ .E..| +000134f0 51 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 |Q.E..P..U......P| +00013500 8d 45 d0 50 e8 d3 02 00 00 83 c4 10 89 45 e0 83 |.E.P.........E..| +00013510 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 |...u..u..u..u..E| +00013520 d0 50 ff 75 08 e8 4a 03 00 00 83 c4 20 89 45 08 |.P.u..J..... .E.| +00013530 90 eb 0f 8b 45 08 8d 50 01 89 55 08 0f b6 55 f3 |....E..P..U...U.| +00013540 88 10 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 |...E..P..U.....E| +00013550 f3 80 7d f3 00 0f 85 a8 fd ff ff 8b 45 08 c6 00 |..}.........E...| +00013560 00 90 c9 c3 55 89 e5 53 83 ec 14 8b 45 08 8b 4d |....U..S....E..M| +00013570 0c bb 00 00 00 00 c6 45 eb 39 c7 45 f8 01 00 00 |.......E.9.E....| +00013580 00 0f b6 10 80 fa 2d 75 0a c7 45 f8 ff ff ff ff |......-u..E.....| +00013590 83 c0 01 83 f9 0a 74 2b 89 ca 83 c2 2f 88 55 eb |......t+..../.U.| +000135a0 eb 21 0f b6 10 80 fa 2f 7e 20 0f b6 10 38 55 eb |.!...../~ ...8U.| +000135b0 7c 18 0f af d9 0f b6 10 0f be d2 01 da 8d 5a d0 ||.............Z.| +000135c0 83 c0 01 0f b6 10 84 d2 75 d8 89 d8 0f af 45 f8 |........u.....E.| +000135d0 83 c4 14 5b 5d c3 55 89 e5 53 8b 55 08 bb 00 00 |...[].U..S.U....| +000135e0 00 00 eb 03 83 c3 01 89 d0 8d 50 01 0f b6 00 84 |..........P.....| +000135f0 c0 75 f1 89 d8 5b 5d c3 55 89 e5 83 ec 18 8b 45 |.u...[].U......E| +00013600 08 89 45 f4 83 7d 0c 00 79 0f 8b 45 f4 8d 50 01 |..E..}..y..E..P.| +00013610 89 55 f4 c6 00 2d f7 5d 0c 83 ec 08 ff 75 0c ff |.U...-.].....u..| +00013620 75 f4 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 |u..........E..E.| +00013630 c6 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 |....U..E.).....U| +00013640 89 e5 83 ec 18 8b 4d 0c ba 67 66 66 66 89 c8 f7 |......M..gfff...| +00013650 ea c1 fa 02 89 c8 c1 f8 1f 29 c2 89 d0 89 45 f4 |.........)....E.| +00013660 83 7d f4 00 79 0e c7 45 f4 cc cc cc 0c c7 45 0c |.}..y..E......E.| +00013670 08 00 00 00 83 7d f4 00 74 14 83 ec 08 ff 75 f4 |.....}..t.....u.| +00013680 ff 75 08 e8 b7 ff ff ff 83 c4 10 89 45 08 8b 4d |.u..........E..M| +00013690 0c ba 67 66 66 66 89 c8 f7 ea c1 fa 02 89 c8 c1 |..gfff..........| +000136a0 f8 1f 29 c2 89 d0 c1 e0 02 01 d0 01 c0 29 c1 89 |..)..........)..| +000136b0 ca 89 d0 8d 48 30 8b 45 08 8d 50 01 89 55 08 89 |....H0.E..P..U..| +000136c0 ca 88 10 8b 45 08 c9 c3 55 89 e5 83 ec 20 c7 45 |....E...U.... .E| +000136d0 e3 30 31 32 33 c7 45 e7 34 35 36 37 c7 45 eb 38 |.0123.E.4567.E.8| +000136e0 39 41 42 c7 45 ef 43 44 45 46 c6 45 f3 00 c7 45 |9AB.E.CDEF.E...E| +000136f0 fc 00 00 00 00 c7 45 f8 00 00 00 00 eb 43 8b 45 |......E......C.E| +00013700 0c 25 00 00 00 f0 89 45 f4 83 7d fc 00 75 0c 83 |.%.....E..}..u..| +00013710 7d f4 00 75 06 83 7d f8 07 75 1e 83 45 fc 01 c1 |}..u..}..u..E...| +00013720 6d f4 1c 8b 45 08 8d 50 01 89 55 08 8d 4d e3 8b |m...E..P..U..M..| +00013730 55 f4 01 ca 0f b6 12 88 10 c1 65 0c 04 83 45 f8 |U.........e...E.| +00013740 01 83 7d f8 07 7e b7 8b 45 08 c6 00 00 8b 45 fc |..}..~..E.....E.| +00013750 c9 c3 55 89 e5 83 ec 10 c7 45 f8 00 00 00 00 8b |..U......E......| +00013760 45 08 89 45 f4 8b 45 0c 25 00 00 00 c0 89 45 f0 |E..E..E.%.....E.| +00013770 c1 6d f0 1e c7 45 fc 00 00 00 00 eb 47 83 7d fc |.m...E......G.}.| +00013780 0a 74 0c 83 7d f0 00 75 06 83 7d f8 00 74 1e c7 |.t..}..u..}..t..| +00013790 45 f8 01 00 00 00 83 65 f0 07 8b 45 f0 8d 48 30 |E......e...E..H0| +000137a0 8b 45 f4 8d 50 01 89 55 f4 89 ca 88 10 c1 65 0c |.E..P..U......e.| +000137b0 03 8b 45 0c 25 00 00 00 e0 89 45 f0 c1 6d f0 1d |..E.%.....E..m..| +000137c0 83 45 fc 01 83 7d fc 0a 7e b3 8b 45 f4 c6 00 00 |.E...}..~..E....| +000137d0 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 |.U..E.).....U...| +000137e0 ec 18 8b 45 08 89 45 f4 83 ec 08 ff 75 0c ff 75 |...E..E.....u..u| +000137f0 f4 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 c6 |..........E..E..| +00013800 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 |...U..E.).....U.| +00013810 e5 83 ec 18 8b 45 0c ba cd cc cc cc f7 e2 89 d0 |.....E..........| +00013820 c1 e8 03 89 45 f4 83 7d f4 00 74 15 8b 45 f4 83 |....E..}..t..E..| +00013830 ec 08 50 ff 75 08 e8 04 fe ff ff 83 c4 10 89 45 |..P.u..........E| +00013840 08 8b 4d 0c ba cd cc cc cc 89 c8 f7 e2 c1 ea 03 |..M.............| +00013850 89 d0 c1 e0 02 01 d0 01 c0 29 c1 89 ca 89 d0 8d |.........)......| +00013860 48 30 8b 45 08 8d 50 01 89 55 08 89 ca 88 10 8b |H0.E..P..U......| +00013870 45 08 c9 c3 55 89 e5 83 ec 18 83 7d 10 00 79 11 |E...U......}..y.| +00013880 83 ec 0c ff 75 0c e8 4b fd ff ff 83 c4 10 89 45 |....u..K.......E| +00013890 10 8b 45 14 2b 45 10 89 45 f0 83 7d f0 00 7e 1d |..E.+E..E..}..~.| +000138a0 83 7d 18 00 75 17 83 ec 04 ff 75 1c ff 75 f0 ff |.}..u.....u..u..| +000138b0 75 08 e8 5a 00 00 00 83 c4 10 89 45 08 c7 45 f4 |u..Z.......E..E.| +000138c0 00 00 00 00 eb 1b 8b 55 f4 8b 45 0c 8d 0c 02 8b |.......U..E.....| +000138d0 45 08 8d 50 01 89 55 08 0f b6 11 88 10 83 45 f4 |E..P..U.......E.| +000138e0 01 8b 45 f4 3b 45 10 7c dd 83 7d f0 00 7e 1d 83 |..E.;E.|..}..~..| +000138f0 7d 18 00 74 17 83 ec 04 ff 75 1c ff 75 f0 ff 75 |}..t.....u..u..u| +00013900 08 e8 0b 00 00 00 83 c4 10 89 45 08 8b 45 08 c9 |..........E..E..| +00013910 c3 55 89 e5 eb 12 8b 45 08 8d 50 01 89 55 08 8b |.U.....E..P..U..| +00013920 55 10 88 10 83 6d 0c 01 83 7d 0c 00 7f e8 8b 45 |U....m...}.....E| +00013930 08 5d c3 00 75 73 65 72 52 3a 20 61 72 67 63 20 |.]..userR: argc | +00013940 25 64 2c 20 61 72 67 73 3a 20 00 28 6e 75 6c 6c |%d, args: .(null| +00013950 29 00 20 25 73 00 0a 00 20 25 63 5b 25 64 2c 25 |). %s... %c[%d,%| +00013960 64 2c 25 64 5d 00 2a 2a 20 52 5b 25 64 5d 20 66 |d,%d].** R[%d] f| +00013970 6f 72 6b 20 63 6f 64 65 20 25 64 0a 00 43 68 69 |ork code %d..Chi| +00013980 6c 64 20 25 64 20 65 78 65 63 28 29 20 23 25 75 |ld %d exec() #%u| +00013990 20 66 61 69 6c 65 64 0a 00 00 00 00 fc 14 00 00 | failed.........| +000139a0 3a 15 00 00 86 16 00 00 86 16 00 00 86 16 00 00 |:...............| +000139b0 86 16 00 00 86 16 00 00 86 16 00 00 86 16 00 00 |................| +000139c0 86 16 00 00 86 16 00 00 86 16 00 00 f4 15 00 00 |................| +000139d0 86 16 00 00 86 16 00 00 86 16 00 00 7e 15 00 00 |............~...| +000139e0 86 16 00 00 35 16 00 00 86 16 00 00 86 16 00 00 |....5...........| +000139f0 b0 15 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00013a00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00013ed0 00 10 00 00 00 00 00 00 03 00 01 00 00 00 00 00 |................| +00013ee0 78 1a 00 00 00 00 00 00 03 00 02 00 00 00 00 00 |x...............| +00013ef0 00 20 00 00 00 00 00 00 03 00 03 00 00 00 00 00 |. ..............| +00013f00 00 20 00 00 00 00 00 00 03 00 04 00 01 00 00 00 |. ..............| +00013f10 00 00 00 00 00 00 00 00 04 00 f1 ff 09 00 00 00 |................| +00013f20 00 00 00 00 00 00 00 00 04 00 f1 ff 11 00 00 00 |................| +00013f30 00 00 00 00 00 00 00 00 04 00 f1 ff 1a 00 00 00 |................| +00013f40 00 00 00 00 00 00 00 00 04 00 f1 ff 24 00 00 00 |............$...| +00013f50 00 00 00 00 00 00 00 00 04 00 f1 ff 2d 00 00 00 |............-...| +00013f60 00 00 00 00 00 00 00 00 04 00 f1 ff 36 00 00 00 |............6...| +00013f70 00 00 00 00 00 00 00 00 04 00 f1 ff 40 00 00 00 |............@...| +00013f80 00 00 00 00 00 00 00 00 04 00 f1 ff 49 00 00 00 |............I...| +00013f90 00 00 00 00 00 00 00 00 04 00 f1 ff 52 00 00 00 |............R...| +00013fa0 00 00 00 00 00 00 00 00 04 00 f1 ff 5b 00 00 00 |............[...| +00013fb0 00 00 00 00 00 00 00 00 04 00 f1 ff 65 00 00 00 |............e...| +00013fc0 00 00 00 00 00 00 00 00 04 00 f1 ff 6e 00 00 00 |............n...| +00013fd0 00 00 00 00 00 00 00 00 04 00 f1 ff 74 00 00 00 |............t...| +00013fe0 44 13 00 00 21 00 00 00 12 00 01 00 7d 00 00 00 |D...!.......}...| +00013ff0 b5 13 00 00 00 00 00 00 10 00 01 00 85 00 00 00 |................| +00014000 29 13 00 00 1b 00 00 00 12 00 01 00 8c 00 00 00 |)...............| +00014010 a8 16 00 00 72 00 00 00 12 00 01 00 94 00 00 00 |....r...........| +00014020 20 19 00 00 32 00 00 00 12 00 01 00 9b 00 00 00 | ...2...........| +00014030 dd 13 00 00 00 00 00 00 10 00 01 00 a2 00 00 00 |................| +00014040 0d 14 00 00 00 00 00 00 10 00 01 00 a8 00 00 00 |................| +00014050 92 13 00 00 1b 00 00 00 12 00 01 00 af 00 00 00 |................| +00014060 55 1a 00 00 22 00 00 00 12 00 01 00 b3 00 00 00 |U..."...........| +00014070 66 12 00 00 75 00 00 00 12 00 01 00 b9 00 00 00 |f...u...........| +00014080 33 14 00 00 75 02 00 00 12 00 01 00 c0 00 00 00 |3...u...........| +00014090 0c 18 00 00 8a 00 00 00 12 00 01 00 c7 00 00 00 |................| +000140a0 52 19 00 00 66 00 00 00 12 00 01 00 86 00 00 00 |R...f...........| +000140b0 d5 13 00 00 00 00 00 00 10 00 01 00 cf 00 00 00 |................| +000140c0 05 14 00 00 00 00 00 00 10 00 01 00 d4 00 00 00 |................| +000140d0 fc 12 00 00 2d 00 00 00 12 00 01 00 dc 00 00 00 |....-...........| +000140e0 c5 13 00 00 00 00 00 00 10 00 01 00 e1 00 00 00 |................| +000140f0 4e 12 00 00 18 00 00 00 12 00 01 00 e6 00 00 00 |N...............| +00014100 65 13 00 00 2d 00 00 00 12 00 01 00 ee 00 00 00 |e...-...........| +00014110 23 14 00 00 00 00 00 00 10 00 01 00 f5 00 00 00 |#...............| +00014120 cd 13 00 00 00 00 00 00 10 00 01 00 fa 00 00 00 |................| +00014130 f5 13 00 00 00 00 00 00 10 00 01 00 02 01 00 00 |................| +00014140 83 17 00 00 89 00 00 00 12 00 01 00 0a 01 00 00 |................| +00014150 bd 13 00 00 00 00 00 00 10 00 01 00 0f 01 00 00 |................| +00014160 00 10 00 00 4e 02 00 00 12 00 01 00 14 01 00 00 |....N...........| +00014170 e5 13 00 00 00 00 00 00 10 00 01 00 1c 01 00 00 |................| +00014180 b8 19 00 00 9d 00 00 00 12 00 01 00 23 01 00 00 |............#...| +00014190 fd 13 00 00 00 00 00 00 10 00 01 00 2b 01 00 00 |............+...| +000141a0 96 18 00 00 8a 00 00 00 12 00 01 00 32 01 00 00 |............2...| +000141b0 db 12 00 00 21 00 00 00 12 00 01 00 3b 01 00 00 |....!.......;...| +000141c0 ed 13 00 00 00 00 00 00 10 00 01 00 43 01 00 00 |............C...| +000141d0 3c 17 00 00 47 00 00 00 12 00 01 00 5c 01 00 00 |<...G.......\...| +000141e0 ad 13 00 00 00 00 00 00 10 00 01 00 4a 01 00 00 |............J...| +000141f0 1a 17 00 00 22 00 00 00 12 00 01 00 51 01 00 00 |....".......Q...| +00014200 15 14 00 00 00 00 00 00 10 00 01 00 57 01 00 00 |............W...| +00014210 1d 14 00 00 00 00 00 00 10 00 01 00 00 70 72 6f |.............pro| +00014220 67 52 2e 63 00 75 6c 69 62 63 2e 63 00 73 70 72 |gR.c.ulibc.c.spr| +00014230 69 6e 74 2e 63 00 73 74 72 32 69 6e 74 2e 63 00 |int.c.str2int.c.| +00014240 73 74 72 6c 65 6e 2e 63 00 63 76 74 64 65 63 2e |strlen.c.cvtdec.| +00014250 63 00 63 76 74 64 65 63 30 2e 63 00 63 76 74 68 |c.cvtdec0.c.cvth| +00014260 65 78 2e 63 00 63 76 74 6f 63 74 2e 63 00 63 76 |ex.c.cvtoct.c.cv| +00014270 74 75 6e 73 2e 63 00 63 76 74 75 6e 73 30 2e 63 |tuns.c.cvtuns0.c| +00014280 00 70 61 64 73 74 72 2e 63 00 70 61 64 2e 63 00 |.padstr.c.pad.c.| +00014290 73 77 72 69 74 65 63 68 00 77 61 69 74 70 69 64 |swritech.waitpid| +000142a0 00 63 77 72 69 74 65 00 73 74 72 32 69 6e 74 00 |.cwrite.str2int.| +000142b0 63 76 74 75 6e 73 00 67 65 74 70 69 64 00 73 6c |cvtuns.getpid.sl| +000142c0 65 65 70 00 73 77 72 69 74 65 00 70 61 64 00 73 |eep.swrite.pad.s| +000142d0 70 61 77 6e 00 73 70 72 69 6e 74 00 63 76 74 68 |pawn.sprint.cvth| +000142e0 65 78 00 63 76 74 75 6e 73 30 00 6b 69 6c 6c 00 |ex.cvtuns0.kill.| +000142f0 63 77 72 69 74 65 73 00 65 78 65 63 00 77 61 69 |cwrites.exec.wai| +00014300 74 00 73 77 72 69 74 65 73 00 5f 73 74 61 72 74 |t.swrites._start| +00014310 00 72 65 61 64 00 67 65 74 70 72 69 6f 00 63 76 |.read.getprio.cv| +00014320 74 64 65 63 30 00 66 6f 72 6b 00 6d 61 69 6e 00 |tdec0.fork.main.| +00014330 67 65 74 70 70 69 64 00 70 61 64 73 74 72 00 73 |getppid.padstr.s| +00014340 65 74 70 72 69 6f 00 63 76 74 6f 63 74 00 63 77 |etprio.cvtoct.cw| +00014350 72 69 74 65 63 68 00 67 65 74 74 69 6d 65 00 63 |ritech.gettime.c| +00014360 76 74 64 65 63 00 73 74 72 6c 65 6e 00 62 6f 67 |vtdec.strlen.bog| +00014370 75 73 00 66 61 6b 65 5f 65 78 69 74 00 00 2e 73 |us.fake_exit...s| +00014380 79 6d 74 61 62 00 2e 73 74 72 74 61 62 00 2e 73 |ymtab..strtab..s| +00014390 68 73 74 72 74 61 62 00 2e 74 65 78 74 00 2e 72 |hstrtab..text..r| +000143a0 6f 64 61 74 61 00 2e 64 61 74 61 00 2e 62 73 73 |odata..data..bss| +000143b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +000143d0 00 00 00 00 00 00 00 00 00 00 00 00 1b 00 00 00 |................| +000143e0 01 00 00 00 06 00 00 00 00 10 00 00 74 00 00 00 |............t...| +000143f0 77 0a 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |w...............| +00014400 00 00 00 00 21 00 00 00 01 00 00 00 02 00 00 00 |....!...........| +00014410 78 1a 00 00 ec 0a 00 00 c0 00 00 00 00 00 00 00 |x...............| +00014420 00 00 00 00 04 00 00 00 00 00 00 00 29 00 00 00 |............)...| +00014430 01 00 00 00 03 00 00 00 00 20 00 00 74 10 00 00 |......... ..t...| +00014440 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +00014450 00 00 00 00 2f 00 00 00 08 00 00 00 03 00 00 00 |..../...........| +00014460 00 20 00 00 74 10 00 00 00 00 00 00 00 00 00 00 |. ..t...........| +00014470 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 |................| +00014480 02 00 00 00 00 00 00 00 00 00 00 00 74 10 00 00 |............t...| +00014490 60 03 00 00 06 00 00 00 12 00 00 00 04 00 00 00 |`...............| +000144a0 10 00 00 00 09 00 00 00 03 00 00 00 00 00 00 00 |................| +000144b0 00 00 00 00 d4 13 00 00 61 01 00 00 00 00 00 00 |........a.......| +000144c0 00 00 00 00 01 00 00 00 00 00 00 00 11 00 00 00 |................| +000144d0 03 00 00 00 00 00 00 00 00 00 00 00 35 15 00 00 |............5...| +000144e0 34 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |4...............| +000144f0 00 00 00 00 00 00 00 00 7f 45 4c 46 01 01 01 00 |.........ELF....| +00014500 00 00 00 00 00 00 00 00 02 00 03 00 01 00 00 00 |................| +00014510 43 13 00 00 34 00 00 00 6c 15 00 00 00 00 00 00 |C...4...l.......| +00014520 34 00 20 00 02 00 28 00 08 00 07 00 01 00 00 00 |4. ...(.........| +00014530 74 00 00 00 00 10 00 00 00 10 00 00 00 10 00 00 |t...............| +00014540 00 10 00 00 07 00 00 00 04 00 00 00 51 e5 74 64 |............Q.td| +00014550 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00014560 00 00 00 00 07 00 00 00 10 00 00 00 8d 4c 24 04 |.............L$.| +00014570 83 e4 f0 ff 71 fc 55 89 e5 53 51 81 ec 90 00 00 |....q.U..SQ.....| +00014580 00 89 cb c6 45 ef 73 c7 45 f4 14 00 00 00 8b 03 |....E.s.E.......| +00014590 83 f8 02 74 1e 83 f8 03 75 2c 8b 43 04 83 c0 08 |...t....u,.C....| +000145a0 8b 00 83 ec 08 6a 0a 50 e8 87 05 00 00 83 c4 10 |.....j.P........| +000145b0 89 45 f4 8b 43 04 83 c0 04 8b 00 0f b6 00 88 45 |.E..C..........E| +000145c0 ef e9 a4 00 00 00 83 ec 04 ff 33 68 98 19 00 00 |..........3h....| +000145d0 8d 85 6f ff ff ff 50 e8 e3 02 00 00 83 c4 10 83 |..o...P.........| +000145e0 ec 0c 8d 85 6f ff ff ff 50 e8 9a 01 00 00 83 c4 |....o...P.......| +000145f0 10 c7 45 f0 00 00 00 00 eb 59 8b 03 8d 14 85 00 |..E......Y......| +00014600 00 00 00 8b 43 04 01 d0 8b 00 85 c0 74 12 8b 03 |....C.......t...| +00014610 8d 14 85 00 00 00 00 8b 43 04 01 d0 8b 00 eb 05 |........C.......| +00014620 b8 af 19 00 00 83 ec 04 50 68 b6 19 00 00 8d 85 |........Ph......| +00014630 6f ff ff ff 50 e8 85 02 00 00 83 c4 10 83 ec 0c |o...P...........| +00014640 8d 85 6f ff ff ff 50 e8 3c 01 00 00 83 c4 10 83 |..o...P.<.......| +00014650 45 f0 01 8b 45 f0 3b 03 7e a0 83 ec 0c 68 ba 19 |E...E.;.~....h..| +00014660 00 00 e8 21 01 00 00 83 c4 10 83 ec 04 6a 01 8d |...!.........j..| +00014670 45 ef 50 6a 01 e8 e7 01 00 00 83 c4 10 8b 45 f4 |E.Pj..........E.| +00014680 69 c0 e8 03 00 00 50 ff 75 f4 68 bc 19 00 00 8d |i.....P.u.h.....| +00014690 85 6f ff ff ff 50 e8 24 02 00 00 83 c4 10 83 ec |.o...P.$........| +000146a0 0c 8d 85 6f ff ff ff 50 e8 db 00 00 00 83 c4 10 |...o...P........| +000146b0 8b 45 f4 69 c0 e8 03 00 00 83 ec 0c 50 e8 d7 01 |.E.i........P...| +000146c0 00 00 83 c4 10 83 ec 04 6a 01 8d 45 ef 50 6a 01 |........j..E.Pj.| +000146d0 e8 8c 01 00 00 83 c4 10 eb d6 55 89 e5 83 ec 08 |..........U.....| +000146e0 83 ec 08 ff 75 08 6a 00 e8 54 01 00 00 83 c4 10 |....u.j..T......| +000146f0 c9 c3 55 89 e5 81 ec 18 01 00 00 e8 49 01 00 00 |..U.........I...| +00014700 89 45 f4 83 7d f4 00 74 05 8b 45 f4 eb 57 e8 56 |.E..}..t..E..W.V| +00014710 01 00 00 89 45 f4 83 ec 08 ff 75 0c ff 75 08 e8 |....E.....u..u..| +00014720 2d 01 00 00 83 c4 10 ff 75 08 ff 75 f4 68 d3 19 |-.......u..u.h..| +00014730 00 00 8d 85 f4 fe ff ff 50 e8 81 01 00 00 83 c4 |........P.......| +00014740 10 83 ec 0c 8d 85 f4 fe ff ff 50 e8 38 00 00 00 |..........P.8...| +00014750 83 c4 10 83 ec 0c 6a ff e8 dc 00 00 00 83 c4 10 |......j.........| +00014760 b8 00 00 00 00 c9 c3 55 89 e5 83 ec 18 8b 45 08 |.......U......E.| +00014770 88 45 f4 83 ec 04 6a 01 8d 45 f4 50 6a 00 e8 de |.E....j..E.Pj...| +00014780 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 83 ec |........U.......| +00014790 0c ff 75 08 e8 0d 04 00 00 83 c4 10 89 45 f4 8b |..u..........E..| +000147a0 45 f4 83 ec 04 50 ff 75 08 6a 00 e8 b1 00 00 00 |E....P.u.j......| +000147b0 83 c4 10 c9 c3 55 89 e5 83 ec 08 83 ec 04 ff 75 |.....U.........u| +000147c0 0c ff 75 08 6a 00 e8 96 00 00 00 83 c4 10 c9 c3 |..u.j...........| +000147d0 55 89 e5 83 ec 18 8b 45 08 88 45 f4 83 ec 04 6a |U......E..E....j| +000147e0 01 8d 45 f4 50 6a 01 e8 75 00 00 00 83 c4 10 c9 |..E.Pj..u.......| +000147f0 c3 55 89 e5 83 ec 18 83 ec 0c ff 75 08 e8 a4 03 |.U.........u....| +00014800 00 00 83 c4 10 89 45 f4 8b 45 f4 83 ec 04 50 ff |......E..E....P.| +00014810 75 08 6a 01 e8 48 00 00 00 83 c4 10 c9 c3 55 89 |u.j..H........U.| +00014820 e5 83 ec 08 83 ec 04 ff 75 0c ff 75 08 6a 01 e8 |........u..u.j..| +00014830 2d 00 00 00 83 c4 10 c9 c3 b8 00 00 00 00 cd 80 |-...............| +00014840 c3 b8 01 00 00 00 cd 80 c3 b8 02 00 00 00 cd 80 |................| +00014850 c3 b8 03 00 00 00 cd 80 c3 b8 04 00 00 00 cd 80 |................| +00014860 c3 b8 05 00 00 00 cd 80 c3 b8 06 00 00 00 cd 80 |................| +00014870 c3 b8 07 00 00 00 cd 80 c3 b8 08 00 00 00 cd 80 |................| +00014880 c3 b8 09 00 00 00 cd 80 c3 b8 0a 00 00 00 cd 80 |................| +00014890 c3 b8 0b 00 00 00 cd 80 c3 b8 0c 00 00 00 cd 80 |................| +000148a0 c3 b8 ad 0b 00 00 cd 80 c3 50 e8 8a ff ff ff e8 |.........P......| +000148b0 b8 fc ff ff 83 ec 0c 50 e8 7c ff ff ff eb fe 55 |.......P.|.....U| +000148c0 89 e5 83 ec 38 8d 45 0c 83 c0 04 89 45 f4 e9 3f |....8.E.....E..?| +000148d0 02 00 00 80 7d f3 25 0f 85 26 02 00 00 c7 45 ec |....}.%..&....E.| +000148e0 00 00 00 00 c7 45 e4 20 00 00 00 c7 45 e8 00 00 |.....E. ....E...| +000148f0 00 00 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 |...E..P..U.....E| +00014900 f3 80 7d f3 2d 75 16 c7 45 ec 01 00 00 00 8b 45 |..}.-u..E......E| +00014910 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 |..P..U.....E..}.| +00014920 30 75 40 c7 45 e4 30 00 00 00 8b 45 0c 8d 50 01 |0u@.E.0....E..P.| +00014930 89 55 0c 0f b6 00 88 45 f3 eb 28 8b 55 e8 89 d0 |.U.....E..(.U...| +00014940 c1 e0 02 01 d0 01 c0 89 45 e8 0f be 45 f3 83 e8 |........E...E...| +00014950 30 01 45 e8 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 |0.E..E..P..U....| +00014960 88 45 f3 80 7d f3 2f 7e 06 80 7d f3 39 7e cc 0f |.E..}./~..}.9~..| +00014970 be 45 f3 83 e8 63 83 f8 15 0f 87 93 01 00 00 8b |.E...c..........| +00014980 04 85 f0 19 00 00 ff e0 8b 45 f4 8d 50 04 89 55 |.........E..P..U| +00014990 f4 8b 00 88 45 f3 0f b6 45 f3 88 45 d0 c6 45 d1 |....E...E..E..E.| +000149a0 00 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 6a 01 8d |.....u..u..u.j..| +000149b0 45 d0 50 ff 75 08 e8 89 04 00 00 83 c4 20 89 45 |E.P.u........ .E| +000149c0 08 e9 4c 01 00 00 8b 45 f4 8d 50 04 89 55 f4 8b |..L....E..P..U..| +000149d0 00 83 ec 08 50 8d 45 d0 50 e8 ea 01 00 00 83 c4 |....P.E.P.......| +000149e0 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 |..E.....u..u..u.| +000149f0 ff 75 e0 8d 45 d0 50 ff 75 08 e8 45 04 00 00 83 |.u..E.P.u..E....| +00014a00 c4 20 89 45 08 e9 08 01 00 00 8b 45 f4 8d 50 04 |. .E.......E..P.| +00014a10 89 55 f4 8b 00 89 45 dc 83 ec 08 ff 75 e4 ff 75 |.U....E.....u..u| +00014a20 ec ff 75 e8 6a ff ff 75 dc ff 75 08 e8 13 04 00 |..u.j..u..u.....| +00014a30 00 83 c4 20 89 45 08 e9 d6 00 00 00 8b 45 f4 8d |... .E.......E..| +00014a40 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 |P..U......P.E.P.| +00014a50 44 02 00 00 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 |D.......E.....u.| +00014a60 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 |.u..u..u..E.P.u.| +00014a70 e8 cf 03 00 00 83 c4 20 89 45 08 e9 92 00 00 00 |....... .E......| +00014a80 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d |.E..P..U......P.| +00014a90 45 d0 50 e8 8a 02 00 00 83 c4 10 89 45 e0 83 ec |E.P.........E...| +00014aa0 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 |..u..u..u..u..E.| +00014ab0 50 ff 75 08 e8 8b 03 00 00 83 c4 20 89 45 08 eb |P.u........ .E..| +00014ac0 51 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 |Q.E..P..U......P| +00014ad0 8d 45 d0 50 e8 d3 02 00 00 83 c4 10 89 45 e0 83 |.E.P.........E..| +00014ae0 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 |...u..u..u..u..E| +00014af0 d0 50 ff 75 08 e8 4a 03 00 00 83 c4 20 89 45 08 |.P.u..J..... .E.| +00014b00 90 eb 0f 8b 45 08 8d 50 01 89 55 08 0f b6 55 f3 |....E..P..U...U.| +00014b10 88 10 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 |...E..P..U.....E| +00014b20 f3 80 7d f3 00 0f 85 a8 fd ff ff 8b 45 08 c6 00 |..}.........E...| +00014b30 00 90 c9 c3 55 89 e5 53 83 ec 14 8b 45 08 8b 4d |....U..S....E..M| +00014b40 0c bb 00 00 00 00 c6 45 eb 39 c7 45 f8 01 00 00 |.......E.9.E....| +00014b50 00 0f b6 10 80 fa 2d 75 0a c7 45 f8 ff ff ff ff |......-u..E.....| +00014b60 83 c0 01 83 f9 0a 74 2b 89 ca 83 c2 2f 88 55 eb |......t+..../.U.| +00014b70 eb 21 0f b6 10 80 fa 2f 7e 20 0f b6 10 38 55 eb |.!...../~ ...8U.| +00014b80 7c 18 0f af d9 0f b6 10 0f be d2 01 da 8d 5a d0 ||.............Z.| +00014b90 83 c0 01 0f b6 10 84 d2 75 d8 89 d8 0f af 45 f8 |........u.....E.| +00014ba0 83 c4 14 5b 5d c3 55 89 e5 53 8b 55 08 bb 00 00 |...[].U..S.U....| +00014bb0 00 00 eb 03 83 c3 01 89 d0 8d 50 01 0f b6 00 84 |..........P.....| +00014bc0 c0 75 f1 89 d8 5b 5d c3 55 89 e5 83 ec 18 8b 45 |.u...[].U......E| +00014bd0 08 89 45 f4 83 7d 0c 00 79 0f 8b 45 f4 8d 50 01 |..E..}..y..E..P.| +00014be0 89 55 f4 c6 00 2d f7 5d 0c 83 ec 08 ff 75 0c ff |.U...-.].....u..| +00014bf0 75 f4 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 |u..........E..E.| +00014c00 c6 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 |....U..E.).....U| +00014c10 89 e5 83 ec 18 8b 4d 0c ba 67 66 66 66 89 c8 f7 |......M..gfff...| +00014c20 ea c1 fa 02 89 c8 c1 f8 1f 29 c2 89 d0 89 45 f4 |.........)....E.| +00014c30 83 7d f4 00 79 0e c7 45 f4 cc cc cc 0c c7 45 0c |.}..y..E......E.| +00014c40 08 00 00 00 83 7d f4 00 74 14 83 ec 08 ff 75 f4 |.....}..t.....u.| +00014c50 ff 75 08 e8 b7 ff ff ff 83 c4 10 89 45 08 8b 4d |.u..........E..M| +00014c60 0c ba 67 66 66 66 89 c8 f7 ea c1 fa 02 89 c8 c1 |..gfff..........| +00014c70 f8 1f 29 c2 89 d0 c1 e0 02 01 d0 01 c0 29 c1 89 |..)..........)..| +00014c80 ca 89 d0 8d 48 30 8b 45 08 8d 50 01 89 55 08 89 |....H0.E..P..U..| +00014c90 ca 88 10 8b 45 08 c9 c3 55 89 e5 83 ec 20 c7 45 |....E...U.... .E| +00014ca0 e3 30 31 32 33 c7 45 e7 34 35 36 37 c7 45 eb 38 |.0123.E.4567.E.8| +00014cb0 39 41 42 c7 45 ef 43 44 45 46 c6 45 f3 00 c7 45 |9AB.E.CDEF.E...E| +00014cc0 fc 00 00 00 00 c7 45 f8 00 00 00 00 eb 43 8b 45 |......E......C.E| +00014cd0 0c 25 00 00 00 f0 89 45 f4 83 7d fc 00 75 0c 83 |.%.....E..}..u..| +00014ce0 7d f4 00 75 06 83 7d f8 07 75 1e 83 45 fc 01 c1 |}..u..}..u..E...| +00014cf0 6d f4 1c 8b 45 08 8d 50 01 89 55 08 8d 4d e3 8b |m...E..P..U..M..| +00014d00 55 f4 01 ca 0f b6 12 88 10 c1 65 0c 04 83 45 f8 |U.........e...E.| +00014d10 01 83 7d f8 07 7e b7 8b 45 08 c6 00 00 8b 45 fc |..}..~..E.....E.| +00014d20 c9 c3 55 89 e5 83 ec 10 c7 45 f8 00 00 00 00 8b |..U......E......| +00014d30 45 08 89 45 f4 8b 45 0c 25 00 00 00 c0 89 45 f0 |E..E..E.%.....E.| +00014d40 c1 6d f0 1e c7 45 fc 00 00 00 00 eb 47 83 7d fc |.m...E......G.}.| +00014d50 0a 74 0c 83 7d f0 00 75 06 83 7d f8 00 74 1e c7 |.t..}..u..}..t..| +00014d60 45 f8 01 00 00 00 83 65 f0 07 8b 45 f0 8d 48 30 |E......e...E..H0| +00014d70 8b 45 f4 8d 50 01 89 55 f4 89 ca 88 10 c1 65 0c |.E..P..U......e.| +00014d80 03 8b 45 0c 25 00 00 00 e0 89 45 f0 c1 6d f0 1d |..E.%.....E..m..| +00014d90 83 45 fc 01 83 7d fc 0a 7e b3 8b 45 f4 c6 00 00 |.E...}..~..E....| +00014da0 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 |.U..E.).....U...| +00014db0 ec 18 8b 45 08 89 45 f4 83 ec 08 ff 75 0c ff 75 |...E..E.....u..u| +00014dc0 f4 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 c6 |..........E..E..| +00014dd0 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 |...U..E.).....U.| +00014de0 e5 83 ec 18 8b 45 0c ba cd cc cc cc f7 e2 89 d0 |.....E..........| +00014df0 c1 e8 03 89 45 f4 83 7d f4 00 74 15 8b 45 f4 83 |....E..}..t..E..| +00014e00 ec 08 50 ff 75 08 e8 04 fe ff ff 83 c4 10 89 45 |..P.u..........E| +00014e10 08 8b 4d 0c ba cd cc cc cc 89 c8 f7 e2 c1 ea 03 |..M.............| +00014e20 89 d0 c1 e0 02 01 d0 01 c0 29 c1 89 ca 89 d0 8d |.........)......| +00014e30 48 30 8b 45 08 8d 50 01 89 55 08 89 ca 88 10 8b |H0.E..P..U......| +00014e40 45 08 c9 c3 55 89 e5 83 ec 18 83 7d 10 00 79 11 |E...U......}..y.| +00014e50 83 ec 0c ff 75 0c e8 4b fd ff ff 83 c4 10 89 45 |....u..K.......E| +00014e60 10 8b 45 14 2b 45 10 89 45 f0 83 7d f0 00 7e 1d |..E.+E..E..}..~.| +00014e70 83 7d 18 00 75 17 83 ec 04 ff 75 1c ff 75 f0 ff |.}..u.....u..u..| +00014e80 75 08 e8 5a 00 00 00 83 c4 10 89 45 08 c7 45 f4 |u..Z.......E..E.| +00014e90 00 00 00 00 eb 1b 8b 55 f4 8b 45 0c 8d 0c 02 8b |.......U..E.....| +00014ea0 45 08 8d 50 01 89 55 08 0f b6 11 88 10 83 45 f4 |E..P..U.......E.| +00014eb0 01 8b 45 f4 3b 45 10 7c dd 83 7d f0 00 7e 1d 83 |..E.;E.|..}..~..| +00014ec0 7d 18 00 74 17 83 ec 04 ff 75 1c ff 75 f0 ff 75 |}..t.....u..u..u| +00014ed0 08 e8 0b 00 00 00 83 c4 10 89 45 08 8b 45 08 c9 |..........E..E..| +00014ee0 c3 55 89 e5 eb 12 8b 45 08 8d 50 01 89 55 08 8b |.U.....E..P..U..| +00014ef0 55 10 88 10 83 6d 0c 01 83 7d 0c 00 7f e8 8b 45 |U....m...}.....E| +00014f00 08 5d c3 00 75 73 65 72 53 3a 20 61 72 67 63 20 |.]..userS: argc | +00014f10 25 64 2c 20 61 72 67 73 3a 20 00 28 6e 75 6c 6c |%d, args: .(null| +00014f20 29 00 20 25 73 00 0a 00 75 73 65 72 53 20 73 6c |). %s...userS sl| +00014f30 65 65 70 69 6e 67 20 25 64 28 25 64 29 0a 00 43 |eeping %d(%d)..C| +00014f40 68 69 6c 64 20 25 64 20 65 78 65 63 28 29 20 23 |hild %d exec() #| +00014f50 25 75 20 66 61 69 6c 65 64 0a 00 00 1c 14 00 00 |%u failed.......| +00014f60 5a 14 00 00 a6 15 00 00 a6 15 00 00 a6 15 00 00 |Z...............| +00014f70 a6 15 00 00 a6 15 00 00 a6 15 00 00 a6 15 00 00 |................| +00014f80 a6 15 00 00 a6 15 00 00 a6 15 00 00 14 15 00 00 |................| +00014f90 a6 15 00 00 a6 15 00 00 a6 15 00 00 9e 14 00 00 |................| +00014fa0 a6 15 00 00 55 15 00 00 a6 15 00 00 a6 15 00 00 |....U...........| +00014fb0 d0 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00014fc0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00015580 00 10 00 00 00 00 00 00 03 00 01 00 00 00 00 00 |................| +00015590 98 19 00 00 00 00 00 00 03 00 02 00 00 00 00 00 |................| +000155a0 00 20 00 00 00 00 00 00 03 00 03 00 00 00 00 00 |. ..............| +000155b0 00 20 00 00 00 00 00 00 03 00 04 00 01 00 00 00 |. ..............| +000155c0 00 00 00 00 00 00 00 00 04 00 f1 ff 09 00 00 00 |................| +000155d0 00 00 00 00 00 00 00 00 04 00 f1 ff 11 00 00 00 |................| +000155e0 00 00 00 00 00 00 00 00 04 00 f1 ff 1a 00 00 00 |................| +000155f0 00 00 00 00 00 00 00 00 04 00 f1 ff 24 00 00 00 |............$...| +00015600 00 00 00 00 00 00 00 00 04 00 f1 ff 2d 00 00 00 |............-...| +00015610 00 00 00 00 00 00 00 00 04 00 f1 ff 36 00 00 00 |............6...| +00015620 00 00 00 00 00 00 00 00 04 00 f1 ff 40 00 00 00 |............@...| +00015630 00 00 00 00 00 00 00 00 04 00 f1 ff 49 00 00 00 |............I...| +00015640 00 00 00 00 00 00 00 00 04 00 f1 ff 52 00 00 00 |............R...| +00015650 00 00 00 00 00 00 00 00 04 00 f1 ff 5b 00 00 00 |............[...| +00015660 00 00 00 00 00 00 00 00 04 00 f1 ff 65 00 00 00 |............e...| +00015670 00 00 00 00 00 00 00 00 04 00 f1 ff 6e 00 00 00 |............n...| +00015680 00 00 00 00 00 00 00 00 04 00 f1 ff 74 00 00 00 |............t...| +00015690 64 12 00 00 21 00 00 00 12 00 01 00 7d 00 00 00 |d...!.......}...| +000156a0 d5 12 00 00 00 00 00 00 10 00 01 00 85 00 00 00 |................| +000156b0 49 12 00 00 1b 00 00 00 12 00 01 00 8c 00 00 00 |I...............| +000156c0 c8 15 00 00 72 00 00 00 12 00 01 00 94 00 00 00 |....r...........| +000156d0 40 18 00 00 32 00 00 00 12 00 01 00 9b 00 00 00 |@...2...........| +000156e0 fd 12 00 00 00 00 00 00 10 00 01 00 a2 00 00 00 |................| +000156f0 2d 13 00 00 00 00 00 00 10 00 01 00 a8 00 00 00 |-...............| +00015700 b2 12 00 00 1b 00 00 00 12 00 01 00 af 00 00 00 |................| +00015710 75 19 00 00 22 00 00 00 12 00 01 00 b3 00 00 00 |u..."...........| +00015720 86 11 00 00 75 00 00 00 12 00 01 00 b9 00 00 00 |....u...........| +00015730 53 13 00 00 75 02 00 00 12 00 01 00 c0 00 00 00 |S...u...........| +00015740 2c 17 00 00 8a 00 00 00 12 00 01 00 c7 00 00 00 |,...............| +00015750 72 18 00 00 66 00 00 00 12 00 01 00 86 00 00 00 |r...f...........| +00015760 f5 12 00 00 00 00 00 00 10 00 01 00 cf 00 00 00 |................| +00015770 25 13 00 00 00 00 00 00 10 00 01 00 d4 00 00 00 |%...............| +00015780 1c 12 00 00 2d 00 00 00 12 00 01 00 dc 00 00 00 |....-...........| +00015790 e5 12 00 00 00 00 00 00 10 00 01 00 e1 00 00 00 |................| +000157a0 6e 11 00 00 18 00 00 00 12 00 01 00 e6 00 00 00 |n...............| +000157b0 85 12 00 00 2d 00 00 00 12 00 01 00 ee 00 00 00 |....-...........| +000157c0 43 13 00 00 00 00 00 00 10 00 01 00 f5 00 00 00 |C...............| +000157d0 ed 12 00 00 00 00 00 00 10 00 01 00 fa 00 00 00 |................| +000157e0 15 13 00 00 00 00 00 00 10 00 01 00 02 01 00 00 |................| +000157f0 a3 16 00 00 89 00 00 00 12 00 01 00 0a 01 00 00 |................| +00015800 dd 12 00 00 00 00 00 00 10 00 01 00 0f 01 00 00 |................| +00015810 00 10 00 00 6e 01 00 00 12 00 01 00 14 01 00 00 |....n...........| +00015820 05 13 00 00 00 00 00 00 10 00 01 00 1c 01 00 00 |................| +00015830 d8 18 00 00 9d 00 00 00 12 00 01 00 23 01 00 00 |............#...| +00015840 1d 13 00 00 00 00 00 00 10 00 01 00 2b 01 00 00 |............+...| +00015850 b6 17 00 00 8a 00 00 00 12 00 01 00 32 01 00 00 |............2...| +00015860 fb 11 00 00 21 00 00 00 12 00 01 00 3b 01 00 00 |....!.......;...| +00015870 0d 13 00 00 00 00 00 00 10 00 01 00 43 01 00 00 |............C...| +00015880 5c 16 00 00 47 00 00 00 12 00 01 00 5c 01 00 00 |\...G.......\...| +00015890 cd 12 00 00 00 00 00 00 10 00 01 00 4a 01 00 00 |............J...| +000158a0 3a 16 00 00 22 00 00 00 12 00 01 00 51 01 00 00 |:...".......Q...| +000158b0 35 13 00 00 00 00 00 00 10 00 01 00 57 01 00 00 |5...........W...| +000158c0 3d 13 00 00 00 00 00 00 10 00 01 00 00 70 72 6f |=............pro| +000158d0 67 53 2e 63 00 75 6c 69 62 63 2e 63 00 73 70 72 |gS.c.ulibc.c.spr| +000158e0 69 6e 74 2e 63 00 73 74 72 32 69 6e 74 2e 63 00 |int.c.str2int.c.| +000158f0 73 74 72 6c 65 6e 2e 63 00 63 76 74 64 65 63 2e |strlen.c.cvtdec.| +00015900 63 00 63 76 74 64 65 63 30 2e 63 00 63 76 74 68 |c.cvtdec0.c.cvth| +00015910 65 78 2e 63 00 63 76 74 6f 63 74 2e 63 00 63 76 |ex.c.cvtoct.c.cv| +00015920 74 75 6e 73 2e 63 00 63 76 74 75 6e 73 30 2e 63 |tuns.c.cvtuns0.c| +00015930 00 70 61 64 73 74 72 2e 63 00 70 61 64 2e 63 00 |.padstr.c.pad.c.| +00015940 73 77 72 69 74 65 63 68 00 77 61 69 74 70 69 64 |swritech.waitpid| +00015950 00 63 77 72 69 74 65 00 73 74 72 32 69 6e 74 00 |.cwrite.str2int.| +00015960 63 76 74 75 6e 73 00 67 65 74 70 69 64 00 73 6c |cvtuns.getpid.sl| +00015970 65 65 70 00 73 77 72 69 74 65 00 70 61 64 00 73 |eep.swrite.pad.s| +00015980 70 61 77 6e 00 73 70 72 69 6e 74 00 63 76 74 68 |pawn.sprint.cvth| +00015990 65 78 00 63 76 74 75 6e 73 30 00 6b 69 6c 6c 00 |ex.cvtuns0.kill.| +000159a0 63 77 72 69 74 65 73 00 65 78 65 63 00 77 61 69 |cwrites.exec.wai| +000159b0 74 00 73 77 72 69 74 65 73 00 5f 73 74 61 72 74 |t.swrites._start| +000159c0 00 72 65 61 64 00 67 65 74 70 72 69 6f 00 63 76 |.read.getprio.cv| +000159d0 74 64 65 63 30 00 66 6f 72 6b 00 6d 61 69 6e 00 |tdec0.fork.main.| +000159e0 67 65 74 70 70 69 64 00 70 61 64 73 74 72 00 73 |getppid.padstr.s| +000159f0 65 74 70 72 69 6f 00 63 76 74 6f 63 74 00 63 77 |etprio.cvtoct.cw| +00015a00 72 69 74 65 63 68 00 67 65 74 74 69 6d 65 00 63 |ritech.gettime.c| +00015a10 76 74 64 65 63 00 73 74 72 6c 65 6e 00 62 6f 67 |vtdec.strlen.bog| +00015a20 75 73 00 66 61 6b 65 5f 65 78 69 74 00 00 2e 73 |us.fake_exit...s| +00015a30 79 6d 74 61 62 00 2e 73 74 72 74 61 62 00 2e 73 |ymtab..strtab..s| +00015a40 68 73 74 72 74 61 62 00 2e 74 65 78 74 00 2e 72 |hstrtab..text..r| +00015a50 6f 64 61 74 61 00 2e 64 61 74 61 00 2e 62 73 73 |odata..data..bss| +00015a60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00015a80 00 00 00 00 00 00 00 00 00 00 00 00 1b 00 00 00 |................| +00015a90 01 00 00 00 06 00 00 00 00 10 00 00 74 00 00 00 |............t...| +00015aa0 97 09 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +00015ab0 00 00 00 00 21 00 00 00 01 00 00 00 02 00 00 00 |....!...........| +00015ac0 98 19 00 00 0c 0a 00 00 b0 00 00 00 00 00 00 00 |................| +00015ad0 00 00 00 00 04 00 00 00 00 00 00 00 29 00 00 00 |............)...| +00015ae0 01 00 00 00 03 00 00 00 00 20 00 00 74 10 00 00 |......... ..t...| +00015af0 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +00015b00 00 00 00 00 2f 00 00 00 08 00 00 00 03 00 00 00 |..../...........| +00015b10 00 20 00 00 74 10 00 00 00 00 00 00 00 00 00 00 |. ..t...........| +00015b20 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 |................| +00015b30 02 00 00 00 00 00 00 00 00 00 00 00 74 10 00 00 |............t...| +00015b40 60 03 00 00 06 00 00 00 12 00 00 00 04 00 00 00 |`...............| +00015b50 10 00 00 00 09 00 00 00 03 00 00 00 00 00 00 00 |................| +00015b60 00 00 00 00 d4 13 00 00 61 01 00 00 00 00 00 00 |........a.......| +00015b70 00 00 00 00 01 00 00 00 00 00 00 00 11 00 00 00 |................| +00015b80 03 00 00 00 00 00 00 00 00 00 00 00 35 15 00 00 |............5...| +00015b90 34 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |4...............| +00015ba0 00 00 00 00 00 00 00 00 7f 45 4c 46 01 01 01 00 |.........ELF....| +00015bb0 00 00 00 00 00 00 00 00 02 00 03 00 01 00 00 00 |................| +00015bc0 40 16 00 00 34 00 00 00 6c 15 00 00 00 00 00 00 |@...4...l.......| +00015bd0 34 00 20 00 02 00 28 00 08 00 07 00 01 00 00 00 |4. ...(.........| +00015be0 74 00 00 00 00 10 00 00 00 10 00 00 00 10 00 00 |t...............| +00015bf0 00 10 00 00 07 00 00 00 04 00 00 00 51 e5 74 64 |............Q.td| +00015c00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00015c10 00 00 00 00 07 00 00 00 10 00 00 00 8d 4c 24 04 |.............L$.| +00015c20 83 e4 f0 ff 71 fc 55 89 e5 53 51 81 ec a0 01 00 |....q.U..SQ.....| +00015c30 00 89 cb c7 45 f4 03 00 00 00 c6 45 cb 36 c7 45 |....E......E.6.E| +00015c40 d0 08 00 00 00 c6 45 f3 01 c6 45 f2 01 c7 45 ec |......E...E...E.| +00015c50 00 00 00 00 c7 85 7c fe ff ff 2a 3f 2a 00 8b 03 |......|...*?*...| +00015c60 83 f8 03 74 32 83 f8 04 74 07 83 f8 02 74 41 eb |...t2...t....tA.| +00015c70 52 8b 43 04 83 c0 0c 8b 00 0f b6 00 3c 6b 0f 95 |R.C.........<k..| +00015c80 c0 88 45 f3 8b 43 04 83 c0 0c 8b 00 0f b6 00 3c |..E..C.........<| +00015c90 77 0f 95 c0 88 45 f2 8b 43 04 83 c0 08 8b 00 83 |w....E..C.......| +00015ca0 ec 08 6a 0a 50 e8 37 08 00 00 83 c4 10 89 45 f4 |..j.P.7.......E.| +00015cb0 8b 43 04 83 c0 04 8b 00 0f b6 00 88 45 cb e9 a4 |.C..........E...| +00015cc0 00 00 00 83 ec 04 ff 33 68 94 1c 00 00 8d 85 4b |.......3h......K| +00015cd0 ff ff ff 50 e8 93 05 00 00 83 c4 10 83 ec 0c 8d |...P............| +00015ce0 85 4b ff ff ff 50 e8 4a 04 00 00 83 c4 10 c7 45 |.K...P.J.......E| +00015cf0 e8 00 00 00 00 eb 59 8b 03 8d 14 85 00 00 00 00 |......Y.........| +00015d00 8b 43 04 01 d0 8b 00 85 c0 74 12 8b 03 8d 14 85 |.C.......t......| +00015d10 00 00 00 00 8b 43 04 01 d0 8b 00 eb 05 b8 ab 1c |.....C..........| +00015d20 00 00 83 ec 04 50 68 b2 1c 00 00 8d 85 4b ff ff |.....Ph......K..| +00015d30 ff 50 e8 35 05 00 00 83 c4 10 83 ec 0c 8d 85 4b |.P.5...........K| +00015d40 ff ff ff 50 e8 ec 03 00 00 83 c4 10 83 45 e8 01 |...P.........E..| +00015d50 8b 45 e8 3b 03 7e a0 83 ec 0c 68 b6 1c 00 00 e8 |.E.;.~....h.....| +00015d60 d1 03 00 00 83 c4 10 0f b6 45 cb 88 85 7d fe ff |.........E...}..| +00015d70 ff 83 ec 04 6a 01 8d 45 cb 50 6a 01 e8 8d 04 00 |....j..E.Pj.....| +00015d80 00 83 c4 10 c7 85 68 fe ff ff b8 1c 00 00 c7 85 |......h.........| +00015d90 6c fe ff ff be 1c 00 00 c7 85 70 fe ff ff c0 1c |l.........p.....| +00015da0 00 00 c7 85 74 fe ff ff c3 1c 00 00 c7 85 78 fe |....t.........x.| +00015db0 ff ff 00 00 00 00 c7 45 e4 00 00 00 00 eb 48 83 |.......E......H.| +00015dc0 ec 08 8d 85 68 fe ff ff 50 6a 10 e8 cf 02 00 00 |....h...Pj......| +00015dd0 83 c4 10 89 45 cc 83 7d cc 00 79 14 83 ec 0c 8d |....E..}..y.....| +00015de0 85 7c fe ff ff 50 e8 b3 03 00 00 83 c4 10 eb 13 |.|...P..........| +00015df0 8b 45 ec 8d 50 01 89 55 ec 8b 55 cc 89 94 85 80 |.E..P..U..U.....| +00015e00 fe ff ff 83 45 e4 01 8b 45 e4 3b 45 f4 7c b0 8b |....E...E.;E.|..| +00015e10 45 d0 69 c0 e8 03 00 00 83 ec 0c 50 e8 25 04 00 |E.i........P.%..| +00015e20 00 83 c4 10 c7 45 e0 00 00 00 00 80 7d f3 00 74 |.....E......}..t| +00015e30 2f 80 7d f2 00 74 0c 8b 45 e0 8b 84 85 80 fe ff |/.}..t..E.......| +00015e40 ff eb 05 b8 00 00 00 00 83 ec 08 8d 95 64 fe ff |.............d..| +00015e50 ff 52 50 e8 96 03 00 00 83 c4 10 89 45 dc eb 19 |.RP.........E...| +00015e60 8b 45 e0 8b 84 85 80 fe ff ff 83 ec 0c 50 e8 cb |.E...........P..| +00015e70 03 00 00 83 c4 10 89 45 dc 83 7d dc 00 0f 89 a1 |.......E..}.....| +00015e80 00 00 00 83 7d dc fc 74 77 80 7d f3 00 74 3f 80 |....}..tw.}..t?.| +00015e90 7d f2 00 74 0c 8b 45 e0 8b 84 85 80 fe ff ff eb |}..t..E.........| +00015ea0 05 b8 00 00 00 00 0f b6 55 cb 0f be d2 83 ec 0c |........U.......| +00015eb0 ff 75 dc 50 52 68 c5 1c 00 00 8d 85 4b ff ff ff |.u.PRh......K...| +00015ec0 50 e8 a6 03 00 00 83 c4 20 e9 9d 01 00 00 8b 45 |P....... ......E| +00015ed0 e0 8b 94 85 80 fe ff ff 0f b6 45 cb 0f be c0 83 |..........E.....| +00015ee0 ec 0c ff 75 dc 52 50 68 e3 1c 00 00 8d 85 4b ff |...u.RPh......K.| +00015ef0 ff ff 50 e8 74 03 00 00 83 c4 20 e9 6b 01 00 00 |..P.t..... .k...| +00015f00 0f b6 45 cb 0f be c0 83 ec 04 50 68 fe 1c 00 00 |..E.......Ph....| +00015f10 8d 85 4b ff ff ff 50 e8 50 03 00 00 83 c4 10 e9 |..K...P.P.......| +00015f20 47 01 00 00 c7 45 d8 ff ff ff ff 80 7d f2 00 74 |G....E......}..t| +00015f30 58 8b 45 e0 8b 94 85 80 fe ff ff 8b 45 dc 39 c2 |X.E.........E.9.| +00015f40 74 41 8b 45 e0 8b 94 85 80 fe ff ff 0f b6 45 cb |tA.E..........E.| +00015f50 0f be c0 83 ec 0c ff 75 dc 52 50 68 14 1d 00 00 |.......u.RPh....| +00015f60 8d 85 4b ff ff ff 50 e8 00 03 00 00 83 c4 20 83 |..K...P....... .| +00015f70 ec 0c 8d 85 4b ff ff ff 50 e8 b7 01 00 00 83 c4 |....K...P.......| +00015f80 10 eb 06 8b 45 e0 89 45 d8 83 7d d8 00 79 2e c7 |....E..E..}..y..| +00015f90 45 d4 00 00 00 00 eb 1d 8b 45 d4 8b 94 85 80 fe |E........E......| +00015fa0 ff ff 8b 45 dc 39 c2 75 08 8b 45 d4 89 45 d8 eb |...E.9.u..E..E..| +00015fb0 0c 83 45 d4 01 8b 45 d4 3b 45 ec 7c db 83 7d d8 |..E...E.;E.|..}.| +00015fc0 00 79 21 0f b6 45 cb 0f be c0 ff 75 dc 50 68 38 |.y!..E.....u.Ph8| +00015fd0 1d 00 00 8d 85 4b ff ff ff 50 e8 8d 02 00 00 83 |.....K...P......| +00015fe0 c4 10 eb 65 8b 45 d8 3b 45 e0 74 31 8b 95 64 fe |...e.E.;E.t1..d.| +00015ff0 ff ff 0f b6 45 cb 0f be c0 83 ec 04 52 ff 75 dc |....E.......R.u.| +00016000 ff 75 e0 ff 75 d8 50 68 60 1d 00 00 8d 85 4b ff |.u..u.Ph`.....K.| +00016010 ff ff 50 e8 54 02 00 00 83 c4 20 eb 2c 8b 95 64 |..P.T..... .,..d| +00016020 fe ff ff 0f b6 45 cb 0f be c0 83 ec 08 52 ff 75 |.....E.......R.u| +00016030 dc ff 75 d8 50 68 84 1d 00 00 8d 85 4b ff ff ff |..u.Ph......K...| +00016040 50 e8 26 02 00 00 83 c4 20 83 ec 0c 8d 85 4b ff |P.&..... .....K.| +00016050 ff ff 50 e8 dd 00 00 00 83 c4 10 83 45 e0 01 8b |..P.........E...| +00016060 45 e0 3b 45 ec 0f 8c c0 fd ff ff 83 ec 0c 6a 00 |E.;E..........j.| +00016070 e8 71 01 00 00 83 c4 10 b8 2a 00 00 00 8d 65 f8 |.q.......*....e.| +00016080 59 5b 5d 8d 61 fc c3 55 89 e5 83 ec 08 83 ec 08 |Y[].a..U........| +00016090 ff 75 08 6a 00 e8 54 01 00 00 83 c4 10 c9 c3 55 |.u.j..T........U| +000160a0 89 e5 81 ec 18 01 00 00 e8 49 01 00 00 89 45 f4 |.........I....E.| +000160b0 83 7d f4 00 74 05 8b 45 f4 eb 57 e8 56 01 00 00 |.}..t..E..W.V...| +000160c0 89 45 f4 83 ec 08 ff 75 0c ff 75 08 e8 2d 01 00 |.E.....u..u..-..| +000160d0 00 83 c4 10 ff 75 08 ff 75 f4 68 a4 1d 00 00 8d |.....u..u.h.....| +000160e0 85 f4 fe ff ff 50 e8 81 01 00 00 83 c4 10 83 ec |.....P..........| +000160f0 0c 8d 85 f4 fe ff ff 50 e8 38 00 00 00 83 c4 10 |.......P.8......| +00016100 83 ec 0c 6a ff e8 dc 00 00 00 83 c4 10 b8 00 00 |...j............| +00016110 00 00 c9 c3 55 89 e5 83 ec 18 8b 45 08 88 45 f4 |....U......E..E.| +00016120 83 ec 04 6a 01 8d 45 f4 50 6a 00 e8 de 00 00 00 |...j..E.Pj......| +00016130 83 c4 10 c9 c3 55 89 e5 83 ec 18 83 ec 0c ff 75 |.....U.........u| +00016140 08 e8 0d 04 00 00 83 c4 10 89 45 f4 8b 45 f4 83 |..........E..E..| +00016150 ec 04 50 ff 75 08 6a 00 e8 b1 00 00 00 83 c4 10 |..P.u.j.........| +00016160 c9 c3 55 89 e5 83 ec 08 83 ec 04 ff 75 0c ff 75 |..U.........u..u| +00016170 08 6a 00 e8 96 00 00 00 83 c4 10 c9 c3 55 89 e5 |.j...........U..| +00016180 83 ec 18 8b 45 08 88 45 f4 83 ec 04 6a 01 8d 45 |....E..E....j..E| +00016190 f4 50 6a 01 e8 75 00 00 00 83 c4 10 c9 c3 55 89 |.Pj..u........U.| +000161a0 e5 83 ec 18 83 ec 0c ff 75 08 e8 a4 03 00 00 83 |........u.......| +000161b0 c4 10 89 45 f4 8b 45 f4 83 ec 04 50 ff 75 08 6a |...E..E....P.u.j| +000161c0 01 e8 48 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec |..H........U....| +000161d0 08 83 ec 04 ff 75 0c ff 75 08 6a 01 e8 2d 00 00 |.....u..u.j..-..| +000161e0 00 83 c4 10 c9 c3 b8 00 00 00 00 cd 80 c3 b8 01 |................| +000161f0 00 00 00 cd 80 c3 b8 02 00 00 00 cd 80 c3 b8 03 |................| +00016200 00 00 00 cd 80 c3 b8 04 00 00 00 cd 80 c3 b8 05 |................| +00016210 00 00 00 cd 80 c3 b8 06 00 00 00 cd 80 c3 b8 07 |................| +00016220 00 00 00 cd 80 c3 b8 08 00 00 00 cd 80 c3 b8 09 |................| +00016230 00 00 00 cd 80 c3 b8 0a 00 00 00 cd 80 c3 b8 0b |................| +00016240 00 00 00 cd 80 c3 b8 0c 00 00 00 cd 80 c3 b8 ad |................| +00016250 0b 00 00 cd 80 c3 50 e8 8a ff ff ff e8 bb f9 ff |......P.........| +00016260 ff 83 ec 0c 50 e8 7c ff ff ff eb fe 55 89 e5 83 |....P.|.....U...| +00016270 ec 38 8d 45 0c 83 c0 04 89 45 f4 e9 3f 02 00 00 |.8.E.....E..?...| +00016280 80 7d f3 25 0f 85 26 02 00 00 c7 45 ec 00 00 00 |.}.%..&....E....| +00016290 00 c7 45 e4 20 00 00 00 c7 45 e8 00 00 00 00 8b |..E. ....E......| +000162a0 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d |E..P..U.....E..}| +000162b0 f3 2d 75 16 c7 45 ec 01 00 00 00 8b 45 0c 8d 50 |.-u..E......E..P| +000162c0 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 30 75 40 |..U.....E..}.0u@| +000162d0 c7 45 e4 30 00 00 00 8b 45 0c 8d 50 01 89 55 0c |.E.0....E..P..U.| +000162e0 0f b6 00 88 45 f3 eb 28 8b 55 e8 89 d0 c1 e0 02 |....E..(.U......| +000162f0 01 d0 01 c0 89 45 e8 0f be 45 f3 83 e8 30 01 45 |.....E...E...0.E| +00016300 e8 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 |..E..P..U.....E.| +00016310 80 7d f3 2f 7e 06 80 7d f3 39 7e cc 0f be 45 f3 |.}./~..}.9~...E.| +00016320 83 e8 63 83 f8 15 0f 87 93 01 00 00 8b 04 85 c0 |..c.............| +00016330 1d 00 00 ff e0 8b 45 f4 8d 50 04 89 55 f4 8b 00 |......E..P..U...| +00016340 88 45 f3 0f b6 45 f3 88 45 d0 c6 45 d1 00 83 ec |.E...E..E..E....| +00016350 08 ff 75 e4 ff 75 ec ff 75 e8 6a 01 8d 45 d0 50 |..u..u..u.j..E.P| +00016360 ff 75 08 e8 89 04 00 00 83 c4 20 89 45 08 e9 4c |.u........ .E..L| +00016370 01 00 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec |....E..P..U.....| +00016380 08 50 8d 45 d0 50 e8 ea 01 00 00 83 c4 10 89 45 |.P.E.P.........E| +00016390 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 |.....u..u..u..u.| +000163a0 8d 45 d0 50 ff 75 08 e8 45 04 00 00 83 c4 20 89 |.E.P.u..E..... .| +000163b0 45 08 e9 08 01 00 00 8b 45 f4 8d 50 04 89 55 f4 |E.......E..P..U.| +000163c0 8b 00 89 45 dc 83 ec 08 ff 75 e4 ff 75 ec ff 75 |...E.....u..u..u| +000163d0 e8 6a ff ff 75 dc ff 75 08 e8 13 04 00 00 83 c4 |.j..u..u........| +000163e0 20 89 45 08 e9 d6 00 00 00 8b 45 f4 8d 50 04 89 | .E.......E..P..| +000163f0 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 44 02 00 |U......P.E.P.D..| +00016400 00 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec |.....E.....u..u.| +00016410 ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 cf 03 |.u..u..E.P.u....| +00016420 00 00 83 c4 20 89 45 08 e9 92 00 00 00 8b 45 f4 |.... .E.......E.| +00016430 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 |.P..U......P.E.P| +00016440 e8 8a 02 00 00 83 c4 10 89 45 e0 83 ec 08 ff 75 |.........E.....u| +00016450 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 |..u..u..u..E.P.u| +00016460 08 e8 8b 03 00 00 83 c4 20 89 45 08 eb 51 8b 45 |........ .E..Q.E| +00016470 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 |..P..U......P.E.| +00016480 50 e8 d3 02 00 00 83 c4 10 89 45 e0 83 ec 08 ff |P.........E.....| +00016490 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff |u..u..u..u..E.P.| +000164a0 75 08 e8 4a 03 00 00 83 c4 20 89 45 08 90 eb 0f |u..J..... .E....| +000164b0 8b 45 08 8d 50 01 89 55 08 0f b6 55 f3 88 10 8b |.E..P..U...U....| +000164c0 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d |E..P..U.....E..}| +000164d0 f3 00 0f 85 a8 fd ff ff 8b 45 08 c6 00 00 90 c9 |.........E......| +000164e0 c3 55 89 e5 53 83 ec 14 8b 45 08 8b 4d 0c bb 00 |.U..S....E..M...| +000164f0 00 00 00 c6 45 eb 39 c7 45 f8 01 00 00 00 0f b6 |....E.9.E.......| +00016500 10 80 fa 2d 75 0a c7 45 f8 ff ff ff ff 83 c0 01 |...-u..E........| +00016510 83 f9 0a 74 2b 89 ca 83 c2 2f 88 55 eb eb 21 0f |...t+..../.U..!.| +00016520 b6 10 80 fa 2f 7e 20 0f b6 10 38 55 eb 7c 18 0f |..../~ ...8U.|..| +00016530 af d9 0f b6 10 0f be d2 01 da 8d 5a d0 83 c0 01 |...........Z....| +00016540 0f b6 10 84 d2 75 d8 89 d8 0f af 45 f8 83 c4 14 |.....u.....E....| +00016550 5b 5d c3 55 89 e5 53 8b 55 08 bb 00 00 00 00 eb |[].U..S.U.......| +00016560 03 83 c3 01 89 d0 8d 50 01 0f b6 00 84 c0 75 f1 |.......P......u.| +00016570 89 d8 5b 5d c3 55 89 e5 83 ec 18 8b 45 08 89 45 |..[].U......E..E| +00016580 f4 83 7d 0c 00 79 0f 8b 45 f4 8d 50 01 89 55 f4 |..}..y..E..P..U.| +00016590 c6 00 2d f7 5d 0c 83 ec 08 ff 75 0c ff 75 f4 e8 |..-.].....u..u..| +000165a0 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 c6 00 00 |........E..E....| +000165b0 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 |.U..E.).....U...| +000165c0 ec 18 8b 4d 0c ba 67 66 66 66 89 c8 f7 ea c1 fa |...M..gfff......| +000165d0 02 89 c8 c1 f8 1f 29 c2 89 d0 89 45 f4 83 7d f4 |......)....E..}.| +000165e0 00 79 0e c7 45 f4 cc cc cc 0c c7 45 0c 08 00 00 |.y..E......E....| +000165f0 00 83 7d f4 00 74 14 83 ec 08 ff 75 f4 ff 75 08 |..}..t.....u..u.| +00016600 e8 b7 ff ff ff 83 c4 10 89 45 08 8b 4d 0c ba 67 |.........E..M..g| +00016610 66 66 66 89 c8 f7 ea c1 fa 02 89 c8 c1 f8 1f 29 |fff............)| +00016620 c2 89 d0 c1 e0 02 01 d0 01 c0 29 c1 89 ca 89 d0 |..........).....| +00016630 8d 48 30 8b 45 08 8d 50 01 89 55 08 89 ca 88 10 |.H0.E..P..U.....| +00016640 8b 45 08 c9 c3 55 89 e5 83 ec 20 c7 45 e3 30 31 |.E...U.... .E.01| +00016650 32 33 c7 45 e7 34 35 36 37 c7 45 eb 38 39 41 42 |23.E.4567.E.89AB| +00016660 c7 45 ef 43 44 45 46 c6 45 f3 00 c7 45 fc 00 00 |.E.CDEF.E...E...| +00016670 00 00 c7 45 f8 00 00 00 00 eb 43 8b 45 0c 25 00 |...E......C.E.%.| +00016680 00 00 f0 89 45 f4 83 7d fc 00 75 0c 83 7d f4 00 |....E..}..u..}..| +00016690 75 06 83 7d f8 07 75 1e 83 45 fc 01 c1 6d f4 1c |u..}..u..E...m..| +000166a0 8b 45 08 8d 50 01 89 55 08 8d 4d e3 8b 55 f4 01 |.E..P..U..M..U..| +000166b0 ca 0f b6 12 88 10 c1 65 0c 04 83 45 f8 01 83 7d |.......e...E...}| +000166c0 f8 07 7e b7 8b 45 08 c6 00 00 8b 45 fc c9 c3 55 |..~..E.....E...U| +000166d0 89 e5 83 ec 10 c7 45 f8 00 00 00 00 8b 45 08 89 |......E......E..| +000166e0 45 f4 8b 45 0c 25 00 00 00 c0 89 45 f0 c1 6d f0 |E..E.%.....E..m.| +000166f0 1e c7 45 fc 00 00 00 00 eb 47 83 7d fc 0a 74 0c |..E......G.}..t.| +00016700 83 7d f0 00 75 06 83 7d f8 00 74 1e c7 45 f8 01 |.}..u..}..t..E..| +00016710 00 00 00 83 65 f0 07 8b 45 f0 8d 48 30 8b 45 f4 |....e...E..H0.E.| +00016720 8d 50 01 89 55 f4 89 ca 88 10 c1 65 0c 03 8b 45 |.P..U......e...E| +00016730 0c 25 00 00 00 e0 89 45 f0 c1 6d f0 1d 83 45 fc |.%.....E..m...E.| +00016740 01 83 7d fc 0a 7e b3 8b 45 f4 c6 00 00 8b 55 f4 |..}..~..E.....U.| +00016750 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 ec 18 8b |.E.).....U......| +00016760 45 08 89 45 f4 83 ec 08 ff 75 0c ff 75 f4 e8 18 |E..E.....u..u...| +00016770 00 00 00 83 c4 10 89 45 f4 8b 45 f4 c6 00 00 8b |.......E..E.....| +00016780 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 ec |U..E.).....U....| +00016790 18 8b 45 0c ba cd cc cc cc f7 e2 89 d0 c1 e8 03 |..E.............| +000167a0 89 45 f4 83 7d f4 00 74 15 8b 45 f4 83 ec 08 50 |.E..}..t..E....P| +000167b0 ff 75 08 e8 04 fe ff ff 83 c4 10 89 45 08 8b 4d |.u..........E..M| +000167c0 0c ba cd cc cc cc 89 c8 f7 e2 c1 ea 03 89 d0 c1 |................| +000167d0 e0 02 01 d0 01 c0 29 c1 89 ca 89 d0 8d 48 30 8b |......)......H0.| +000167e0 45 08 8d 50 01 89 55 08 89 ca 88 10 8b 45 08 c9 |E..P..U......E..| +000167f0 c3 55 89 e5 83 ec 18 83 7d 10 00 79 11 83 ec 0c |.U......}..y....| +00016800 ff 75 0c e8 4b fd ff ff 83 c4 10 89 45 10 8b 45 |.u..K.......E..E| +00016810 14 2b 45 10 89 45 f0 83 7d f0 00 7e 1d 83 7d 18 |.+E..E..}..~..}.| +00016820 00 75 17 83 ec 04 ff 75 1c ff 75 f0 ff 75 08 e8 |.u.....u..u..u..| +00016830 5a 00 00 00 83 c4 10 89 45 08 c7 45 f4 00 00 00 |Z.......E..E....| +00016840 00 eb 1b 8b 55 f4 8b 45 0c 8d 0c 02 8b 45 08 8d |....U..E.....E..| +00016850 50 01 89 55 08 0f b6 11 88 10 83 45 f4 01 8b 45 |P..U.......E...E| +00016860 f4 3b 45 10 7c dd 83 7d f0 00 7e 1d 83 7d 18 00 |.;E.|..}..~..}..| +00016870 74 17 83 ec 04 ff 75 1c ff 75 f0 ff 75 08 e8 0b |t.....u..u..u...| +00016880 00 00 00 83 c4 10 89 45 08 8b 45 08 c9 c3 55 89 |.......E..E...U.| +00016890 e5 eb 12 8b 45 08 8d 50 01 89 55 08 8b 55 10 88 |....E..P..U..U..| +000168a0 10 83 6d 0c 01 83 7d 0c 00 7f e8 8b 45 08 5d c3 |..m...}.....E.].| +000168b0 6d 61 69 6e 36 3a 20 61 72 67 63 20 25 64 2c 20 |main6: argc %d, | +000168c0 61 72 67 73 3a 20 00 28 6e 75 6c 6c 29 00 20 25 |args: .(null). %| +000168d0 73 00 0a 00 75 73 65 72 57 00 57 00 31 30 00 35 |s...userW.W.10.5| +000168e0 00 21 21 20 25 63 3a 20 77 61 69 74 70 69 64 28 |.!! %c: waitpid(| +000168f0 25 64 29 20 73 74 61 74 75 73 20 25 64 0a 00 21 |%d) status %d..!| +00016900 21 20 25 63 3a 20 6b 69 6c 6c 28 25 64 29 20 73 |! %c: kill(%d) s| +00016910 74 61 74 75 73 20 25 64 0a 00 21 21 20 25 63 3a |tatus %d..!! %c:| +00016920 20 6e 6f 20 63 68 69 6c 64 72 65 6e 0a 00 00 00 | no children....| +00016930 2a 2a 20 25 63 3a 20 77 61 69 74 2f 6b 69 6c 6c |** %c: wait/kill| +00016940 20 50 49 44 20 25 64 2c 20 67 6f 74 20 25 64 0a | PID %d, got %d.| +00016950 00 00 00 00 21 21 20 25 63 3a 20 63 68 69 6c 64 |....!! %c: child| +00016960 20 50 49 44 20 25 64 20 74 65 72 6d 2c 20 4e 4f | PID %d term, NO| +00016970 54 20 46 4f 55 4e 44 0a 00 00 00 00 3d 3d 20 25 |T FOUND.....== %| +00016980 63 3a 20 63 68 69 6c 64 20 25 64 20 28 25 64 2c |c: child %d (%d,| +00016990 25 64 29 20 73 74 61 74 75 73 20 25 64 0a 00 00 |%d) status %d...| +000169a0 3d 3d 20 25 63 3a 20 63 68 69 6c 64 20 25 64 20 |== %c: child %d | +000169b0 28 25 64 29 20 73 74 61 74 75 73 20 25 64 0a 00 |(%d) status %d..| +000169c0 43 68 69 6c 64 20 25 64 20 65 78 65 63 28 29 20 |Child %d exec() | +000169d0 23 25 75 20 66 61 69 6c 65 64 0a 00 19 17 00 00 |#%u failed......| +000169e0 57 17 00 00 a3 18 00 00 a3 18 00 00 a3 18 00 00 |W...............| +000169f0 a3 18 00 00 a3 18 00 00 a3 18 00 00 a3 18 00 00 |................| +00016a00 a3 18 00 00 a3 18 00 00 a3 18 00 00 11 18 00 00 |................| +00016a10 a3 18 00 00 a3 18 00 00 a3 18 00 00 9b 17 00 00 |................| +00016a20 a3 18 00 00 52 18 00 00 a3 18 00 00 a3 18 00 00 |....R...........| +00016a30 cd 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00016a40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00016c30 00 10 00 00 00 00 00 00 03 00 01 00 00 00 00 00 |................| +00016c40 94 1c 00 00 00 00 00 00 03 00 02 00 00 00 00 00 |................| +00016c50 00 20 00 00 00 00 00 00 03 00 03 00 00 00 00 00 |. ..............| +00016c60 00 20 00 00 00 00 00 00 03 00 04 00 01 00 00 00 |. ..............| +00016c70 00 00 00 00 00 00 00 00 04 00 f1 ff 0b 00 00 00 |................| +00016c80 00 00 00 00 00 00 00 00 04 00 f1 ff 13 00 00 00 |................| +00016c90 00 00 00 00 00 00 00 00 04 00 f1 ff 1c 00 00 00 |................| +00016ca0 00 00 00 00 00 00 00 00 04 00 f1 ff 26 00 00 00 |............&...| +00016cb0 00 00 00 00 00 00 00 00 04 00 f1 ff 2f 00 00 00 |............/...| +00016cc0 00 00 00 00 00 00 00 00 04 00 f1 ff 38 00 00 00 |............8...| +00016cd0 00 00 00 00 00 00 00 00 04 00 f1 ff 42 00 00 00 |............B...| +00016ce0 00 00 00 00 00 00 00 00 04 00 f1 ff 4b 00 00 00 |............K...| +00016cf0 00 00 00 00 00 00 00 00 04 00 f1 ff 54 00 00 00 |............T...| +00016d00 00 00 00 00 00 00 00 00 04 00 f1 ff 5d 00 00 00 |............]...| +00016d10 00 00 00 00 00 00 00 00 04 00 f1 ff 67 00 00 00 |............g...| +00016d20 00 00 00 00 00 00 00 00 04 00 f1 ff 70 00 00 00 |............p...| +00016d30 00 00 00 00 00 00 00 00 04 00 f1 ff 76 00 00 00 |............v...| +00016d40 61 15 00 00 21 00 00 00 12 00 01 00 7f 00 00 00 |a...!...........| +00016d50 d2 15 00 00 00 00 00 00 10 00 01 00 87 00 00 00 |................| +00016d60 46 15 00 00 1b 00 00 00 12 00 01 00 8e 00 00 00 |F...............| +00016d70 c5 18 00 00 72 00 00 00 12 00 01 00 96 00 00 00 |....r...........| +00016d80 3d 1b 00 00 32 00 00 00 12 00 01 00 9d 00 00 00 |=...2...........| +00016d90 fa 15 00 00 00 00 00 00 10 00 01 00 a4 00 00 00 |................| +00016da0 2a 16 00 00 00 00 00 00 10 00 01 00 aa 00 00 00 |*...............| +00016db0 af 15 00 00 1b 00 00 00 12 00 01 00 b1 00 00 00 |................| +00016dc0 72 1c 00 00 22 00 00 00 12 00 01 00 b5 00 00 00 |r..."...........| +00016dd0 83 14 00 00 75 00 00 00 12 00 01 00 bb 00 00 00 |....u...........| +00016de0 50 16 00 00 75 02 00 00 12 00 01 00 c2 00 00 00 |P...u...........| +00016df0 29 1a 00 00 8a 00 00 00 12 00 01 00 c9 00 00 00 |)...............| +00016e00 6f 1b 00 00 66 00 00 00 12 00 01 00 88 00 00 00 |o...f...........| +00016e10 f2 15 00 00 00 00 00 00 10 00 01 00 d1 00 00 00 |................| +00016e20 22 16 00 00 00 00 00 00 10 00 01 00 d6 00 00 00 |"...............| +00016e30 19 15 00 00 2d 00 00 00 12 00 01 00 de 00 00 00 |....-...........| +00016e40 e2 15 00 00 00 00 00 00 10 00 01 00 e3 00 00 00 |................| +00016e50 6b 14 00 00 18 00 00 00 12 00 01 00 e8 00 00 00 |k...............| +00016e60 82 15 00 00 2d 00 00 00 12 00 01 00 f0 00 00 00 |....-...........| +00016e70 40 16 00 00 00 00 00 00 10 00 01 00 f7 00 00 00 |@...............| +00016e80 ea 15 00 00 00 00 00 00 10 00 01 00 fc 00 00 00 |................| +00016e90 12 16 00 00 00 00 00 00 10 00 01 00 04 01 00 00 |................| +00016ea0 a0 19 00 00 89 00 00 00 12 00 01 00 0c 01 00 00 |................| +00016eb0 da 15 00 00 00 00 00 00 10 00 01 00 11 01 00 00 |................| +00016ec0 00 10 00 00 6b 04 00 00 12 00 01 00 16 01 00 00 |....k...........| +00016ed0 02 16 00 00 00 00 00 00 10 00 01 00 1e 01 00 00 |................| +00016ee0 d5 1b 00 00 9d 00 00 00 12 00 01 00 25 01 00 00 |............%...| +00016ef0 1a 16 00 00 00 00 00 00 10 00 01 00 2d 01 00 00 |............-...| +00016f00 b3 1a 00 00 8a 00 00 00 12 00 01 00 34 01 00 00 |............4...| +00016f10 f8 14 00 00 21 00 00 00 12 00 01 00 3d 01 00 00 |....!.......=...| +00016f20 0a 16 00 00 00 00 00 00 10 00 01 00 45 01 00 00 |............E...| +00016f30 59 19 00 00 47 00 00 00 12 00 01 00 5e 01 00 00 |Y...G.......^...| +00016f40 ca 15 00 00 00 00 00 00 10 00 01 00 4c 01 00 00 |............L...| +00016f50 37 19 00 00 22 00 00 00 12 00 01 00 53 01 00 00 |7...".......S...| +00016f60 32 16 00 00 00 00 00 00 10 00 01 00 59 01 00 00 |2...........Y...| +00016f70 3a 16 00 00 00 00 00 00 10 00 01 00 00 70 72 6f |:............pro| +00016f80 67 54 55 56 2e 63 00 75 6c 69 62 63 2e 63 00 73 |gTUV.c.ulibc.c.s| +00016f90 70 72 69 6e 74 2e 63 00 73 74 72 32 69 6e 74 2e |print.c.str2int.| +00016fa0 63 00 73 74 72 6c 65 6e 2e 63 00 63 76 74 64 65 |c.strlen.c.cvtde| +00016fb0 63 2e 63 00 63 76 74 64 65 63 30 2e 63 00 63 76 |c.c.cvtdec0.c.cv| +00016fc0 74 68 65 78 2e 63 00 63 76 74 6f 63 74 2e 63 00 |thex.c.cvtoct.c.| +00016fd0 63 76 74 75 6e 73 2e 63 00 63 76 74 75 6e 73 30 |cvtuns.c.cvtuns0| +00016fe0 2e 63 00 70 61 64 73 74 72 2e 63 00 70 61 64 2e |.c.padstr.c.pad.| +00016ff0 63 00 73 77 72 69 74 65 63 68 00 77 61 69 74 70 |c.swritech.waitp| +00017000 69 64 00 63 77 72 69 74 65 00 73 74 72 32 69 6e |id.cwrite.str2in| +00017010 74 00 63 76 74 75 6e 73 00 67 65 74 70 69 64 00 |t.cvtuns.getpid.| +00017020 73 6c 65 65 70 00 73 77 72 69 74 65 00 70 61 64 |sleep.swrite.pad| +00017030 00 73 70 61 77 6e 00 73 70 72 69 6e 74 00 63 76 |.spawn.sprint.cv| +00017040 74 68 65 78 00 63 76 74 75 6e 73 30 00 6b 69 6c |thex.cvtuns0.kil| +00017050 6c 00 63 77 72 69 74 65 73 00 65 78 65 63 00 77 |l.cwrites.exec.w| +00017060 61 69 74 00 73 77 72 69 74 65 73 00 5f 73 74 61 |ait.swrites._sta| +00017070 72 74 00 72 65 61 64 00 67 65 74 70 72 69 6f 00 |rt.read.getprio.| +00017080 63 76 74 64 65 63 30 00 66 6f 72 6b 00 6d 61 69 |cvtdec0.fork.mai| +00017090 6e 00 67 65 74 70 70 69 64 00 70 61 64 73 74 72 |n.getppid.padstr| +000170a0 00 73 65 74 70 72 69 6f 00 63 76 74 6f 63 74 00 |.setprio.cvtoct.| +000170b0 63 77 72 69 74 65 63 68 00 67 65 74 74 69 6d 65 |cwritech.gettime| +000170c0 00 63 76 74 64 65 63 00 73 74 72 6c 65 6e 00 62 |.cvtdec.strlen.b| +000170d0 6f 67 75 73 00 66 61 6b 65 5f 65 78 69 74 00 00 |ogus.fake_exit..| +000170e0 2e 73 79 6d 74 61 62 00 2e 73 74 72 74 61 62 00 |.symtab..strtab.| +000170f0 2e 73 68 73 74 72 74 61 62 00 2e 74 65 78 74 00 |.shstrtab..text.| +00017100 2e 72 6f 64 61 74 61 00 2e 64 61 74 61 00 2e 62 |.rodata..data..b| +00017110 73 73 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |ss..............| +00017120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00017130 00 00 00 00 00 00 00 00 00 00 00 00 1b 00 00 00 |................| +00017140 01 00 00 00 06 00 00 00 00 10 00 00 74 00 00 00 |............t...| +00017150 94 0c 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +00017160 00 00 00 00 21 00 00 00 01 00 00 00 02 00 00 00 |....!...........| +00017170 94 1c 00 00 08 0d 00 00 84 01 00 00 00 00 00 00 |................| +00017180 00 00 00 00 04 00 00 00 00 00 00 00 29 00 00 00 |............)...| +00017190 01 00 00 00 03 00 00 00 00 20 00 00 74 10 00 00 |......... ..t...| +000171a0 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +000171b0 00 00 00 00 2f 00 00 00 08 00 00 00 03 00 00 00 |..../...........| +000171c0 00 20 00 00 74 10 00 00 00 00 00 00 00 00 00 00 |. ..t...........| +000171d0 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 |................| +000171e0 02 00 00 00 00 00 00 00 00 00 00 00 74 10 00 00 |............t...| +000171f0 60 03 00 00 06 00 00 00 12 00 00 00 04 00 00 00 |`...............| +00017200 10 00 00 00 09 00 00 00 03 00 00 00 00 00 00 00 |................| +00017210 00 00 00 00 d4 13 00 00 63 01 00 00 00 00 00 00 |........c.......| +00017220 00 00 00 00 01 00 00 00 00 00 00 00 11 00 00 00 |................| +00017230 03 00 00 00 00 00 00 00 00 00 00 00 37 15 00 00 |............7...| +00017240 34 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |4...............| +00017250 00 00 00 00 00 00 00 00 7f 45 4c 46 01 01 01 00 |.........ELF....| +00017260 00 00 00 00 00 00 00 00 02 00 03 00 01 00 00 00 |................| +00017270 d9 13 00 00 34 00 00 00 6c 15 00 00 00 00 00 00 |....4...l.......| +00017280 34 00 20 00 02 00 28 00 08 00 07 00 01 00 00 00 |4. ...(.........| +00017290 74 00 00 00 00 10 00 00 00 10 00 00 00 10 00 00 |t...............| +000172a0 00 10 00 00 07 00 00 00 04 00 00 00 51 e5 74 64 |............Q.td| +000172b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +000172c0 00 00 00 00 07 00 00 00 10 00 00 00 8d 4c 24 04 |.............L$.| +000172d0 83 e4 f0 ff 71 fc 55 89 e5 53 51 81 ec a0 00 00 |....q.U..SQ.....| +000172e0 00 89 cb c7 45 f4 14 00 00 00 c6 45 df 77 c7 45 |....E......E.w.E| +000172f0 f0 03 00 00 00 8b 03 83 f8 03 74 25 83 f8 04 74 |..........t%...t| +00017300 07 83 f8 02 74 34 eb 45 8b 43 04 83 c0 0c 8b 00 |....t4.E.C......| +00017310 83 ec 08 6a 0a 50 e8 0f 06 00 00 83 c4 10 89 45 |...j.P.........E| +00017320 f0 8b 43 04 83 c0 08 8b 00 83 ec 08 6a 0a 50 e8 |..C.........j.P.| +00017330 f6 05 00 00 83 c4 10 89 45 f4 8b 43 04 83 c0 04 |........E..C....| +00017340 8b 00 0f b6 00 88 45 df e9 a4 00 00 00 83 ec 04 |......E.........| +00017350 ff 33 68 30 1a 00 00 8d 85 5f ff ff ff 50 e8 52 |.3h0....._...P.R| +00017360 03 00 00 83 c4 10 83 ec 0c 8d 85 5f ff ff ff 50 |..........._...P| +00017370 e8 09 02 00 00 83 c4 10 c7 45 ec 00 00 00 00 eb |.........E......| +00017380 59 8b 03 8d 14 85 00 00 00 00 8b 43 04 01 d0 8b |Y..........C....| +00017390 00 85 c0 74 12 8b 03 8d 14 85 00 00 00 00 8b 43 |...t...........C| +000173a0 04 01 d0 8b 00 eb 05 b8 47 1a 00 00 83 ec 04 50 |........G......P| +000173b0 68 4e 1a 00 00 8d 85 5f ff ff ff 50 e8 f4 02 00 |hN....._...P....| +000173c0 00 83 c4 10 83 ec 0c 8d 85 5f ff ff ff 50 e8 ab |........._...P..| +000173d0 01 00 00 83 c4 10 83 45 ec 01 8b 45 ec 3b 03 7e |.......E...E.;.~| +000173e0 a0 83 ec 0c 68 52 1a 00 00 e8 90 01 00 00 83 c4 |....hR..........| +000173f0 10 e8 69 02 00 00 89 45 e4 e8 71 02 00 00 89 45 |..i....E..q....E| +00017400 e0 0f b6 45 df 0f be c0 83 ec 0c ff 75 e0 ff 75 |...E........u..u| +00017410 e4 50 68 54 1a 00 00 8d 85 5f ff ff ff 50 e8 92 |.PhT....._...P..| +00017420 02 00 00 83 c4 20 83 ec 0c 8d 85 5f ff ff ff 50 |..... ....._...P| +00017430 e8 b2 01 00 00 83 c4 10 83 ec 04 6a 01 8d 45 df |...........j..E.| +00017440 50 6a 01 e8 0f 02 00 00 83 c4 10 c7 45 e8 00 00 |Pj..........E...| +00017450 00 00 eb 58 e8 16 02 00 00 89 45 e0 0f b6 45 df |...X......E...E.| +00017460 0f be c0 83 ec 0c ff 75 e0 ff 75 e4 50 68 5f 1a |.......u..u.Ph_.| +00017470 00 00 8d 85 5f ff ff ff 50 e8 37 02 00 00 83 c4 |...._...P.7.....| +00017480 20 83 ec 0c 8d 85 5f ff ff ff 50 e8 57 01 00 00 | ....._...P.W...| +00017490 83 c4 10 8b 45 f0 69 c0 e8 03 00 00 83 ec 0c 50 |....E.i........P| +000174a0 e8 ea 01 00 00 83 c4 10 83 45 e8 01 8b 45 e8 3b |.........E...E.;| +000174b0 45 f4 7c a0 83 ec 0c 6a 00 e8 71 01 00 00 83 c4 |E.|....j..q.....| +000174c0 10 b8 2a 00 00 00 8d 65 f8 59 5b 5d 8d 61 fc c3 |..*....e.Y[].a..| +000174d0 55 89 e5 83 ec 08 83 ec 08 ff 75 08 6a 00 e8 54 |U.........u.j..T| +000174e0 01 00 00 83 c4 10 c9 c3 55 89 e5 81 ec 18 01 00 |........U.......| +000174f0 00 e8 49 01 00 00 89 45 f4 83 7d f4 00 74 05 8b |..I....E..}..t..| +00017500 45 f4 eb 57 e8 56 01 00 00 89 45 f4 83 ec 08 ff |E..W.V....E.....| +00017510 75 0c ff 75 08 e8 2d 01 00 00 83 c4 10 ff 75 08 |u..u..-.......u.| +00017520 ff 75 f4 68 6b 1a 00 00 8d 85 f4 fe ff ff 50 e8 |.u.hk.........P.| +00017530 81 01 00 00 83 c4 10 83 ec 0c 8d 85 f4 fe ff ff |................| +00017540 50 e8 38 00 00 00 83 c4 10 83 ec 0c 6a ff e8 dc |P.8.........j...| +00017550 00 00 00 83 c4 10 b8 00 00 00 00 c9 c3 55 89 e5 |.............U..| +00017560 83 ec 18 8b 45 08 88 45 f4 83 ec 04 6a 01 8d 45 |....E..E....j..E| +00017570 f4 50 6a 00 e8 de 00 00 00 83 c4 10 c9 c3 55 89 |.Pj...........U.| +00017580 e5 83 ec 18 83 ec 0c ff 75 08 e8 0d 04 00 00 83 |........u.......| +00017590 c4 10 89 45 f4 8b 45 f4 83 ec 04 50 ff 75 08 6a |...E..E....P.u.j| +000175a0 00 e8 b1 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec |...........U....| +000175b0 08 83 ec 04 ff 75 0c ff 75 08 6a 00 e8 96 00 00 |.....u..u.j.....| +000175c0 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 8b 45 08 88 |......U......E..| +000175d0 45 f4 83 ec 04 6a 01 8d 45 f4 50 6a 01 e8 75 00 |E....j..E.Pj..u.| +000175e0 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 83 ec 0c |.......U........| +000175f0 ff 75 08 e8 a4 03 00 00 83 c4 10 89 45 f4 8b 45 |.u..........E..E| +00017600 f4 83 ec 04 50 ff 75 08 6a 01 e8 48 00 00 00 83 |....P.u.j..H....| +00017610 c4 10 c9 c3 55 89 e5 83 ec 08 83 ec 04 ff 75 0c |....U.........u.| +00017620 ff 75 08 6a 01 e8 2d 00 00 00 83 c4 10 c9 c3 b8 |.u.j..-.........| +00017630 00 00 00 00 cd 80 c3 b8 01 00 00 00 cd 80 c3 b8 |................| +00017640 02 00 00 00 cd 80 c3 b8 03 00 00 00 cd 80 c3 b8 |................| +00017650 04 00 00 00 cd 80 c3 b8 05 00 00 00 cd 80 c3 b8 |................| +00017660 06 00 00 00 cd 80 c3 b8 07 00 00 00 cd 80 c3 b8 |................| +00017670 08 00 00 00 cd 80 c3 b8 09 00 00 00 cd 80 c3 b8 |................| +00017680 0a 00 00 00 cd 80 c3 b8 0b 00 00 00 cd 80 c3 b8 |................| +00017690 0c 00 00 00 cd 80 c3 b8 ad 0b 00 00 cd 80 c3 50 |...............P| +000176a0 e8 8a ff ff ff e8 22 fc ff ff 83 ec 0c 50 e8 7c |......"......P.|| +000176b0 ff ff ff eb fe 55 89 e5 83 ec 38 8d 45 0c 83 c0 |.....U....8.E...| +000176c0 04 89 45 f4 e9 3f 02 00 00 80 7d f3 25 0f 85 26 |..E..?....}.%..&| +000176d0 02 00 00 c7 45 ec 00 00 00 00 c7 45 e4 20 00 00 |....E......E. ..| +000176e0 00 c7 45 e8 00 00 00 00 8b 45 0c 8d 50 01 89 55 |..E......E..P..U| +000176f0 0c 0f b6 00 88 45 f3 80 7d f3 2d 75 16 c7 45 ec |.....E..}.-u..E.| +00017700 01 00 00 00 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 |.....E..P..U....| +00017710 88 45 f3 80 7d f3 30 75 40 c7 45 e4 30 00 00 00 |.E..}.0u@.E.0...| +00017720 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 eb |.E..P..U.....E..| +00017730 28 8b 55 e8 89 d0 c1 e0 02 01 d0 01 c0 89 45 e8 |(.U...........E.| +00017740 0f be 45 f3 83 e8 30 01 45 e8 8b 45 0c 8d 50 01 |..E...0.E..E..P.| +00017750 89 55 0c 0f b6 00 88 45 f3 80 7d f3 2f 7e 06 80 |.U.....E..}./~..| +00017760 7d f3 39 7e cc 0f be 45 f3 83 e8 63 83 f8 15 0f |}.9~...E...c....| +00017770 87 93 01 00 00 8b 04 85 88 1a 00 00 ff e0 8b 45 |...............E| +00017780 f4 8d 50 04 89 55 f4 8b 00 88 45 f3 0f b6 45 f3 |..P..U....E...E.| +00017790 88 45 d0 c6 45 d1 00 83 ec 08 ff 75 e4 ff 75 ec |.E..E......u..u.| +000177a0 ff 75 e8 6a 01 8d 45 d0 50 ff 75 08 e8 89 04 00 |.u.j..E.P.u.....| +000177b0 00 83 c4 20 89 45 08 e9 4c 01 00 00 8b 45 f4 8d |... .E..L....E..| +000177c0 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 |P..U......P.E.P.| +000177d0 ea 01 00 00 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 |........E.....u.| +000177e0 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 |.u..u..u..E.P.u.| +000177f0 e8 45 04 00 00 83 c4 20 89 45 08 e9 08 01 00 00 |.E..... .E......| +00017800 8b 45 f4 8d 50 04 89 55 f4 8b 00 89 45 dc 83 ec |.E..P..U....E...| +00017810 08 ff 75 e4 ff 75 ec ff 75 e8 6a ff ff 75 dc ff |..u..u..u.j..u..| +00017820 75 08 e8 13 04 00 00 83 c4 20 89 45 08 e9 d6 00 |u........ .E....| +00017830 00 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 |...E..P..U......| +00017840 50 8d 45 d0 50 e8 44 02 00 00 83 c4 10 89 45 e0 |P.E.P.D.......E.| +00017850 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d |....u..u..u..u..| +00017860 45 d0 50 ff 75 08 e8 cf 03 00 00 83 c4 20 89 45 |E.P.u........ .E| +00017870 08 e9 92 00 00 00 8b 45 f4 8d 50 04 89 55 f4 8b |.......E..P..U..| +00017880 00 83 ec 08 50 8d 45 d0 50 e8 8a 02 00 00 83 c4 |....P.E.P.......| +00017890 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 |..E.....u..u..u.| +000178a0 ff 75 e0 8d 45 d0 50 ff 75 08 e8 8b 03 00 00 83 |.u..E.P.u.......| +000178b0 c4 20 89 45 08 eb 51 8b 45 f4 8d 50 04 89 55 f4 |. .E..Q.E..P..U.| +000178c0 8b 00 83 ec 08 50 8d 45 d0 50 e8 d3 02 00 00 83 |.....P.E.P......| +000178d0 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 |...E.....u..u..u| +000178e0 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 4a 03 00 00 |..u..E.P.u..J...| +000178f0 83 c4 20 89 45 08 90 eb 0f 8b 45 08 8d 50 01 89 |.. .E.....E..P..| +00017900 55 08 0f b6 55 f3 88 10 8b 45 0c 8d 50 01 89 55 |U...U....E..P..U| +00017910 0c 0f b6 00 88 45 f3 80 7d f3 00 0f 85 a8 fd ff |.....E..}.......| +00017920 ff 8b 45 08 c6 00 00 90 c9 c3 55 89 e5 53 83 ec |..E.......U..S..| +00017930 14 8b 45 08 8b 4d 0c bb 00 00 00 00 c6 45 eb 39 |..E..M.......E.9| +00017940 c7 45 f8 01 00 00 00 0f b6 10 80 fa 2d 75 0a c7 |.E..........-u..| +00017950 45 f8 ff ff ff ff 83 c0 01 83 f9 0a 74 2b 89 ca |E...........t+..| +00017960 83 c2 2f 88 55 eb eb 21 0f b6 10 80 fa 2f 7e 20 |../.U..!...../~ | +00017970 0f b6 10 38 55 eb 7c 18 0f af d9 0f b6 10 0f be |...8U.|.........| +00017980 d2 01 da 8d 5a d0 83 c0 01 0f b6 10 84 d2 75 d8 |....Z.........u.| +00017990 89 d8 0f af 45 f8 83 c4 14 5b 5d c3 55 89 e5 53 |....E....[].U..S| +000179a0 8b 55 08 bb 00 00 00 00 eb 03 83 c3 01 89 d0 8d |.U..............| +000179b0 50 01 0f b6 00 84 c0 75 f1 89 d8 5b 5d c3 55 89 |P......u...[].U.| +000179c0 e5 83 ec 18 8b 45 08 89 45 f4 83 7d 0c 00 79 0f |.....E..E..}..y.| +000179d0 8b 45 f4 8d 50 01 89 55 f4 c6 00 2d f7 5d 0c 83 |.E..P..U...-.]..| +000179e0 ec 08 ff 75 0c ff 75 f4 e8 18 00 00 00 83 c4 10 |...u..u.........| +000179f0 89 45 f4 8b 45 f4 c6 00 00 8b 55 f4 8b 45 08 29 |.E..E.....U..E.)| +00017a00 c2 89 d0 c9 c3 55 89 e5 83 ec 18 8b 4d 0c ba 67 |.....U......M..g| +00017a10 66 66 66 89 c8 f7 ea c1 fa 02 89 c8 c1 f8 1f 29 |fff............)| +00017a20 c2 89 d0 89 45 f4 83 7d f4 00 79 0e c7 45 f4 cc |....E..}..y..E..| +00017a30 cc cc 0c c7 45 0c 08 00 00 00 83 7d f4 00 74 14 |....E......}..t.| +00017a40 83 ec 08 ff 75 f4 ff 75 08 e8 b7 ff ff ff 83 c4 |....u..u........| +00017a50 10 89 45 08 8b 4d 0c ba 67 66 66 66 89 c8 f7 ea |..E..M..gfff....| +00017a60 c1 fa 02 89 c8 c1 f8 1f 29 c2 89 d0 c1 e0 02 01 |........).......| +00017a70 d0 01 c0 29 c1 89 ca 89 d0 8d 48 30 8b 45 08 8d |...)......H0.E..| +00017a80 50 01 89 55 08 89 ca 88 10 8b 45 08 c9 c3 55 89 |P..U......E...U.| +00017a90 e5 83 ec 20 c7 45 e3 30 31 32 33 c7 45 e7 34 35 |... .E.0123.E.45| +00017aa0 36 37 c7 45 eb 38 39 41 42 c7 45 ef 43 44 45 46 |67.E.89AB.E.CDEF| +00017ab0 c6 45 f3 00 c7 45 fc 00 00 00 00 c7 45 f8 00 00 |.E...E......E...| +00017ac0 00 00 eb 43 8b 45 0c 25 00 00 00 f0 89 45 f4 83 |...C.E.%.....E..| +00017ad0 7d fc 00 75 0c 83 7d f4 00 75 06 83 7d f8 07 75 |}..u..}..u..}..u| +00017ae0 1e 83 45 fc 01 c1 6d f4 1c 8b 45 08 8d 50 01 89 |..E...m...E..P..| +00017af0 55 08 8d 4d e3 8b 55 f4 01 ca 0f b6 12 88 10 c1 |U..M..U.........| +00017b00 65 0c 04 83 45 f8 01 83 7d f8 07 7e b7 8b 45 08 |e...E...}..~..E.| +00017b10 c6 00 00 8b 45 fc c9 c3 55 89 e5 83 ec 10 c7 45 |....E...U......E| +00017b20 f8 00 00 00 00 8b 45 08 89 45 f4 8b 45 0c 25 00 |......E..E..E.%.| +00017b30 00 00 c0 89 45 f0 c1 6d f0 1e c7 45 fc 00 00 00 |....E..m...E....| +00017b40 00 eb 47 83 7d fc 0a 74 0c 83 7d f0 00 75 06 83 |..G.}..t..}..u..| +00017b50 7d f8 00 74 1e c7 45 f8 01 00 00 00 83 65 f0 07 |}..t..E......e..| +00017b60 8b 45 f0 8d 48 30 8b 45 f4 8d 50 01 89 55 f4 89 |.E..H0.E..P..U..| +00017b70 ca 88 10 c1 65 0c 03 8b 45 0c 25 00 00 00 e0 89 |....e...E.%.....| +00017b80 45 f0 c1 6d f0 1d 83 45 fc 01 83 7d fc 0a 7e b3 |E..m...E...}..~.| +00017b90 8b 45 f4 c6 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 |.E.....U..E.)...| +00017ba0 c9 c3 55 89 e5 83 ec 18 8b 45 08 89 45 f4 83 ec |..U......E..E...| +00017bb0 08 ff 75 0c ff 75 f4 e8 18 00 00 00 83 c4 10 89 |..u..u..........| +00017bc0 45 f4 8b 45 f4 c6 00 00 8b 55 f4 8b 45 08 29 c2 |E..E.....U..E.).| +00017bd0 89 d0 c9 c3 55 89 e5 83 ec 18 8b 45 0c ba cd cc |....U......E....| +00017be0 cc cc f7 e2 89 d0 c1 e8 03 89 45 f4 83 7d f4 00 |..........E..}..| +00017bf0 74 15 8b 45 f4 83 ec 08 50 ff 75 08 e8 04 fe ff |t..E....P.u.....| +00017c00 ff 83 c4 10 89 45 08 8b 4d 0c ba cd cc cc cc 89 |.....E..M.......| +00017c10 c8 f7 e2 c1 ea 03 89 d0 c1 e0 02 01 d0 01 c0 29 |...............)| +00017c20 c1 89 ca 89 d0 8d 48 30 8b 45 08 8d 50 01 89 55 |......H0.E..P..U| +00017c30 08 89 ca 88 10 8b 45 08 c9 c3 55 89 e5 83 ec 18 |......E...U.....| +00017c40 83 7d 10 00 79 11 83 ec 0c ff 75 0c e8 4b fd ff |.}..y.....u..K..| +00017c50 ff 83 c4 10 89 45 10 8b 45 14 2b 45 10 89 45 f0 |.....E..E.+E..E.| +00017c60 83 7d f0 00 7e 1d 83 7d 18 00 75 17 83 ec 04 ff |.}..~..}..u.....| +00017c70 75 1c ff 75 f0 ff 75 08 e8 5a 00 00 00 83 c4 10 |u..u..u..Z......| +00017c80 89 45 08 c7 45 f4 00 00 00 00 eb 1b 8b 55 f4 8b |.E..E........U..| +00017c90 45 0c 8d 0c 02 8b 45 08 8d 50 01 89 55 08 0f b6 |E.....E..P..U...| +00017ca0 11 88 10 83 45 f4 01 8b 45 f4 3b 45 10 7c dd 83 |....E...E.;E.|..| +00017cb0 7d f0 00 7e 1d 83 7d 18 00 74 17 83 ec 04 ff 75 |}..~..}..t.....u| +00017cc0 1c ff 75 f0 ff 75 08 e8 0b 00 00 00 83 c4 10 89 |..u..u..........| +00017cd0 45 08 8b 45 08 c9 c3 55 89 e5 eb 12 8b 45 08 8d |E..E...U.....E..| +00017ce0 50 01 89 55 08 8b 55 10 88 10 83 6d 0c 01 83 7d |P..U..U....m...}| +00017cf0 0c 00 7f e8 8b 45 08 5d c3 00 00 00 75 73 65 72 |.....E.]....user| +00017d00 57 3a 20 61 72 67 63 20 25 64 2c 20 61 72 67 73 |W: argc %d, args| +00017d10 3a 20 00 28 6e 75 6c 6c 29 00 20 25 73 00 0a 00 |: .(null). %s...| +00017d20 20 25 63 5b 25 64 2c 25 75 5d 00 20 25 63 5b 25 | %c[%d,%u]. %c[%| +00017d30 64 2c 25 75 5d 20 00 43 68 69 6c 64 20 25 64 20 |d,%u] .Child %d | +00017d40 65 78 65 63 28 29 20 23 25 75 20 66 61 69 6c 65 |exec() #%u faile| +00017d50 64 0a 00 00 b2 14 00 00 f0 14 00 00 3c 16 00 00 |d...........<...| +00017d60 3c 16 00 00 3c 16 00 00 3c 16 00 00 3c 16 00 00 |<...<...<...<...| +* +00017d80 3c 16 00 00 aa 15 00 00 3c 16 00 00 3c 16 00 00 |<.......<...<...| +00017d90 3c 16 00 00 34 15 00 00 3c 16 00 00 eb 15 00 00 |<...4...<.......| +00017da0 3c 16 00 00 3c 16 00 00 66 15 00 00 00 00 00 00 |<...<...f.......| +00017db0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +000182e0 00 10 00 00 00 00 00 00 03 00 01 00 00 00 00 00 |................| +000182f0 30 1a 00 00 00 00 00 00 03 00 02 00 00 00 00 00 |0...............| +00018300 00 20 00 00 00 00 00 00 03 00 03 00 00 00 00 00 |. ..............| +00018310 00 20 00 00 00 00 00 00 03 00 04 00 01 00 00 00 |. ..............| +00018320 00 00 00 00 00 00 00 00 04 00 f1 ff 09 00 00 00 |................| +00018330 00 00 00 00 00 00 00 00 04 00 f1 ff 11 00 00 00 |................| +00018340 00 00 00 00 00 00 00 00 04 00 f1 ff 1a 00 00 00 |................| +00018350 00 00 00 00 00 00 00 00 04 00 f1 ff 24 00 00 00 |............$...| +00018360 00 00 00 00 00 00 00 00 04 00 f1 ff 2d 00 00 00 |............-...| +00018370 00 00 00 00 00 00 00 00 04 00 f1 ff 36 00 00 00 |............6...| +00018380 00 00 00 00 00 00 00 00 04 00 f1 ff 40 00 00 00 |............@...| +00018390 00 00 00 00 00 00 00 00 04 00 f1 ff 49 00 00 00 |............I...| +000183a0 00 00 00 00 00 00 00 00 04 00 f1 ff 52 00 00 00 |............R...| +000183b0 00 00 00 00 00 00 00 00 04 00 f1 ff 5b 00 00 00 |............[...| +000183c0 00 00 00 00 00 00 00 00 04 00 f1 ff 65 00 00 00 |............e...| +000183d0 00 00 00 00 00 00 00 00 04 00 f1 ff 6e 00 00 00 |............n...| +000183e0 00 00 00 00 00 00 00 00 04 00 f1 ff 74 00 00 00 |............t...| +000183f0 fa 12 00 00 21 00 00 00 12 00 01 00 7d 00 00 00 |....!.......}...| +00018400 6b 13 00 00 00 00 00 00 10 00 01 00 85 00 00 00 |k...............| +00018410 df 12 00 00 1b 00 00 00 12 00 01 00 8c 00 00 00 |................| +00018420 5e 16 00 00 72 00 00 00 12 00 01 00 94 00 00 00 |^...r...........| +00018430 d6 18 00 00 32 00 00 00 12 00 01 00 9b 00 00 00 |....2...........| +00018440 93 13 00 00 00 00 00 00 10 00 01 00 a2 00 00 00 |................| +00018450 c3 13 00 00 00 00 00 00 10 00 01 00 a8 00 00 00 |................| +00018460 48 13 00 00 1b 00 00 00 12 00 01 00 af 00 00 00 |H...............| +00018470 0b 1a 00 00 22 00 00 00 12 00 01 00 b3 00 00 00 |...."...........| +00018480 1c 12 00 00 75 00 00 00 12 00 01 00 b9 00 00 00 |....u...........| +00018490 e9 13 00 00 75 02 00 00 12 00 01 00 c0 00 00 00 |....u...........| +000184a0 c2 17 00 00 8a 00 00 00 12 00 01 00 c7 00 00 00 |................| +000184b0 08 19 00 00 66 00 00 00 12 00 01 00 86 00 00 00 |....f...........| +000184c0 8b 13 00 00 00 00 00 00 10 00 01 00 cf 00 00 00 |................| +000184d0 bb 13 00 00 00 00 00 00 10 00 01 00 d4 00 00 00 |................| +000184e0 b2 12 00 00 2d 00 00 00 12 00 01 00 dc 00 00 00 |....-...........| +000184f0 7b 13 00 00 00 00 00 00 10 00 01 00 e1 00 00 00 |{...............| +00018500 04 12 00 00 18 00 00 00 12 00 01 00 e6 00 00 00 |................| +00018510 1b 13 00 00 2d 00 00 00 12 00 01 00 ee 00 00 00 |....-...........| +00018520 d9 13 00 00 00 00 00 00 10 00 01 00 f5 00 00 00 |................| +00018530 83 13 00 00 00 00 00 00 10 00 01 00 fa 00 00 00 |................| +00018540 ab 13 00 00 00 00 00 00 10 00 01 00 02 01 00 00 |................| +00018550 39 17 00 00 89 00 00 00 12 00 01 00 0a 01 00 00 |9...............| +00018560 73 13 00 00 00 00 00 00 10 00 01 00 0f 01 00 00 |s...............| +00018570 00 10 00 00 04 02 00 00 12 00 01 00 14 01 00 00 |................| +00018580 9b 13 00 00 00 00 00 00 10 00 01 00 1c 01 00 00 |................| +00018590 6e 19 00 00 9d 00 00 00 12 00 01 00 23 01 00 00 |n...........#...| +000185a0 b3 13 00 00 00 00 00 00 10 00 01 00 2b 01 00 00 |............+...| +000185b0 4c 18 00 00 8a 00 00 00 12 00 01 00 32 01 00 00 |L...........2...| +000185c0 91 12 00 00 21 00 00 00 12 00 01 00 3b 01 00 00 |....!.......;...| +000185d0 a3 13 00 00 00 00 00 00 10 00 01 00 43 01 00 00 |............C...| +000185e0 f2 16 00 00 47 00 00 00 12 00 01 00 5c 01 00 00 |....G.......\...| +000185f0 63 13 00 00 00 00 00 00 10 00 01 00 4a 01 00 00 |c...........J...| +00018600 d0 16 00 00 22 00 00 00 12 00 01 00 51 01 00 00 |....".......Q...| +00018610 cb 13 00 00 00 00 00 00 10 00 01 00 57 01 00 00 |............W...| +00018620 d3 13 00 00 00 00 00 00 10 00 01 00 00 70 72 6f |.............pro| +00018630 67 57 2e 63 00 75 6c 69 62 63 2e 63 00 73 70 72 |gW.c.ulibc.c.spr| +00018640 69 6e 74 2e 63 00 73 74 72 32 69 6e 74 2e 63 00 |int.c.str2int.c.| +00018650 73 74 72 6c 65 6e 2e 63 00 63 76 74 64 65 63 2e |strlen.c.cvtdec.| +00018660 63 00 63 76 74 64 65 63 30 2e 63 00 63 76 74 68 |c.cvtdec0.c.cvth| +00018670 65 78 2e 63 00 63 76 74 6f 63 74 2e 63 00 63 76 |ex.c.cvtoct.c.cv| +00018680 74 75 6e 73 2e 63 00 63 76 74 75 6e 73 30 2e 63 |tuns.c.cvtuns0.c| +00018690 00 70 61 64 73 74 72 2e 63 00 70 61 64 2e 63 00 |.padstr.c.pad.c.| +000186a0 73 77 72 69 74 65 63 68 00 77 61 69 74 70 69 64 |swritech.waitpid| +000186b0 00 63 77 72 69 74 65 00 73 74 72 32 69 6e 74 00 |.cwrite.str2int.| +000186c0 63 76 74 75 6e 73 00 67 65 74 70 69 64 00 73 6c |cvtuns.getpid.sl| +000186d0 65 65 70 00 73 77 72 69 74 65 00 70 61 64 00 73 |eep.swrite.pad.s| +000186e0 70 61 77 6e 00 73 70 72 69 6e 74 00 63 76 74 68 |pawn.sprint.cvth| +000186f0 65 78 00 63 76 74 75 6e 73 30 00 6b 69 6c 6c 00 |ex.cvtuns0.kill.| +00018700 63 77 72 69 74 65 73 00 65 78 65 63 00 77 61 69 |cwrites.exec.wai| +00018710 74 00 73 77 72 69 74 65 73 00 5f 73 74 61 72 74 |t.swrites._start| +00018720 00 72 65 61 64 00 67 65 74 70 72 69 6f 00 63 76 |.read.getprio.cv| +00018730 74 64 65 63 30 00 66 6f 72 6b 00 6d 61 69 6e 00 |tdec0.fork.main.| +00018740 67 65 74 70 70 69 64 00 70 61 64 73 74 72 00 73 |getppid.padstr.s| +00018750 65 74 70 72 69 6f 00 63 76 74 6f 63 74 00 63 77 |etprio.cvtoct.cw| +00018760 72 69 74 65 63 68 00 67 65 74 74 69 6d 65 00 63 |ritech.gettime.c| +00018770 76 74 64 65 63 00 73 74 72 6c 65 6e 00 62 6f 67 |vtdec.strlen.bog| +00018780 75 73 00 66 61 6b 65 5f 65 78 69 74 00 00 2e 73 |us.fake_exit...s| +00018790 79 6d 74 61 62 00 2e 73 74 72 74 61 62 00 2e 73 |ymtab..strtab..s| +000187a0 68 73 74 72 74 61 62 00 2e 74 65 78 74 00 2e 72 |hstrtab..text..r| +000187b0 6f 64 61 74 61 00 2e 64 61 74 61 00 2e 62 73 73 |odata..data..bss| +000187c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +000187e0 00 00 00 00 00 00 00 00 00 00 00 00 1b 00 00 00 |................| +000187f0 01 00 00 00 06 00 00 00 00 10 00 00 74 00 00 00 |............t...| +00018800 2d 0a 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |-...............| +00018810 00 00 00 00 21 00 00 00 01 00 00 00 02 00 00 00 |....!...........| +00018820 30 1a 00 00 a4 0a 00 00 b0 00 00 00 00 00 00 00 |0...............| +00018830 00 00 00 00 04 00 00 00 00 00 00 00 29 00 00 00 |............)...| +00018840 01 00 00 00 03 00 00 00 00 20 00 00 74 10 00 00 |......... ..t...| +00018850 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +00018860 00 00 00 00 2f 00 00 00 08 00 00 00 03 00 00 00 |..../...........| +00018870 00 20 00 00 74 10 00 00 00 00 00 00 00 00 00 00 |. ..t...........| +00018880 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 |................| +00018890 02 00 00 00 00 00 00 00 00 00 00 00 74 10 00 00 |............t...| +000188a0 60 03 00 00 06 00 00 00 12 00 00 00 04 00 00 00 |`...............| +000188b0 10 00 00 00 09 00 00 00 03 00 00 00 00 00 00 00 |................| +000188c0 00 00 00 00 d4 13 00 00 61 01 00 00 00 00 00 00 |........a.......| +000188d0 00 00 00 00 01 00 00 00 00 00 00 00 11 00 00 00 |................| +000188e0 03 00 00 00 00 00 00 00 00 00 00 00 35 15 00 00 |............5...| +000188f0 34 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |4...............| +00018900 00 00 00 00 00 00 00 00 7f 45 4c 46 01 01 01 00 |.........ELF....| +00018910 00 00 00 00 00 00 00 00 02 00 03 00 01 00 00 00 |................| +00018920 62 13 00 00 34 00 00 00 6c 15 00 00 00 00 00 00 |b...4...l.......| +00018930 34 00 20 00 02 00 28 00 08 00 07 00 01 00 00 00 |4. ...(.........| +00018940 74 00 00 00 00 10 00 00 00 10 00 00 00 10 00 00 |t...............| +00018950 00 10 00 00 07 00 00 00 04 00 00 00 51 e5 74 64 |............Q.td| +00018960 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00018970 00 00 00 00 07 00 00 00 10 00 00 00 8d 4c 24 04 |.............L$.| +00018980 83 e4 f0 ff 71 fc 55 89 e5 53 51 81 ec a0 00 00 |....q.U..SQ.....| +00018990 00 89 cb c7 45 f4 14 00 00 00 c6 45 f3 78 8b 03 |....E......E.x..| +000189a0 83 f8 02 74 1e 83 f8 03 75 2c 8b 43 04 83 c0 08 |...t....u,.C....| +000189b0 8b 00 83 ec 08 6a 0a 50 e8 a6 05 00 00 83 c4 10 |.....j.P........| +000189c0 89 45 f4 8b 43 04 83 c0 04 8b 00 0f b6 00 88 45 |.E..C..........E| +000189d0 f3 e9 a4 00 00 00 83 ec 04 ff 33 68 b8 19 00 00 |..........3h....| +000189e0 8d 85 60 ff ff ff 50 e8 02 03 00 00 83 c4 10 83 |..`...P.........| +000189f0 ec 0c 8d 85 60 ff ff ff 50 e8 b9 01 00 00 83 c4 |....`...P.......| +00018a00 10 c7 45 ec 00 00 00 00 eb 59 8b 03 8d 14 85 00 |..E......Y......| +00018a10 00 00 00 8b 43 04 01 d0 8b 00 85 c0 74 12 8b 03 |....C.......t...| +00018a20 8d 14 85 00 00 00 00 8b 43 04 01 d0 8b 00 eb 05 |........C.......| +00018a30 b8 cf 19 00 00 83 ec 04 50 68 d6 19 00 00 8d 85 |........Ph......| +00018a40 60 ff ff ff 50 e8 a4 02 00 00 83 c4 10 83 ec 0c |`...P...........| +00018a50 8d 85 60 ff ff ff 50 e8 5b 01 00 00 83 c4 10 83 |..`...P.[.......| +00018a60 45 ec 01 8b 45 ec 3b 03 7e a0 83 ec 0c 68 da 19 |E...E.;.~....h..| +00018a70 00 00 e8 40 01 00 00 83 c4 10 e8 19 02 00 00 89 |...@............| +00018a80 45 e0 0f be 45 f3 ff 75 e0 50 68 dc 19 00 00 8d |E...E..u.Ph.....| +00018a90 85 60 ff ff ff 50 e8 53 02 00 00 83 c4 10 83 ec |.`...P.S........| +00018aa0 0c 8d 85 60 ff ff ff 50 e8 73 01 00 00 83 c4 10 |...`...P.s......| +00018ab0 c7 45 e8 00 00 00 00 eb 2c 83 ec 0c 8d 85 60 ff |.E......,.....`.| +00018ac0 ff ff 50 e8 58 01 00 00 83 c4 10 c7 45 e4 00 00 |..P.X.......E...| +00018ad0 00 00 eb 04 83 45 e4 01 81 7d e4 9f 25 26 00 7e |.....E...}..%&.~| +00018ae0 f3 83 45 e8 01 8b 45 e8 3b 45 f4 7c cc 83 ec 0c |..E...E.;E.|....| +00018af0 6a 0c e8 71 01 00 00 83 c4 10 b8 2a 00 00 00 8d |j..q.......*....| +00018b00 65 f8 59 5b 5d 8d 61 fc c3 55 89 e5 83 ec 08 83 |e.Y[].a..U......| +00018b10 ec 08 ff 75 08 6a 00 e8 54 01 00 00 83 c4 10 c9 |...u.j..T.......| +00018b20 c3 55 89 e5 81 ec 18 01 00 00 e8 49 01 00 00 89 |.U.........I....| +00018b30 45 f4 83 7d f4 00 74 05 8b 45 f4 eb 57 e8 56 01 |E..}..t..E..W.V.| +00018b40 00 00 89 45 f4 83 ec 08 ff 75 0c ff 75 08 e8 2d |...E.....u..u..-| +00018b50 01 00 00 83 c4 10 ff 75 08 ff 75 f4 68 e4 19 00 |.......u..u.h...| +00018b60 00 8d 85 f4 fe ff ff 50 e8 81 01 00 00 83 c4 10 |.......P........| +00018b70 83 ec 0c 8d 85 f4 fe ff ff 50 e8 38 00 00 00 83 |.........P.8....| +00018b80 c4 10 83 ec 0c 6a ff e8 dc 00 00 00 83 c4 10 b8 |.....j..........| +00018b90 00 00 00 00 c9 c3 55 89 e5 83 ec 18 8b 45 08 88 |......U......E..| +00018ba0 45 f4 83 ec 04 6a 01 8d 45 f4 50 6a 00 e8 de 00 |E....j..E.Pj....| +00018bb0 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 83 ec 0c |.......U........| +00018bc0 ff 75 08 e8 0d 04 00 00 83 c4 10 89 45 f4 8b 45 |.u..........E..E| +00018bd0 f4 83 ec 04 50 ff 75 08 6a 00 e8 b1 00 00 00 83 |....P.u.j.......| +00018be0 c4 10 c9 c3 55 89 e5 83 ec 08 83 ec 04 ff 75 0c |....U.........u.| +00018bf0 ff 75 08 6a 00 e8 96 00 00 00 83 c4 10 c9 c3 55 |.u.j...........U| +00018c00 89 e5 83 ec 18 8b 45 08 88 45 f4 83 ec 04 6a 01 |......E..E....j.| +00018c10 8d 45 f4 50 6a 01 e8 75 00 00 00 83 c4 10 c9 c3 |.E.Pj..u........| +00018c20 55 89 e5 83 ec 18 83 ec 0c ff 75 08 e8 a4 03 00 |U.........u.....| +00018c30 00 83 c4 10 89 45 f4 8b 45 f4 83 ec 04 50 ff 75 |.....E..E....P.u| +00018c40 08 6a 01 e8 48 00 00 00 83 c4 10 c9 c3 55 89 e5 |.j..H........U..| +00018c50 83 ec 08 83 ec 04 ff 75 0c ff 75 08 6a 01 e8 2d |.......u..u.j..-| +00018c60 00 00 00 83 c4 10 c9 c3 b8 00 00 00 00 cd 80 c3 |................| +00018c70 b8 01 00 00 00 cd 80 c3 b8 02 00 00 00 cd 80 c3 |................| +00018c80 b8 03 00 00 00 cd 80 c3 b8 04 00 00 00 cd 80 c3 |................| +00018c90 b8 05 00 00 00 cd 80 c3 b8 06 00 00 00 cd 80 c3 |................| +00018ca0 b8 07 00 00 00 cd 80 c3 b8 08 00 00 00 cd 80 c3 |................| +00018cb0 b8 09 00 00 00 cd 80 c3 b8 0a 00 00 00 cd 80 c3 |................| +00018cc0 b8 0b 00 00 00 cd 80 c3 b8 0c 00 00 00 cd 80 c3 |................| +00018cd0 b8 ad 0b 00 00 cd 80 c3 50 e8 8a ff ff ff e8 99 |........P.......| +00018ce0 fc ff ff 83 ec 0c 50 e8 7c ff ff ff eb fe 55 89 |......P.|.....U.| +00018cf0 e5 83 ec 38 8d 45 0c 83 c0 04 89 45 f4 e9 3f 02 |...8.E.....E..?.| +00018d00 00 00 80 7d f3 25 0f 85 26 02 00 00 c7 45 ec 00 |...}.%..&....E..| +00018d10 00 00 00 c7 45 e4 20 00 00 00 c7 45 e8 00 00 00 |....E. ....E....| +00018d20 00 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 |..E..P..U.....E.| +00018d30 80 7d f3 2d 75 16 c7 45 ec 01 00 00 00 8b 45 0c |.}.-u..E......E.| +00018d40 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 30 |.P..U.....E..}.0| +00018d50 75 40 c7 45 e4 30 00 00 00 8b 45 0c 8d 50 01 89 |u@.E.0....E..P..| +00018d60 55 0c 0f b6 00 88 45 f3 eb 28 8b 55 e8 89 d0 c1 |U.....E..(.U....| +00018d70 e0 02 01 d0 01 c0 89 45 e8 0f be 45 f3 83 e8 30 |.......E...E...0| +00018d80 01 45 e8 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 |.E..E..P..U.....| +00018d90 45 f3 80 7d f3 2f 7e 06 80 7d f3 39 7e cc 0f be |E..}./~..}.9~...| +00018da0 45 f3 83 e8 63 83 f8 15 0f 87 93 01 00 00 8b 04 |E...c...........| +00018db0 85 00 1a 00 00 ff e0 8b 45 f4 8d 50 04 89 55 f4 |........E..P..U.| +00018dc0 8b 00 88 45 f3 0f b6 45 f3 88 45 d0 c6 45 d1 00 |...E...E..E..E..| +00018dd0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 6a 01 8d 45 |....u..u..u.j..E| +00018de0 d0 50 ff 75 08 e8 89 04 00 00 83 c4 20 89 45 08 |.P.u........ .E.| +00018df0 e9 4c 01 00 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 |.L....E..P..U...| +00018e00 83 ec 08 50 8d 45 d0 50 e8 ea 01 00 00 83 c4 10 |...P.E.P........| +00018e10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff |.E.....u..u..u..| +00018e20 75 e0 8d 45 d0 50 ff 75 08 e8 45 04 00 00 83 c4 |u..E.P.u..E.....| +00018e30 20 89 45 08 e9 08 01 00 00 8b 45 f4 8d 50 04 89 | .E.......E..P..| +00018e40 55 f4 8b 00 89 45 dc 83 ec 08 ff 75 e4 ff 75 ec |U....E.....u..u.| +00018e50 ff 75 e8 6a ff ff 75 dc ff 75 08 e8 13 04 00 00 |.u.j..u..u......| +00018e60 83 c4 20 89 45 08 e9 d6 00 00 00 8b 45 f4 8d 50 |.. .E.......E..P| +00018e70 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 44 |..U......P.E.P.D| +00018e80 02 00 00 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff |.......E.....u..| +00018e90 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 |u..u..u..E.P.u..| +00018ea0 cf 03 00 00 83 c4 20 89 45 08 e9 92 00 00 00 8b |...... .E.......| +00018eb0 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 |E..P..U......P.E| +00018ec0 d0 50 e8 8a 02 00 00 83 c4 10 89 45 e0 83 ec 08 |.P.........E....| +00018ed0 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 |.u..u..u..u..E.P| +00018ee0 ff 75 08 e8 8b 03 00 00 83 c4 20 89 45 08 eb 51 |.u........ .E..Q| +00018ef0 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d |.E..P..U......P.| +00018f00 45 d0 50 e8 d3 02 00 00 83 c4 10 89 45 e0 83 ec |E.P.........E...| +00018f10 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 |..u..u..u..u..E.| +00018f20 50 ff 75 08 e8 4a 03 00 00 83 c4 20 89 45 08 90 |P.u..J..... .E..| +00018f30 eb 0f 8b 45 08 8d 50 01 89 55 08 0f b6 55 f3 88 |...E..P..U...U..| +00018f40 10 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 |..E..P..U.....E.| +00018f50 80 7d f3 00 0f 85 a8 fd ff ff 8b 45 08 c6 00 00 |.}.........E....| +00018f60 90 c9 c3 55 89 e5 53 83 ec 14 8b 45 08 8b 4d 0c |...U..S....E..M.| +00018f70 bb 00 00 00 00 c6 45 eb 39 c7 45 f8 01 00 00 00 |......E.9.E.....| +00018f80 0f b6 10 80 fa 2d 75 0a c7 45 f8 ff ff ff ff 83 |.....-u..E......| +00018f90 c0 01 83 f9 0a 74 2b 89 ca 83 c2 2f 88 55 eb eb |.....t+..../.U..| +00018fa0 21 0f b6 10 80 fa 2f 7e 20 0f b6 10 38 55 eb 7c |!...../~ ...8U.|| +00018fb0 18 0f af d9 0f b6 10 0f be d2 01 da 8d 5a d0 83 |.............Z..| +00018fc0 c0 01 0f b6 10 84 d2 75 d8 89 d8 0f af 45 f8 83 |.......u.....E..| +00018fd0 c4 14 5b 5d c3 55 89 e5 53 8b 55 08 bb 00 00 00 |..[].U..S.U.....| +00018fe0 00 eb 03 83 c3 01 89 d0 8d 50 01 0f b6 00 84 c0 |.........P......| +00018ff0 75 f1 89 d8 5b 5d c3 55 89 e5 83 ec 18 8b 45 08 |u...[].U......E.| +00019000 89 45 f4 83 7d 0c 00 79 0f 8b 45 f4 8d 50 01 89 |.E..}..y..E..P..| +00019010 55 f4 c6 00 2d f7 5d 0c 83 ec 08 ff 75 0c ff 75 |U...-.].....u..u| +00019020 f4 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 c6 |..........E..E..| +00019030 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 |...U..E.).....U.| +00019040 e5 83 ec 18 8b 4d 0c ba 67 66 66 66 89 c8 f7 ea |.....M..gfff....| +00019050 c1 fa 02 89 c8 c1 f8 1f 29 c2 89 d0 89 45 f4 83 |........)....E..| +00019060 7d f4 00 79 0e c7 45 f4 cc cc cc 0c c7 45 0c 08 |}..y..E......E..| +00019070 00 00 00 83 7d f4 00 74 14 83 ec 08 ff 75 f4 ff |....}..t.....u..| +00019080 75 08 e8 b7 ff ff ff 83 c4 10 89 45 08 8b 4d 0c |u..........E..M.| +00019090 ba 67 66 66 66 89 c8 f7 ea c1 fa 02 89 c8 c1 f8 |.gfff...........| +000190a0 1f 29 c2 89 d0 c1 e0 02 01 d0 01 c0 29 c1 89 ca |.)..........)...| +000190b0 89 d0 8d 48 30 8b 45 08 8d 50 01 89 55 08 89 ca |...H0.E..P..U...| +000190c0 88 10 8b 45 08 c9 c3 55 89 e5 83 ec 20 c7 45 e3 |...E...U.... .E.| +000190d0 30 31 32 33 c7 45 e7 34 35 36 37 c7 45 eb 38 39 |0123.E.4567.E.89| +000190e0 41 42 c7 45 ef 43 44 45 46 c6 45 f3 00 c7 45 fc |AB.E.CDEF.E...E.| +000190f0 00 00 00 00 c7 45 f8 00 00 00 00 eb 43 8b 45 0c |.....E......C.E.| +00019100 25 00 00 00 f0 89 45 f4 83 7d fc 00 75 0c 83 7d |%.....E..}..u..}| +00019110 f4 00 75 06 83 7d f8 07 75 1e 83 45 fc 01 c1 6d |..u..}..u..E...m| +00019120 f4 1c 8b 45 08 8d 50 01 89 55 08 8d 4d e3 8b 55 |...E..P..U..M..U| +00019130 f4 01 ca 0f b6 12 88 10 c1 65 0c 04 83 45 f8 01 |.........e...E..| +00019140 83 7d f8 07 7e b7 8b 45 08 c6 00 00 8b 45 fc c9 |.}..~..E.....E..| +00019150 c3 55 89 e5 83 ec 10 c7 45 f8 00 00 00 00 8b 45 |.U......E......E| +00019160 08 89 45 f4 8b 45 0c 25 00 00 00 c0 89 45 f0 c1 |..E..E.%.....E..| +00019170 6d f0 1e c7 45 fc 00 00 00 00 eb 47 83 7d fc 0a |m...E......G.}..| +00019180 74 0c 83 7d f0 00 75 06 83 7d f8 00 74 1e c7 45 |t..}..u..}..t..E| +00019190 f8 01 00 00 00 83 65 f0 07 8b 45 f0 8d 48 30 8b |......e...E..H0.| +000191a0 45 f4 8d 50 01 89 55 f4 89 ca 88 10 c1 65 0c 03 |E..P..U......e..| +000191b0 8b 45 0c 25 00 00 00 e0 89 45 f0 c1 6d f0 1d 83 |.E.%.....E..m...| +000191c0 45 fc 01 83 7d fc 0a 7e b3 8b 45 f4 c6 00 00 8b |E...}..~..E.....| +000191d0 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 ec |U..E.).....U....| +000191e0 18 8b 45 08 89 45 f4 83 ec 08 ff 75 0c ff 75 f4 |..E..E.....u..u.| +000191f0 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 c6 00 |.........E..E...| +00019200 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 |..U..E.).....U..| +00019210 83 ec 18 8b 45 0c ba cd cc cc cc f7 e2 89 d0 c1 |....E...........| +00019220 e8 03 89 45 f4 83 7d f4 00 74 15 8b 45 f4 83 ec |...E..}..t..E...| +00019230 08 50 ff 75 08 e8 04 fe ff ff 83 c4 10 89 45 08 |.P.u..........E.| +00019240 8b 4d 0c ba cd cc cc cc 89 c8 f7 e2 c1 ea 03 89 |.M..............| +00019250 d0 c1 e0 02 01 d0 01 c0 29 c1 89 ca 89 d0 8d 48 |........)......H| +00019260 30 8b 45 08 8d 50 01 89 55 08 89 ca 88 10 8b 45 |0.E..P..U......E| +00019270 08 c9 c3 55 89 e5 83 ec 18 83 7d 10 00 79 11 83 |...U......}..y..| +00019280 ec 0c ff 75 0c e8 4b fd ff ff 83 c4 10 89 45 10 |...u..K.......E.| +00019290 8b 45 14 2b 45 10 89 45 f0 83 7d f0 00 7e 1d 83 |.E.+E..E..}..~..| +000192a0 7d 18 00 75 17 83 ec 04 ff 75 1c ff 75 f0 ff 75 |}..u.....u..u..u| +000192b0 08 e8 5a 00 00 00 83 c4 10 89 45 08 c7 45 f4 00 |..Z.......E..E..| +000192c0 00 00 00 eb 1b 8b 55 f4 8b 45 0c 8d 0c 02 8b 45 |......U..E.....E| +000192d0 08 8d 50 01 89 55 08 0f b6 11 88 10 83 45 f4 01 |..P..U.......E..| +000192e0 8b 45 f4 3b 45 10 7c dd 83 7d f0 00 7e 1d 83 7d |.E.;E.|..}..~..}| +000192f0 18 00 74 17 83 ec 04 ff 75 1c ff 75 f0 ff 75 08 |..t.....u..u..u.| +00019300 e8 0b 00 00 00 83 c4 10 89 45 08 8b 45 08 c9 c3 |.........E..E...| +00019310 55 89 e5 eb 12 8b 45 08 8d 50 01 89 55 08 8b 55 |U.....E..P..U..U| +00019320 10 88 10 83 6d 0c 01 83 7d 0c 00 7f e8 8b 45 08 |....m...}.....E.| +00019330 5d c3 00 00 75 73 65 72 58 3a 20 61 72 67 63 20 |]...userX: argc | +00019340 25 64 2c 20 61 72 67 73 3a 20 00 28 6e 75 6c 6c |%d, args: .(null| +00019350 29 00 20 25 73 00 0a 00 20 25 63 5b 25 64 5d 00 |). %s... %c[%d].| +00019360 43 68 69 6c 64 20 25 64 20 65 78 65 63 28 29 20 |Child %d exec() | +00019370 23 25 75 20 66 61 69 6c 65 64 0a 00 3b 14 00 00 |#%u failed..;...| +00019380 79 14 00 00 c5 15 00 00 c5 15 00 00 c5 15 00 00 |y...............| +00019390 c5 15 00 00 c5 15 00 00 c5 15 00 00 c5 15 00 00 |................| +000193a0 c5 15 00 00 c5 15 00 00 c5 15 00 00 33 15 00 00 |............3...| +000193b0 c5 15 00 00 c5 15 00 00 c5 15 00 00 bd 14 00 00 |................| +000193c0 c5 15 00 00 74 15 00 00 c5 15 00 00 c5 15 00 00 |....t...........| +000193d0 ef 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +000193e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00019990 00 10 00 00 00 00 00 00 03 00 01 00 00 00 00 00 |................| +000199a0 b8 19 00 00 00 00 00 00 03 00 02 00 00 00 00 00 |................| +000199b0 00 20 00 00 00 00 00 00 03 00 03 00 00 00 00 00 |. ..............| +000199c0 00 20 00 00 00 00 00 00 03 00 04 00 01 00 00 00 |. ..............| +000199d0 00 00 00 00 00 00 00 00 04 00 f1 ff 09 00 00 00 |................| +000199e0 00 00 00 00 00 00 00 00 04 00 f1 ff 11 00 00 00 |................| +000199f0 00 00 00 00 00 00 00 00 04 00 f1 ff 1a 00 00 00 |................| +00019a00 00 00 00 00 00 00 00 00 04 00 f1 ff 24 00 00 00 |............$...| +00019a10 00 00 00 00 00 00 00 00 04 00 f1 ff 2d 00 00 00 |............-...| +00019a20 00 00 00 00 00 00 00 00 04 00 f1 ff 36 00 00 00 |............6...| +00019a30 00 00 00 00 00 00 00 00 04 00 f1 ff 40 00 00 00 |............@...| +00019a40 00 00 00 00 00 00 00 00 04 00 f1 ff 49 00 00 00 |............I...| +00019a50 00 00 00 00 00 00 00 00 04 00 f1 ff 52 00 00 00 |............R...| +00019a60 00 00 00 00 00 00 00 00 04 00 f1 ff 5b 00 00 00 |............[...| +00019a70 00 00 00 00 00 00 00 00 04 00 f1 ff 65 00 00 00 |............e...| +00019a80 00 00 00 00 00 00 00 00 04 00 f1 ff 6e 00 00 00 |............n...| +00019a90 00 00 00 00 00 00 00 00 04 00 f1 ff 74 00 00 00 |............t...| +00019aa0 83 12 00 00 21 00 00 00 12 00 01 00 7d 00 00 00 |....!.......}...| +00019ab0 f4 12 00 00 00 00 00 00 10 00 01 00 85 00 00 00 |................| +00019ac0 68 12 00 00 1b 00 00 00 12 00 01 00 8c 00 00 00 |h...............| +00019ad0 e7 15 00 00 72 00 00 00 12 00 01 00 94 00 00 00 |....r...........| +00019ae0 5f 18 00 00 32 00 00 00 12 00 01 00 9b 00 00 00 |_...2...........| +00019af0 1c 13 00 00 00 00 00 00 10 00 01 00 a2 00 00 00 |................| +00019b00 4c 13 00 00 00 00 00 00 10 00 01 00 a8 00 00 00 |L...............| +00019b10 d1 12 00 00 1b 00 00 00 12 00 01 00 af 00 00 00 |................| +00019b20 94 19 00 00 22 00 00 00 12 00 01 00 b3 00 00 00 |...."...........| +00019b30 a5 11 00 00 75 00 00 00 12 00 01 00 b9 00 00 00 |....u...........| +00019b40 72 13 00 00 75 02 00 00 12 00 01 00 c0 00 00 00 |r...u...........| +00019b50 4b 17 00 00 8a 00 00 00 12 00 01 00 c7 00 00 00 |K...............| +00019b60 91 18 00 00 66 00 00 00 12 00 01 00 86 00 00 00 |....f...........| +00019b70 14 13 00 00 00 00 00 00 10 00 01 00 cf 00 00 00 |................| +00019b80 44 13 00 00 00 00 00 00 10 00 01 00 d4 00 00 00 |D...............| +00019b90 3b 12 00 00 2d 00 00 00 12 00 01 00 dc 00 00 00 |;...-...........| +00019ba0 04 13 00 00 00 00 00 00 10 00 01 00 e1 00 00 00 |................| +00019bb0 8d 11 00 00 18 00 00 00 12 00 01 00 e6 00 00 00 |................| +00019bc0 a4 12 00 00 2d 00 00 00 12 00 01 00 ee 00 00 00 |....-...........| +00019bd0 62 13 00 00 00 00 00 00 10 00 01 00 f5 00 00 00 |b...............| +00019be0 0c 13 00 00 00 00 00 00 10 00 01 00 fa 00 00 00 |................| +00019bf0 34 13 00 00 00 00 00 00 10 00 01 00 02 01 00 00 |4...............| +00019c00 c2 16 00 00 89 00 00 00 12 00 01 00 0a 01 00 00 |................| +00019c10 fc 12 00 00 00 00 00 00 10 00 01 00 0f 01 00 00 |................| +00019c20 00 10 00 00 8d 01 00 00 12 00 01 00 14 01 00 00 |................| +00019c30 24 13 00 00 00 00 00 00 10 00 01 00 1c 01 00 00 |$...............| +00019c40 f7 18 00 00 9d 00 00 00 12 00 01 00 23 01 00 00 |............#...| +00019c50 3c 13 00 00 00 00 00 00 10 00 01 00 2b 01 00 00 |<...........+...| +00019c60 d5 17 00 00 8a 00 00 00 12 00 01 00 32 01 00 00 |............2...| +00019c70 1a 12 00 00 21 00 00 00 12 00 01 00 3b 01 00 00 |....!.......;...| +00019c80 2c 13 00 00 00 00 00 00 10 00 01 00 43 01 00 00 |,...........C...| +00019c90 7b 16 00 00 47 00 00 00 12 00 01 00 5c 01 00 00 |{...G.......\...| +00019ca0 ec 12 00 00 00 00 00 00 10 00 01 00 4a 01 00 00 |............J...| +00019cb0 59 16 00 00 22 00 00 00 12 00 01 00 51 01 00 00 |Y...".......Q...| +00019cc0 54 13 00 00 00 00 00 00 10 00 01 00 57 01 00 00 |T...........W...| +00019cd0 5c 13 00 00 00 00 00 00 10 00 01 00 00 70 72 6f |\............pro| +00019ce0 67 58 2e 63 00 75 6c 69 62 63 2e 63 00 73 70 72 |gX.c.ulibc.c.spr| +00019cf0 69 6e 74 2e 63 00 73 74 72 32 69 6e 74 2e 63 00 |int.c.str2int.c.| +00019d00 73 74 72 6c 65 6e 2e 63 00 63 76 74 64 65 63 2e |strlen.c.cvtdec.| +00019d10 63 00 63 76 74 64 65 63 30 2e 63 00 63 76 74 68 |c.cvtdec0.c.cvth| +00019d20 65 78 2e 63 00 63 76 74 6f 63 74 2e 63 00 63 76 |ex.c.cvtoct.c.cv| +00019d30 74 75 6e 73 2e 63 00 63 76 74 75 6e 73 30 2e 63 |tuns.c.cvtuns0.c| +00019d40 00 70 61 64 73 74 72 2e 63 00 70 61 64 2e 63 00 |.padstr.c.pad.c.| +00019d50 73 77 72 69 74 65 63 68 00 77 61 69 74 70 69 64 |swritech.waitpid| +00019d60 00 63 77 72 69 74 65 00 73 74 72 32 69 6e 74 00 |.cwrite.str2int.| +00019d70 63 76 74 75 6e 73 00 67 65 74 70 69 64 00 73 6c |cvtuns.getpid.sl| +00019d80 65 65 70 00 73 77 72 69 74 65 00 70 61 64 00 73 |eep.swrite.pad.s| +00019d90 70 61 77 6e 00 73 70 72 69 6e 74 00 63 76 74 68 |pawn.sprint.cvth| +00019da0 65 78 00 63 76 74 75 6e 73 30 00 6b 69 6c 6c 00 |ex.cvtuns0.kill.| +00019db0 63 77 72 69 74 65 73 00 65 78 65 63 00 77 61 69 |cwrites.exec.wai| +00019dc0 74 00 73 77 72 69 74 65 73 00 5f 73 74 61 72 74 |t.swrites._start| +00019dd0 00 72 65 61 64 00 67 65 74 70 72 69 6f 00 63 76 |.read.getprio.cv| +00019de0 74 64 65 63 30 00 66 6f 72 6b 00 6d 61 69 6e 00 |tdec0.fork.main.| +00019df0 67 65 74 70 70 69 64 00 70 61 64 73 74 72 00 73 |getppid.padstr.s| +00019e00 65 74 70 72 69 6f 00 63 76 74 6f 63 74 00 63 77 |etprio.cvtoct.cw| +00019e10 72 69 74 65 63 68 00 67 65 74 74 69 6d 65 00 63 |ritech.gettime.c| +00019e20 76 74 64 65 63 00 73 74 72 6c 65 6e 00 62 6f 67 |vtdec.strlen.bog| +00019e30 75 73 00 66 61 6b 65 5f 65 78 69 74 00 00 2e 73 |us.fake_exit...s| +00019e40 79 6d 74 61 62 00 2e 73 74 72 74 61 62 00 2e 73 |ymtab..strtab..s| +00019e50 68 73 74 72 74 61 62 00 2e 74 65 78 74 00 2e 72 |hstrtab..text..r| +00019e60 6f 64 61 74 61 00 2e 64 61 74 61 00 2e 62 73 73 |odata..data..bss| +00019e70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +00019e90 00 00 00 00 00 00 00 00 00 00 00 00 1b 00 00 00 |................| +00019ea0 01 00 00 00 06 00 00 00 00 10 00 00 74 00 00 00 |............t...| +00019eb0 b6 09 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +00019ec0 00 00 00 00 21 00 00 00 01 00 00 00 02 00 00 00 |....!...........| +00019ed0 b8 19 00 00 2c 0a 00 00 a0 00 00 00 00 00 00 00 |....,...........| +00019ee0 00 00 00 00 04 00 00 00 00 00 00 00 29 00 00 00 |............)...| +00019ef0 01 00 00 00 03 00 00 00 00 20 00 00 74 10 00 00 |......... ..t...| +00019f00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +00019f10 00 00 00 00 2f 00 00 00 08 00 00 00 03 00 00 00 |..../...........| +00019f20 00 20 00 00 74 10 00 00 00 00 00 00 00 00 00 00 |. ..t...........| +00019f30 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 |................| +00019f40 02 00 00 00 00 00 00 00 00 00 00 00 74 10 00 00 |............t...| +00019f50 60 03 00 00 06 00 00 00 12 00 00 00 04 00 00 00 |`...............| +00019f60 10 00 00 00 09 00 00 00 03 00 00 00 00 00 00 00 |................| +00019f70 00 00 00 00 d4 13 00 00 61 01 00 00 00 00 00 00 |........a.......| +00019f80 00 00 00 00 01 00 00 00 00 00 00 00 11 00 00 00 |................| +00019f90 03 00 00 00 00 00 00 00 00 00 00 00 35 15 00 00 |............5...| +00019fa0 34 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |4...............| +00019fb0 00 00 00 00 00 00 00 00 7f 45 4c 46 01 01 01 00 |.........ELF....| +00019fc0 00 00 00 00 00 00 00 00 02 00 03 00 01 00 00 00 |................| +00019fd0 72 13 00 00 34 00 00 00 6c 15 00 00 00 00 00 00 |r...4...l.......| +00019fe0 34 00 20 00 02 00 28 00 08 00 07 00 01 00 00 00 |4. ...(.........| +00019ff0 74 00 00 00 00 10 00 00 00 10 00 00 00 10 00 00 |t...............| +0001a000 00 10 00 00 07 00 00 00 04 00 00 00 51 e5 74 64 |............Q.td| +0001a010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +0001a020 00 00 00 00 07 00 00 00 10 00 00 00 8d 4c 24 04 |.............L$.| +0001a030 83 e4 f0 ff 71 fc 55 89 e5 53 51 81 ec a0 00 00 |....q.U..SQ.....| +0001a040 00 89 cb c7 45 f4 0a 00 00 00 c6 45 f3 79 8b 03 |....E......E.y..| +0001a050 83 f8 02 74 1e 83 f8 03 75 2c 8b 43 04 83 c0 08 |...t....u,.C....| +0001a060 8b 00 83 ec 08 6a 0a 50 e8 b6 05 00 00 83 c4 10 |.....j.P........| +0001a070 89 45 f4 8b 43 04 83 c0 04 8b 00 0f b6 00 88 45 |.E..C..........E| +0001a080 f3 e9 a4 00 00 00 83 ec 04 ff 33 68 c8 19 00 00 |..........3h....| +0001a090 8d 85 60 ff ff ff 50 e8 12 03 00 00 83 c4 10 83 |..`...P.........| +0001a0a0 ec 0c 8d 85 60 ff ff ff 50 e8 c9 01 00 00 83 c4 |....`...P.......| +0001a0b0 10 c7 45 ec 00 00 00 00 eb 59 8b 03 8d 14 85 00 |..E......Y......| +0001a0c0 00 00 00 8b 43 04 01 d0 8b 00 85 c0 74 12 8b 03 |....C.......t...| +0001a0d0 8d 14 85 00 00 00 00 8b 43 04 01 d0 8b 00 eb 05 |........C.......| +0001a0e0 b8 db 19 00 00 83 ec 04 50 68 e2 19 00 00 8d 85 |........Ph......| +0001a0f0 60 ff ff ff 50 e8 b4 02 00 00 83 c4 10 83 ec 0c |`...P...........| +0001a100 8d 85 60 ff ff ff 50 e8 6b 01 00 00 83 c4 10 83 |..`...P.k.......| +0001a110 45 ec 01 8b 45 ec 3b 03 7e a0 83 ec 0c 68 e6 19 |E...E.;.~....h..| +0001a120 00 00 e8 50 01 00 00 83 c4 10 e8 29 02 00 00 89 |...P.......)....| +0001a130 45 e0 0f be 45 f3 ff 75 e0 50 68 e8 19 00 00 8d |E...E..u.Ph.....| +0001a140 85 60 ff ff ff 50 e8 63 02 00 00 83 c4 10 83 ec |.`...P.c........| +0001a150 0c 8d 85 60 ff ff ff 50 e8 83 01 00 00 83 c4 10 |...`...P........| +0001a160 c7 45 e8 00 00 00 00 eb 3c 83 ec 0c 8d 85 60 ff |.E......<.....`.| +0001a170 ff ff 50 e8 68 01 00 00 83 c4 10 c7 45 e4 00 00 |..P.h.......E...| +0001a180 00 00 eb 04 83 45 e4 01 81 7d e4 9f 25 26 00 7e |.....E...}..%&.~| +0001a190 f3 83 ec 0c 68 e8 03 00 00 e8 ea 01 00 00 83 c4 |....h...........| +0001a1a0 10 83 45 e8 01 8b 45 e8 3b 45 f4 7c bc 83 ec 0c |..E...E.;E.|....| +0001a1b0 6a 00 e8 71 01 00 00 83 c4 10 b8 2a 00 00 00 8d |j..q.......*....| +0001a1c0 65 f8 59 5b 5d 8d 61 fc c3 55 89 e5 83 ec 08 83 |e.Y[].a..U......| +0001a1d0 ec 08 ff 75 08 6a 00 e8 54 01 00 00 83 c4 10 c9 |...u.j..T.......| +0001a1e0 c3 55 89 e5 81 ec 18 01 00 00 e8 49 01 00 00 89 |.U.........I....| +0001a1f0 45 f4 83 7d f4 00 74 05 8b 45 f4 eb 57 e8 56 01 |E..}..t..E..W.V.| +0001a200 00 00 89 45 f4 83 ec 08 ff 75 0c ff 75 08 e8 2d |...E.....u..u..-| +0001a210 01 00 00 83 c4 10 ff 75 08 ff 75 f4 68 f0 19 00 |.......u..u.h...| +0001a220 00 8d 85 f4 fe ff ff 50 e8 81 01 00 00 83 c4 10 |.......P........| +0001a230 83 ec 0c 8d 85 f4 fe ff ff 50 e8 38 00 00 00 83 |.........P.8....| +0001a240 c4 10 83 ec 0c 6a ff e8 dc 00 00 00 83 c4 10 b8 |.....j..........| +0001a250 00 00 00 00 c9 c3 55 89 e5 83 ec 18 8b 45 08 88 |......U......E..| +0001a260 45 f4 83 ec 04 6a 01 8d 45 f4 50 6a 00 e8 de 00 |E....j..E.Pj....| +0001a270 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 83 ec 0c |.......U........| +0001a280 ff 75 08 e8 0d 04 00 00 83 c4 10 89 45 f4 8b 45 |.u..........E..E| +0001a290 f4 83 ec 04 50 ff 75 08 6a 00 e8 b1 00 00 00 83 |....P.u.j.......| +0001a2a0 c4 10 c9 c3 55 89 e5 83 ec 08 83 ec 04 ff 75 0c |....U.........u.| +0001a2b0 ff 75 08 6a 00 e8 96 00 00 00 83 c4 10 c9 c3 55 |.u.j...........U| +0001a2c0 89 e5 83 ec 18 8b 45 08 88 45 f4 83 ec 04 6a 01 |......E..E....j.| +0001a2d0 8d 45 f4 50 6a 01 e8 75 00 00 00 83 c4 10 c9 c3 |.E.Pj..u........| +0001a2e0 55 89 e5 83 ec 18 83 ec 0c ff 75 08 e8 a4 03 00 |U.........u.....| +0001a2f0 00 83 c4 10 89 45 f4 8b 45 f4 83 ec 04 50 ff 75 |.....E..E....P.u| +0001a300 08 6a 01 e8 48 00 00 00 83 c4 10 c9 c3 55 89 e5 |.j..H........U..| +0001a310 83 ec 08 83 ec 04 ff 75 0c ff 75 08 6a 01 e8 2d |.......u..u.j..-| +0001a320 00 00 00 83 c4 10 c9 c3 b8 00 00 00 00 cd 80 c3 |................| +0001a330 b8 01 00 00 00 cd 80 c3 b8 02 00 00 00 cd 80 c3 |................| +0001a340 b8 03 00 00 00 cd 80 c3 b8 04 00 00 00 cd 80 c3 |................| +0001a350 b8 05 00 00 00 cd 80 c3 b8 06 00 00 00 cd 80 c3 |................| +0001a360 b8 07 00 00 00 cd 80 c3 b8 08 00 00 00 cd 80 c3 |................| +0001a370 b8 09 00 00 00 cd 80 c3 b8 0a 00 00 00 cd 80 c3 |................| +0001a380 b8 0b 00 00 00 cd 80 c3 b8 0c 00 00 00 cd 80 c3 |................| +0001a390 b8 ad 0b 00 00 cd 80 c3 50 e8 8a ff ff ff e8 89 |........P.......| +0001a3a0 fc ff ff 83 ec 0c 50 e8 7c ff ff ff eb fe 55 89 |......P.|.....U.| +0001a3b0 e5 83 ec 38 8d 45 0c 83 c0 04 89 45 f4 e9 3f 02 |...8.E.....E..?.| +0001a3c0 00 00 80 7d f3 25 0f 85 26 02 00 00 c7 45 ec 00 |...}.%..&....E..| +0001a3d0 00 00 00 c7 45 e4 20 00 00 00 c7 45 e8 00 00 00 |....E. ....E....| +0001a3e0 00 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 |..E..P..U.....E.| +0001a3f0 80 7d f3 2d 75 16 c7 45 ec 01 00 00 00 8b 45 0c |.}.-u..E......E.| +0001a400 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 7d f3 30 |.P..U.....E..}.0| +0001a410 75 40 c7 45 e4 30 00 00 00 8b 45 0c 8d 50 01 89 |u@.E.0....E..P..| +0001a420 55 0c 0f b6 00 88 45 f3 eb 28 8b 55 e8 89 d0 c1 |U.....E..(.U....| +0001a430 e0 02 01 d0 01 c0 89 45 e8 0f be 45 f3 83 e8 30 |.......E...E...0| +0001a440 01 45 e8 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 |.E..E..P..U.....| +0001a450 45 f3 80 7d f3 2f 7e 06 80 7d f3 39 7e cc 0f be |E..}./~..}.9~...| +0001a460 45 f3 83 e8 63 83 f8 15 0f 87 93 01 00 00 8b 04 |E...c...........| +0001a470 85 0c 1a 00 00 ff e0 8b 45 f4 8d 50 04 89 55 f4 |........E..P..U.| +0001a480 8b 00 88 45 f3 0f b6 45 f3 88 45 d0 c6 45 d1 00 |...E...E..E..E..| +0001a490 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 6a 01 8d 45 |....u..u..u.j..E| +0001a4a0 d0 50 ff 75 08 e8 89 04 00 00 83 c4 20 89 45 08 |.P.u........ .E.| +0001a4b0 e9 4c 01 00 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 |.L....E..P..U...| +0001a4c0 83 ec 08 50 8d 45 d0 50 e8 ea 01 00 00 83 c4 10 |...P.E.P........| +0001a4d0 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff |.E.....u..u..u..| +0001a4e0 75 e0 8d 45 d0 50 ff 75 08 e8 45 04 00 00 83 c4 |u..E.P.u..E.....| +0001a4f0 20 89 45 08 e9 08 01 00 00 8b 45 f4 8d 50 04 89 | .E.......E..P..| +0001a500 55 f4 8b 00 89 45 dc 83 ec 08 ff 75 e4 ff 75 ec |U....E.....u..u.| +0001a510 ff 75 e8 6a ff ff 75 dc ff 75 08 e8 13 04 00 00 |.u.j..u..u......| +0001a520 83 c4 20 89 45 08 e9 d6 00 00 00 8b 45 f4 8d 50 |.. .E.......E..P| +0001a530 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 44 |..U......P.E.P.D| +0001a540 02 00 00 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff |.......E.....u..| +0001a550 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 |u..u..u..E.P.u..| +0001a560 cf 03 00 00 83 c4 20 89 45 08 e9 92 00 00 00 8b |...... .E.......| +0001a570 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 |E..P..U......P.E| +0001a580 d0 50 e8 8a 02 00 00 83 c4 10 89 45 e0 83 ec 08 |.P.........E....| +0001a590 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 |.u..u..u..u..E.P| +0001a5a0 ff 75 08 e8 8b 03 00 00 83 c4 20 89 45 08 eb 51 |.u........ .E..Q| +0001a5b0 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d |.E..P..U......P.| +0001a5c0 45 d0 50 e8 d3 02 00 00 83 c4 10 89 45 e0 83 ec |E.P.........E...| +0001a5d0 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 |..u..u..u..u..E.| +0001a5e0 50 ff 75 08 e8 4a 03 00 00 83 c4 20 89 45 08 90 |P.u..J..... .E..| +0001a5f0 eb 0f 8b 45 08 8d 50 01 89 55 08 0f b6 55 f3 88 |...E..P..U...U..| +0001a600 10 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 |..E..P..U.....E.| +0001a610 80 7d f3 00 0f 85 a8 fd ff ff 8b 45 08 c6 00 00 |.}.........E....| +0001a620 90 c9 c3 55 89 e5 53 83 ec 14 8b 45 08 8b 4d 0c |...U..S....E..M.| +0001a630 bb 00 00 00 00 c6 45 eb 39 c7 45 f8 01 00 00 00 |......E.9.E.....| +0001a640 0f b6 10 80 fa 2d 75 0a c7 45 f8 ff ff ff ff 83 |.....-u..E......| +0001a650 c0 01 83 f9 0a 74 2b 89 ca 83 c2 2f 88 55 eb eb |.....t+..../.U..| +0001a660 21 0f b6 10 80 fa 2f 7e 20 0f b6 10 38 55 eb 7c |!...../~ ...8U.|| +0001a670 18 0f af d9 0f b6 10 0f be d2 01 da 8d 5a d0 83 |.............Z..| +0001a680 c0 01 0f b6 10 84 d2 75 d8 89 d8 0f af 45 f8 83 |.......u.....E..| +0001a690 c4 14 5b 5d c3 55 89 e5 53 8b 55 08 bb 00 00 00 |..[].U..S.U.....| +0001a6a0 00 eb 03 83 c3 01 89 d0 8d 50 01 0f b6 00 84 c0 |.........P......| +0001a6b0 75 f1 89 d8 5b 5d c3 55 89 e5 83 ec 18 8b 45 08 |u...[].U......E.| +0001a6c0 89 45 f4 83 7d 0c 00 79 0f 8b 45 f4 8d 50 01 89 |.E..}..y..E..P..| +0001a6d0 55 f4 c6 00 2d f7 5d 0c 83 ec 08 ff 75 0c ff 75 |U...-.].....u..u| +0001a6e0 f4 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 c6 |..........E..E..| +0001a6f0 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 |...U..E.).....U.| +0001a700 e5 83 ec 18 8b 4d 0c ba 67 66 66 66 89 c8 f7 ea |.....M..gfff....| +0001a710 c1 fa 02 89 c8 c1 f8 1f 29 c2 89 d0 89 45 f4 83 |........)....E..| +0001a720 7d f4 00 79 0e c7 45 f4 cc cc cc 0c c7 45 0c 08 |}..y..E......E..| +0001a730 00 00 00 83 7d f4 00 74 14 83 ec 08 ff 75 f4 ff |....}..t.....u..| +0001a740 75 08 e8 b7 ff ff ff 83 c4 10 89 45 08 8b 4d 0c |u..........E..M.| +0001a750 ba 67 66 66 66 89 c8 f7 ea c1 fa 02 89 c8 c1 f8 |.gfff...........| +0001a760 1f 29 c2 89 d0 c1 e0 02 01 d0 01 c0 29 c1 89 ca |.)..........)...| +0001a770 89 d0 8d 48 30 8b 45 08 8d 50 01 89 55 08 89 ca |...H0.E..P..U...| +0001a780 88 10 8b 45 08 c9 c3 55 89 e5 83 ec 20 c7 45 e3 |...E...U.... .E.| +0001a790 30 31 32 33 c7 45 e7 34 35 36 37 c7 45 eb 38 39 |0123.E.4567.E.89| +0001a7a0 41 42 c7 45 ef 43 44 45 46 c6 45 f3 00 c7 45 fc |AB.E.CDEF.E...E.| +0001a7b0 00 00 00 00 c7 45 f8 00 00 00 00 eb 43 8b 45 0c |.....E......C.E.| +0001a7c0 25 00 00 00 f0 89 45 f4 83 7d fc 00 75 0c 83 7d |%.....E..}..u..}| +0001a7d0 f4 00 75 06 83 7d f8 07 75 1e 83 45 fc 01 c1 6d |..u..}..u..E...m| +0001a7e0 f4 1c 8b 45 08 8d 50 01 89 55 08 8d 4d e3 8b 55 |...E..P..U..M..U| +0001a7f0 f4 01 ca 0f b6 12 88 10 c1 65 0c 04 83 45 f8 01 |.........e...E..| +0001a800 83 7d f8 07 7e b7 8b 45 08 c6 00 00 8b 45 fc c9 |.}..~..E.....E..| +0001a810 c3 55 89 e5 83 ec 10 c7 45 f8 00 00 00 00 8b 45 |.U......E......E| +0001a820 08 89 45 f4 8b 45 0c 25 00 00 00 c0 89 45 f0 c1 |..E..E.%.....E..| +0001a830 6d f0 1e c7 45 fc 00 00 00 00 eb 47 83 7d fc 0a |m...E......G.}..| +0001a840 74 0c 83 7d f0 00 75 06 83 7d f8 00 74 1e c7 45 |t..}..u..}..t..E| +0001a850 f8 01 00 00 00 83 65 f0 07 8b 45 f0 8d 48 30 8b |......e...E..H0.| +0001a860 45 f4 8d 50 01 89 55 f4 89 ca 88 10 c1 65 0c 03 |E..P..U......e..| +0001a870 8b 45 0c 25 00 00 00 e0 89 45 f0 c1 6d f0 1d 83 |.E.%.....E..m...| +0001a880 45 fc 01 83 7d fc 0a 7e b3 8b 45 f4 c6 00 00 8b |E...}..~..E.....| +0001a890 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 83 ec |U..E.).....U....| +0001a8a0 18 8b 45 08 89 45 f4 83 ec 08 ff 75 0c ff 75 f4 |..E..E.....u..u.| +0001a8b0 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 f4 c6 00 |.........E..E...| +0001a8c0 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 e5 |..U..E.).....U..| +0001a8d0 83 ec 18 8b 45 0c ba cd cc cc cc f7 e2 89 d0 c1 |....E...........| +0001a8e0 e8 03 89 45 f4 83 7d f4 00 74 15 8b 45 f4 83 ec |...E..}..t..E...| +0001a8f0 08 50 ff 75 08 e8 04 fe ff ff 83 c4 10 89 45 08 |.P.u..........E.| +0001a900 8b 4d 0c ba cd cc cc cc 89 c8 f7 e2 c1 ea 03 89 |.M..............| +0001a910 d0 c1 e0 02 01 d0 01 c0 29 c1 89 ca 89 d0 8d 48 |........)......H| +0001a920 30 8b 45 08 8d 50 01 89 55 08 89 ca 88 10 8b 45 |0.E..P..U......E| +0001a930 08 c9 c3 55 89 e5 83 ec 18 83 7d 10 00 79 11 83 |...U......}..y..| +0001a940 ec 0c ff 75 0c e8 4b fd ff ff 83 c4 10 89 45 10 |...u..K.......E.| +0001a950 8b 45 14 2b 45 10 89 45 f0 83 7d f0 00 7e 1d 83 |.E.+E..E..}..~..| +0001a960 7d 18 00 75 17 83 ec 04 ff 75 1c ff 75 f0 ff 75 |}..u.....u..u..u| +0001a970 08 e8 5a 00 00 00 83 c4 10 89 45 08 c7 45 f4 00 |..Z.......E..E..| +0001a980 00 00 00 eb 1b 8b 55 f4 8b 45 0c 8d 0c 02 8b 45 |......U..E.....E| +0001a990 08 8d 50 01 89 55 08 0f b6 11 88 10 83 45 f4 01 |..P..U.......E..| +0001a9a0 8b 45 f4 3b 45 10 7c dd 83 7d f0 00 7e 1d 83 7d |.E.;E.|..}..~..}| +0001a9b0 18 00 74 17 83 ec 04 ff 75 1c ff 75 f0 ff 75 08 |..t.....u..u..u.| +0001a9c0 e8 0b 00 00 00 83 c4 10 89 45 08 8b 45 08 c9 c3 |.........E..E...| +0001a9d0 55 89 e5 eb 12 8b 45 08 8d 50 01 89 55 08 8b 55 |U.....E..P..U..U| +0001a9e0 10 88 10 83 6d 0c 01 83 7d 0c 00 7f e8 8b 45 08 |....m...}.....E.| +0001a9f0 5d c3 00 00 3f 3a 20 61 72 67 63 20 25 64 2c 20 |]...?: argc %d, | +0001aa00 61 72 67 73 3a 20 00 28 6e 75 6c 6c 29 00 20 25 |args: .(null). %| +0001aa10 73 00 0a 00 20 25 63 5b 25 64 5d 00 43 68 69 6c |s... %c[%d].Chil| +0001aa20 64 20 25 64 20 65 78 65 63 28 29 20 23 25 75 20 |d %d exec() #%u | +0001aa30 66 61 69 6c 65 64 0a 00 4b 14 00 00 89 14 00 00 |failed..K.......| +0001aa40 d5 15 00 00 d5 15 00 00 d5 15 00 00 d5 15 00 00 |................| +* +0001aa60 d5 15 00 00 d5 15 00 00 43 15 00 00 d5 15 00 00 |........C.......| +0001aa70 d5 15 00 00 d5 15 00 00 cd 14 00 00 d5 15 00 00 |................| +0001aa80 84 15 00 00 d5 15 00 00 d5 15 00 00 ff 14 00 00 |................| +0001aa90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +0001b040 00 10 00 00 00 00 00 00 03 00 01 00 00 00 00 00 |................| +0001b050 c8 19 00 00 00 00 00 00 03 00 02 00 00 00 00 00 |................| +0001b060 00 20 00 00 00 00 00 00 03 00 03 00 00 00 00 00 |. ..............| +0001b070 00 20 00 00 00 00 00 00 03 00 04 00 01 00 00 00 |. ..............| +0001b080 00 00 00 00 00 00 00 00 04 00 f1 ff 09 00 00 00 |................| +0001b090 00 00 00 00 00 00 00 00 04 00 f1 ff 11 00 00 00 |................| +0001b0a0 00 00 00 00 00 00 00 00 04 00 f1 ff 1a 00 00 00 |................| +0001b0b0 00 00 00 00 00 00 00 00 04 00 f1 ff 24 00 00 00 |............$...| +0001b0c0 00 00 00 00 00 00 00 00 04 00 f1 ff 2d 00 00 00 |............-...| +0001b0d0 00 00 00 00 00 00 00 00 04 00 f1 ff 36 00 00 00 |............6...| +0001b0e0 00 00 00 00 00 00 00 00 04 00 f1 ff 40 00 00 00 |............@...| +0001b0f0 00 00 00 00 00 00 00 00 04 00 f1 ff 49 00 00 00 |............I...| +0001b100 00 00 00 00 00 00 00 00 04 00 f1 ff 52 00 00 00 |............R...| +0001b110 00 00 00 00 00 00 00 00 04 00 f1 ff 5b 00 00 00 |............[...| +0001b120 00 00 00 00 00 00 00 00 04 00 f1 ff 65 00 00 00 |............e...| +0001b130 00 00 00 00 00 00 00 00 04 00 f1 ff 6e 00 00 00 |............n...| +0001b140 00 00 00 00 00 00 00 00 04 00 f1 ff 74 00 00 00 |............t...| +0001b150 93 12 00 00 21 00 00 00 12 00 01 00 7d 00 00 00 |....!.......}...| +0001b160 04 13 00 00 00 00 00 00 10 00 01 00 85 00 00 00 |................| +0001b170 78 12 00 00 1b 00 00 00 12 00 01 00 8c 00 00 00 |x...............| +0001b180 f7 15 00 00 72 00 00 00 12 00 01 00 94 00 00 00 |....r...........| +0001b190 6f 18 00 00 32 00 00 00 12 00 01 00 9b 00 00 00 |o...2...........| +0001b1a0 2c 13 00 00 00 00 00 00 10 00 01 00 a2 00 00 00 |,...............| +0001b1b0 5c 13 00 00 00 00 00 00 10 00 01 00 a8 00 00 00 |\...............| +0001b1c0 e1 12 00 00 1b 00 00 00 12 00 01 00 af 00 00 00 |................| +0001b1d0 a4 19 00 00 22 00 00 00 12 00 01 00 b3 00 00 00 |...."...........| +0001b1e0 b5 11 00 00 75 00 00 00 12 00 01 00 b9 00 00 00 |....u...........| +0001b1f0 82 13 00 00 75 02 00 00 12 00 01 00 c0 00 00 00 |....u...........| +0001b200 5b 17 00 00 8a 00 00 00 12 00 01 00 c7 00 00 00 |[...............| +0001b210 a1 18 00 00 66 00 00 00 12 00 01 00 86 00 00 00 |....f...........| +0001b220 24 13 00 00 00 00 00 00 10 00 01 00 cf 00 00 00 |$...............| +0001b230 54 13 00 00 00 00 00 00 10 00 01 00 d4 00 00 00 |T...............| +0001b240 4b 12 00 00 2d 00 00 00 12 00 01 00 dc 00 00 00 |K...-...........| +0001b250 14 13 00 00 00 00 00 00 10 00 01 00 e1 00 00 00 |................| +0001b260 9d 11 00 00 18 00 00 00 12 00 01 00 e6 00 00 00 |................| +0001b270 b4 12 00 00 2d 00 00 00 12 00 01 00 ee 00 00 00 |....-...........| +0001b280 72 13 00 00 00 00 00 00 10 00 01 00 f5 00 00 00 |r...............| +0001b290 1c 13 00 00 00 00 00 00 10 00 01 00 fa 00 00 00 |................| +0001b2a0 44 13 00 00 00 00 00 00 10 00 01 00 02 01 00 00 |D...............| +0001b2b0 d2 16 00 00 89 00 00 00 12 00 01 00 0a 01 00 00 |................| +0001b2c0 0c 13 00 00 00 00 00 00 10 00 01 00 0f 01 00 00 |................| +0001b2d0 00 10 00 00 9d 01 00 00 12 00 01 00 14 01 00 00 |................| +0001b2e0 34 13 00 00 00 00 00 00 10 00 01 00 1c 01 00 00 |4...............| +0001b2f0 07 19 00 00 9d 00 00 00 12 00 01 00 23 01 00 00 |............#...| +0001b300 4c 13 00 00 00 00 00 00 10 00 01 00 2b 01 00 00 |L...........+...| +0001b310 e5 17 00 00 8a 00 00 00 12 00 01 00 32 01 00 00 |............2...| +0001b320 2a 12 00 00 21 00 00 00 12 00 01 00 3b 01 00 00 |*...!.......;...| +0001b330 3c 13 00 00 00 00 00 00 10 00 01 00 43 01 00 00 |<...........C...| +0001b340 8b 16 00 00 47 00 00 00 12 00 01 00 5c 01 00 00 |....G.......\...| +0001b350 fc 12 00 00 00 00 00 00 10 00 01 00 4a 01 00 00 |............J...| +0001b360 69 16 00 00 22 00 00 00 12 00 01 00 51 01 00 00 |i...".......Q...| +0001b370 64 13 00 00 00 00 00 00 10 00 01 00 57 01 00 00 |d...........W...| +0001b380 6c 13 00 00 00 00 00 00 10 00 01 00 00 70 72 6f |l............pro| +0001b390 67 59 2e 63 00 75 6c 69 62 63 2e 63 00 73 70 72 |gY.c.ulibc.c.spr| +0001b3a0 69 6e 74 2e 63 00 73 74 72 32 69 6e 74 2e 63 00 |int.c.str2int.c.| +0001b3b0 73 74 72 6c 65 6e 2e 63 00 63 76 74 64 65 63 2e |strlen.c.cvtdec.| +0001b3c0 63 00 63 76 74 64 65 63 30 2e 63 00 63 76 74 68 |c.cvtdec0.c.cvth| +0001b3d0 65 78 2e 63 00 63 76 74 6f 63 74 2e 63 00 63 76 |ex.c.cvtoct.c.cv| +0001b3e0 74 75 6e 73 2e 63 00 63 76 74 75 6e 73 30 2e 63 |tuns.c.cvtuns0.c| +0001b3f0 00 70 61 64 73 74 72 2e 63 00 70 61 64 2e 63 00 |.padstr.c.pad.c.| +0001b400 73 77 72 69 74 65 63 68 00 77 61 69 74 70 69 64 |swritech.waitpid| +0001b410 00 63 77 72 69 74 65 00 73 74 72 32 69 6e 74 00 |.cwrite.str2int.| +0001b420 63 76 74 75 6e 73 00 67 65 74 70 69 64 00 73 6c |cvtuns.getpid.sl| +0001b430 65 65 70 00 73 77 72 69 74 65 00 70 61 64 00 73 |eep.swrite.pad.s| +0001b440 70 61 77 6e 00 73 70 72 69 6e 74 00 63 76 74 68 |pawn.sprint.cvth| +0001b450 65 78 00 63 76 74 75 6e 73 30 00 6b 69 6c 6c 00 |ex.cvtuns0.kill.| +0001b460 63 77 72 69 74 65 73 00 65 78 65 63 00 77 61 69 |cwrites.exec.wai| +0001b470 74 00 73 77 72 69 74 65 73 00 5f 73 74 61 72 74 |t.swrites._start| +0001b480 00 72 65 61 64 00 67 65 74 70 72 69 6f 00 63 76 |.read.getprio.cv| +0001b490 74 64 65 63 30 00 66 6f 72 6b 00 6d 61 69 6e 00 |tdec0.fork.main.| +0001b4a0 67 65 74 70 70 69 64 00 70 61 64 73 74 72 00 73 |getppid.padstr.s| +0001b4b0 65 74 70 72 69 6f 00 63 76 74 6f 63 74 00 63 77 |etprio.cvtoct.cw| +0001b4c0 72 69 74 65 63 68 00 67 65 74 74 69 6d 65 00 63 |ritech.gettime.c| +0001b4d0 76 74 64 65 63 00 73 74 72 6c 65 6e 00 62 6f 67 |vtdec.strlen.bog| +0001b4e0 75 73 00 66 61 6b 65 5f 65 78 69 74 00 00 2e 73 |us.fake_exit...s| +0001b4f0 79 6d 74 61 62 00 2e 73 74 72 74 61 62 00 2e 73 |ymtab..strtab..s| +0001b500 68 73 74 72 74 61 62 00 2e 74 65 78 74 00 2e 72 |hstrtab..text..r| +0001b510 6f 64 61 74 61 00 2e 64 61 74 61 00 2e 62 73 73 |odata..data..bss| +0001b520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +0001b540 00 00 00 00 00 00 00 00 00 00 00 00 1b 00 00 00 |................| +0001b550 01 00 00 00 06 00 00 00 00 10 00 00 74 00 00 00 |............t...| +0001b560 c6 09 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +0001b570 00 00 00 00 21 00 00 00 01 00 00 00 02 00 00 00 |....!...........| +0001b580 c8 19 00 00 3c 0a 00 00 9c 00 00 00 00 00 00 00 |....<...........| +0001b590 00 00 00 00 04 00 00 00 00 00 00 00 29 00 00 00 |............)...| +0001b5a0 01 00 00 00 03 00 00 00 00 20 00 00 74 10 00 00 |......... ..t...| +0001b5b0 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +0001b5c0 00 00 00 00 2f 00 00 00 08 00 00 00 03 00 00 00 |..../...........| +0001b5d0 00 20 00 00 74 10 00 00 00 00 00 00 00 00 00 00 |. ..t...........| +0001b5e0 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 |................| +0001b5f0 02 00 00 00 00 00 00 00 00 00 00 00 74 10 00 00 |............t...| +0001b600 60 03 00 00 06 00 00 00 12 00 00 00 04 00 00 00 |`...............| +0001b610 10 00 00 00 09 00 00 00 03 00 00 00 00 00 00 00 |................| +0001b620 00 00 00 00 d4 13 00 00 61 01 00 00 00 00 00 00 |........a.......| +0001b630 00 00 00 00 01 00 00 00 00 00 00 00 11 00 00 00 |................| +0001b640 03 00 00 00 00 00 00 00 00 00 00 00 35 15 00 00 |............5...| +0001b650 34 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |4...............| +0001b660 00 00 00 00 00 00 00 00 7f 45 4c 46 01 01 01 00 |.........ELF....| +0001b670 00 00 00 00 00 00 00 00 02 00 03 00 01 00 00 00 |................| +0001b680 95 13 00 00 34 00 00 00 6c 15 00 00 00 00 00 00 |....4...l.......| +0001b690 34 00 20 00 02 00 28 00 08 00 07 00 01 00 00 00 |4. ...(.........| +0001b6a0 74 00 00 00 00 10 00 00 00 10 00 00 00 10 00 00 |t...............| +0001b6b0 00 10 00 00 07 00 00 00 04 00 00 00 51 e5 74 64 |............Q.td| +0001b6c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +0001b6d0 00 00 00 00 07 00 00 00 10 00 00 00 8d 4c 24 04 |.............L$.| +0001b6e0 83 e4 f0 ff 71 fc 55 89 e5 53 51 81 ec a0 00 00 |....q.U..SQ.....| +0001b6f0 00 89 cb c7 45 f4 0a 00 00 00 c6 45 f3 7a 8b 03 |....E......E.z..| +0001b700 83 f8 02 74 1e 83 f8 03 75 2c 8b 43 04 83 c0 08 |...t....u,.C....| +0001b710 8b 00 83 ec 08 6a 0a 50 e8 d9 05 00 00 83 c4 10 |.....j.P........| +0001b720 89 45 f4 8b 43 04 83 c0 04 8b 00 0f b6 00 88 45 |.E..C..........E| +0001b730 f3 e9 a4 00 00 00 83 ec 04 ff 33 68 ec 19 00 00 |..........3h....| +0001b740 8d 85 60 ff ff ff 50 e8 35 03 00 00 83 c4 10 83 |..`...P.5.......| +0001b750 ec 0c 8d 85 60 ff ff ff 50 e8 ec 01 00 00 83 c4 |....`...P.......| +0001b760 10 c7 45 ec 00 00 00 00 eb 59 8b 03 8d 14 85 00 |..E......Y......| +0001b770 00 00 00 8b 43 04 01 d0 8b 00 85 c0 74 12 8b 03 |....C.......t...| +0001b780 8d 14 85 00 00 00 00 8b 43 04 01 d0 8b 00 eb 05 |........C.......| +0001b790 b8 ff 19 00 00 83 ec 04 50 68 06 1a 00 00 8d 85 |........Ph......| +0001b7a0 60 ff ff ff 50 e8 d7 02 00 00 83 c4 10 83 ec 0c |`...P...........| +0001b7b0 8d 85 60 ff ff ff 50 e8 8e 01 00 00 83 c4 10 83 |..`...P.........| +0001b7c0 45 ec 01 8b 45 ec 3b 03 7e a0 83 ec 0c 68 0a 1a |E...E.;.~....h..| +0001b7d0 00 00 e8 73 01 00 00 83 c4 10 e8 4c 02 00 00 89 |...s.......L....| +0001b7e0 45 e0 0f be 45 f3 ff 75 e0 50 68 0c 1a 00 00 8d |E...E..u.Ph.....| +0001b7f0 85 60 ff ff ff 50 e8 86 02 00 00 83 c4 10 83 ec |.`...P..........| +0001b800 0c 8d 85 60 ff ff ff 50 e8 a6 01 00 00 83 c4 10 |...`...P........| +0001b810 c7 45 e8 00 00 00 00 eb 5f 0f be 45 f3 ff 75 e8 |.E......_..E..u.| +0001b820 50 68 0c 1a 00 00 8d 85 60 ff ff ff 50 e8 4f 02 |Ph......`...P.O.| +0001b830 00 00 83 c4 10 83 ec 0c 8d 85 60 ff ff ff 50 e8 |..........`...P.| +0001b840 6f 01 00 00 83 c4 10 c7 45 e4 00 00 00 00 eb 04 |o.......E.......| +0001b850 83 45 e4 01 81 7d e4 9f 25 26 00 7e f3 8b 45 e8 |.E...}..%&.~..E.| +0001b860 83 e0 01 85 c0 74 0d 83 ec 0c 6a 00 e8 ea 01 00 |.....t....j.....| +0001b870 00 83 c4 10 83 45 e8 01 8b 45 e8 3b 45 f4 7c 99 |.....E...E.;E.|.| +0001b880 83 ec 0c 6a 00 e8 71 01 00 00 83 c4 10 b8 2a 00 |...j..q.......*.| +0001b890 00 00 8d 65 f8 59 5b 5d 8d 61 fc c3 55 89 e5 83 |...e.Y[].a..U...| +0001b8a0 ec 08 83 ec 08 ff 75 08 6a 00 e8 54 01 00 00 83 |......u.j..T....| +0001b8b0 c4 10 c9 c3 55 89 e5 81 ec 18 01 00 00 e8 49 01 |....U.........I.| +0001b8c0 00 00 89 45 f4 83 7d f4 00 74 05 8b 45 f4 eb 57 |...E..}..t..E..W| +0001b8d0 e8 56 01 00 00 89 45 f4 83 ec 08 ff 75 0c ff 75 |.V....E.....u..u| +0001b8e0 08 e8 2d 01 00 00 83 c4 10 ff 75 08 ff 75 f4 68 |..-.......u..u.h| +0001b8f0 14 1a 00 00 8d 85 f4 fe ff ff 50 e8 81 01 00 00 |..........P.....| +0001b900 83 c4 10 83 ec 0c 8d 85 f4 fe ff ff 50 e8 38 00 |............P.8.| +0001b910 00 00 83 c4 10 83 ec 0c 6a ff e8 dc 00 00 00 83 |........j.......| +0001b920 c4 10 b8 00 00 00 00 c9 c3 55 89 e5 83 ec 18 8b |.........U......| +0001b930 45 08 88 45 f4 83 ec 04 6a 01 8d 45 f4 50 6a 00 |E..E....j..E.Pj.| +0001b940 e8 de 00 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 18 |..........U.....| +0001b950 83 ec 0c ff 75 08 e8 0d 04 00 00 83 c4 10 89 45 |....u..........E| +0001b960 f4 8b 45 f4 83 ec 04 50 ff 75 08 6a 00 e8 b1 00 |..E....P.u.j....| +0001b970 00 00 83 c4 10 c9 c3 55 89 e5 83 ec 08 83 ec 04 |.......U........| +0001b980 ff 75 0c ff 75 08 6a 00 e8 96 00 00 00 83 c4 10 |.u..u.j.........| +0001b990 c9 c3 55 89 e5 83 ec 18 8b 45 08 88 45 f4 83 ec |..U......E..E...| +0001b9a0 04 6a 01 8d 45 f4 50 6a 01 e8 75 00 00 00 83 c4 |.j..E.Pj..u.....| +0001b9b0 10 c9 c3 55 89 e5 83 ec 18 83 ec 0c ff 75 08 e8 |...U.........u..| +0001b9c0 a4 03 00 00 83 c4 10 89 45 f4 8b 45 f4 83 ec 04 |........E..E....| +0001b9d0 50 ff 75 08 6a 01 e8 48 00 00 00 83 c4 10 c9 c3 |P.u.j..H........| +0001b9e0 55 89 e5 83 ec 08 83 ec 04 ff 75 0c ff 75 08 6a |U.........u..u.j| +0001b9f0 01 e8 2d 00 00 00 83 c4 10 c9 c3 b8 00 00 00 00 |..-.............| +0001ba00 cd 80 c3 b8 01 00 00 00 cd 80 c3 b8 02 00 00 00 |................| +0001ba10 cd 80 c3 b8 03 00 00 00 cd 80 c3 b8 04 00 00 00 |................| +0001ba20 cd 80 c3 b8 05 00 00 00 cd 80 c3 b8 06 00 00 00 |................| +0001ba30 cd 80 c3 b8 07 00 00 00 cd 80 c3 b8 08 00 00 00 |................| +0001ba40 cd 80 c3 b8 09 00 00 00 cd 80 c3 b8 0a 00 00 00 |................| +0001ba50 cd 80 c3 b8 0b 00 00 00 cd 80 c3 b8 0c 00 00 00 |................| +0001ba60 cd 80 c3 b8 ad 0b 00 00 cd 80 c3 50 e8 8a ff ff |...........P....| +0001ba70 ff e8 66 fc ff ff 83 ec 0c 50 e8 7c ff ff ff eb |..f......P.|....| +0001ba80 fe 55 89 e5 83 ec 38 8d 45 0c 83 c0 04 89 45 f4 |.U....8.E.....E.| +0001ba90 e9 3f 02 00 00 80 7d f3 25 0f 85 26 02 00 00 c7 |.?....}.%..&....| +0001baa0 45 ec 00 00 00 00 c7 45 e4 20 00 00 00 c7 45 e8 |E......E. ....E.| +0001bab0 00 00 00 00 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 |.....E..P..U....| +0001bac0 88 45 f3 80 7d f3 2d 75 16 c7 45 ec 01 00 00 00 |.E..}.-u..E.....| +0001bad0 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 88 45 f3 80 |.E..P..U.....E..| +0001bae0 7d f3 30 75 40 c7 45 e4 30 00 00 00 8b 45 0c 8d |}.0u@.E.0....E..| +0001baf0 50 01 89 55 0c 0f b6 00 88 45 f3 eb 28 8b 55 e8 |P..U.....E..(.U.| +0001bb00 89 d0 c1 e0 02 01 d0 01 c0 89 45 e8 0f be 45 f3 |..........E...E.| +0001bb10 83 e8 30 01 45 e8 8b 45 0c 8d 50 01 89 55 0c 0f |..0.E..E..P..U..| +0001bb20 b6 00 88 45 f3 80 7d f3 2f 7e 06 80 7d f3 39 7e |...E..}./~..}.9~| +0001bb30 cc 0f be 45 f3 83 e8 63 83 f8 15 0f 87 93 01 00 |...E...c........| +0001bb40 00 8b 04 85 30 1a 00 00 ff e0 8b 45 f4 8d 50 04 |....0......E..P.| +0001bb50 89 55 f4 8b 00 88 45 f3 0f b6 45 f3 88 45 d0 c6 |.U....E...E..E..| +0001bb60 45 d1 00 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 6a |E......u..u..u.j| +0001bb70 01 8d 45 d0 50 ff 75 08 e8 89 04 00 00 83 c4 20 |..E.P.u........ | +0001bb80 89 45 08 e9 4c 01 00 00 8b 45 f4 8d 50 04 89 55 |.E..L....E..P..U| +0001bb90 f4 8b 00 83 ec 08 50 8d 45 d0 50 e8 ea 01 00 00 |......P.E.P.....| +0001bba0 83 c4 10 89 45 e0 83 ec 08 ff 75 e4 ff 75 ec ff |....E.....u..u..| +0001bbb0 75 e8 ff 75 e0 8d 45 d0 50 ff 75 08 e8 45 04 00 |u..u..E.P.u..E..| +0001bbc0 00 83 c4 20 89 45 08 e9 08 01 00 00 8b 45 f4 8d |... .E.......E..| +0001bbd0 50 04 89 55 f4 8b 00 89 45 dc 83 ec 08 ff 75 e4 |P..U....E.....u.| +0001bbe0 ff 75 ec ff 75 e8 6a ff ff 75 dc ff 75 08 e8 13 |.u..u.j..u..u...| +0001bbf0 04 00 00 83 c4 20 89 45 08 e9 d6 00 00 00 8b 45 |..... .E.......E| +0001bc00 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 50 8d 45 d0 |..P..U......P.E.| +0001bc10 50 e8 44 02 00 00 83 c4 10 89 45 e0 83 ec 08 ff |P.D.......E.....| +0001bc20 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d 45 d0 50 ff |u..u..u..u..E.P.| +0001bc30 75 08 e8 cf 03 00 00 83 c4 20 89 45 08 e9 92 00 |u........ .E....| +0001bc40 00 00 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec 08 |...E..P..U......| +0001bc50 50 8d 45 d0 50 e8 8a 02 00 00 83 c4 10 89 45 e0 |P.E.P.........E.| +0001bc60 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 8d |....u..u..u..u..| +0001bc70 45 d0 50 ff 75 08 e8 8b 03 00 00 83 c4 20 89 45 |E.P.u........ .E| +0001bc80 08 eb 51 8b 45 f4 8d 50 04 89 55 f4 8b 00 83 ec |..Q.E..P..U.....| +0001bc90 08 50 8d 45 d0 50 e8 d3 02 00 00 83 c4 10 89 45 |.P.E.P.........E| +0001bca0 e0 83 ec 08 ff 75 e4 ff 75 ec ff 75 e8 ff 75 e0 |.....u..u..u..u.| +0001bcb0 8d 45 d0 50 ff 75 08 e8 4a 03 00 00 83 c4 20 89 |.E.P.u..J..... .| +0001bcc0 45 08 90 eb 0f 8b 45 08 8d 50 01 89 55 08 0f b6 |E.....E..P..U...| +0001bcd0 55 f3 88 10 8b 45 0c 8d 50 01 89 55 0c 0f b6 00 |U....E..P..U....| +0001bce0 88 45 f3 80 7d f3 00 0f 85 a8 fd ff ff 8b 45 08 |.E..}.........E.| +0001bcf0 c6 00 00 90 c9 c3 55 89 e5 53 83 ec 14 8b 45 08 |......U..S....E.| +0001bd00 8b 4d 0c bb 00 00 00 00 c6 45 eb 39 c7 45 f8 01 |.M.......E.9.E..| +0001bd10 00 00 00 0f b6 10 80 fa 2d 75 0a c7 45 f8 ff ff |........-u..E...| +0001bd20 ff ff 83 c0 01 83 f9 0a 74 2b 89 ca 83 c2 2f 88 |........t+..../.| +0001bd30 55 eb eb 21 0f b6 10 80 fa 2f 7e 20 0f b6 10 38 |U..!...../~ ...8| +0001bd40 55 eb 7c 18 0f af d9 0f b6 10 0f be d2 01 da 8d |U.|.............| +0001bd50 5a d0 83 c0 01 0f b6 10 84 d2 75 d8 89 d8 0f af |Z.........u.....| +0001bd60 45 f8 83 c4 14 5b 5d c3 55 89 e5 53 8b 55 08 bb |E....[].U..S.U..| +0001bd70 00 00 00 00 eb 03 83 c3 01 89 d0 8d 50 01 0f b6 |............P...| +0001bd80 00 84 c0 75 f1 89 d8 5b 5d c3 55 89 e5 83 ec 18 |...u...[].U.....| +0001bd90 8b 45 08 89 45 f4 83 7d 0c 00 79 0f 8b 45 f4 8d |.E..E..}..y..E..| +0001bda0 50 01 89 55 f4 c6 00 2d f7 5d 0c 83 ec 08 ff 75 |P..U...-.].....u| +0001bdb0 0c ff 75 f4 e8 18 00 00 00 83 c4 10 89 45 f4 8b |..u..........E..| +0001bdc0 45 f4 c6 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 |E.....U..E.)....| +0001bdd0 c3 55 89 e5 83 ec 18 8b 4d 0c ba 67 66 66 66 89 |.U......M..gfff.| +0001bde0 c8 f7 ea c1 fa 02 89 c8 c1 f8 1f 29 c2 89 d0 89 |...........)....| +0001bdf0 45 f4 83 7d f4 00 79 0e c7 45 f4 cc cc cc 0c c7 |E..}..y..E......| +0001be00 45 0c 08 00 00 00 83 7d f4 00 74 14 83 ec 08 ff |E......}..t.....| +0001be10 75 f4 ff 75 08 e8 b7 ff ff ff 83 c4 10 89 45 08 |u..u..........E.| +0001be20 8b 4d 0c ba 67 66 66 66 89 c8 f7 ea c1 fa 02 89 |.M..gfff........| +0001be30 c8 c1 f8 1f 29 c2 89 d0 c1 e0 02 01 d0 01 c0 29 |....)..........)| +0001be40 c1 89 ca 89 d0 8d 48 30 8b 45 08 8d 50 01 89 55 |......H0.E..P..U| +0001be50 08 89 ca 88 10 8b 45 08 c9 c3 55 89 e5 83 ec 20 |......E...U.... | +0001be60 c7 45 e3 30 31 32 33 c7 45 e7 34 35 36 37 c7 45 |.E.0123.E.4567.E| +0001be70 eb 38 39 41 42 c7 45 ef 43 44 45 46 c6 45 f3 00 |.89AB.E.CDEF.E..| +0001be80 c7 45 fc 00 00 00 00 c7 45 f8 00 00 00 00 eb 43 |.E......E......C| +0001be90 8b 45 0c 25 00 00 00 f0 89 45 f4 83 7d fc 00 75 |.E.%.....E..}..u| +0001bea0 0c 83 7d f4 00 75 06 83 7d f8 07 75 1e 83 45 fc |..}..u..}..u..E.| +0001beb0 01 c1 6d f4 1c 8b 45 08 8d 50 01 89 55 08 8d 4d |..m...E..P..U..M| +0001bec0 e3 8b 55 f4 01 ca 0f b6 12 88 10 c1 65 0c 04 83 |..U.........e...| +0001bed0 45 f8 01 83 7d f8 07 7e b7 8b 45 08 c6 00 00 8b |E...}..~..E.....| +0001bee0 45 fc c9 c3 55 89 e5 83 ec 10 c7 45 f8 00 00 00 |E...U......E....| +0001bef0 00 8b 45 08 89 45 f4 8b 45 0c 25 00 00 00 c0 89 |..E..E..E.%.....| +0001bf00 45 f0 c1 6d f0 1e c7 45 fc 00 00 00 00 eb 47 83 |E..m...E......G.| +0001bf10 7d fc 0a 74 0c 83 7d f0 00 75 06 83 7d f8 00 74 |}..t..}..u..}..t| +0001bf20 1e c7 45 f8 01 00 00 00 83 65 f0 07 8b 45 f0 8d |..E......e...E..| +0001bf30 48 30 8b 45 f4 8d 50 01 89 55 f4 89 ca 88 10 c1 |H0.E..P..U......| +0001bf40 65 0c 03 8b 45 0c 25 00 00 00 e0 89 45 f0 c1 6d |e...E.%.....E..m| +0001bf50 f0 1d 83 45 fc 01 83 7d fc 0a 7e b3 8b 45 f4 c6 |...E...}..~..E..| +0001bf60 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 55 89 |...U..E.).....U.| +0001bf70 e5 83 ec 18 8b 45 08 89 45 f4 83 ec 08 ff 75 0c |.....E..E.....u.| +0001bf80 ff 75 f4 e8 18 00 00 00 83 c4 10 89 45 f4 8b 45 |.u..........E..E| +0001bf90 f4 c6 00 00 8b 55 f4 8b 45 08 29 c2 89 d0 c9 c3 |.....U..E.).....| +0001bfa0 55 89 e5 83 ec 18 8b 45 0c ba cd cc cc cc f7 e2 |U......E........| +0001bfb0 89 d0 c1 e8 03 89 45 f4 83 7d f4 00 74 15 8b 45 |......E..}..t..E| +0001bfc0 f4 83 ec 08 50 ff 75 08 e8 04 fe ff ff 83 c4 10 |....P.u.........| +0001bfd0 89 45 08 8b 4d 0c ba cd cc cc cc 89 c8 f7 e2 c1 |.E..M...........| +0001bfe0 ea 03 89 d0 c1 e0 02 01 d0 01 c0 29 c1 89 ca 89 |...........)....| +0001bff0 d0 8d 48 30 8b 45 08 8d 50 01 89 55 08 89 ca 88 |..H0.E..P..U....| +0001c000 10 8b 45 08 c9 c3 55 89 e5 83 ec 18 83 7d 10 00 |..E...U......}..| +0001c010 79 11 83 ec 0c ff 75 0c e8 4b fd ff ff 83 c4 10 |y.....u..K......| +0001c020 89 45 10 8b 45 14 2b 45 10 89 45 f0 83 7d f0 00 |.E..E.+E..E..}..| +0001c030 7e 1d 83 7d 18 00 75 17 83 ec 04 ff 75 1c ff 75 |~..}..u.....u..u| +0001c040 f0 ff 75 08 e8 5a 00 00 00 83 c4 10 89 45 08 c7 |..u..Z.......E..| +0001c050 45 f4 00 00 00 00 eb 1b 8b 55 f4 8b 45 0c 8d 0c |E........U..E...| +0001c060 02 8b 45 08 8d 50 01 89 55 08 0f b6 11 88 10 83 |..E..P..U.......| +0001c070 45 f4 01 8b 45 f4 3b 45 10 7c dd 83 7d f0 00 7e |E...E.;E.|..}..~| +0001c080 1d 83 7d 18 00 74 17 83 ec 04 ff 75 1c ff 75 f0 |..}..t.....u..u.| +0001c090 ff 75 08 e8 0b 00 00 00 83 c4 10 89 45 08 8b 45 |.u..........E..E| +0001c0a0 08 c9 c3 55 89 e5 eb 12 8b 45 08 8d 50 01 89 55 |...U.....E..P..U| +0001c0b0 08 8b 55 10 88 10 83 6d 0c 01 83 7d 0c 00 7f e8 |..U....m...}....| +0001c0c0 8b 45 08 5d c3 00 00 00 3f 3a 20 61 72 67 63 20 |.E.]....?: argc | +0001c0d0 25 64 2c 20 61 72 67 73 3a 20 00 28 6e 75 6c 6c |%d, args: .(null| +0001c0e0 29 00 20 25 73 00 0a 00 20 25 63 5b 25 64 5d 00 |). %s... %c[%d].| +0001c0f0 43 68 69 6c 64 20 25 64 20 65 78 65 63 28 29 20 |Child %d exec() | +0001c100 23 25 75 20 66 61 69 6c 65 64 0a 00 6e 14 00 00 |#%u failed..n...| +0001c110 ac 14 00 00 f8 15 00 00 f8 15 00 00 f8 15 00 00 |................| +0001c120 f8 15 00 00 f8 15 00 00 f8 15 00 00 f8 15 00 00 |................| +0001c130 f8 15 00 00 f8 15 00 00 f8 15 00 00 66 15 00 00 |............f...| +0001c140 f8 15 00 00 f8 15 00 00 f8 15 00 00 f0 14 00 00 |................| +0001c150 f8 15 00 00 a7 15 00 00 f8 15 00 00 f8 15 00 00 |................| +0001c160 22 15 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |"...............| +0001c170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +0001c6f0 00 10 00 00 00 00 00 00 03 00 01 00 00 00 00 00 |................| +0001c700 ec 19 00 00 00 00 00 00 03 00 02 00 00 00 00 00 |................| +0001c710 00 20 00 00 00 00 00 00 03 00 03 00 00 00 00 00 |. ..............| +0001c720 00 20 00 00 00 00 00 00 03 00 04 00 01 00 00 00 |. ..............| +0001c730 00 00 00 00 00 00 00 00 04 00 f1 ff 09 00 00 00 |................| +0001c740 00 00 00 00 00 00 00 00 04 00 f1 ff 11 00 00 00 |................| +0001c750 00 00 00 00 00 00 00 00 04 00 f1 ff 1a 00 00 00 |................| +0001c760 00 00 00 00 00 00 00 00 04 00 f1 ff 24 00 00 00 |............$...| +0001c770 00 00 00 00 00 00 00 00 04 00 f1 ff 2d 00 00 00 |............-...| +0001c780 00 00 00 00 00 00 00 00 04 00 f1 ff 36 00 00 00 |............6...| +0001c790 00 00 00 00 00 00 00 00 04 00 f1 ff 40 00 00 00 |............@...| +0001c7a0 00 00 00 00 00 00 00 00 04 00 f1 ff 49 00 00 00 |............I...| +0001c7b0 00 00 00 00 00 00 00 00 04 00 f1 ff 52 00 00 00 |............R...| +0001c7c0 00 00 00 00 00 00 00 00 04 00 f1 ff 5b 00 00 00 |............[...| +0001c7d0 00 00 00 00 00 00 00 00 04 00 f1 ff 65 00 00 00 |............e...| +0001c7e0 00 00 00 00 00 00 00 00 04 00 f1 ff 6e 00 00 00 |............n...| +0001c7f0 00 00 00 00 00 00 00 00 04 00 f1 ff 74 00 00 00 |............t...| +0001c800 b6 12 00 00 21 00 00 00 12 00 01 00 7d 00 00 00 |....!.......}...| +0001c810 27 13 00 00 00 00 00 00 10 00 01 00 85 00 00 00 |'...............| +0001c820 9b 12 00 00 1b 00 00 00 12 00 01 00 8c 00 00 00 |................| +0001c830 1a 16 00 00 72 00 00 00 12 00 01 00 94 00 00 00 |....r...........| +0001c840 92 18 00 00 32 00 00 00 12 00 01 00 9b 00 00 00 |....2...........| +0001c850 4f 13 00 00 00 00 00 00 10 00 01 00 a2 00 00 00 |O...............| +0001c860 7f 13 00 00 00 00 00 00 10 00 01 00 a8 00 00 00 |................| +0001c870 04 13 00 00 1b 00 00 00 12 00 01 00 af 00 00 00 |................| +0001c880 c7 19 00 00 22 00 00 00 12 00 01 00 b3 00 00 00 |...."...........| +0001c890 d8 11 00 00 75 00 00 00 12 00 01 00 b9 00 00 00 |....u...........| +0001c8a0 a5 13 00 00 75 02 00 00 12 00 01 00 c0 00 00 00 |....u...........| +0001c8b0 7e 17 00 00 8a 00 00 00 12 00 01 00 c7 00 00 00 |~...............| +0001c8c0 c4 18 00 00 66 00 00 00 12 00 01 00 86 00 00 00 |....f...........| +0001c8d0 47 13 00 00 00 00 00 00 10 00 01 00 cf 00 00 00 |G...............| +0001c8e0 77 13 00 00 00 00 00 00 10 00 01 00 d4 00 00 00 |w...............| +0001c8f0 6e 12 00 00 2d 00 00 00 12 00 01 00 dc 00 00 00 |n...-...........| +0001c900 37 13 00 00 00 00 00 00 10 00 01 00 e1 00 00 00 |7...............| +0001c910 c0 11 00 00 18 00 00 00 12 00 01 00 e6 00 00 00 |................| +0001c920 d7 12 00 00 2d 00 00 00 12 00 01 00 ee 00 00 00 |....-...........| +0001c930 95 13 00 00 00 00 00 00 10 00 01 00 f5 00 00 00 |................| +0001c940 3f 13 00 00 00 00 00 00 10 00 01 00 fa 00 00 00 |?...............| +0001c950 67 13 00 00 00 00 00 00 10 00 01 00 02 01 00 00 |g...............| +0001c960 f5 16 00 00 89 00 00 00 12 00 01 00 0a 01 00 00 |................| +0001c970 2f 13 00 00 00 00 00 00 10 00 01 00 0f 01 00 00 |/...............| +0001c980 00 10 00 00 c0 01 00 00 12 00 01 00 14 01 00 00 |................| +0001c990 57 13 00 00 00 00 00 00 10 00 01 00 1c 01 00 00 |W...............| +0001c9a0 2a 19 00 00 9d 00 00 00 12 00 01 00 23 01 00 00 |*...........#...| +0001c9b0 6f 13 00 00 00 00 00 00 10 00 01 00 2b 01 00 00 |o...........+...| +0001c9c0 08 18 00 00 8a 00 00 00 12 00 01 00 32 01 00 00 |............2...| +0001c9d0 4d 12 00 00 21 00 00 00 12 00 01 00 3b 01 00 00 |M...!.......;...| +0001c9e0 5f 13 00 00 00 00 00 00 10 00 01 00 43 01 00 00 |_...........C...| +0001c9f0 ae 16 00 00 47 00 00 00 12 00 01 00 5c 01 00 00 |....G.......\...| +0001ca00 1f 13 00 00 00 00 00 00 10 00 01 00 4a 01 00 00 |............J...| +0001ca10 8c 16 00 00 22 00 00 00 12 00 01 00 51 01 00 00 |....".......Q...| +0001ca20 87 13 00 00 00 00 00 00 10 00 01 00 57 01 00 00 |............W...| +0001ca30 8f 13 00 00 00 00 00 00 10 00 01 00 00 70 72 6f |.............pro| +0001ca40 67 5a 2e 63 00 75 6c 69 62 63 2e 63 00 73 70 72 |gZ.c.ulibc.c.spr| +0001ca50 69 6e 74 2e 63 00 73 74 72 32 69 6e 74 2e 63 00 |int.c.str2int.c.| +0001ca60 73 74 72 6c 65 6e 2e 63 00 63 76 74 64 65 63 2e |strlen.c.cvtdec.| +0001ca70 63 00 63 76 74 64 65 63 30 2e 63 00 63 76 74 68 |c.cvtdec0.c.cvth| +0001ca80 65 78 2e 63 00 63 76 74 6f 63 74 2e 63 00 63 76 |ex.c.cvtoct.c.cv| +0001ca90 74 75 6e 73 2e 63 00 63 76 74 75 6e 73 30 2e 63 |tuns.c.cvtuns0.c| +0001caa0 00 70 61 64 73 74 72 2e 63 00 70 61 64 2e 63 00 |.padstr.c.pad.c.| +0001cab0 73 77 72 69 74 65 63 68 00 77 61 69 74 70 69 64 |swritech.waitpid| +0001cac0 00 63 77 72 69 74 65 00 73 74 72 32 69 6e 74 00 |.cwrite.str2int.| +0001cad0 63 76 74 75 6e 73 00 67 65 74 70 69 64 00 73 6c |cvtuns.getpid.sl| +0001cae0 65 65 70 00 73 77 72 69 74 65 00 70 61 64 00 73 |eep.swrite.pad.s| +0001caf0 70 61 77 6e 00 73 70 72 69 6e 74 00 63 76 74 68 |pawn.sprint.cvth| +0001cb00 65 78 00 63 76 74 75 6e 73 30 00 6b 69 6c 6c 00 |ex.cvtuns0.kill.| +0001cb10 63 77 72 69 74 65 73 00 65 78 65 63 00 77 61 69 |cwrites.exec.wai| +0001cb20 74 00 73 77 72 69 74 65 73 00 5f 73 74 61 72 74 |t.swrites._start| +0001cb30 00 72 65 61 64 00 67 65 74 70 72 69 6f 00 63 76 |.read.getprio.cv| +0001cb40 74 64 65 63 30 00 66 6f 72 6b 00 6d 61 69 6e 00 |tdec0.fork.main.| +0001cb50 67 65 74 70 70 69 64 00 70 61 64 73 74 72 00 73 |getppid.padstr.s| +0001cb60 65 74 70 72 69 6f 00 63 76 74 6f 63 74 00 63 77 |etprio.cvtoct.cw| +0001cb70 72 69 74 65 63 68 00 67 65 74 74 69 6d 65 00 63 |ritech.gettime.c| +0001cb80 76 74 64 65 63 00 73 74 72 6c 65 6e 00 62 6f 67 |vtdec.strlen.bog| +0001cb90 75 73 00 66 61 6b 65 5f 65 78 69 74 00 00 2e 73 |us.fake_exit...s| +0001cba0 79 6d 74 61 62 00 2e 73 74 72 74 61 62 00 2e 73 |ymtab..strtab..s| +0001cbb0 68 73 74 72 74 61 62 00 2e 74 65 78 74 00 2e 72 |hstrtab..text..r| +0001cbc0 6f 64 61 74 61 00 2e 64 61 74 61 00 2e 62 73 73 |odata..data..bss| +0001cbd0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +* +0001cbf0 00 00 00 00 00 00 00 00 00 00 00 00 1b 00 00 00 |................| +0001cc00 01 00 00 00 06 00 00 00 00 10 00 00 74 00 00 00 |............t...| +0001cc10 e9 09 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +0001cc20 00 00 00 00 21 00 00 00 01 00 00 00 02 00 00 00 |....!...........| +0001cc30 ec 19 00 00 60 0a 00 00 9c 00 00 00 00 00 00 00 |....`...........| +0001cc40 00 00 00 00 04 00 00 00 00 00 00 00 29 00 00 00 |............)...| +0001cc50 01 00 00 00 03 00 00 00 00 20 00 00 74 10 00 00 |......... ..t...| +0001cc60 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |................| +0001cc70 00 00 00 00 2f 00 00 00 08 00 00 00 03 00 00 00 |..../...........| +0001cc80 00 20 00 00 74 10 00 00 00 00 00 00 00 00 00 00 |. ..t...........| +0001cc90 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 |................| +0001cca0 02 00 00 00 00 00 00 00 00 00 00 00 74 10 00 00 |............t...| +0001ccb0 60 03 00 00 06 00 00 00 12 00 00 00 04 00 00 00 |`...............| +0001ccc0 10 00 00 00 09 00 00 00 03 00 00 00 00 00 00 00 |................| +0001ccd0 00 00 00 00 d4 13 00 00 61 01 00 00 00 00 00 00 |........a.......| +0001cce0 00 00 00 00 01 00 00 00 00 00 00 00 11 00 00 00 |................| +0001ccf0 03 00 00 00 00 00 00 00 00 00 00 00 35 15 00 00 |............5...| +0001cd00 34 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 |4...............| +0001cd10 00 00 00 00 00 00 00 00 |........| +0001cd18 diff --git a/doc/usermatrix.txt b/doc/usermatrix.txt new file mode 100644 index 0000000..4c7191b --- /dev/null +++ b/doc/usermatrix.txt @@ -0,0 +1,53 @@ +Process/Syscall matrix +====================== + +System calls in this system: + process management: exit, waitpid, fork, exec, kill + i/o: read write + information: getpid getppid gettime getprio + other: sleep, setprio + +There is also a "bogus" system call which attempts to use an invalid +system call code; this should be caught by the syscall handler and +the process should be terminated. + +These are the system calls which are used in each of the user-level +main functions. Some main functions only invoke certain system calls +when given specific command-line arguments. + +Note that some system calls are nested inside library functions - e.g., +cwrite*() and swrite*() perform write(), etc. + + progABC runs for userA, userB, and userC + progDE runs for userD and userE + progFG runs for userF and userG + progKL runs for userK and userL + progMN runs for userM and userN + progTUV runs for userT, userU, and userV + all others run individual main functions + + baseline system calls in use +prog ext wtp for exe rea wrt gpi gpp gti kil slp gtp stp bog +----- --- --- --- --- --- --- --- --- --- --- --- --- --- --- +init . X . . . X . . . . . . . . +idle X . . . . X X . X . . X X . +shell X X X X X X . . . . . . . . +----- --- --- --- --- --- --- --- --- --- --- --- --- --- --- +abc X . . . . X . . . . . . . . +de . . . . . X . . . . . . . . +fg X . . . . X . . . . X . . . +h X . X X . X . . . . X . . . +i X X X X . X . . . X X . . . +j X . X X . X . . . . . . . . +kl X . X X . X . . . . X . . . +mn X . X X . X . . . . . . . . +p X . . . . X . . X . X . . . +q X . . . . X . . . . . . . X +r X . X . . X X X . . X . . . +s X . . . . X . . . . X . . . +tuv X X X X . X . . . X X . . . +w X . . . . X X . X . X . . . +x X . . . . X . . . . . . . . +y X . . . . X X . . . X . . . +z X . . . . X X . . . X . . . +........................................................................... diff --git a/include/bootstrap.h b/include/bootstrap.h new file mode 100644 index 0000000..ade778a --- /dev/null +++ b/include/bootstrap.h @@ -0,0 +1,120 @@ +/* +** SCCS ID: @(#)bootstrap.h 2.4 1/22/25 +** +** @file bootstrap.h +** +** @author K. Reek +** @author Warren R. Carithers, Garrett C. Smith +** +** Addresses where various stuff goes in memory. +*/ + +#ifndef BOOTSTRAP_H_ +#define BOOTSTRAP_H_ + +/* +** The boot device +*/ +#define BDEV_FLOPPY 0x00 +#define BDEV_USB 0x80 /* hard drive */ + +#define BDEV BDEV_USB /* default */ + +/* +** Bootstrap definitions +*/ +#define BOOT_SEG 0x07c0 /* 07c0:0000 */ +#define BOOT_DISP 0x0000 +#define BOOT_ADDR ((BOOT_SEG << 4) + BOOT_DISP) + +#define PART2_DISP 0x0200 /* 07c0:0200 */ +#define PART2_ADDR ((BOOT_SEG << 4) + PART2_DISP) + +#define SECTOR_SIZE 0x200 /* 512 bytes */ + +/* Note: this assumes the bootstrap is two sectors long! */ +#define BOOT_SIZE (SECTOR_SIZE + SECTOR_SIZE) + +#define OFFSET_LIMIT (0x10000 - SECTOR_SIZE) + +#define BOOT_SP_DISP 0x4000 /* stack pointer 07c0:4000, or 0xbc00 */ +#define BOOT_SP_ADDR ((BOOT_SEG << 4) + BOOT_SP_DISP) + +#define SECTOR1_END (BOOT_ADDR + SECTOR_SIZE) +#define SECTOR2_END (BOOT_ADDR + BOOT_SIZE) + +// location of the user blob data +// (three halfwords of data) +#define USER_BLOB_DATA (SECTOR2_END - 12) + +/* +** The target program itself +*/ +#define TARGET_SEG 0x00001000 /* 1000:0000 */ +#define TARGET_ADDR 0x00010000 /* and upward */ +#define TARGET_STACK 0x00010000 /* and downward */ + +/* +** The Global Descriptor Table (0000:0500 - 0000:2500) +*/ +#define GDT_SEG 0x00000050 +#define GDT_ADDR 0x00000500 + + /* segment register values */ +#define GDT_LINEAR 0x0008 /* All of memory, R/W */ +#define GDT_CODE 0x0010 /* All of memory, R/E */ +#define GDT_DATA 0x0018 /* All of memory, R/W */ +#define GDT_STACK 0x0020 /* All of memory, R/W */ + +/* +** The Interrupt Descriptor Table (0000:2500 - 0000:2D00) +*/ +#define IDT_SEG 0x00000250 +#define IDT_ADDR 0x00002500 + +/* +** Additional I/O ports used by the bootstrap code +*/ + +// keyboard controller +#define KBD_DATA 0x60 +#define KBD_CMD 0x64 +#define KBD_STAT 0x64 + +// status register bits +#define KBD_OBSTAT 0x01 +#define KBD_IBSTAT 0x02 +#define KBD_SYSFLAG 0x04 +#define KBD_CMDDAT 0x08 + +// commands +#define KBD_P1_DISABLE 0xad +#define KBD_P1_ENABLE 0xae +#define KBD_RD_OPORT 0xd0 +#define KBD_WT_OPORT 0xd1 + +#ifdef ASM_SRC + +// segment descriptor macros for use in assembly source files +// layout: +// .word lower 16 bits of limit +// .word lower 16 bits of base +// .byte middle 8 bits of base +// .byte type byte +// .byte granularity byte +// .byte upper 8 bits of base +// we use 4K units, so we ignore the lower 12 bits of the limit +#define SEGNULL \ + .word 0, 0, 0, 0 + +#define SEGMENT(base,limit,dpl,type) \ + .word (((limit) >> 12) & 0xffff); \ + .word ((base) & 0xffff) ; \ + .byte (((base) >> 16) & 0xff) ; \ + .byte (SEG_PRESENT | (dpl) | SEG_NON_SYSTEM | (type)) ; \ + .byte (SEG_GRAN_4KBYTE | SEG_DB_32BIT | (((limit) >> 28) & 0xf)) ; \ + .byte (((base) >> 24) & 0xff) + +#endif /* ASM_SRC */ + +#endif diff --git a/include/cio.h b/include/cio.h new file mode 100644 index 0000000..1854f6e --- /dev/null +++ b/include/cio.h @@ -0,0 +1,287 @@ +/** +** SCCS ID: @(#)cio.h 2.7 1/22/25 +** +** @file cio.h +** +** @author Warren R. Carithers +** @authors K. Reek, Jon Coles +** +** Based on: c_io.c 1.13 (Ken Reek, Jon Coles, Warren R. Carithers) +** +** Declarations and descriptions of console I/O routines +** +** These routines provide a rudimentary capability for printing to +** the screen and reading from the keyboard. +** +** Screen output: +** There are two families of functions. The first provides a window +** that behaves in the usual manner: writes extending beyond the right +** edge of the window wrap around to the next line, the top line +** scrolls off the window to make room for new lines at the bottom. +** However, you may choose what part of the screen contains this +** scrolling window. This allows you to print some text at fixed +** locations on the screen while the rest of the screen scrolls. +** +** The second family allows for printing at fixed locations on the +** screen. No scrolling or line wrapping are done for these functions. +** It is not intended that these functions be used to write in the +** scrolling area of the screen. +** +** In both sets of functions, the (x,y) coordinates are interpreted +** as (column,row), with the upper left corner of the screen being +** (0,0) and the lower right corner being (79,24). +** +** The printf provided in both sets of functions has the same +** conversion capabilities. Format codes are of the form: +** +** %-0WC +** +** where "-", "0", and "W" are all optional: +** "-" is the left-adjust flag (default is right-adjust) +** "0" is the zero-fill flag (default is space-fill) +** "W" is a number specifying the minimum field width (default: 1 ) +** and "C" is the conversion type, which must be one of these: +** "c" print a single character +** "s" print a null-terminated string +** "d" print an integer as a decimal value +** "x" print an integer as a hexadecimal value +** "o" print an integer as a octal value +** +** Keyboard input: +** Two functions are provided: getting a single character and getting +** a newline-terminated line. A third function returns a count of +** the number of characters available for immediate reading. +** No conversions are provided (yet). +*/ + +#ifndef CIO_H_ +#define CIO_H_ + +#ifndef ASM_SRC + +// EOT indicator (control-D) +#define EOT '\04' + +/***************************************************************************** +** +** INITIALIZATION ROUTINES +** +** Initializes the I/O system. +*/ + +/** +** cio_init +** +** Initializes the I/O routines. Must be called before +** any CIO functions can be used. +** +** @param notify pointer to an input notification function, or NULL +*/ +void cio_init( void (*notify)(int) ); + +/***************************************************************************** +** +** SCROLLING OUTPUT ROUTINES +** +** Each operation begins at the current cursor position and advances +** it. If a newline is output, the reminder of that line is cleared. +** Output extending past the end of the line is wrapped. If the +** cursor is moved below the scrolling region's bottom edge, scrolling +** is delayed until the next output is produced. +*/ + +/** +** cio_setscroll +** +** This sets the scrolling region to be the area defined by the arguments. +** The remainder of the screen does not scroll and may be used to display +** data you do not want to move. By default, the scrolling region is the +** entire screen. X and Y coordinates begin at 0 in the upper left corner +** of the screen. +** +** @param min_x,min_y upper-left corner of the region +** @param max_x,max_y lower-right corner of the region +*/ +void cio_setscroll( unsigned int min_x, unsigned int min_y, + unsigned int max_x, unsigned int max_y ); + +/** +** cio_moveto +** +** Moves the cursor to the specified position. (0,0) indicates +** the upper left corner of the scrolling region. Subsequent +** output will begin at the cursor position. +** +** @param x,y desired coordinate position +*/ +void cio_moveto( unsigned int x, unsigned int y ); + +/** +** cio_putchar +** +** Prints a single character. +** +** @param c the character to be printed +*/ +void cio_putchar( unsigned int c ); + +/** +** cio_puts +** +** Prints the characters in the string up to but not including +** the terminating null byte. +** +** @param str pointer to a NUL-terminated string to be printed +*/ +void cio_puts( const char *str ); + +/** +** cio_write +** +** Prints "length" characters from the buffer. +** +** @param buf the buffer of characters +** @param length the number of characters to print +*/ +void cio_write( const char *buf, int length ); + +/** +** cio_printf +** +** Limited form of printf (see the beginning of this file for +** a list of what is implemented). +** +** @param fmt a printf-style format control string +** @param ... optional additional values to be printed +*/ +void cio_printf( char *fmt, ... ); + +/** +** cio_scroll +** +** Scroll the scrolling region up by the given number of lines. +** The output routines scroll automatically so normally you +** do not need to call this routine yourself. +** +** @param lines the number of lines to scroll +*/ +void cio_scroll( unsigned int lines ); + +/** +** cio_clearscroll +** +** Clears the entire scrolling region to blank spaces, and +** moves the cursor to (0,0). +*/ +void cio_clearscroll( void ); + +/***************************************************************************** +** +** NON-SCROLLING OUTPUT ROUTINES +** +** Coordinates are relative to the entire screen: (0,0) is the upper +** left corner. There is no line wrap or scrolling. +*/ + +/** +** cio_putchar_at +** +** Prints the given character. If a newline is printed, +** the rest of the line is cleared. If this happens to the +** left of the scrolling region, the clearing stops when the +** region is reached. If this happens inside the scrolling +** region, the clearing stops when the edge of the region +** is reached. +** +** @param x,y desired coordinate position +** @param c the character to be printed +*/ +void cio_putchar_at( unsigned int x, unsigned int y, unsigned int c ); + +/** +** cio_puts_at +** +** Prints the given string. cio_putchar_at is used to print +** the individual characters; see that description for details. +** +** @param x,y desired coordinate position +** @param str pointer to a NUL-terminated string to be printed +*/ +void cio_puts_at( unsigned int x, unsigned int y, const char *str ); + +/** +** cio_printf_at +** +** Limited form of printf (see the beginning of this file for +** a list of what is implemented). +** +** @param x,y desired coordinate position +** @param fmt a printf-style format control string +** @param ... optional additional values to be printed +*/ +void cio_printf_at( unsigned int x, unsigned int y, char *fmt, ... ); + +/** +** cio_clearscreen +** +** This function clears the entire screen, including the scrolling region. +*/ +void cio_clearscreen( void ); + +/***************************************************************************** +** +** INPUT ROUTINES +** +** When interrupts are enabled, a keyboard ISR collects keystrokes +** and saves them until the program calls for them. If the input +** queue fills, additional characters are silently discarded. +** When interrupts are not enabled, keystrokes made when no input +** routines have been ** called are lost. This can cause errors in +** the input translation because the states of the Shift and Ctrl keys +** may not be tracked accurately. If interrupts are disabled, the user +** is advised to refrain from typing anything except when the program is +** waiting for input. +*/ + +/** +** cio_getchar +** +** If the character is not immediately available, the function +** waits until the character arrives. +** +** @return the next character from the keyboard input buffer +*/ +int cio_getchar( void ); + +/** +** cio_gets +** +** This function reads a newline-terminated line from the +** keyboard. cio_getchar is used to obtain the characters; +** see that description for more details. The function +** returns when: +** a newline is entered (this is stored in the buffer) +** ctrl-D is entered (not stored in the buffer) +** the buffer becomes full. +** The buffer is null-terminated in all cases. +** +** @param buffer destination buffer for the input character sequence +** @param size the buffer length +** +** @return count of the number of characters read into the buffer +*/ +int cio_gets( char *buffer, unsigned int size ); + +/** +** cio_input_queue +** +** This function lets the program determine whether there is input +** available. This indicates whether or not a call to cio_getchar() +** would block. +** +** @return number of characters in the input queue +*/ +int cio_input_queue( void ); +#endif /* !ASM_SRC */ + +#endif diff --git a/include/clock.h b/include/clock.h new file mode 100644 index 0000000..6eae41f --- /dev/null +++ b/include/clock.h @@ -0,0 +1,55 @@ +/** +** @file clock.h +** +** @author CSCI-452 class of 20245 +** +** @brief Clock module declarations +*/ + +#ifndef CLOCK_H_ +#define CLOCK_H_ + +#include <common.h> + +/* +** General (C and/or assembly) definitions +*/ + +// conversion functions for seconds, ms, and ticks +// (SEC_TO_MS is defined in defs.h) +#define MS_TO_TICKS(n) ((n)) +#define SEC_TO_TICKS(n) (MS_TO_TICKS(SEC_TO_MS(n))) +#define TICKS_TO_SEC(n) ((n) / CLOCK_FREQ) +#define TICKS_TO_SEC_ROUNDED(n) (((n)+(CLOCK_FREQ-1)) / CLOCK_FREQ) + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +*/ + +/* +** Types +*/ + +/* +** Globals +*/ + +// current system time +extern uint32_t system_time; + +/* +** Prototypes +*/ + +/** +** Name: clk_init +** +** Clock module initialization +*/ +void clk_init( void ); + +#endif /* !ASM_SRC */ + +#endif diff --git a/include/common.h b/include/common.h new file mode 100644 index 0000000..599c492 --- /dev/null +++ b/include/common.h @@ -0,0 +1,31 @@ +/** +** @file common.h +** +** @author Warren R. Carithers +** +** @brief Common definitions for the baseline system. +** +** This header file pulls in the standard header information needed +** by all parts of the system. It is purely for our convenience. +*/ + +#ifndef COMMON_H_ +#define COMMON_H_ + +// everything needs these; they also pull in +// the kernel- or user-level defs and lib headers +#include <types.h> +#include <params.h> +#include <defs.h> +#include <lib.h> + +#ifdef KERNEL_SRC + +// only kernel code needs these headers +#include <common.h> +#include <cio.h> +#include <debug.h> + +#endif /* KERNEL_SRC */ + +#endif diff --git a/include/compat.h b/include/compat.h new file mode 100644 index 0000000..ee62090 --- /dev/null +++ b/include/compat.h @@ -0,0 +1,131 @@ +/** +** @file compat.h +** +** @author Warren R. Carithers +** +** @brief Compatibility definitions for standard modules. +** +** These definitions are here to simplify the integration +** of some pre-written modules into the 452 baseline system. +** This is used primarily for the 'kmem' and 'sio' modules. +** +** We use CPP symbols and not actual data types for things here, +** as this means we don't need to include any other header files +** into this file. This helps get around "include loops" (e.g., +** a.h includes b.h, which includes c.h, which includes a.h) when +** there are many interdependencies between source files. +*/ + +#ifndef COMPAT_H_ +#define COMPAT_H_ + +#include <common.h> +#include <procs.h> + +/* +** Section 1: sized integer types +** +** Internally, we use standard names for "sized" integer types for +** simplicity. If those disagree with the names used in the rest of +** the system, we take the opportunity to define our names here. +** +** To enable these, uncomment them, and place the apropriate +** existing type names in place of the '?' characters. +*/ + +// standard "sized integer" types +// #define int8_t ? +// #define uint8_t ? +// #define int16_t ? +// #define uint16_t ? +// #define int32_t ? +// #define uint32_t ? +// #define int64_t ? +// #define uint64_t ? +// #define bool_t ? + +/* +** Section 2: other types +** +** Add type definitions here as needed. +** +** Note: we do not include the PCB and Queue declarations +** here because we don't actually need them in this header +** file - we're only defining CPP macros. Whatever file +** uses these macros, however, must include the appropriate +** headers if it uses these macros. +** +** To enable these, uncomment them, and place the apropriate +** existing type names in place of the '?' characters. +*/ + +// type name for the PCB +#define PCBTYPE pcb_t + +// type name for our queue +#define QTYPE pcb_queue_t + +/* +** Section 3: interface and behavior +** +** Include #define statements here as needed to define +** the names of functions and globals used in these modules +** in terms of the names used in the rest of the baseline. +** +** To enable these, uncomment them, and place the apropriate +** existing variable or function names in place of the '?' characters. +*/ + +// string functions +#define SLENGTH strlen + +// scheduler +#define SCHED schedule + +// dispatcher +#define DISPATCH dispatch + +/* +** blocked queue for reading processes +** +** Define this if we are blocking processes which try to +** read from the SIO when no characters are available. +** Its value should be the name of the globally-visible +** queue to be used. +*/ +#define QNAME sioread + +#ifdef QNAME + +// Only define these macros if we need to be able to create and +// manage a queue of things. It is expected that these will need +// to be customized based on the names and calling sequences of +// the appropriate functions. + +// invoke the queue creation function +// examples: +// +// #define QCREATE(q) do { +// _que_create( &(q), NULL ); +// } while(0) +// +// #define QCREATE(q) // do nothing + +#define QCREATE(q) // handled elsewhere for us + +// check to see if the queue is empty +// examples: +// +// #define QEMPTY(q) queue_is_empty(q) +// #define QEMPTY(q) (quene_length(q) > 0) +#define QEMPTY(q) pcb_queue_empty(q) + +// this macro expands into code that removes a value from +// 'q' and places it into 'd' +#define QDEQUE(q,d) do { \ + assert(pcb_queue_remove( (q), (pcb_t **) &(d) ) == SUCCESS ); \ + } while(0) + +#endif /* QNAME */ + +#endif diff --git a/include/debug.h b/include/debug.h new file mode 100644 index 0000000..c8ddfb4 --- /dev/null +++ b/include/debug.h @@ -0,0 +1,324 @@ +/** +** @file debug.h +** +** @author Numerous CSCI-452 classes +** +** Debugging macros and constants. +** +*/ + +#ifndef DEBUG_H_ +#define DEBUG_H_ + +// Standard system headers + +#include <cio.h> +#include <support.h> + +// Kernel library + +#include <lib.h> + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +*/ + +/* +** General function entry/exit announcements +*/ + +#ifdef ANNOUNCE_ENTRY +// Announce that we have entered a kernel function +// usage: ENTERING( "name" ), EXITING( "name" ) +// currently, these do not use the macro parameter, but could be +// modified to do so; instead, we use the __func__ CPP pseudo-macro +// to get the function name +#define ENTERING(n) do { cio_puts( " enter " __func__ ); } while(0) +#define EXITING(n) do { cio_puts( " exit " __func__ ); } while(0) +#else +#define ENTERING(m) // do nothing +#define EXITING(m) // do nothing +#endif + +/* +** Console messages when error conditions are noted. +*/ + +// Warning messages to the console +// m: message (condition, etc.) +#define WARNING(m) do { \ + cio_printf( "\n** %s (%s @ %d): ", __func__, __FILE__, __LINE__ ); \ + cio_puts( m ); \ + cio_putchar( '\n' ); \ + } while(0) + +// Panic messages to the console +// n: severity level +// m: message (condition, etc.) +#define PANIC(n,m) do { \ + sprint( b512, "%s (%s @ %d), %d: %s\n", \ + __func__, __FILE__, __LINE__, n, # m ); \ + kpanic( b512 ); \ + } while(0) + +/* +** Assertions are categorized by the "sanity level" being used in this +** compilation; each only triggers a fault if the sanity level is at or +** above a specific value. This allows selective enabling/disabling of +** debugging checks. +** +** The sanity level is set during compilation with the CPP macro +** "SANITY". A sanity level of 0 disables conditional assertions, +** but not the basic assert() version. +*/ + +#ifndef SANITY +// default sanity check level: check everything! +#define SANITY 9999 +#endif + +// Always-active assertions +#define assert(x) if( !(x) ) { PANIC(0,x); } + +// only provide these macros if the sanity check level is positive + +#if SANITY > 0 + +#define assert1(x) if( SANITY >= 1 && !(x) ) { PANIC(1,x); } +#define assert2(x) if( SANITY >= 2 && !(x) ) { PANIC(2,x); } +#define assert3(x) if( SANITY >= 3 && !(x) ) { PANIC(3,x); } +#define assert4(x) if( SANITY >= 4 && !(x) ) { PANIC(4,x); } +// arbitrary sanity level +#define assertN(n,x) if( SANITY >= (n) && !(x) ) { PANIC(n,x); } + +#else + +#define assert1(x) // do nothing +#define assert2(x) // do nothing +#define assert3(x) // do nothing +#define assert4(x) // do nothing +#define assertN(n,x) // do nothing + +#endif /* SANITY > 0 */ + +/* +** Tracing options are enabled by defining one or more of the T_ +** macros described in the Makefile. +** +** To add a tracing option: +** +** 1) Pick a short name for it (e.g., "PCB", "VM", ...) +** 2) At the end of this list, add code like this, with "name" +** replaced by your short name, and "nnnnnnnn" replaced by a +** unique bit that will designate this tracing option: +** +** #ifdef T_name +** #define TRname 0xnnnnnnnn +** #else +** #define TRname 0 +** #endif +** +** Use the next bit position following the one in last list entry. +** 3) Add this to the end of the "TRACE" macro definition: +** +** | TRname +** +** 4) In the list of "TRACING_*" macros, add one for your option +** (using a name that might be more descriptive) in the 'then' clause: +** +** #define TRACING_bettername ((TRACE & TRname) != 0) +** +** 5) Also add a "null" version in the 'else' clause: +** +** #define TRACING_bettername 0 +** +** 6) Maybe add your T_name choice to the Makefile with an explanation +** on the off chance you want anyone else to be able to understand +** what it's used for. :-) +** +** We're making CPP work for its pay with this file. +*/ + +// 2^0 bit +#ifdef T_PCB +#define TRPCB 0x00000001 +#else +#define TRPCB 0 +#endif + +#ifdef T_VM +#define TRVM 0x00000002 +#else +#define TRVM 0 +#endif + +#ifdef T_QUE +#define TRQUEUE 0x00000004 +#else +#define TRQUEUE 0 +#endif + +#ifdef T_SCH +#define TRSCHED 0x00000008 +#else +#define TRSCHED 0 +#endif + +// 2^4 bit +#ifdef T_DSP +#define TRDISP 0x00000010 +#else +#define TRDISP 0 +#endif + +#ifdef T_SCALL +#define TRSYSCALLS 0x00000020 +#else +#define TRSYSCALLS 0 +#endif + +#ifdef T_SRET +#define TRSYSRETS 0x00000040 +#else +#define TRSYSRETS 0 +#endif + +#ifdef T_EXIT +#define TREXIT 0x00000080 +#else +#define TREXIT 0 +#endif + +// 2^8 bit +#ifdef T_INIT +#define TRINIT 0x00000100 +#else +#define TRINIT 0 +#endif + +#ifdef T_KM +#define TRKMEM 0x00000200 +#else +#define TRKMEM 0 +#endif + +#ifdef T_KMFR +#define TRKMEM_F 0x00000400 +#else +#define TRKMEM_F 0 +#endif + +#ifdef T_KMIN +#define TRKMEM_I 0x00000800 +#else +#define TRKMEM_I 0 +#endif + +// 2^12 bit +#ifdef T_FORK +#define TRFORK 0x00001000 +#else +#define TRFORK 0 +#endif + +#ifdef T_EXEC +#define TREXEC 0x00002000 +#else +#define TREXEC 0 +#endif + +#ifdef T_SIO +#define TRSIO_STAT 0x00004000 +#else +#define TRSIO_STAT 0 +#endif + +#ifdef T_SIOR +#define TRSIO_RD 0x00008000 +#else +#define TRSIO_RD 0 +#endif + +// 2^16 bit +#ifdef T_SIOW +#define TRSIO_WR 0x00010000 +#else +#define TRSIO_WR 0 +#endif + +#ifdef T_USER +#define TRUSER 0x00020000 +#else +#define TRUSER 0 +#endif + +#ifdef T_ELF +#define TRELF 0x00040000 +#else +#define TRELF 0 +#endif + +// 13 bits remaining for tracing options +// next available bit: 0x00080000 + +#define TRACE (TRDISP | TREXIT | TRINIT | TRKMEM | TRKMEM_F | TRKMEM_I | TRPCB | TRQUEUE | TRSCHED | TREXEC | TRSIO_RD | TRSIO_STAT | TRSIO_WR | TRFORK | TRVM | TRSYSCALLS | TRSYSRETS | TRUSER | TRELF) + +#if TRACE > 0 + +// compile-time expressions for testing trace options +// usage: #if TRACING_thing +#define TRACING_PCB ((TRACE & TRPCB) != 0) +#define TRACING_VM ((TRACE & TRVM) != 0) +#define TRACING_QUEUE ((TRACE & TRQUEUE) != 0) +#define TRACING_SCHED ((TRACE & TRSCHED) != 0) +#define TRACING_SYSCALLS ((TRACE & TRSYSCALLS) != 0) +#define TRACING_SYSRETS ((TRACE & TRSYSRETS) != 0) +#define TRACING_EXIT ((TRACE & TREXIT) != 0) +#define TRACING_DISPATCH ((TRACE & TRDISPATCH) != 0) +#define TRACING_INIT ((TRACE & TRINIT) != 0) +#define TRACING_KMEM ((TRACE & TRKMEM) != 0) +#define TRACING_KMEM_FREELIST ((TRACE & TRKMEM_F) != 0) +#define TRACING_KMEM_INIT ((TRACE & TRKMEM_I) != 0) +#define TRACING_SPAWN ((TRACE & TRSPAWN) != 0) +#define TRACING_SIO_STAT ((TRACE & TRSIO_STAT) != 0) +#define TRACING_SIO_ISR ((TRACE & TRSIO_ISR) != 0) +#define TRACING_SIO_RD ((TRACE & TRSIO_RD) != 0) +#define TRACING_SIO_WR ((TRACE & TRSIO_WR) != 0) +#define TRACING_USER ((TRACE & TRUSER) != 0) +#define TRACING_ELF ((TRACE & TRELF) != 0) + +#define TRACING_SOMETHING (TRACE != 0) + +#else + +// TRACE == 0, so just define these all as "false" + +#define TRACING_PCB 0 +#define TRACING_STACK 0 +#define TRACING_QUEUE 0 +#define TRACING_SCHED 0 +#define TRACING_SYSCALLS 0 +#define TRACING_SYSRET 0 +#define TRACING_EXIT 0 +#define TRACING_DISPATCH 0 +#define TRACING_INIT 0 +#define TRACING_KMEM 0 +#define TRACING_KMEM_FREELIST 0 +#define TRACING_KMEM_INIT 0 +#define TRACING_SPAWN 0 +#define TRACING_SI_STAT 0 +#define TRACING_SIO_ISR 0 +#define TRACING_SIO_RD 0 +#define TRACING_SIO_WR 0 +#define TRACING_USER 0 +#define TRACING_ELF 0 + +#define TRACING_SOMETHING 0 + +#endif /* TRACE */ + +#endif /* !ASM_SRC */ + +#endif diff --git a/include/defs.h b/include/defs.h new file mode 100644 index 0000000..0280c47 --- /dev/null +++ b/include/defs.h @@ -0,0 +1,129 @@ +/** +** @file defs.h +** +** @author Warren R. Carithers +** +** @brief Common definitions. +** +** This header file defines things which are neede by all +** parts of the system (OS and user levels). +** +** Things which are kernel-specific go in the kdefs.h file; +** things which are user-specific go in the udefs.h file. +** The correct one of these will be automatically included +** at the end of this file. +*/ + +#ifndef DEFS_H_ +#define DEFS_H_ + +/* +** General (C and/or assembly) definitions +** +** This section of the header file contains definitions that can be +** used in either C or assembly-language source code. +*/ + +// NULL pointer value +// +// we define this the traditional way so that +// it's usable from both C and assembly + +#define NULL 0 + +// predefined i/o channels + +#define CHAN_CIO 0 +#define CHAN_SIO 1 + +// maximum allowable number of command-line arguments +#define MAX_ARGS 10 + +// sizes of various things +#define NUM_1KB 0x00000400 // 2^10 +#define NUM_4KB 0x00001000 // 2^12 +#define NUM_1MB 0x00100000 // 2^20 +#define NUM_4MB 0x00400000 // 2^22 +#define NUM_1GB 0x40000000 // 2^30 +#define NUM_2GB 0x80000000 // 2^31 +#define NUM_3GB 0xc0000000 + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +** +** Anything that should not be visible to something other than +** the C compiler should be put here. +*/ + +/* +** System error codes +** +** These can be returned to both system functions +** and to user system calls. +*/ + // success! +#define SUCCESS (0) +# define E_SUCCESS SUCCESS + // generic "something went wrong" +#define E_FAILURE (-1) + // specific failure reasons +#define E_BAD_PARAM (-2) +#define E_BAD_CHAN (-3) +#define E_NO_CHILDREN (-4) +#define E_NO_MEMORY (-5) +#define E_NOT_FOUND (-6) +#define E_NO_PROCS (-7) + +/* +** These error codes are internal to the OS. +*/ +#define E_EMPTY_QUEUE (-100) +#define E_NO_PCBS (-101) +#define E_NO_PTE (-102) +#define E_LOAD_LIMIT (-103) + +// exit status values +#define EXIT_SUCCESS (0) +#define EXIT_FAILURE (-1) +#define EXIT_KILLED (-101) +#define EXIT_BAD_SYSCALL (-102) + +/* +** Process priority values +*/ +enum priority_e { + PRIO_HIGH, PRIO_STD, PRIO_LOW, PRIO_DEFERRED + // sentinel + , N_PRIOS +}; + +// halves of various data sizes + +#define UI16_UPPER 0xff00 +#define UI16_LOWER 0x00ff + +#define UI32_UPPER 0xffff0000 +#define UI32_LOWER 0x0000ffff + +#define UI64_UPPER 0xffffffff00000000LL +#define UI64_LOWER 0x00000000ffffffffLL + +// Simple conversion pseudo-functions usable by everyone + +// convert seconds to ms +#define SEC_TO_MS(n) ((n) * 1000) + +#endif /* !ASM_SRC */ + +/* +** Level-specific definitions +*/ +#ifdef KERNEL_SRC +#include <kdefs.h> +#else +#include <udefs.h> +#endif /* KERNEL_SRC */ + +#endif diff --git a/include/elf.h b/include/elf.h new file mode 100644 index 0000000..a43e5c3 --- /dev/null +++ b/include/elf.h @@ -0,0 +1,235 @@ +/** +** @file elf.h +** +** @author Warren R. Carithers +** +** @brief ELF format declarations +*/ + +#ifndef ELF_H_ +#define ELF_H_ + +#include <common.h> + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +*/ + +// ELF data types (TIS ELF Spec v1.2, May 1995 +typedef uint32_t e32_a; // 32-bit unsigned address +typedef uint16_t e32_h; // 16-bit unsigned "medium" integer +typedef uint32_t e32_o; // 32-bit unsigned offset +typedef int32_t e32_sw; // 32-bit signed "large" integer +typedef uint32_t e32_w; // 32-bit unsigned "large" integer +typedef uint8_t e32_si; // 8-bit unsigned "small" integer + +// ELF magic number - first four bytes +#define ELF_MAGIC 0x464C457FU // "\x7FELF" in little-endian order +#define EI_NIDENT 16 + +union elfident_u { + uint8_t bytes[EI_NIDENT]; // array of 16 bytes + struct { + uint32_t magic; // magic number + uint8_t class; // file class + uint8_t data; // data encoding + uint8_t version; // file version + uint8_t osabi; // OS ABI identification + uint8_t abivers; // ABI version + uint8_t pad[7]; // padding to 16 bytes + } f; +}; + +// indices for byte fields in the ident array +#define EI_MAGIC 0 +# define EI_MAG0 EI_MAGIC +# define EI_MAG1 1 +# define EI_MAG2 2 +# define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_OSABI 7 +#define EI_ABIVERSION 8 + +// ELF classes +#define ELF_CLASS_NONE 0 +#define ELF_CLASS_32 1 // 32-bit objects +#define ELF_CLASS_64 2 // 64-bit objects + +// ELF data encoding +#define ELF_DATA_NONE 0 // invalid data encoding +#define ELF_DATA_2LSB 1 // two's complement little-endian +#define ELF_DATA_2MSB 2 // two's complement big-endian + +// ELF versions +#define ELF_VERSION__NONE 0 // invalid version +# define EV_NONE ELF_VERSION_NONE +#define ELF_VERSION__CURRENT 1 // current version +# define EV_CURRENT ELF_VERSION_CURRENT + +// ELF header +// +// field names are from the TIS ELF Spec v1.2, May 1995 +typedef struct elfhdr_s { + union elfident_u e_ident; // file identification + e32_h e_type; // file type + e32_h e_machine; // required architecture + e32_w e_version; // object file version + e32_a e_entry; // entry point (VA) + e32_o e_phoff; // offset to program header table (PHT) + e32_o e_shoff; // offset to section header table (SHT) + e32_w e_flags; // processor-specific flags + e32_h e_ehsize; // ELF header size (bytes) + e32_h e_phentsize; // size of one PHT entry (bytes) + e32_h e_phnum; // number of PHT entries + e32_h e_shentsize; // size of one SHT entry (bytes) + e32_h e_shnum; // number of SHT entries + e32_h e_shstrndx; // SHT index of the sect. name string table +} elfhdr_t; + +#define SZ_ELFHDR sizeof(elfhdr_t) + +// field values +// e_type +#define ET_NONE 0 // no file type +#define ET_REL 1 // relocatable file +#define ET_EXEC 2 // executable file +#define ET_DYN 3 // shared object file +#define ET_CORE 4 // core file +#define ET_LO_OS 0xfe00 // processor-specific +#define ET_HI_OS 0xfeff // processor-specific +#define ET_LO_CP 0xff00 // processor-specific +#define ET_HI_CP 0xffff // processor-specific + +// e_machine +#define EM_NONE 0x00 // no machine type +#define EM_M32 0x01 // AT&T WE 32100 +#define EM_SPARC 0x02 // SUN SPARC +#define EM_386 0x03 // Intel Architecture +#define EM_68K 0x04 // Motorola 68000 +#define EM_88K 0x05 // Motorola 88000 +#define EM_IAMCU 0x06 // Intel MCU +#define EM_860 0x07 // Intel 80860 +#define EM_MIPS 0x08 // MIPS RS3000 Big-Endian +#define EM_S370 0x09 // IBM System/370 +#define EM_MIPS_RS3_LE 0x0a // MIPS RS3000 Big-Endian +#define EM_SPARC32PLLUS 0x12 // Sun "v8plus" +#define EM_PPC 0x14 // IBM PowerPC +#define EM_PPC64 0x15 // IBM PowerPC 64-bit +#define EM_S390 0x16 // IBM System/390 +#define EM_ARM 0x28 // ARM up to V7/AArch32 +#define EM_SPARCV9 0x2b // SPARC V9 64-bit +#define EM_IA_64 0x32 // Intel Itanium (Merced) +#define EM_MIPS_X 0x32 // Stanford MIPS-X +#define EM_X86_64 0x3E // AMD x86-64 (Intel64) +#define EM_PDP11 0x40 // DEC PDP-11 +#define EM_VAX 0x4b // DEC VAX +#define EM_AARCH64 0xb7 // ARM AArch64 +#define EM_Z80 0xec // Zilog Z-80 +#define EM_AMDGPU 0xf0 // AMD GPU +#define EM_RISCV 0xf3 // RISC-V +#define EM_BPF 0xf7 // Berkeley Packet Filter + +// ELF section header +// +// field names are from the TIS ELF Spec v1.2, May 1995 +typedef struct shdr_s { + e32_w sh_name; // section name (index into string table) + e32_w sh_type; // section contents/semantics + e32_w sh_flags; // attribute flag bits + e32_a sh_addr; // 0, or load point of this section in memory + e32_o sh_offset; // byte offset within the file + e32_w sh_size; // section size in bytes + e32_w sh_link; // section header index table link + e32_w sh_info; // "extra information" + e32_w sh_addralign; // required alignment + e32_w sh_entsize; // 0, or size of each entry in the section +} elfsecthdr_t; + +#define SZ_ELFSECTHDR sizeof(elfsecthdr_t) + +// sh_name +#define SHN_UNDEF 0 + +// sh_type +#define SHT_NULL 0x00 +#define SHT_PROGBITS 0x01 +#define SHT_SYMTAB 0x02 +#define SHT_STRTAB 0x03 +#define SHT_RELA 0x04 +#define SHT_HASH 0x05 +#define SHT_DYNAMIC 0x06 +#define SHT_NOTE 0x07 +#define SHT_NOBITS 0x08 +#define SHT_REL 0x09 +#define SHT_SHLIB 0x0a +#define SHT_DYNSYM 0x0b +#define SHT_LO_CP 0x70000000 +#define SHT_HI_CP 0x7fffffff +#define SHT_LO_US 0x80000000 +#define SHT_HI_US 0x8fffffff + +// sh_flags +#define SHF_WRITE 0x001 +#define SHF_ALLOC 0x002 +#define SHF_EXECINSTR 0x004 +#define SHF_MERGE 0x010 +#define SHF_STRINGS 0x020 +#define SHF_INFO_LINK 0x040 +#define SHF_LINK_ORDER 0x080 +#define SHF_OS_NONCON 0x100 +#define SHF_GROUP 0x200 +#define SHF_TLS 0x400 +#define SHF_MASKOS 0x0ff00000 +#define SHF_MASKPROC 0xf0000000 + +// ELF program header +// +// field names are from the TIS ELF Spec v1.2, May 1995 +typedef struct phdr_s { + e32_w p_type; // type of segment + e32_o p_offset; // byte offset in file + e32_a p_va; // load point in memory (virtual address) + e32_a p_pa; // load point in memory (physical address) + e32_w p_filesz; // number of bytes in this file + e32_w p_memsz; // number of bytes in memory + e32_w p_flags; // attribute flag bits + e32_w p_align; // required alignment +} elfproghdr_t; + +#define SZ_ELFPROGHDR sizeof(elfproghdr_t) + +// p_type +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_TLS 7 +#define PT_LO_OS 0x70000000 +#define PT_HI_OS 0x7fffffff +#define PT_LO_CP 0x70000000 +#define PT_HI_CP 0x7fffffff + +// p_flags +#define PF_E 0x1 +#define PF_W 0x2 +#define PF_R 0x4 +#define PF_MASKPROC 0xf0000000 + +/* +** Globals +*/ + +/* +** Prototypes +*/ + +#endif /* !ASM_SRC */ + +#endif diff --git a/include/kdefs.h b/include/kdefs.h new file mode 100644 index 0000000..f9fe853 --- /dev/null +++ b/include/kdefs.h @@ -0,0 +1,146 @@ +/** +** @file kdefs.h +** +** @author CSCI-452 class of 20245 +** +** @brief Kernel-only declarations. +*/ + +#ifndef KDEFS_H_ +#define KDEFS_H_ + +// debugging macros +#include <debug.h> + +/* +** General (C and/or assembly) definitions +*/ + +// page sizes +#define SZ_PAGE NUM_4KB +#define SZ_BIGPAGE NUM_4MB + +// kernel stack size (bytes) +#define N_KSTKPAGES 1 +#define SZ_KSTACK (N_KSTKPAGES * SZ_PAGE) + +// user stack size +#define N_USTKPAGES 2 +#define SZ_USTACK (N_USTKPAGES * SZ_PAGE) + +// declarations for modulus checking of (e.g.) sizes and addresses + +#define MOD4_BITS 0x00000003 +#define MOD4_MASK 0xfffffffc +#define MOD4_INC 0x00000004 +#define MOD4_SHIFT 2 + +#define MOD16_BITS 0x0000000f +#define MOD16_MASK 0xfffffff0 +#define MOD16_INC 0x00000010 +#define MOD16_SHIFT 4 + +#define MOD1K_BITS 0x000003ff +#define MOD1K_MASK 0xfffffc00 +#define MOD1K_INC 0x00000400 +#define MOD1K_SHIFT 10 + +#define MOD4K_BITS 0x00000fff +#define MOD4K_MASK 0xfffff000 +#define MOD4K_INC 0x00001000 +#define MOD4K_SHIFT 12 + +#define MOD1M_BITS 0x000fffff +#define MOD1M_MASK 0xfff00000 +#define MOD1M_INC 0x00100000 +#define MOD1M_SHIFT 20 + +#define MOD1G_BITS 0x3fffffff +#define MOD1G_MASK 0xc0000000 +#define MOD1G_INC 0x40000000 +#define MOD1G_SHIFT 30 + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +*/ + +// unit conversion macros +#define B_TO_KB(x) (((uint_t)(x))>>10) +#define B_TO_MB(x) (((uint_t)(x))>>20) +#define B_TO_GB(x) (((uint_t)(x))>>30) + +#define KB_TO_B(x) (((uint_t)(x))<<10) +#define KB_TO_MB(x) (((uint_t)(x))>>10) +#define KB_TO_GB(x) (((uint_t)(x))>>20) + +#define MB_TO_B(x) (((uint_t)(x))<<20) +#define MB_TO_KB(x) (((uint_t)(x))<<10) +#define MB_TO_GB(x) (((uint_t)(x))>>10) + +#define GB_TO_B(x) (((uint_t)(x))<<30) +#define GB_TO_KB(x) (((uint_t)(x))<<20) +#define GB_TO_MB(x) (((uint_t)(x))<<10) + +// potetially useful compiler attributes +#define ALIGN(x) __attribute__((__aligned__(x))) +#define PACKED __attribute__((__packed__)) + +/* +** Utility macros +*/ + +// +// macros to clear data structures +// +// these are usable for clearing single-valued data items (e.g., +// a PCB, etc.) +#define CLEAR(v) memclr( &v, sizeof(v) ) +#define CLEAR_PTR(p) memclr( p, sizeof(*p) ) + +// +// macros for access registers and system call arguments +// + +// REG(pcb,x) -- access a specific register in a process context +#define REG(pcb,x) ((pcb)->context->x) + +// RET(pcb) -- access return value register in a process context +#define RET(pcb) ((pcb)->context->eax) + +// ARG(pcb,n) -- access argument #n from the indicated process +// +// ARG(pcb,0) --> return address +// ARG(pcb,1) --> first parameter +// ARG(pcb,2) --> second parameter +// etc. +// +// ASSUMES THE STANDARD 32-BIT ABI, WITH PARAMETERS PUSHED ONTO THE +// STACK. IF THE PARAMETER PASSING MECHANISM CHANGES, SO MUST THIS! +#define ARG(pcb,n) ( ( (uint32_t *) (((pcb)->context) + 1) ) [(n)] ) + +/* +** Types +*/ + +/* +** Globals +*/ + +// general-purpose character buffer +extern char b256[256]; + +// buffer for use by PANIC() macro +extern char b512[512]; + +// kernel stack +extern uint8_t kstack[SZ_KSTACK]; + +/* +** Prototypes +*/ + +#endif /* !ASM_SRC */ + +#endif diff --git a/include/klib.h b/include/klib.h new file mode 100644 index 0000000..c1d270c --- /dev/null +++ b/include/klib.h @@ -0,0 +1,57 @@ +/* +** @file klib.h +** +** @author Warren R. Carithers +** +** Additional support functions for the kernel. +*/ + +#ifndef KLIB_H_ +#define KLIB_H_ + +#include <common.h> + +#ifndef ASM_SRC + +#include <x86/ops.h> + +/** +** Name: put_char_or_code( ch ) +** +** Description: Prints a character on the console, unless it +** is a non-printing character, in which case its hex code +** is printed +** +** @param ch The character to be printed +*/ +void put_char_or_code( int ch ); + +/** +** Name: backtrace +** +** Perform a simple stack backtrace. Could be augmented to use the +** symbol table to print function/variable names, etc., if so desired. +** +** @param ebp Initial EBP to use +** @param args Number of function argument values to print +*/ +void backtrace( uint32_t *ebp, uint_t args ); + +/** +** Name: kpanic +** +** Kernel-level panic routine +** +** usage: kpanic( msg ) +** +** Prefix routine for panic() - can be expanded to do other things +** (e.g., printing a stack traceback) +** +** @param msg[in] String containing a relevant message to be printed, +** or NULL +*/ +void kpanic( const char *msg ); + +#endif /* !ASM_SRC */ + +#endif diff --git a/include/kmem.h b/include/kmem.h new file mode 100644 index 0000000..5a98765 --- /dev/null +++ b/include/kmem.h @@ -0,0 +1,138 @@ +/** +** @file kmem.h +** +** @author Warren R. Carithers +** @author Kenneth Reek +** @author 4003-506 class of 20013 +** +** @brief Support for dynamic memory allocation within the OS. +** +** This is a basic page allocator. Each allocation request returns +** a pointer to a single 4096-byte page of memory. +** +** The module also supports subddivision of pages into "slices", +** each of which is 1KB (i.e., 1/4 of a page). +*/ + +#ifndef KMEM_H_ +#define KMEM_H_ + +#define KERNEL_SRC + +// standard types etc. +#include <common.h> + +/* +** General (C and/or assembly) definitions +*/ + +// Slab and slice sizes, in bytes + +#define SZ_SLAB SZ_PAGE +#define SZ_SLICE (SZ_SLAB >> 2) + +// memory limits +// +// these determine the range of memory addresses the kmem +// module will manage +// +// we won't map any memory below 1MB or above 1GB +#define KM_LOW_CUTOFF NUM_1MB +#define KM_HIGH_CUTOFF NUM_1GB + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +*/ + +/* +** Types +*/ + +/* +** Globals +*/ + +/* +** Prototypes +*/ + +/** +** Name: km_init +** +** Find what memory is present on the system and +** construct the list of free memory blocks. +** +** Dependencies: +** Must be called before any other init routine that uses +** dynamic storage is called. +*/ +void km_init( void ); + +/** +** Name: km_dump +** +** Dump information about the free lists to the console. By default, +** prints only the list sizes; if 'addrs' is true, also dumps the list +** of page addresses; if 'all' is also true, dumps page addresses and +** slice addresses. +** +** @param addrs Also dump page addresses +** @param both Also dump slice addresses +*/ +void km_dump( bool_t addrs, bool_t both ); + +/* +** Functions that manipulate free memory blocks. +*/ + +/** +** Name: km_page_alloc +** +** Allocate a page of memory from the free list. +** +** @return a pointer to the beginning of the allocated page, +** or NULL if no memory is available +*/ +void *km_page_alloc( void ); + +/** +** Name: km_page_free +** +** Returns a memory block to the list of available blocks, +** combining it with adjacent blocks if they're present. +** +** CRITICAL ASSUMPTION: multi-page blocks will be freed one page +** at a time! +** +** @param[in] block Pointer to the page to be returned to the free list +*/ +void km_page_free( void *block ); + +/** +** Name: km_slice_alloc +** +** Dynamically allocates a slice (1/4 of a page). If no +** memory is available, we return NULL (unless ALLOC_FAIL_PANIC +** was defined, in which case we panic). +** +** @return a pointer to the allocated slice +*/ +void *km_slice_alloc( void ); + +/** +** Name: km_slice_free +** +** Returns a slice to the list of available slices. +** +** We make no attempt to merge slices, as they are independent +** blocks of memory (unlike pages). +** +** @param[in] block Pointer to the slice (1/4 page) to be freed +*/ +void km_slice_free( void *block ); + +#endif /* !ASM_SRC */ + +#endif diff --git a/include/lib.h b/include/lib.h new file mode 100644 index 0000000..bd19111 --- /dev/null +++ b/include/lib.h @@ -0,0 +1,287 @@ +/** +** @file lib.h +** +** @author Numerous CSCI-452 classes +** +** @brief C declarations of common library functions +** +** These are callable from either kernel or user code. Care should be taken +** that user code is linked against these separately from kernel code, to +** ensure separation of the address spaces. +*/ + +#ifndef LIB_H_ +#define LIB_H_ + +#ifndef ASM_SRC + +#include <common.h> + +/* +********************************************** +** MEMORY MANIPULATION FUNCTIONS +********************************************** +*/ + +/** +** memset(buf,len,value) +** +** initialize all bytes of a block of memory to a specific value +** +** @param buf The buffer to initialize +** @param len Buffer size (in bytes) +** @param value Initialization value +*/ +void memset( void *buf, register uint32_t len, register uint32_t value ); + +/** +** memclr(buf,len) +** +** Initialize all bytes of a block of memory to zero +** +** @param buf The buffer to initialize +** @param len Buffer size (in bytes) +*/ +void memclr( void *buf, register uint32_t len ); + +/** +** memcpy(dst,src,len) +** +** Copy a block from one place to another +** +** May not correctly deal with overlapping buffers +** +** @param dst Destination buffer +** @param src Source buffer +** @param len Buffer size (in bytes) +*/ +void memcpy( void *dst, register const void *src, register uint32_t len ); + +/* +********************************************** +** STRING MANIPULATION FUNCTIONS +********************************************** +*/ + +/** +** str2int(str,base) - convert a string to a number in the specified base +** +** @param str The string to examine +** @param base The radix to use in the conversion +** +** @return The converted integer +*/ +int str2int( register const char *str, register int base ); + +/** +** strlen(str) - return length of a NUL-terminated string +** +** @param str The string to examine +** +** @return The length of the string, or 0 +*/ +uint32_t strlen( register const char *str ); + +/** +** strcmp(s1,s2) - compare two NUL-terminated strings +** +** @param s1 The first source string +** @param s2 The second source string +** +** @return negative if s1 < s2, zero if equal, and positive if s1 > s2 +*/ +int strcmp( register const char *s1, register const char *s2 ); + +/** +** strcpy(dst,src) - copy a NUL-terminated string +** +** @param dst The destination buffer +** @param src The source buffer +** +** @return The dst parameter +** +** NOTE: assumes dst is large enough to hold the copied string +*/ +char *strcpy( register char *dst, register const char *src ); + +/** +** strcat(dst,src) - append one string to another +** +** @param dst The destination buffer +** @param src The source buffer +** +** @return The dst parameter +** +** NOTE: assumes dst is large enough to hold the resulting string +*/ +char *strcat( register char *dst, register const char *src ); + +/** +** pad(dst,extra,padchar) - generate a padding string +** +** @param dst Pointer to where the padding should begin +** @param extra How many padding bytes to add +** @param padchar What character to pad with +** +** @return Pointer to the first byte after the padding +** +** NOTE: does NOT NUL-terminate the buffer +*/ +char *pad( char *dst, int extra, int padchar ); + +/** +** padstr(dst,str,len,width,leftadjust,padchar - add padding characters +** to a string +** +** @param dst The destination buffer +** @param str The string to be padded +** @param len The string length, or -1 +** @param width The desired final length of the string +** @param leftadjust Should the string be left-justified? +** @param padchar What character to pad with +** +** @return Pointer to the first byte after the padded string +** +** NOTE: does NOT NUL-terminate the buffer +*/ +char *padstr( char *dst, char *str, int len, int width, + int leftadjust, int padchar ); + +/** +** sprint(dst,fmt,...) - formatted output into a string buffer +** +** @param dst The string buffer +** @param fmt Format string +** +** The format string parameter is followed by zero or more additional +** parameters which are interpreted according to the format string. +** +** NOTE: assumes the buffer is large enough to hold the result string +** +** NOTE: relies heavily on the x86 parameter passing convention +** (parameters are pushed onto the stack in reverse order as +** 32-bit values). +*/ +void sprint( char *dst, char *fmt, ... ); + +/* +********************************************** +** CONVERSION FUNCTIONS +********************************************** +*/ + +/** +** cvtuns0(buf,value) - local support routine for cvtuns() +** +** Convert a 32-bit unsigned value into a NUL-terminated character string +** +** @param buf Result buffer +** @param value Value to be converted +** +** @return Pointer to the first unused byte in the buffer +** +** NOTE: assumes buf is large enough to hold the resulting string +*/ +char *cvtuns0( char *buf, uint32_t value ); + +/** +** cvtuns(buf,value) +** +** Convert a 32-bit unsigned value into a NUL-terminated character string +** +** @param buf Result buffer +** @param value Value to be converted +** +** @return Length of the resulting buffer +** +** NOTE: assumes buf is large enough to hold the resulting string +*/ +int cvtuns( char *buf, uint32_t value ); + +/** +** cvtdec0(buf,value) - local support routine for cvtdec() +** +** convert a 32-bit unsigned integer into a NUL-terminated character string +** +** @param buf Destination buffer +** @param value Value to convert +** +** @return The number of characters placed into the buffer +** (not including the NUL) +** +** NOTE: assumes buf is large enough to hold the resulting string +*/ +char *cvtdec0( char *buf, int value ); + +/** +** cvtdec(buf,value) +** +** convert a 32-bit signed value into a NUL-terminated character string +** +** @param buf Destination buffer +** @param value Value to convert +** +** @return The number of characters placed into the buffer +** (not including the NUL) +** +** NOTE: assumes buf is large enough to hold the resulting string +*/ +int cvtdec( char *buf, int32_t value ); + +/** +** cvthex(buf,value) +** +** convert a 32-bit unsigned value into a mininal-length (up to +** 8-character) NUL-terminated character string +** +** @param buf Destination buffer +** @param value Value to convert +** +** @return The number of characters placed into the buffer +** (not including the NUL) +** +** NOTE: assumes buf is large enough to hold the resulting string +*/ +int cvthex( char *buf, uint32_t value ); + +/** +** cvtoct(buf,value) +** +** convert a 32-bit unsigned value into a mininal-length (up to +** 11-character) NUL-terminated character string +** +** @param buf Destination buffer +** @param value Value to convert +** +** @return The number of characters placed into the buffer +** (not including the NUL) +** +** NOTE: assumes buf is large enough to hold the resulting string +*/ +int cvtoct( char *buf, uint32_t value ); + +/** +** bound(min,value,max) +** +** This function confines an argument within specified bounds. +** +** @param min Lower bound +** @param value Value to be constrained +** @param max Upper bound +** +** @return The constrained value +*/ +uint32_t bound( uint32_t min, uint32_t value, uint32_t max ); + +#endif /* !ASM_SRC */ + +/* +** Finally, pull in the level-specific library headers +*/ +#ifdef KERNEL_SRC +#include <klib.h> +#else +#include <ulib.h> +#endif /* KERNEL_SRC */ + +#endif diff --git a/include/list.h b/include/list.h new file mode 100644 index 0000000..28c2377 --- /dev/null +++ b/include/list.h @@ -0,0 +1,68 @@ +/** +** @file list.h +** +** @author Warren R. Carithers +** +** @brief Support for a basic linked list data type. +** +** This module provides a very basic linked list data structure. +** A list can contain anything that has a pointer field in the first +** four bytes; these routines assume those bytes contain a pointer to +** the following entry in the list, whatever that may be. +*/ + +#ifndef LIST_H_ +#define LIST_H_ + +#define KERNEL_SRC + +// standard types etc. +#include <common.h> + +/* +** General (C and/or assembly) definitions +*/ + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +*/ + +/* +** Data types +*/ + +// The list structure +typedef struct list_s { + struct list_s *next; // link to the successor +} list_t; + +/* +** Prototypes +*/ + +/** +** Name: list_add +** +** Add the supplied data to the beginning of the specified list. +** +** @param[in,out] list The address of a list_t variable +** @param[in] data The data to prepend to the list +*/ +void list_add( list_t *list, void *data ); + +/** +** Name: list_remove +** +** Remove the first entry from a linked list. +** +** @param[in,out] list The address of a list_t variable +** +** @return a pointer to the removed data, or NULL if the list was empty +*/ +void *list_remove( list_t *list ); + +#endif /* !ASM_SRC */ + +#endif diff --git a/include/params.h b/include/params.h new file mode 100644 index 0000000..52eb81d --- /dev/null +++ b/include/params.h @@ -0,0 +1,31 @@ +/** +** @file params.h +** +** @author CSCI-452 class of 20245 +** +** @brief System configuration settings +** +** This header file contains many of the "easily tunable" system +** settings, such as clock rate, number of simultaneous user +** processes, etc. This provides a sort of "one-stop shop" for +** things that might be tweaked frequently. +*/ + +#ifndef PARAMS_H_ +#define PARAMS_H_ + +/* +** General (C and/or assembly) definitions +*/ + +// Upper bound on the number of simultaneous user-level +// processes in the system (completely arbitrary) + +#define N_PROCS 25 + +// Clock frequency (Hz) + +#define CLOCK_FREQ 1000 +#define TICKS_PER_MS 1 + +#endif diff --git a/include/procs.h b/include/procs.h new file mode 100644 index 0000000..9db4ac8 --- /dev/null +++ b/include/procs.h @@ -0,0 +1,452 @@ +/* +** @file procs.h +** +** @author CSCI-452 class of 20245 +** +** @brief Process-related declarations +*/ + +#ifndef PROCS_H_ +#define PROCS_H_ + +#include <common.h> + +/* +** General (C and/or assembly) definitions +*/ + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +*/ + +/* +** Types +*/ + +/* +** Process states +*/ +enum state_e { + // pre-viable + STATE_UNUSED = 0, STATE_NEW, + // runnable + STATE_READY, STATE_RUNNING, + // runnable, but waiting for some event + STATE_SLEEPING, STATE_BLOCKED, STATE_WAITING, + // no longer runnable + STATE_KILLED, STATE_ZOMBIE + // sentinel value + , N_STATES +}; + +// these may be handy for checking general conditions of processes +// they depend on the order of the state names in the enum! +#define FIRST_VIABLE STATE_READY +#define FIRST_BLOCKED STATE_SLEEPING +#define LAST_VIABLE STATE_WAITING + +/* +** Process priorities are defined in <defs.h> +*/ + +/* +** Quantum lengths - values are number of clock ticks +*/ +enum quantum_e { + QUANTUM_SHORT = 1, + QUANTUM_STANDARD = 3, + QUANTUM_LONG = 5 +}; + +/* +** PID-related definitions +*/ +#define PID_INIT 1 +#define FIRST_USER_PID 2 + +/* +** Process context structure +** +** NOTE: the order of data members here depends on the +** register save code in isr_stubs.S!!!! +** +** This will be at the top of the user stack when we enter +** an ISR. In the case of a system call, it will be followed +** by the return address and the system call parameters. +*/ + +typedef struct context_s { + uint32_t ss; // pushed by isr_save + uint32_t gs; + uint32_t fs; + uint32_t es; + uint32_t ds; + uint32_t edi; + uint32_t esi; + uint32_t ebp; + uint32_t esp; + uint32_t ebx; + uint32_t edx; + uint32_t ecx; + uint32_t eax; + uint32_t vector; + uint32_t code; // pushed by isr_save or the hardware + uint32_t eip; // pushed by the hardware + uint32_t cs; + uint32_t eflags; +} context_t; + +#define SZ_CONTEXT sizeof(context_t) + +/* +** program section information for user processes +*/ + +typedef struct section_s { + uint_t length; // length, in some units + uint_t addr; // location, in some units +} section_t; + +// note: these correspond to the PT_LOAD sections found in +// an ELF file, not necessarily to text/data/bss +#define SECT_L1 0 +#define SECT_L2 1 +#define SECT_L3 2 +#define SECT_STACK 3 + +// total number of section table entries in our PCB +#define N_SECTS 4 +// number of those that can be loaded from an ELF module +#define N_LOADABLE 3 + +/* +** The process control block +** +** Fields are ordered by size to avoid padding +** +** Currently, this is 72 bytes long. It could be reduced to 64 (2^6) +** bytes by making the last four fields uint16_t types; that would +** divide nicely into 1024 bytes, giving 16 PCBs per 1/4 page of memory. +*/ + +typedef struct pcb_s { + + // four-byte fields + // start with these four bytes, for easy access in assembly + context_t *context; // pointer to context save area on stack + + // VM information + pde_t *pdir; // page directory for this process + section_t sects[N_SECTS]; // per-section memory information + + // queue linkage + struct pcb_s *next; // next PCB in queue + + // process state information + struct pcb_s *parent; // pointer to PCB of our parent process + uint32_t wakeup; // wakeup time, for sleeping processes + int32_t exit_status; // termination status, for parent's use + + // these things may not need to be four bytes + uint_t pid; // PID of this process + enum state_e state; // process' current state + enum priority_e priority; // process priority level + uint_t ticks; // remaining ticks in this time slice + +} pcb_t; + +#define SZ_PCB sizeof(pcb_t) + +/* +** PCB queue structure (opaque to the rest of the kernel) +*/ +typedef struct pcb_queue_s *pcb_queue_t; + +/* +** Queue ordering methods +*/ +enum pcb_queue_order_e { + O_FIFO, O_PRIO, O_PID, O_WAKEUP + // sentinel + , N_ORDERINGS +}; +#define O_FIRST_STYLE O_FIFO +#define O_LAST_STYLE O_WAKEUP + +/* +** Globals +*/ + +// public-facing queue handles +extern pcb_queue_t pcb_freelist; +extern pcb_queue_t ready; +extern pcb_queue_t waiting; +extern pcb_queue_t sleeping; +extern pcb_queue_t zombie; +extern pcb_queue_t sioread; + +// pointer to the currently-running process +extern pcb_t *current; + +// the process table +extern pcb_t ptable[N_PROCS]; + +// next available PID +extern uint_t next_pid; + +// pointer to the PCB for the 'init' process +extern pcb_t *init_pcb; + +// table of state name strings +extern const char *state_str[N_STATES]; + +// table of priority name strings +extern const char *prio_str[N_PRIOS]; + +// table of queue ordering name strings +extern const char *ord_str[N_ORDERINGS]; + +/* +** Prototypes +*/ + +/** +** Name: pcb_init +** +** Initialization for the Process module. +*/ +void pcb_init( void ); + +/** +** Name: pcb_alloc +** +** Allocate a PCB from the list of free PCBs. +** +** @param pcb Pointer to a pcb_t * where the PCB pointer will be returned. +** +** @return status of the allocation attempt +*/ +int pcb_alloc( pcb_t **pcb ); + +/** +** Name: pcb_free +** +** Return a PCB to the list of free PCBs. +** +** @param pcb Pointer to the PCB to be deallocated. +*/ +void pcb_free( pcb_t *pcb ); + +/** +** Name: pcb_zombify +** +** Turn the indicated process into a Zombie. This function +** does most of the real work for exit() and kill() calls. +** Is also called from the scheduler and dispatcher. +** +** @param pcb Pointer to the newly-undead PCB +*/ +void pcb_zombify( register pcb_t *victim ); + +/** +** Name: pcb_cleanup +** +** Reclaim a process' data structures +** +** @param pcb The PCB to reclaim +*/ +void pcb_cleanup( pcb_t *pcb ); + +/** +** Name: pcb_find_pid +** +** Locate the PCB for the process with the specified PID +** +** @param pid The PID to be located +** +** @return Pointer to the PCB, or NULL +*/ +pcb_t *pcb_find_pid( uint_t pid ); + +/** +** Name: pcb_find_ppid +** +** Locate the PCB for the process with the specified parent +** +** @param pid The PID to be located +** +** @return Pointer to the PCB, or NULL +*/ +pcb_t *pcb_find_ppid( uint_t pid ); + +/** +** Name: pcb_queue_reset +** +** Initialize a PCB queue. +** +** @param queue[out] The queue to be initialized +** @param order[in] The desired ordering for the queue +** +** @return status of the init request +*/ +int pcb_queue_reset( pcb_queue_t queue, enum pcb_queue_order_e style ); + +/** +** Name: pcb_queue_empty +** +** Determine whether a queue is empty. Essentially just a wrapper +** for the PCB_QUEUE_EMPTY() macro, for use outside this module. +** +** @param[in] queue The queue to check +** +** @return true if the queue is empty, else false +*/ +bool_t pcb_queue_empty( pcb_queue_t queue ); + +/** +** Name: pcb_queue_length +** +** Return the count of elements in the specified queue. +** +** @param[in] queue The queue to check +** +** @return the count (0 if the queue is empty) +*/ +uint_t pcb_queue_length( const pcb_queue_t queue ); + +/** +** Name: pcb_queue_insert +** +** Inserts a PCB into the indicated queue. +** +** @param queue[in,out] The queue to be used +** @param pcb[in] The PCB to be inserted +** +** @return status of the insertion request +*/ +int pcb_queue_insert( pcb_queue_t queue, pcb_t *pcb ); + +/** +** Name: pcb_queue_peek +** +** Return the first PCB from the indicated queue, but don't +** remove it from the queue +** +** @param queue[in] The queue to be used +** +** @return the PCB pointer, or NULL if the queue is empty +*/ +pcb_t *pcb_queue_peek( const pcb_queue_t queue ); + +/** +** Name: pcb_queue_remove +** +** Remove the first PCB from the indicated queue. +** +** @param queue[in,out] The queue to be used +** @param pcb[out] Pointer to where the PCB pointer will be saved +** +** @return status of the removal request +*/ +int pcb_queue_remove( pcb_queue_t queue, pcb_t **pcb ); + +/** +** Name: pcb_queue_remove_this +** +** Remove the specified PCB from the indicated queue. +** +** @param queue[in,out] The queue to be used +** @param pcb[in] Pointer to the PCB to be removed +** +** @return status of the removal request +*/ +int pcb_queue_remove_this( pcb_queue_t queue, pcb_t *pcb ); + +/* +** Scheduler routines +*/ + +/** +** schedule(pcb) +** +** Schedule the supplied process +** +** @param pcb Pointer to the PCB of the process to be scheduled +*/ +void schedule( pcb_t *pcb ); + +/** +** dispatch() +** +** Select the next process to receive the CPU +*/ +void dispatch( void ); + +/* +** Debugging/tracing routines +*/ + +/** +** Name: ctx_dump +** +** Dumps the contents of this process context to the console +** +** @param msg[in] An optional message to print before the dump +** @param c[in] The context to dump out +*/ +void ctx_dump( const char *msg, register context_t *c ); + +/** +** Name: ctx_dump_all +** +** dump the process context for all active processes +** +** @param msg[in] Optional message to print +*/ +void ctx_dump_all( const char *msg ); + +/** +** Name: pcb_dump +** +** Dumps the contents of this PCB to the console +** +** @param msg[in] An optional message to print before the dump +** @param p[in] The PCB to dump +** @param all[in] Dump all the contents? +*/ +void pcb_dump( const char *msg, register pcb_t *p, bool_t all ); + +/** +** Name: pcb_queue_dump +** +** Dump the contents of the specified queue to the console +** +** @param msg[in] An optional message to print before the dump +** @param queue[in] The queue to dump +** @param contents[in] Also dump (some) contents? +*/ +void pcb_queue_dump( const char *msg, pcb_queue_t queue, bool_t contents ); + +/** +** Name: ptable_dump +** +** dump the contents of the "active processes" table +** +** @param msg[in] Optional message to print +** @param all[in] Dump all or only part of the relevant data +*/ +void ptable_dump( const char *msg, bool_t all ); + +/** +** Name: ptable_dump_counts +** +** Prints basic information about the process table (number of +** entries, number with each process state, etc.). +*/ +void ptable_dump_counts( void ); + +#endif /* !ASM_SRC */ + +#endif diff --git a/include/sio.h b/include/sio.h new file mode 100644 index 0000000..dca80ed --- /dev/null +++ b/include/sio.h @@ -0,0 +1,168 @@ +/** +** @file sio.h +** +** @author Warren R. Carithers +** +** @brief SIO definitions +*/ + +#ifndef SIO_H_ +#define SIO_H_ + +// compatibility definitions +#include <compat.h> + +/* +** General (C and/or assembly) definitions +*/ + +// sio interrupt settings + +#define SIO_TX 0x01 +#define SIO_RX 0x02 +#define SIO_BOTH (SIO_TX | SIO_RX) + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +*/ + +#include <common.h> + +#include <procs.h> + +/* +** PUBLIC GLOBAL VARIABLES +*/ + +// queue for read-blocked processes +extern QTYPE QNAME; + +/* +** PUBLIC FUNCTIONS +*/ + +/** +** sio_init() +** +** Initialize the UART chip. +*/ +void sio_init( void ); + +/** +** sio_enable() +** +** Enable SIO interrupts +** +** usage: uint8_t old = sio_enable( uint8_t which ) +** +** @param which Bit mask indicating which interrupt(s) to enable +** +** @return the prior IER setting +*/ +uint8_t sio_enable( uint8_t which ); + +/** +** sio_disable() +** +** Disable SIO interrupts +** +** usage: uint8_t old = sio_disable( uint8_t which ) +** +** @param which Bit mask indicating which interrupt(s) to disable +** +** @return the prior IER setting +*/ +uint8_t sio_disable( uint8_t which ); + +/** +** sio_inq_length() +** +** Get the input queue length +** +** usage: int num = sio_inq_length() +** +** @return the count of characters still in the input queue +*/ +int sio_inq_length( void ); + +/** +** sio_readc() +** +** Get the next input character +** +** usage: int ch = sio_readc() +** +** @return the next character, or -1 if no character is available +*/ +int sio_readc( void ); + +/** +** sio_read() +** +** Read the entire input buffer into a user buffer of a specified size +** +** usage: int num = sio_read( char *buffer, int length ) +** +** @param buf The destination buffer +** @param length Length of the buffer +** +** @return the number of bytes copied, or 0 if no characters were available +*/ +int sio_read( char *buffer, int length ); + +/** +** sio_writec( ch ) +** +** Write a character to the serial output +** +** usage: sio_writec( int ch ) +** +** @param ch Character to be written (in the low-order 8 bits) +*/ +void sio_writec( int ch ); + +/** +** sio_write( ch ) +** +** Write a buffer of characters to the serial output +** +** usage: int num = sio_write( const char *buffer, int length ) +** +** @param buffer Buffer containing characters to write +** @param length Number of characters to write +** +** @return the number of characters copied into the SIO output buffer +*/ +int sio_write( const char *buffer, int length ); + +/** +** sio_puts( buf ) +** +** Write a NUL-terminated buffer of characters to the serial output +** +** usage: n = sio_puts( const char *buffer ); +** +** @param buffer The buffer containing a NUL-terminated string +** +** @return the count of bytes transferred +*/ +int sio_puts( const char *buffer ); + +/** +** sio_dump( full ) +** +** Dump the contents of the SIO buffers to the console +** +** usage: sio_dump(true) or sio_dump(false) +** +** @param full Boolean indicating whether or not a "full" dump +** is being requested (which includes the contents +** of the queues) +*/ +void sio_dump( bool_t full ); + +#endif /* !ASM_SRC */ + +#endif diff --git a/include/support.h b/include/support.h new file mode 100644 index 0000000..bdc5dc6 --- /dev/null +++ b/include/support.h @@ -0,0 +1,87 @@ +/** +** SCCS ID: @(#)support.h 2.3 1/22/25 +** +** @file support.h +** +** @author K. Reek +** @author Warren R. Carithers +** +** Declarations for functions provided in support.c, and +** some hardware characteristics needed in the initialization. +** +*/ + +#ifndef SUPPORT_H +#define SUPPORT_H + +/* +** Delay values +** +** Notes: The parameter to the delay() function is ambiguous; it +** purports to indicate a delay length, but that isn't really tied +** to any real-world time measurement. +** +** On the original systems we used (dual 500MHz Intel P3 CPUs), each +** "unit" was approximately one tenth of a second, so delay(10) would +** delay for about one second. +** +** On the current machines (Intel Core i5-7500), delay(100) is about +** 2.5 seconds, so each "unit" is roughly 0.025 seconds. +** +** Ultimately, just remember that THESE VALUES ARE APPROXIMATE AT BEST. +*/ +#define DELAY_1_SEC 40 +#define DELAY_1_25_SEC 50 +#define DELAY_2_SEC 80 +#define DELAY_2_5_SEC 100 +#define DELAY_3_SEC 120 +#define DELAY_5_SEC 200 +#define DELAY_7_SEC 280 +#define DELAY_10_SEC 400 + +#ifndef ASM_SRC +/** +** panic +** +** Called when we find an unrecoverable error, this routine disables +** interrupts, prints a description of the error and then goes into a +** hard loop to prevent any further processing. +** +** @param reason NUL-terminated message to be printed. +*/ +void panic( char *reason ); + +/** +** init_interrupts +** +** (Re)initilizes the interrupt system. This includes initializing the +** IDT and the PIC. It is up to the user to enable processor interrupts +** when they're ready. +*/ +void init_interrupts( void ); + +/* +** install_isr +** +** Installs a second-level handler for a specific interrupt. Returns the +** previously-installed handler for reinstallation (if desired). +** +** @param vector the interrupt vector number +** @param handler the second-stage ISR function to be called by the stub +** +** @return a pointer to the previously-registered ISR +*/ +void (*install_isr( int vector, + void ( *handler )(int,int) ) )( int, int ); + +/* +** Name: delay +** +** See the comment above about the relative accuracy of the 'length' +** parameter. +*/ +void delay( int length ); + +#endif /* !ASM_SRC */ + +#endif diff --git a/include/syscalls.h b/include/syscalls.h new file mode 100644 index 0000000..e66f6c0 --- /dev/null +++ b/include/syscalls.h @@ -0,0 +1,80 @@ +/** +** @file syscalls.h +** +** @author CSCI-452 class of 20245 +** +** @brief System call declarations +*/ + +#ifndef SYSCALLS_H_ +#define SYSCALLS_H_ + +#include <common.h> + +/* +** General (C and/or assembly) definitions +*/ + +/* +** system call codes +** +** these are used in the user-level C library stub functions, +** and are defined here as CPP macros instead of as an enum +** so that they can be used from assembly +*/ + +#define SYS_exit 0 +#define SYS_waitpid 1 +#define SYS_fork 2 +#define SYS_exec 3 +#define SYS_read 4 +#define SYS_write 5 +#define SYS_getpid 6 +#define SYS_getppid 7 +#define SYS_gettime 8 +#define SYS_getprio 9 +#define SYS_setprio 10 +#define SYS_kill 11 +#define SYS_sleep 12 + +// UPDATE THIS DEFINITION IF MORE SYSCALLS ARE ADDED! +#define N_SYSCALLS 13 + +// dummy system call code for testing our ISR +#define SYS_bogus 0xbad + +// interrupt vector entry for system calls +#define VEC_SYSCALL 0x80 + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +*/ + +/* +** Types +*/ + +/* +** Globals +*/ + +/* +** Prototypes +*/ + +#ifdef KERNEL_SRC + +/** +** Name: sys_init +** +** Syscall module initialization routine +*/ +void sys_init( void ); + +#endif /* KERNEL_SRC */ + +#endif /* !ASM_SRC */ + +#endif diff --git a/include/types.h b/include/types.h new file mode 100644 index 0000000..2f934f1 --- /dev/null +++ b/include/types.h @@ -0,0 +1,58 @@ +/** +** @file types.h +** +** @author Warren R. Carithers +** +** @brief Common type declarations. +** +** This header file contains type declarations used throughout +** the kernel and user code. +*/ + +#ifndef TYPES_H_ +#define TYPES_H_ + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +** +** Anything that should not be visible to something other than +** the C compiler should be put here. +*/ + +/* +** Types +*/ + +// standard integer sized types +typedef char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned int uint32_t; +typedef long long int int64_t; +typedef unsigned long long int uint64_t; + +// other integer types +typedef unsigned char uchar_t; +typedef unsigned int uint_t; +typedef unsigned long int ulong_t; + +// Boolean values +typedef uint8_t bool_t; + +#define true 1 +#define false 0 + +#ifdef KERNEL_SRC +// we define these here instead of in vm.h in order to get around a +// nasty chick/egg dependency between procs.h and vm.h +typedef uint32_t pde_t; // page directory entry +typedef uint32_t pte_t; // page table entry +#endif /* KERNEL_SRC */ + +#endif /* !ASM_SRC */ + +#endif diff --git a/include/udefs.h b/include/udefs.h new file mode 100644 index 0000000..50b6952 --- /dev/null +++ b/include/udefs.h @@ -0,0 +1,113 @@ +/** +** @file udefs.h +** +** @author CSCI-452 class of 20245 +** +** @brief "Userland" configuration information +*/ + +#ifndef UDEFS_H_ +#define UDEFS_H_ + +#include <common.h> + +/* +** General (C and/or assembly) definitions +** +** This section of the header file contains definitions that can be +** used in either C or assembly-language source code. +*/ + +// delay loop counts + +#define DELAY_LONG 100000000 +#define DELAY_MED 4500000 +#define DELAY_SHORT 2500000 + +#define DELAY_STD DELAY_SHORT + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +*/ + +// convenience macros + +// a delay loop - kind of ugly, but it works + +#define DELAY(n) do { \ + for(int _dlc = 0; _dlc < (DELAY_##n); ++_dlc) continue; \ + } while(0) + +/* +** We need the list of program IDs so that we can request +** their execution +*/ + +#include <userids.h> + +/* +** All user main() functions have the following prototype: +** +** int name( int argc, char *argv[] ); +** +** To simplify declaring them, we define a macro that expands into +** that header. This can be used both in the implementation (followed +** by the function body) and in places where we just need the prototype +** (following it with a semicolon). +*/ + +#define USERMAIN(f) int f( int argc, char *argv[] ) + +/* +** User process controls. +** +** To enable a specific test, define the symbol SPAWN_name here, and +** guard the places in other code that use or refer to that test. For +** example, test 'A' is enabled by definining SPAWN_A here, and all +** places that refer to test 'A' are guarded with: +** +** #ifdef SPAWN_A +** ... conditionally-compiled code +** #endif +** +** Generally, most of these will exit with a status of 0. If a process +** returns from its main function when it shouldn't (e.g., if it had +** called exit() but continued to run), it will usually return a status +** of ?. +*/ + +/* +** The standard set of test programs, start by the shell (which is started +** automatically from the initial user process) +** +** There is no user 'O' program, and programs 'W' through 'Z' are spawned +** from other processes and are never spawned directly. +*/ + +#define SPAWN_A +#define SPAWN_B +#define SPAWN_C +#define SPAWN_D +#define SPAWN_E +#define SPAWN_F +#define SPAWN_G +#define SPAWN_H +#define SPAWN_I +#define SPAWN_J +#define SPAWN_K +#define SPAWN_L +#define SPAWN_M +#define SPAWN_N +#define SPAWN_P +#define SPAWN_Q +#define SPAWN_R +#define SPAWN_S +#define SPAWN_T +#define SPAWN_U +#define SPAWN_V + +#endif /* !ASM_SRC */ + +#endif diff --git a/include/ulib.h b/include/ulib.h new file mode 100644 index 0000000..d254d6a --- /dev/null +++ b/include/ulib.h @@ -0,0 +1,315 @@ +/** +** @file ulib.h +** +** @author CSCI-452 class of 20245 +** +** @brief Declarations for user-level library functions +** +** This module implements a simple collection of support functions +** similar to the standard C library. +*/ + +#ifndef ULIB_H_ +#define ULIB_H_ + +#include <common.h> + +/* +** General (C and/or assembly) definitions +*/ + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +*/ + +/* +** Types +*/ + +/* +** Globals +*/ + +/* +** Prototypes +*/ + +/* +************************************************* +** SYSTEM CALLS ********************************* +************************************************* +*/ + +/** +** exit - terminate the calling process +** +** usage: exit(status); +** +** @param status Termination status of this process +** +** Does not return. +*/ +void exit( int32_t status ); + +/** +** waitpid - wait for a child process to terminate +** +** usage: pid = waitpid(pid,&status); +** +** @param pid PID of the desired child, or 0 for any child +** @param status Pointer to int32_t into which the child's status is placed, +** or NULL +** +** @return The PID of the terminated child, or an error code +** +** If there are no children in the system, returns an error code (*status +** is unchanged). +** +** If there are one or more children in the system and at least one has +** terminated but hasn't yet been cleaned up, cleans up that process and +** returns its information; otherwise, blocks until a child terminates. +*/ +int waitpid( uint_t pid, int32_t *status ); + +/** +** fork - create a duplicate of the calling process +** +** usage: pid = fork(); +** +** @return parent - the pid of the new child, or an error code +** child - 0 +*/ +int fork( void ); + +/** +** exec - replace the memory image of the calling process +** +** usage: exec( what, args ) +** +** @param what program table index of the program to exec +** @param args the command-line argument vector +** +** Does not return if it succeeds; if it returns, something has +** gone wrong. +*/ +void exec( uint_t what, char **args ); + +/** +** read - read into a buffer from a stream +** +** usage: n = read(channel,buf,length) +** +** @param chan I/O stream to read from +** @param buf Buffer to read into +** @param length Maximum capacity of the buffer +** +** @return The count of bytes transferred, or an error code +*/ +int read( uint_t chan, void *buffer, uint_t length ); + +/** +** write - write from a buffer to a stream +** +** usage: n = write(channel,buf,length) +** +** @param chan I/O stream to write to +** @param buf Buffer to write from +** @param length Maximum capacity of the buffer +** +** @return The count of bytes transferred, or an error code +*/ +int write( uint_t chan, const void *buffer, uint_t length ); + +/** +** getpid - get the PID of the calling process +** +** usage: pid = getpid() +** +** @return the PID of this process +*/ +uint_t getpid( void ); + +/** +** getppid - get the PID of the calling process' parent +** +** usage: pid = getppid() +** +** @return the PID of this process' parent +*/ +uint_t getppid( void ); + +/** +** gettime - get the current system time +** +** usage: pid = gettime() +** +** @return the system time +*/ +uint32_t gettime( void ); + +/** +** getprio - get the scheduling priority of the calling process +** +** usage: prio = getprio() +** +** @return the process' priority +*/ +int getprio( void ); + +/** +** setprio - set the scheduling priority of the calling process +** +** usage: oldprio = setprio(newprio) +** +** @param new the desired new priority +** +** @return the old priority value +*/ +int setprio( int new ); + +/** +** kill - terminate a process with extreme prejudice +** +** usage: n = kill( pid ) +** +** @param pid the intended victim +** +** @return 0 on success, else an error code +*/ +int32_t kill( uint_t pid ); + +/** +** sleep - put the current process to sleep for some length of time +** +** usage: sleep(n); +** +** @param ms Desired sleep time (in ms), or 0 to yield the CPU +** +** @return the time the process spent sleeping (in ms) +*/ +int sleep( uint32_t ms ); + +/** +** bogus - a nonexistent system call, to test our syscall ISR +** +** usage: bogus() +** +** Does not return. +*/ +void bogus( void ); + +/* +************************************************* +** CONVENIENT "SHORTHAND" VERSIONS OF SYSCALLS ** +************************************************* +** +** These are library functions that perform specific common +** variants of system calls. This helps reduce the total number +** of system calls, keeping our baseline OS as lean and mean +** as we can make it. :-) +*/ + +/** +** wait - wait for any child to exit +** +** usage: pid = wait(&status) +** +** Calls waitpid(0,status) +** +** @param status Pointer to int32_t into which the child's status is placed, +** or NULL +** +** @return The PID of the terminated child, or an error code +*/ +int wait( int32_t *status ); + +/** +** spawn - create a new process running a different program +** +** usage: n = spawn(what,args) +** +** Creates a new process and then execs 'what' +** +** @param what Program table index of the program to spawn +** @param args The command-line argument vector for the process +** +** @return The PID of the child, or an error code +*/ +int spawn( uint_t what, char **args ); + +/** +** cwritech(ch) - write a single character to the console +** +** @param ch The character to write +** +** @return The return value from calling write() +*/ +int cwritech( char ch ); + +/** +** cwrites(str) - write a NUL-terminated string to the console +** +** @param str The string to write +** +*/ +int cwrites( const char *str ); + +/** +** cwrite(buf,leng) - write a sized buffer to the console +** +** @param buf The buffer to write +** @param leng The number of bytes to write +** +** @return The return value from calling write() +*/ +int cwrite( const char *buf, uint32_t leng ); + +/** +** swritech(ch) - write a single character to the SIO +** +** @param ch The character to write +** +** @return The return value from calling write() +*/ +int swritech( char ch ); + +/** +** swrites(str) - write a NUL-terminated string to the SIO +** +** @param str The string to write +** +** @return The return value from calling write() +*/ +int swrites( const char *str ); + +/** +** swrite(buf,leng) - write a sized buffer to the SIO +** +** @param buf The buffer to write +** @param leng The number of bytes to write +** +** @return The return value from calling write() +*/ +int swrite( const char *buf, uint32_t leng ); + +/* +************************************************* +** MISCELLANEOUS USEFUL SUPPORT FUNCTIONS ******* +************************************************* +*/ + +/** +** fake_exit() +** +** dummy "startup" function +** +** calls exit(%eax) - serves as the "return to" code for +** main() functions, in case they don't call exit() themselves +*/ +void fake_exit( void ); + +#endif /* !ASM_SRC */ + +#endif diff --git a/include/user.h b/include/user.h new file mode 100644 index 0000000..4d9402f --- /dev/null +++ b/include/user.h @@ -0,0 +1,138 @@ +/** +** @file user.h +** +** @author CSCI-452 class of 20245 +** +** @brief Declarations of user-level code management routines +*/ + +#ifndef USER_H_ +#define USER_H_ + +#include <common.h> + +#include <procs.h> +#include <x86/arch.h> + +// default value for EFLAGS in new processes +#define DEFAULT_EFLAGS (EFL_MB1 | EFL_IF) + +/* +** General (C and/or assembly) definitions +*/ + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +*/ + +/* +** Types +*/ + +/* +** Blob file organization +** +** The file begins with a four-byte magic number and a four-byte integer +** indicating the number of ELF files contained in the blob. This is +** followed by an array of 32-byte file table entries, and then the contents +** of the ELF files in the order they appear in the program file table. +** +** Bytes Contents +** ----- ---------------------------- +** 0 - 3 File magic number ("BLB\0") +** 4 - 7 Number of ELF files in blob ("n") +** 8 - n*32+8 Program file table +** n*32+9 - ? ELF file contents +** +** Each program file table entry contains the following information: +** +** name File name (up to 19 characters long) +** offset Byte offset to the ELF header for this file +** size Size of this ELF file, in bytes +** flags Flags related to this file +*/ + +// user program blob header +typedef struct header_s { + char magic[4]; + uint32_t num; +} header_t; + +// length of the file name field +#define NAMELEN 20 + +// program descriptor +typedef struct prog_s { + char name[NAMELEN]; // truncated name (15 chars) + uint32_t offset; // offset from the beginning of the blob + uint32_t size; // size of this ELF module + uint32_t flags; // miscellaneous flags +} prog_t; + +/* +** Globals +*/ + +/* +** Prototypes +*/ + +/** +** Name: user_init +** +** Initializes the user support module. +*/ +void user_init( void ); + +/** +** Name: user_locate +** +** Locates a user program in the user code archive. +** +** @param what The ID of the user program to find +** +** @return pointer to the program table entry in the code archive, or NULL +*/ +prog_t *user_locate( uint_t what ); + +/** +** Name: user_duplicate +** +** Duplicates the memory setup for an existing process. +** +** @param new The PCB for the new copy of the program +** @param old The PCB for the existing the program +** +** @return the status of the duplicate attempt +*/ +int user_duplicate( pcb_t *new, pcb_t *old ); + +/** +** Name: user_load +** +** Loads a user program from the user code archive into memory. +** Allocates all needed frames and sets up the VM tables. +** +** @param prog A pointer to the program table entry to be loaded +** @param pcb The PCB for the program being loaded +** @param args The argument vector for the program +** +** @return the status of the load attempt +*/ +int user_load( prog_t *prog, pcb_t *pcb, const char **args ); + +/** +** Name: user_cleanup +** +** "Unloads" a user program. Deallocates all memory frames and +** cleans up the VM structures. +** +** @param pcb The PCB of the program to be cleaned up +*/ +void user_cleanup( pcb_t *pcb ); + +#endif /* !ASM_SRC */ + +#endif diff --git a/include/userids.h b/include/userids.h new file mode 100644 index 0000000..284f3ee --- /dev/null +++ b/include/userids.h @@ -0,0 +1,33 @@ +/** +** @file userids.h +** +** @author Warren R. Carithers +** +** @brief IDs for user-level programs +** +** NOTE: this file is automatically generated when the user.img file +** is created. Do not edit this manually! +*/ + +#ifndef USERIDS_H_ +#define USERIDS_H_ + +#ifndef ASM_SRC +/* +** These IDs are used to identify the various user programs. +** Each call to exec() will provide one of these as the first +** argument. +** +** This list should be updated if/when the collection of +** user processes changes. +*/ +enum users_e { + Init, Idle, Shell, ProgABC, ProgDE, ProgFG, ProgH, ProgI, + ProgJ, ProgKL, ProgMN, ProgP, ProgQ, ProgR, ProgS, ProgTUV, + ProgW, ProgX, ProgY, ProgZ + // sentinel + , N_USERS +}; +#endif /* !ASM_SRC */ + +#endif diff --git a/include/vm.h b/include/vm.h new file mode 100644 index 0000000..d557d5e --- /dev/null +++ b/include/vm.h @@ -0,0 +1,433 @@ +/** +** @file vm.h +** +** @author CSCI-452 class of 20245 +** +** @brief Virtual memory-related declarations. +*/ + +#ifndef VM_H_ +#define VM_H_ + +#include <defs.h> +#include <types.h> + +#include <procs.h> + +/* +** VM layout of the system +** +** User processes use the first 4MB of the 32-bit address space; see the +** next comment for details. +** +** Kernel virtual addresses are in the "higher half" range, beginning +** at 0x80000000. We define our mapping such that virtual address +** 0x8nnnnnnn maps to physical address 0x0nnnnnnn, so converting between +** the two is trivial. +*/ + +/* +** VM layout of process' address space +** +** Processes are limited to the first 4MB of the 32-bit address space: +** +** Address Range Contents +** ======================= ================================ +** 0x00000000 - 0x00000fff page 0 is inaccessible +** 0x00001000 - 0x000..fff text occupies pages 1 - N +** 0x000..000 - 0x000..fff data occupies pages N+1 - N+d +** 0x000..000 - 0x000..fff bss occupies pages N+d+1 - N+d+b +** 0x000..000 - 0x003fdfff unusable +** 0x003fe000 - 0x003fffff stack occupies last two pages +** +** This gives us the following page table structure: +** +** Page directory: +** Entries Contents +** ======== ============================== +** 0 point to PMT for address space +** 1 - 1023 invalid +** +** Page map table: +** Entries Contents +** ======== ============================== +** 0 invalid +** 1 - N text frames +** N+1 - N+d data frames +** N+d+1 - N+d+b bss frames +** N+d+b+1 - 1021 invalid +** 1022 - 1023 stack frames +*/ + +/* +** General (C and/or assembly) definitions +*/ + +// user virtual addresses +#define USER_TEXT 0x00001000 +#define USER_STACK 0x003fe000 +#define USER_STK_END 0x00400000 + +// how to find the addresses of the stack pages in the VM hierarchy +// user address space is the first 4MB of virtual memory +#define USER_PDE 0 +// the stack occupies the last two pages of the address space +#define USER_STK_PTE1 1022 +#define USER_STK_PTE2 1023 + +// some important memory addresses +#define KERN_BASE 0x80000000 // start of "kernel" memory +#define EXT_BASE 0x00100000 // start of "extended" memory (1MB) +#define DEV_BASE 0xfe000000 // "device" memory +#define PHYS_TOP 0x7fffffff // last usable physical address + +// where the kernel actually lives +#define KERN_PLINK 0x00010000 +#define KERN_VLINK (KERN_BASE + KERN_PLINK) + +// physical/virtual converters +#ifndef ASM_SRC +// uses casting +#define V2P(a) (((uint_t)(a)) - KERN_BASE) +#define P2V(a) ((void *)(((uint_t)(a)) + KERN_BASE)) +#else +// doesn't use casting +#define V2P(a) ((a) - KERN_BASE) +#define P2V(a) ((a) + KERN_BASE) +#endif /* !ASM_SRC */ + +// number of entries in a page directory or page table +#define N_PDE 1024 +#define N_PTE 1024 + +// index field shift counts and masks +#define PDIX_SHIFT 22 +#define PTIX_SHIFT 12 +#define PIX2I_MASK 0x3ff + +#ifndef ASM_SRC +// 4KB frame numbers are 20 bits wide +#define FRAME_4K_SHIFT 12 +#define F2I_4K_MASK 0x000fffff +#define TO_4KFRAME(n) (((n)&F2I_4K_MASK) << FRAME_4K_SHIFT) +#define GET_4KFRAME(n) (((n) >> FRAME_4K_SHIFT)&F2I_4K_MASK) + +// 4MB frame numbers are 10 bits wide +#define FRAME_4M_SHIFT 22 +#define F2I_4M_MASK 0x000003ff +#define TO_4MFRAME(n) (((n)&F2I_4M_MASK) << FRAME_4M_SHIFT) +#define GET_4MFRAME(n) (((n) >> FRAME_4M_SHIFT)&F2I_4M_MASK) + +// extract the PMT address or frame address from a table entry +#define FRAME_MASK MOD4K_MASK +#define PERM_MASK MOD4K_BITS +#define PDE_ADDR(p) (((uint32_t)(p))&FRAME_MASK) +#define PTE_ADDR(p) (((uint32_t)(p))&FRAME_MASK) +#define PERMS(p) (((uint32_t)(p))&PERM_MASK) + +// extract the table indices from a 32-bit address +#define PDIX(v) ((((uint32_t)(v)) >> PDIX_SHIFT) & PIX2I_MASK) +#define PTIX(v) ((((uint32_t)(v)) >> PTIX_SHIFT) & PIX2I_MASK) + +// page-size address rounding macros +#define SZ_PG_M1 MOD4K_BITS +#define SZ_PG_MASK MOD4K_MASK +#define PGUP(a) (((a)+SZ_PG_M1) & SZ_PG_MASK) +#define PGDOWN(a) ((a) & SZ_PG_MASK) + +// page directory entry fields +#define PDE_P 0x00000001 +#define PDE_RW 0x00000002 +#define PDE_US 0x00000004 +#define PDE_PWT 0x00000008 +#define PDE_PCD 0x00000010 +#define PDE_A 0x00000020 +#define PDE_AVL1 0x00000040 +#define PDE_PS 0x00000080 +#define PDE_AVL2 0x00000f00 +#define PDE_BA 0xfffff000 + +// page table entry fields +#define PTE_P 0x00000001 +#define PTE_RW 0x00000002 +#define PTE_US 0x00000004 +#define PTE_PWT 0x00000008 +#define PTE_PCD 0x00000010 +#define PTE_A 0x00000020 +#define PTE_D 0x00000040 +#define PTE_PAT 0x00000080 +#define PTE_G 0x00000100 +#define PTE_AVL2 0x00000e00 +#define PTE_FA 0xfffff000 + +#define PG_CODE (PTE_USER | PTE_PRESENT) +#define PG_DATA (PTE_USER | PTE_RW | PTE_PRESENT) + +// error code bit assignments for page faults +#define PFLT_P 0x00000001 +#define PFLT_W 0x00000002 +#define PFLT_US 0x00000004 +#define PFLT_RSVD 0x00000008 +#define PFLT_ID 0x00000010 +#define PFLT_PK 0x00000020 +#define PFLT_SS 0x00000040 +#define PFLT_HLAT 0x00000080 +#define PFLT_SGX 0x00008000 +#define PFLT_UNUSED 0xffff7f00 + +// create a pde/pte from an integer frame number and permission bits +#define MKPDE(f,p) ((pde_t)( TO_FRAME((f)) | (p) )) +#define MKPTE(f,p) ((pte_t)( TO_FRAME((f)) | (p) )) + +// is a PDE/PTE present? +// (P bit is in the same place in both) +#define IS_PRESENT(entry) (((entry) & PDE_P) != 0 ) + +// is a PDE a 4MB page entry? +#define IS_LARGE(pde) (((pde) & PDE_PS) != 0 ) +#endif /* !ASM_SRC */ + +#ifndef ASM_SRC + +/* +** Start of C-only definitions +*/ + +/* +** Types +*/ + +// page directory entries + +// as a 32-bit word, in types.h +// typedef uint32_t pde_t; + +// PDE for 4KB pages +typedef struct pdek_s { + uint_t p :1; // present + uint_t rw :1; // writable + uint_t us :1; // user/supervisor + uint_t pwt :1; // cache write-through + uint_t pcd :1; // cache disable + uint_t a :1; // accessed + uint_t avl1 :1; // ignored (available) + uint_t ps :1; // page size (must be 0) + uint_t avl2 :4; // ignored (available) + uint_t fa :20; // frame address +} pdek_f_t; + +// PDE for 4MB pages +typedef struct pdem_s { + uint_t p :1; // present + uint_t rw :1; // writable + uint_t us :1; // user/supervisor + uint_t pwt :1; // cache write-through + uint_t pcd :1; // cache disable + uint_t a :1; // accessed + uint_t d :1; // dirty + uint_t ps :1; // page size (must be 1) + uint_t g :1; // global + uint_t avl :3; // ignored (available) + uint_t fa :20; // frame address +} pdem_f_t; + +// page table entries + +// as a 32-bit word, in types.h +// typedef uint32_t pte_t; + +// broken out into fields +typedef struct pte_s { + uint_t p :1; // present + uint_t rw :1; // writable + uint_t us :1; // user/supervisor + uint_t pwt :1; // cache write-through + uint_t pcd :1; // cache disable + uint_t a :1; // accessed + uint_t d :1; // dirty + uint_t pat :1; // page attribute table in use + uint_t g :1; // global + uint_t avl :3; // ignored (available) + uint_t fa :20; // frame address +} ptef_t; + +// page fault error code bits +// comment: meaning when 1 / meaning when 0 +struct pfec_s { + uint_t p :1; // page-level protection violation / !present + uint_t w :1; // write / read + uint_t us :1; // user-mode access / supervisor-mode access + uint_t rsvd :1; // reserved bit violation / not + uint_t id :1; // instruction fetch / data fetch + uint_t pk :1; // protection-key violation / !pk + uint_t ss :1; // shadow stack access / !ss + uint_t hlat :1; // HLAT paging / ordinary paging or access rights + uint_t xtr1 :7; // unused + uint_t sgz :1; // SGX-specific access control violation / !SGX + uint_t xtr2 :16; // more unused +}; + +typedef union pfec_u { + uint32_t u; + struct pfec_s s; +} pfec_t; + +// Mapping descriptor for VA::PA mappings +typedef struct mapping_t { + uint32_t va_start; // starting virtual address for this range + uint32_t pa_start; // first physical address in the range + uint32_t pa_end; // last physical address in the range + uint32_t perm; // access control +} mapping_t; + +/* +** Globals +*/ + +// created page directory for the kernel +extern pde_t *kpdir; + +/* +** Prototypes +*/ + +/** +** Name: vm_init +** +** Initialize the VM module +** +** Note: should not be called until after the memory free list has +** been set up. +*/ +void vm_init( void ); + +/** +** Name: vm_pagedup +** +** Duplicate a page of memory +** +** @param old Pointer to the first byte of a page +** +** @return a pointer to the new, duplicate page, or NULL +*/ +void *vm_pagedup( void *old ); + +/** +** Name: vm_ptdup +** +** Duplicate a page directory entry +** +** @param dst Pointer to where the duplicate should go +** @param curr Pointer to the entry to be duplicated +** +** @return true on success, else false +*/ +bool_t vm_ptdup( pde_t *dst, pde_t *curr ); + +/** +** Name: vm_getpte +** +** Return the address of the PTE corresponding to the virtual address +** 'va' within the address space controlled by 'pgdir'. If there is no +** page table for that VA and 'alloc' is true, create the necessary +** page table entries. +** +** @param pdir Pointer to the page directory to be searched +** @param va The virtual address we're looking for +** @param alloc Should we allocate a page table if there isn't one? +** +** @return A pointer to the page table entry for this VA, or NULL +*/ +pte_t *vm_getpte( pde_t *pdir, const void *va, bool_t alloc ); + +/** +** Name: vm_mkkvm +** +** Create the kernel's page table hierarchy +*/ +pde_t *vm_mkkvm( void ); + +/** +** Name: vm_mkuvm +** +** Create the page table hierarchy for a user process +*/ +pde_t *vm_mkuvm( void ); + +/** +** Name: vm_set_kvm +** +** Switch the page table register to the kernel's page directory +*/ +void vm_set_kvm( void ); + +/** +** Name: vm_set_uvm +** +** Switch the page table register to the page directory for a user process. +** +** @param p The PCB of the user process +*/ +void vm_set_uvm( pcb_t *p ); + +/** +** Name: vm_add +** +** Add pages to the page hierarchy for a process, copying data into +** them if necessary. +** +** @param pdir Pointer to the page directory to modify +** @param wr "Writable" flag for the PTE +** @param sys "System" flag for the PTE +** @param va Starting VA of the range +** @param size Amount of physical memory to allocate +** @param data Pointer to data to copy, or NULL +** @param bytes Number of bytes to copy +** +** @return status of the allocation attempt +*/ +int vm_add( pde_t *pdir, bool_t wr, bool_t sys, + void *va, uint32_t size, char *data, uint32_t bytes ); + +/** +** Name: vm_free +** +** Deallocate a page table hierarchy and all physical memory frames +** in the user portion. +** +** @param pdir Pointer to the page directory +*/ +void vm_free( pde_t *pdir ); + +/* +** Name: vm_map +** +** Create PTEs for virtual addresses starting at 'va' that refer to +** physical addresses in the range [pa, pa+size-1]. We aren't guaranteed +** that va is page-aligned. +** +** @param pdir Page directory for this address space +** @param va The starting virtual address +** @param size Length of the range to be mapped +** @param pa The starting physical address +** @param perm Permission bits for the PTEs +*/ +int vm_map( pde_t *pdir, void *va, uint_t size, uint_t pa, int perm ); + +/** +** Name: vm_uvmdup +** +** Create a duplicate of the user portio of an existing page table +** hierarchy. We assume that the "new" page directory exists and +** the system portions of it should not be touched. +** +** @param old Existing page directory +** @param new New page directory +** +** @return status of the duplication attempt +*/ +int vm_uvmdup( pde_t *old, pde_t *new ); + +#endif /* !ASM_SRC */ + +#endif diff --git a/include/vmtables.h b/include/vmtables.h new file mode 100644 index 0000000..17f6e0a --- /dev/null +++ b/include/vmtables.h @@ -0,0 +1,43 @@ +/** +** @file vmtables.h +** +** @author CSCI-452 class of 20245 +** +** @brief Predefined VM tables +*/ + +#ifndef VMTABLES_H_ +#define VMTABLES_H_ + +#include <defs.h> +#include <types.h> +#include <vm.h> + +#ifndef ASM_SRC + +/* +** Initial page directory, for when the kernel is starting up +** +** we use large (4MB) pages here to allow us to use a one-level +** paging hierarchy; the kernel will create a new page table +** hierarchy once memory is initialized +*/ +extern pde_t firstpdir[]; + +/* +** "Identity" page map table. +** +** This just maps the first 4MB of physical memory. It is initialized +** in vm_init(). +*/ +extern pte_t id_map[]; + +/* +** Kernel address mappings, present in every page table +*/ +extern mapping_t kmap[]; +extern const uint32_t n_kmap; + +#endif /* !ASM_SRC */ + +#endif diff --git a/include/x86/arch.h b/include/x86/arch.h new file mode 100644 index 0000000..113c76b --- /dev/null +++ b/include/x86/arch.h @@ -0,0 +1,303 @@ +/* +** @file arch.h +** +** @author Warren R. Carithers +** @author K. Reek +** +** Definitions of constants and macros for use +** with the x86 architecture and registers. +** +*/ + +#ifndef X86ARCH_H_ +#define X86ARCH_H_ + +/* +** Video stuff +*/ +#define VID_BASE_ADDR 0xB8000 + +/* +** Memory management +*/ +#define SEG_PRESENT 0x80 +#define SEG_PL_0 0x00 +#define SEG_PL_1 0x20 +#define SEG_PL_2 0x40 +#define SEG_PL_3 0x50 +#define SEG_SYSTEM 0x00 +#define SEG_NON_SYSTEM 0x10 +#define SEG_32BIT 0x04 +#define DESC_IGATE 0x06 + +/* +** Exceptions +*/ +#define N_EXCEPTIONS 256 + +/* +** Bit definitions in registers +** +** See IA-32 Intel Architecture SW Dev. Manual, Volume 3: System +** Programming Guide, page 2-8. +*/ + +/* +** EFLAGS +*/ +#define EFL_RSVD 0xffc00000 /* reserved */ +#define EFL_MB0 0x00008020 /* must be zero */ +#define EFL_MB1 0x00000002 /* must be 1 */ + +#define EFL_ID 0x00200000 +#define EFL_VIP 0x00100000 +#define EFL_VIF 0x00080000 +#define EFL_AC 0x00040000 +#define EFL_VM 0x00020000 +#define EFL_RF 0x00010000 +#define EFL_NT 0x00004000 +#define EFL_IOPL 0x00003000 +#define EFL_OF 0x00000800 +#define EFL_DF 0x00000400 +#define EFL_IF 0x00000200 +#define EFL_TF 0x00000100 +#define EFL_SF 0x00000080 +#define EFL_ZF 0x00000040 +#define EFL_AF 0x00000010 +#define EFL_PF 0x00000004 +#define EFL_CF 0x00000001 + +/* +** CR0, CR1, CR2, CR3, CR4 +** +** IA-32 V3, page 2-12. +*/ +#define CR0_RSVD 0x1ffaffc0 +#define CR0_PG 0x80000000 +#define CR0_CD 0x40000000 +#define CR0_NW 0x20000000 +#define CR0_AM 0x00040000 +#define CR0_WP 0x00010000 +#define CR0_NE 0x00000020 +#define CR0_ET 0x00000010 +#define CR0_TS 0x00000008 +#define CR0_EM 0x00000004 +#define CR0_MP 0x00000002 +#define CR0_PE 0x00000001 + +#define CR1_RSVD 0xffffffff + +#define CR2_RSVD 0x00000000 +#define CR2_PF_LIN_ADDR 0xffffffff + +#define CR3_RSVD 0x00000fe7 +#define CR3_PD_BASE 0xfffff000 +#define CR3_PCD 0x00000010 +#define CR3_PWT 0x00000008 + +#define CR4_RSVD 0xfd001000 +#define CR4_UINT 0x02000000 +#define CR4_PKS 0x01000000 +#define CR4_CET 0x00800000 +#define CR4_PKE 0x00400000 +#define CR4_SMAP 0x00200000 +#define CR4_SMEP 0x00100000 +#define CR4_KL 0x00080000 +#define CR4_OSXS 0x00040000 +#define CR4_PCID 0x00020000 +#define CR4_FSGS 0x00010000 +#define CR4_SMXE 0x00004000 +#define CR4_VMXE 0x00002000 +#define CR4_LA57 0x00001000 +#define CR4_UMIP 0x00000800 +#define CR4_OSXMMEXCPT 0x00000400 +#define CR4_OSFXSR 0x00000200 +#define CR4_PCE 0x00000100 +#define CR4_PGE 0x00000080 +#define CR4_MCE 0x00000040 +#define CR4_PAE 0x00000020 +#define CR4_PSE 0x00000010 +#define CR4_DE 0x00000008 +#define CR4_TSD 0x00000004 +#define CR4_PVI 0x00000002 +#define CR4_VME 0x00000001 + +/* +** PMode segment selector field masks +** +** IA-32 V3, page 3-8. +*/ +#define SEG_SEL_IX_MASK 0xfff8 +#define SEG_SEL_TI_MASK 0x0004 +#define SEG_SEL_RPL_MASK 0x0003 + +/* +** Segment descriptor bytes +** +** IA-32 V3, page 3-10. +** +** Bytes: +** 0, 1: segment limit 15:0 +** 2, 3: base address 15:0 +** 4: base address 23:16 +** 7: base address 31:24 +*/ + +/* +** Byte 5: access control bits +** 7: present +** 6-5: DPL +** 4: system/user +** 3-0: type +*/ +#define SEG_ACCESS_P_MASK 0x80 +# define SEG_PRESENT 0x80 +# define SEG_NOT_PRESENT 0x00 + +#define SEG_ACCESS_DPL_MASK 0x60 +# define SEG_DPL_0 0x00 +# define SEG_DPL_1 0x20 +# define SEG_DPL_2 0x40 +# define SEG_DPL_3 0x60 + +#define SEG_ACCESS_S_MASK 0x10 +# define SEG_SYSTEM 0x00 +# define SEG_NON_SYSTEM 0x10 + +#define SEG_TYPE_MASK 0x0f +# define SEG_DATA_A_BIT 0x1 +# define SEG_DATA_W_BIT 0x2 +# define SEG_DATA_E_BIT 0x4 +# define SEG_CODE_A_BIT 0x1 +# define SEG_CODE_R_BIT 0x2 +# define SEG_CODE_C_BIT 0x4 +# define SEG_DATA_RO 0x0 +# define SEG_DATA_ROA 0x1 +# define SEG_DATA_RW 0x2 +# define SEG_DATA_RWA 0x3 +# define SEG_DATA_RO_XD 0x4 +# define SEG_DATA_RO_XDA 0x5 +# define SEG_DATA_RW_XW 0x6 +# define SEG_DATA_RW_XWA 0x7 +# define SEG_CODE_XO 0x8 +# define SEG_CODE_XOA 0x9 +# define SEG_CODE_XR 0xa +# define SEG_CODE_XRA 0xb +# define SEG_CODE_XO_C 0xc +# define SEG_CODE_XO_CA 0xd +# define SEG_CODE_XR_C 0xe +# define SEG_CODE_XR_CA 0xf + +/* +** Byte 6: sizes +** 7: granularity +** 6: d/b +** 5: long mode +** 4: available! +** 3-0: upper 4 bits of limit +** 7: base address 31:24 +*/ +#define SEG_SIZE_G_MASK 0x80 +# define SEG_GRAN_BYTE 0x00 +# define SEG_GRAN_4KBYTE 0x80 + +#define SEG_SIZE_D_B_MASK 0x40 +# define SEG_DB_16BIT 0x00 +# define SEG_DB_32BIT 0x40 + +#define SEG_SIZE_L_MASK 0x20 +# define SEG_L_64BIT 0x20 +# define SEG_L_32BIT 0x00 + +#define SEG_SIZE_AVL_MASK 0x10 + +#define SEG_SIZE_LIM_19_16_MASK 0x0f + + +/* +** System-segment and gate-descriptor types +** +** IA-32 V3, page 3-15. +*/ + // type 0: reserved +#define SEG_SYS_16BIT_TSS_AVAIL 0x1 +#define SEG_SYS_LDT 0x2 +#define SEG_SYS_16BIT_TSS_BUSY 0x3 +#define SEG_SYS_16BIT_CALL_GATE 0x4 +#define SEG_SYS_TASK_GATE 0x5 +#define SEG_SYS_16BIT_INT_GATE 0x6 +#define SEG_SYS_16BIT_TRAP_GATE 0x7 + // type 8: reserved +#define SEG_SYS_32BIT_TSS_AVAIL 0x9 + // type A: reserved +#define SEG_SYS_32BIT_TSS_BUSY 0xb +#define SEG_SYS_32BIT_CALL_GATE 0xc + // type D: reserved +#define SEG_SYS_32BIT_INT_GATE 0xe +#define SEG_SYS_32BIT_TRAP_GATE 0xf + +/* +** IDT Descriptors +** +** IA-32 V3, page 5-13. +** +** All have a segment selector in bytes 2 and 3; Task Gate descriptors +** have bytes 0, 1, 4, 6, and 7 reserved; others have bytes 0, 1, 6, +** and 7 devoted to the 16 bits of the Offset, with the low nybble of +** byte 4 reserved. +*/ +#define IDT_PRESENT 0x8000 +#define IDT_DPL_MASK 0x6000 +# define IDT_DPL_0 0x0000 +# define IDT_DPL_1 0x2000 +# define IDT_DPL_2 0x4000 +# define IDT_DPL_3 0x6000 +#define IDT_GATE_TYPE 0x0f00 +# define IDT_TASK_GATE 0x0500 +# define IDT_INT16_GATE 0x0600 +# define IDT_INT32_GATE 0x0e00 +# define IDT_TRAP16_GATE 0x0700 +# define IDT_TRAP32_GATE 0x0f00 + +/* +** Interrupt vectors +*/ + +// predefined by the architecture +#define VEC_DIVIDE_ERROR 0x00 +#define VEC_DEBUG_EXCEPTION 0x01 +#define VEC_NMI_INTERRUPT 0x02 +#define VEC_BREAKPOINT 0x03 +#define VEC_OVERFLOW 0x04 +#define VEC_BOUND_RANGE_EXCEEDED 0x05 +#define VEC_INVALID_OPCODE 0x06 +#define VEC_DEVICE_NOT_AVAILABLE 0x07 +#define VEC_DOUBLE_FAULT 0x08 +#define VEC_COPROCESSOR_OVERRUN 0x09 +#define VEC_INVALID_TSS 0x0a +#define VEC_SEGMENT_NOT_PRESENT 0x0b +#define VEC_STACK_FAULT 0x0c +#define VEC_GENERAL_PROTECTION 0x0d +#define VEC_PAGE_FAULT 0x0e +// 0x0f is reserved - unused +#define VEC_FPU_ERROR 0x10 +#define VEC_ALIGNMENT_CHECK 0x11 +#define VEC_MACHINE_CHECK 0x12 +#define VEC_SIMD_FP_EXCEPTION 0x13 +#define VEC_VIRT_EXCEPTION 0x14 +#define VEC_CTRL_PROT_EXCEPTION 0x15 +// 0x16 through 0x1f are reserved + +// 0x20 through 0xff are user-defined, non-reserved + +// IRQ0 through IRQ15 will use vectors 0x20 through 0x2f +#define VEC_TIMER 0x20 +#define VEC_KBD 0x21 +#define VEC_COM2 0x23 +#define VEC_COM1 0x24 +#define VEC_PARALLEL 0x25 +#define VEC_FLOPPY 0x26 +#define VEC_MYSTERY 0x27 +#define VEC_MOUSE 0x2c + +#endif diff --git a/include/x86/bios.h b/include/x86/bios.h new file mode 100644 index 0000000..a19e570 --- /dev/null +++ b/include/x86/bios.h @@ -0,0 +1,73 @@ +/* +** @file bios.h +** +** @author Warren R. Carithers +** +** BIOS-related declarations +*/ + +#ifndef BIOS_H_ +#define BIOS_H_ + +/* +** BIOS-related memory addresses +*/ + +#define BIOS_BDA 0x0400 + +/* +** Selected BIOS interrupt numbers +*/ + +#define BIOS_TIMER 0x08 +#define BIOS_KBD 0x09 +#define BIOS_VIDEO 0x10 +#define BIOS_EQUIP 0x11 +#define BIOS_MSIZ 0x12 +#define BIOS_DISK 0x13 +#define BIOS_SERIAL 0x14 +#define BIOS_MISC 0x15 +#define BIOS_KBDSVC 0x16 +#define BIOS_PRTSVC 0x17 +#define BIOS_BOOT 0x19 +#define BIOS_RTCPCI 0x1a + +// BIOS video commands (AH) +#define BV_W_ADV 0x0e + +// BIOS disk commands (AH) +#define BD_RESET 0x00 +#define BD_CHECK 0x01 +#define BD_RDSECT 0x02 +#define BD_WRSECT 0x03 +#define BD_PARAMS 0x08 + +// BIOS disk commands with parameters (AX) +#define BD_READ(n) ((BD_RDSECT << 8) | (n)) +#define BD_READ1 0x0201 + +// CMOS ports (used for masking NMIs) +#define CMOS_ADDR 0x70 +#define CMOS_DATA 0x71 + +// important related commands +#define NMI_ENABLE 0x00 +#define NMI_DISABLE 0x80 + +/* +** Physical Memory Map Table (0000:2D00 - 0000:7c00) +** +** Primarily used with the BIOS_MISC interrupt +*/ +#define MMAP_SEG 0x02D0 +#define MMAP_DISP 0x0000 +#define MMAP_ADDR ((MMAP_SEG << 4) + MMAP_DISP) +#define MMAP_SECTORS 0x0a + +#define MMAP_ENT 24 /* bytes per entry */ +#define MMAP_MAX_ENTS (BOOT_ADDR - MMAP_ADDR - 4) / 24 + +#define MMAP_CODE 0xE820 /* int 0x15 code */ +#define MMAP_MAGIC_NUM 0x534D4150 /* for 0xE820 interrupt */ + +#endif diff --git a/include/x86/ops.h b/include/x86/ops.h new file mode 100644 index 0000000..ad795b9 --- /dev/null +++ b/include/x86/ops.h @@ -0,0 +1,443 @@ +/** +** @file ops.h +** +** @author Warren R. Carithers +** +** @brief Inline escapes to assembly for efficiency +** +** Inspiration from: +** Martins Mozeiko, https://gist.github.com/mmozeiko/f68ad2546bd6ab953315 +** MIT's xv6, https://github.com/mit-pdos/xv6-public +** +** Note: normally, GCC doesn't inline unless the optimization level is +** over 1. This can be forced by adding +** +** __attribute__((always_inline)) +** +** after the parameter list on each declaration. This is enabled by +** defining the compile-time CPP symbol FORCE_INLINING. +*/ + +#ifndef OPS_H_ +#define OPS_H_ + +#include <common.h> + +#ifndef ASM_SRC + +// control "forced" inlining +#ifdef FORCE_INLINING +#define OPSINLINED __attribute__((always_inline)) +#else +#define OPSINLINED /* no-op */ +#endif /* FORCE_INLINING */ + +/**************************** +** Data movement +****************************/ + +/** +** Block move functions +** +** Variations: movsb(), movsl(), movsq() +** +** Description: Copy from source buffer to destination buffer +** +** @param dst Destination buffer +** @param src Source buffer +** @param len Byte count +*/ +static inline void +movsb( void* dst, const void* src, uint32_t len ) OPSINLINED +{ + __asm__ __volatile__( "cld; rep movsb" + : "+D"(dst), "+S"(src), "+c"(len) + : : "memory" ); +} + +static inline void +movsw( void* dst, const void* src, uint32_t len ) OPSINLINED +{ + __asm__ __volatile__( "cld; rep movsw" + : "+D"(dst), "+S"(src), "+c"(len) + : : "memory" ); +} + +static inline void +movsl( void* dst, const void* src, uint32_t len ) OPSINLINED +{ + __asm__ __volatile__( "cld; rep movsl" + : "+D"(dst), "+S"(src), "+c"(len) + : : "memory" ); +} + +static inline void +movsq( void* dst, const void* src, uint32_t len ) OPSINLINED +{ + __asm__ __volatile__( "cld; rep movsq" + : "+D"(dst), "+S"(src), "+c"(len) + : : "memory" ); +} + +/** +** Block store functions +** +** Variations: stosb(), stosw(), stosl() +** +** Description: Store a specific value into destination buffer +** +** @param dst Destination buffer +** @param val Data to copy +** @param len Byte count +*/ +static inline void +stosb( void *dst, uint8_t val, uint32_t len ) OPSINLINED +{ + __asm__ __volatile__( "cld; rep stosb" + : "=D" (dst), "=c" (len) + : "0" (dst), "1" (len), "a" (val) + : "memory", "cc" ); +} + +static inline void +stosw( void *dst, uint16_t val, uint32_t len ) OPSINLINED +{ + __asm__ __volatile__( "cld; rep stos2" + : "=D" (dst), "=c" (len) + : "0" (dst), "1" (len), "a" (val) + : "memory", "cc" ); +} + +static inline void +stosl( void *dst, uint32_t val, uint32_t len ) OPSINLINED +{ + __asm__ __volatile__( "cld; rep stosl" + : "=D" (dst), "=c" (len) + : "0" (dst), "1" (len), "a" (val) + : "memory", "cc" ); +} + +/**************************** +** Special register access +****************************/ + +/** +** Register read functions +** +** Variations: r_cr0(), r_cr2(), r_cr3(), r_cr4(), r_eflags(), +** r_ebp(), r_esp() +** +** Description: Reads the register indicated by its name +** +** @return Contents of the register +*/ +static inline uint32_t +r_cr0( void ) OPSINLINED +{ + uint32_t val; + __asm__ __volatile__( "movl %%cr0,%0" : "=r" (val) ); + return val; +} + +static inline uint32_t +r_cr2( void ) OPSINLINED +{ + uint32_t val; + __asm__ __volatile__( "movl %%cr2,%0" : "=r" (val) ); + return val; +} + +static inline uint32_t +r_cr3( void ) OPSINLINED +{ + uint32_t val; + __asm__ __volatile__( "movl %%cr3,%0" : "=r" (val) ); + return val; +} + +static inline uint32_t +r_cr4( void ) OPSINLINED +{ + uint32_t val; + __asm__ __volatile__( "movl %%cr4,%0" : "=r" (val) ); + return val; +} + +static inline uint32_t +r_eflags(void) OPSINLINED +{ + uint32_t val; + __asm__ __volatile__( "pushfl; popl %0" : "=r" (val) ); + return val; +} + +static inline uint32_t +r_ebp(void) OPSINLINED +{ + uint32_t val; + __asm__ __volatile__( "movl %%ebp,%0" : "=r" (val) ); + return val; +} + +static inline uint32_t +r_esp(void) OPSINLINED +{ + uint32_t val; + __asm__ __volatile__( "movl %%esp,%0" : "=r" (val) ); + return val; +} + +/** +** Register write functions +** +** Variations: w_cr0(), w_cr2(), w_cr3(), w_cr4(), w_eflags() +** +** Description: Writes a value into the CR indicated by its name +*/ +static inline void +w_cr0( uint32_t val ) OPSINLINED +{ + __asm__ __volatile__( "movl %0,%%cr0" : : "r" (val) ); +} + +static inline void +w_cr2( uint32_t val ) OPSINLINED +{ + __asm__ __volatile__( "movl %0,%%cr2" : : "r" (val) ); +} + +static inline void +w_cr3( uint32_t val ) OPSINLINED +{ + __asm__ __volatile__( "movl %0,%%cr3" : : "r" (val) ); +} + +static inline void +w_cr4( uint32_t val ) OPSINLINED +{ + __asm__ __volatile__( "movl %0,%%cr4" : : "r" (val) ); +} + +static inline void +w_eflags(uint32_t eflags) OPSINLINED +{ + __asm__ __volatile__( "pushl %0; popfl" : : "r" (eflags) ); +} + +/** +** Descriptor table load functions +** +** Variations: w_gdt(), w_idt() +** +** Description: Load an address into the specified processor register +** +** @param addr The value to be loaded into the register +*/ +static inline void +w_gdt( void *addr ) OPSINLINED +{ + __asm__ __volatile__( "lgdt (%0)" : : "r" (addr) ); +} + +static inline void +w_idt( void *addr ) OPSINLINED +{ + __asm__ __volatile__( "lidt (%0)" : : "r" (addr) ); +} + +/** +** CPU ID access +** +** Description: Retrieve CPUID information +** +** @param op Value to be placed into %eax for the operation +** @param ap Pointer to where %eax contents should be saved, or NULL +** @param bp Pointer to where %ebx contents should be saved, or NULL +** @param cp Pointer to where %ecx contents should be saved, or NULL +** @param dp Pointer to where %edx contents should be saved, or NULL +*/ +static inline void +cpuid( uint32_t op, uint32_t *ap, uint32_t *bp, + uint32_t *cp, uint32_t *dp ) OPSINLINED +{ + uint32_t eax, ebx, ecx, edx; + __asm__ __volatile__( "cpuid" + : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) + : "a" (op) ); + + if( ap ) *ap = eax; + if( bp ) *bp = ebx; + if( cp ) *cp = ecx; + if( dp ) *dp = edx; +} + +/**************************** +** TLB management +****************************/ + +/** +** TLB invalidation for one page +** +** Description: Invalidate the TLB entry for an address +** +** @param addr An address within the page to be flushed +*/ +static inline void +invlpg( uint32_t addr ) OPSINLINED +{ + __asm__ __volatile__( "invlpg (%0)" : : "r" (addr) : "memory" ); +} + +/** +** TLB invalidation for all pages +** +** Description: Flush all entries from the TLB +** +** We do this by changing CR3. +*/ +static inline void +flushtlb( void ) OPSINLINED +{ + uint32_t cr3; + __asm__ __volatile__( "movl %%cr3,%0" : "=r" (cr3) ); + __asm__ __volatile__( "movl %0,%%cr2" : : "r" (cr3) ); +} + +/**************************** +** I/O instructions +****************************/ + +/** +** Name: inN +** +** Variations: inb(), inw(), inl() +** +** Description: Read some amount of data from the supplied I/O port +** +** @param port The i/o port to read from +** +** @return The data read from the specified port +*/ +static inline uint8_t +inb( int port ) OPSINLINED +{ + uint8_t data; + __asm__ __volatile__( "inb %w1,%0" : "=a" (data) : "d" (port) ); + return data; +} + +static inline uint16_t +inw( int port ) OPSINLINED +{ + uint16_t data; + __asm__ __volatile__( "inw %w1,%0" : "=a" (data) : "d" (port) ); + return data; +} + +static inline uint32_t +inl( int port ) OPSINLINED +{ + uint32_t data; + __asm__ __volatile__( "inl %w1,%0" : "=a" (data) : "d" (port) ); + return data; +} + +/** +** Name: outN +** +** Variations: outb(), outw(), outl() +** +** Description: Write some data to the specified I/O port +** +** @param port The i/o port to write to +** @param data The data to be written to the port +** +** @return The data read from the specified port +*/ +static inline void +outb( int port, uint8_t data ) OPSINLINED +{ + __asm__ __volatile__( "outb %0,%w1" : : "a" (data), "d" (port) ); +} + +static inline void +outw( int port, uint16_t data ) OPSINLINED +{ + __asm__ __volatile__( "outw %0,%w1" : : "a" (data), "d" (port) ); +} + +static inline void +outl( int port, uint32_t data ) OPSINLINED +{ + __asm__ __volatile__( "outl %0,%w1" : : "a" (data), "d" (port) ); +} + +/**************************** +** Miscellaneous instructions +****************************/ + +/** +** Name: breakpoint +** +** Description: Cause a breakpoint interrupt for debugging purposes +*/ +static inline void +breakpoint( void ) OPSINLINED +{ + __asm__ __volatile__( "int3" ); +} + +/** +** Name: get_ra +** +** Description: Get the return address for the calling function +** (i.e., where whoever called us will go back to) +** +** @return The address the calling routine will return to as a uint32_t +*/ +static inline uint32_t +get_ra( void ) OPSINLINED +{ + uint32_t val; + __asm__ __volatile__( "movl 4(%%ebp),%0" : "=r" (val) ); + return val; +} + +/** +** Name: ev_wait +** +** Description: Pause until something happens +*/ +static inline void +ev_wait( void ) OPSINLINED +{ + __asm__ __volatile__( "sti ; hlt" ); +} + + +/** +** Name: xchgl +** +** Description: Perform an atomic exchange with memory +** +** @param addr Memory location to be modified +** @param data Data to exchange +** +** @return The old contents of the memory location +*/ +static inline uint32_t +xchgl( volatile uint32_t *addr, uint32_t data ) OPSINLINED +{ + uint32_t old; + + // + indicates a read-modify-write operand + __asm__ __volatile__( "lock; xchgl %0, %1" + : "+m" (*addr), "=a" (old) + : "1" (data) + : "cc"); + return old; +} + +#endif /* !ASM_SRC */ + +#endif diff --git a/include/x86/pic.h b/include/x86/pic.h new file mode 100644 index 0000000..d4fa93b --- /dev/null +++ b/include/x86/pic.h @@ -0,0 +1,139 @@ +/** +** @file pic.h +** +** @author Warren R. Carithers +** @author K. Reek +** +** Definitions of constants and macros for the Intel 8259 Programmable +** Interrupt Controller. +** +*/ + +#ifndef X86PIC_H_ +#define X86PIC_H_ + +/* +** Our expected configuration is two PICs, with the secondary connected +** through the IRQ2 pin of the primary. +*/ + +/* +** Port addresses for the command port and interrupt mask register port +** for both the primary and secondary PICs. +*/ +#define PIC1_CMD 0x20 // primary command +#define PIC1_DATA (PIC1_CMD + 1) // primary data / int mask register +#define PIC2_CMD 0xA0 // secondary command +#define PIC2_DATA (PIC2_CMD + 1) // secondary data / int mask register + +/* +** Initialization Command Word (ICW) definitions +** +** Initialization sequence: +** ICW1 Init command is sent to each command port. +** ICW2 vector commands are sent to the data ports. +** If "cascade mode" was selected, send ICW3 commands to the data ports. +** If "need ICW4" was selected, send ICW4 commands to the data ports. +** +** Following that sequence, the PIC is ready to accept interrupts; +** it will also accept Output Command Words (OCWs) to the data ports. +** +** PIC1_* defines are intended for the primary PIC +** PIC2_* defines are intended for the secondary PIC +** PIC_* defines are sent to both PICs +*/ + +/* +** ICW1: initialization, send to command port +*/ +#define PIC_CW1_INIT 0x10 // start initialization sequence +#define PIC_CW1_NEED4 0x01 // ICW4 will also be set +#define PIC_CW1_SINGLE 0x02 // select single (vs. cascade) mode +#define PIC_CW1_INTVAL 0x04 // set call interval to 4 (vs. 8) +#define PIC_CW1_LEVEL 0x08 // use level-triggered mode (vs. edge) + +/* +** ICW2: interrupt vector base offsets, send to data port +*/ +#define PIC1_CW2_VECBASE 0x20 // IRQ0 int vector number +#define PIC2_CW2_VECBASE 0x28 // IRQ8 int vector number + +/* +** ICW3: secondary::primary attachment, send to data port +*/ +#define PIC1_CW3_SEC_IRQ2 0x04 // bit mask: secondary is on pin 2 +#define PIC2_CW3_SEC_ID 0x02 // integer: secondary id + +/* +** ICW4: operating mode, send to data port +*/ +#define PIC_CW4_PM86 0x01 // 8086 mode (vs. 8080/8085) +#define PIC_CW4_AUTOEOI 0x02 // do auto eoi's +#define PIC_CW4_UNBUF 0x00 // unbuffered mode +#define PIC_CW4_SEC_BUF 0x08 // put secondary in buffered mode +#define PIC_CW4_PRI_BUF 0x0C // put primary in buffered mode +#define PIC_CW4_SFNMODE 0x10 // "special fully nested" mode + +/* +** Operation Control Words (OCWs) +** +** After the init sequence, can send these +*/ + +/* +** OCW1: interrupt mask; send to data port +*/ +#define PIC_MASK_NONE 0x00 // allow all interrupts +#define PIC_MASK_NO_IRQ0 0x01 // prevent IRQ0 interrupts +#define PIC_MASK_NO_IRQ1 0x02 // prevent IRQ1 interrupts +#define PIC_MASK_NO_IRQ2 0x04 // prevent IRQ2 interrupts +#define PIC_MASK_NO_IRQ3 0x08 // prevent IRQ3 interrupts +#define PIC_MASK_NO_IRQ4 0x10 // prevent IRQ4 interrupts +#define PIC_MASK_NO_IRQ5 0x20 // prevent IRQ5 interrupts +#define PIC_MASK_NO_IRQ6 0x40 // prevent IRQ6 interrupts +#define PIC_MASK_NO_IRQ7 0x80 // prevent IRQ7 interrupts +#define PIC_MASK_ALL 0xff // prevent all interrupts + +/* +** OCW2: EOI control, interrupt level; send to command port +*/ +#define PIC_LVL_0 0x00 // act on IRQ level 0 +#define PIC_LVL_1 0x01 // act on IRQ level 1 +#define PIC_LVL_2 0x02 // act on IRQ level 2 +#define PIC_LVL_3 0x03 // act on IRQ level 3 +#define PIC_LVL_4 0x04 // act on IRQ level 4 +#define PIC_LVL_5 0x05 // act on IRQ level 5 +#define PIC_LVL_6 0x06 // act on IRQ level 6 +#define PIC_LVL_7 0x07 // act on IRQ level 7 + +#define PIC_EOI_NON_SPEC 0x20 // non-specific EOI command +# define PIC_EOI PIC_EOI_NON_SPEC + +#define PIC_EOI_SPEC 0x60 // specific EOI command +# define PIC_SEOI PIC_EOI_SPEC +# define PIC_SEOI_LVL0 (PIC_EOI_SPEC | PIC_LVL_0) +# define PIC_SEOI_LVL1 (PIC_EOI_SPEC | PIC_LVL_1) +# define PIC_SEOI_LVL2 (PIC_EOI_SPEC | PIC_LVL_2) +# define PIC_SEOI_LVL3 (PIC_EOI_SPEC | PIC_LVL_3) +# define PIC_SEOI_LVL4 (PIC_EOI_SPEC | PIC_LVL_4) +# define PIC_SEOI_LVL5 (PIC_EOI_SPEC | PIC_LVL_5) +# define PIC_SEOI_LVL6 (PIC_EOI_SPEC | PIC_LVL_6) +# define PIC_SEOI_LVL7 (PIC_EOI_SPEC | PIC_LVL_7) + +#define PIC_EOI_ROT_NONSP 0xa0 // rotate on non-spec EOI cmd +#define PIC_EOI_SET_ROT_AUTO 0x80 // set "rotate in auto EOI mode" +#define PIC_EOI_CLR_ROT_AUTO 0x00 // clear "rotate in auto EOI mode" +#define PIC_EOI_ROT_SPEC 0xe0 // rotate on spec EOI cmd (+ level) +#define PIC_EOI_SET_PRIO 0xc0 // set priority (+ level) +#define PIC_EOI_NOP 0x40 // no operation + +/* +** OCW3: read requests, special mask mode; send to command port +*/ +#define PIC_READIRR 0x0a // read the IR register +#define PIC_READISR 0x0b // read the IS register +#define PIC_POLL 0x0c // poll +#define PIC_MASK_RESET 0x48 // reset special mask mode +#define PIC_MASK_SET 0x68 // set special mask mode + +#endif diff --git a/include/x86/pit.h b/include/x86/pit.h new file mode 100644 index 0000000..269fcec --- /dev/null +++ b/include/x86/pit.h @@ -0,0 +1,82 @@ +/* +** @file pit.h +** +** @author Warren R. Carithers +** @author K. Reek +** +** Definitions of constants and macros for the +** Intel 8254 Programmable Interval Timer +** +*/ + +#ifndef X86PIT_H_ +#define X86PIT_H_ + + +/* +** Hardware timer (Intel 8254 Programmable Interval Timer) +** +** Control word layout: +** +** Bit 7 6 | 5 4 | 3 2 1 | 0 +** Field SC1 SC0|RW1 RW0|M2 M1 M0 |BCD +** +** SC - select counter +** RW - read/write +** M - mode +** BCD - binary or BCD counter +*/ + +/* Frequency settings */ +#define PIT_DEFAULT_TICKS_PER_SECOND 18 // actually 18.2065Hz +#define PIT_DEFAULT_MS_PER_TICK (1000/PIT_DEFAULT_TICKS_PER_SECOND) +#define PIT_FREQ 1193182 // clock cycles/sec + +/* Port assignments */ +#define PIT_BASE_PORT 0x40 // I/O port for the timer +# define PIT_0_PORT (PIT_BASE_PORT) +# define PIT_1_PORT (PIT_BASE_PORT+1) +# define PIT_2_PORT (PIT_BASE_PORT+2) +# define PIT_CONTROL_PORT (PIT_BASE_PORT+3) + +/* BCD field */ +#define PIT_USE_DECIMAL 0x00 // 16-bit binary counter (default) +#define PIT_USE_BCD 0x01 // BCD counter + +/* Timer modes */ +#define PIT_MODE_0 0x00 // int on terminal count +#define PIT_MODE_1 0x02 // one-shot +#define PIT_MODE_2 0x04 // divide-by-N +#define PIT_MODE_3 0x06 // square-wave +#define PIT_MODE_4 0x08 // software strobe +#define PIT_MODE_5 0x0a // hardware strobe + +/* Timer 0 settings */ +#define PIT_0_SELECT 0x00 // select timer 0 +#define PIT_0_LOAD 0x30 // load LSB, then MSB +#define PIT_0_NDIV PIT_MODE_2 // divide-by-N counter +#define PIT_0_SQUARE PIT_MODE_3 // square-wave mode +#define PIT_0_ENDSIGNAL 0x00 // assert OUT at end of count + +/* Timer 1 settings */ +#define PIT_1_SELECT 0x40 // select timer 1 +#define PIT_1_READ 0x30 // read/load LSB then MSB +#define PIT_1_RATE 0x06 // square-wave, for USART + +/* Timer 2 settings */ +#define PIT_2_SELECT 0x80 // select timer 1 +#define PIT_2_READ 0x30 // read/load LSB then MSB +#define PIT_2_RATE 0x06 // square-wave, for USART + +/* Timer read-back */ +#define PIT_READBACK 0xc0 // perform a read-back +#define PIT_RB_NOT_COUNT 0x20 // don't latch the count +#define PIT_RB_NOT_STATUS 0x10 // don't latch the status +#define PIT_RB_CHAN_2 0x08 // read back channel 2 +#define PIT_RB_CHAN_1 0x04 // read back channel 1 +#define PIT_RB_CHAN_0 0x02 // read back channel 0 +#define PIT_RB_ACCESS_MASK 0x30 // access mode field +#define PIT_RB_OP_MASK 0x0e // oper mode field +#define PIT_RB_BCD_MASK 0x01 // BCD mode field + +#endif diff --git a/include/x86/uart.h b/include/x86/uart.h new file mode 100644 index 0000000..0c6194b --- /dev/null +++ b/include/x86/uart.h @@ -0,0 +1,349 @@ +/* +** @file uart.h +** +** @author M. Reek +** @authors K. Reek, Warren R. Carithers +** +** Definitions for a 16540/16550 compatible UART. Definitions are taken +** from datasheets for the National Semiconductor INS8250, NS16450, and +** NS16550 UART chips, and the PC87309 Super I/O legacy peripheral chip. +** +** The naming convention is UAx_yyy_zzzzz. "x" is either 4 or 5 (see below), +** "yyy" is the name of the register to which this value applies, and +** "zzzzz" is the name of the value or field. +** +** The UA4 prefix denotes 16540 compatible functions, available in both +** chips. The UA5 prefix denotes 16550-only functions (primarily the FIFOs). +** +** For many items there are two names: one short one that matches the name +** in the chip manual, and another that is more readable. +*/ + +#ifndef UART_H +#define UART_H + +/********************************************************************* +***************************** I/O PORTS ****************************** +*********************************************************************/ + +/* +** Base port number assigned to the device +*/ +#define UA4_COM1_PORT 0x3f8 +#define UA4_COM2_PORT 0x2f8 +#define UA4_COM3_PORT 0x3e8 +#define UA4_COM4_PORT 0x2e8 + +// short name for the one we'll use +#define UA4_PORT UA4_COM1_PORT +#define UA5_PORT UA4_COM1_PORT + +/* +** Registers +** +** The 164x0 chips have the following registers. The (RO) and (WO) +** suffixes indicate read-only and write-only access. +** +** Index Register(s) +** ===== ========================================= +** 0 Receiver Data (RO), Transmitter Data (WO) +** 1 Interrupt Enable +** 2 Interrupt ID (RO), FIFO Control (WO) +** 3 Line Control, Divisor Latch +** 4 Modem Control +** 5 Line Status +** 6 Modem Status +** 7 Scratch +** +** Registers indices are relative to the base I/O port for the +** specific UART port being used (e.g., for COM1, the port addresses +** are 0x3f8 through 0x3ff). When two registers share a port and have +** different access methods (RO vs. WO), a read from the port accesses +** the RO register and a write to the port access the WO register. +** +** The Line Control and Divisor Latch registers are accessed by writing +** a byte to the port; the high-order bit determines which register is +** accessed (0 selects Line Control, 1 selects Divisor Latch), with the +** remaining bits selecting fields within the indicated register. +*/ + +/* +** Receiver Data Register (read-only) +*/ +#define UA4_RXD (UA4_PORT+0) +# define UA4_RX_DATA UA4_RXD + +/* +** Transmitter Data Register (write-only) +*/ +#define UA4_TXD (UA4_PORT+0) +# define UA4_TX_DATA UA4_TXD + +/* +** Interrupt Enable Register +*/ +#define UA4_IER (UA4_PORT+1) +# define UA4_INT_ENABLE_REG UA4_IER + +// fields +#define UA4_IER_RX_IE 0x01 // Rcvr High-Data-Level Int Enable +#define UA4_IER_TX_IE 0x02 // Xmitter Low-data-level Int Enable +#define UA4_IER_LS_IE 0x04 // Line Status Int Enable +#define UA4_IER_MS_IE 0x08 // Modem Status Int Enable + +// aliases +#define UA4_IER_RX_INT_ENABLE UA4_IER_RX_IE +#define UA4_IER_TX_INT_ENABLE UA4_IER_TX_IE +#define UA4_IER_LINE_STATUS_INT_ENABLE UA4_IER_LS_IE +#define UA4_IER_MODEM_STATUS_INT_ENABLE UA4_IER_MS_IE + +/* +** Interrupt Identification Register (read-only) +** +** a.k.a. Event Identification Register +*/ +#define UA4_IIR (UA4_PORT+2) +# define UA4_EVENT_ID UA4_IIR + +// fields +#define UA4_IIR_IPF 0x01 // Interrupt Pending flag + +#define UA4_IIR_IPR_MASK 0x06 // Interrupt Priority mask +# define UA4_IIR_IPR0_MASK 0x02 // IPR bit 0 mask +# define UA4_IIR_IPR1_MASK 0x04 // IPR bit 1 mask + +#define UA5_IIR_RXFT 0x08 // RX_FIFO Timeout +#define UA5_IIR_FEN0 0x40 // FIFOs Enabled +#define UA5_IIR_FEN1 0x80 // FIFOs Enabled + +// aliases +#define UA4_IIR_INT_PENDING UA4_IIR_IPF +#define UA4_IIR_INT_PRIORITY UA4_IIR_IPR +#define UA5_IIR_RX_FIFO_TIMEOUT UA5_IIR_RXFT +#define UA5_IIR_FIFO_ENABLED_0 UA5_IIR_FEN0 +#define UA5_IIR_FIFO_ENABLED_1 UA5_IIR_FEN1 + +// IIR interrupt priorities (four-bit values) +#define UA4_IIR_INT_PRI_MASK 0x0f // Mask for extracting int priority +# define UA4_IIR_NO_INT 0x01 // no interrupt +# define UA4_IIR_LINE_STATUS 0x06 // line status interrupt +# define UA4_IIR_RX 0x04 // Receiver High Data Level +# define UA5_IIR_RX_FIFO 0x0c // Receiver FIFO timeout (16550) +# define UA4_IIR_TX 0x02 // Transmitter Low Data level +# define UA4_IIR_MODEM_STATUS 0x00 // Modem Status + +// aliases +#define UA4_IIR_NO_INT_PENDING UA4_IIR_NO_INT +#define UA4_IIR_LINE_STATUS_INT_PENDING UA4_IIR_LINE_STATUS +#define UA4_IIR_RX_INT_PENDING UA4_IIR_RX +#define UA5_IIR_RX_FIFO_TIMEOUT_INT_PENDING UA5_IIR_RX_FIFO +#define UA4_IIR_TX_INT_PENDING UA4_IIR_TX +#define UA4_IIR_MODEM_STATUS_INT_PENDING UA4_IIR_MODEM_STATUS + +/* +** FIFO Control Register (16550 only, write-only) +*/ +#define UA5_FCR (UA5_PORT+2) +# define UA5_FIFO_CTL UA5_FCR + +#define UA5_FCR_FIFO_RESET 0x00 // Reset the FIFO +#define UA5_FCR_FIFO_EN 0x01 // FIFO Enable +#define UA5_FCR_RXSR 0x02 // Receiver Soft Reset +#define UA5_FCR_TXSR 0x04 // Transmitter Soft Reset + +#define UA5_FCR_TXFT_MASK 0x30 // TX_FIFO threshold level mask +# define UA5_FCR_TXFT0_MASK 0x10 // TXFT bit 0 mask +# define UA5_FCR_TXFT1_MASK 0x20 // TXFT bit 1 mask +# define UA5_FCR_TX_FIFO_1 0x00 // 1 char +# define UA5_FCR_TX_FIFO_3 0x10 // 3 char +# define UA5_FCR_TX_FIFO_9 0x20 // 9 char +# define UA5_FCR_TX_FIFO_13 0x30 // 13 char + +#define UA5_FCR_RXFT_MASK 0xc0 // RX_FIFO threshold level mask +# define UA5_FCR_RXFT0_MASK 0x40 // RXFT bit 0 mask +# define UA5_FCR_RXFT1_MASK 0x80 // RXFT bit 1 mask +# define UA5_FCR_RX_FIFO_1 0x00 // 1 char +# define UA5_FCR_RX_FIFO_4 0x40 // 4 char +# define UA5_FCR_RX_FIFO_8 0x80 // 8 char +# define UA5_FCR_RX_FIFO_14 0xc0 // 14 char + +// aliases +#define UA5_FCR_FIFO_ENABLED UA5_FCR_FIFO_EN +#define UA5_FCR_RX_SOFT_RESET UA5_FCR_RXSR +#define UA5_FCR_TX_SOFT_RESET UA5_FCR_TXSR +#define UA5_FCR_TX_FIFO_1_CHAR UA5_FCR_TX_FIFO_1 +#define UA5_FCR_TX_FIFO_3_CHAR UA5_FCR_TX_FIFO_3 +#define UA5_FCR_TX_FIFO_9_CHAR UA5_FCR_TX_FIFO_9 +#define UA5_FCR_TX_FIFO_13_CHAR UA5_FCR_TX_FIFO_13 +#define UA5_FCR_RX_FIFO_1_CHAR UA5_FCR_RX_FIFO_1 +#define UA5_FCR_RX_FIFO_4_CHAR UA5_FCR_RX_FIFO_4 +#define UA5_FCR_RX_FIFO_8_CHAR UA5_FCR_RX_FIFO_8 +#define UA5_FCR_RX_FIFO_14_CHAR UA5_FCR_RX_FIFO_14 + +/* +** Line Control Register (available in all banks) +** +** Selected when bit 7 of the value written to the port is a 0. +*/ +#define UA4_LCR (UA4_PORT+3) +# define UA4_LINE_CTL UA4_LCR + +#define UA4_LCR_WLS_MASK 0x03 // Word Length Select mask +# define UA4_LCR_WLS0_MASK 0x01 // WLS bit 0 mask +# define UA4_LCR_WLS1_MASK 0x02 // WLS bit 1 mask +# define UA4_LCR_WLS_5 0x00 // 5 bits per char +# define UA4_LCR_WLS_6 0x01 // 6 bits per char +# define UA4_LCR_WLS_7 0x02 // 7 bits per char +# define UA4_LCR_WLS_8 0x03 // 8 bits per char + +#define UA4_LCR_STB 0x04 // Stop Bits +# define UA4_LCR_1_STOP_BIT 0x00 +# define UA4_LCR_2_STOP_BIT 0x04 + +#define UA4_LCR_PEN 0x08 // Parity Enable +#define UA4_LCR_EPS 0x10 // Even Parity Select +#define UA4_LCR_STKP 0x20 // Sticky Parity +# define UA4_LCR_NO_PARITY 0x00 +# define UA4_LCR_ODD_PARITY UA4_LCR_PEN +# define UA4_LCR_EVEN_PARITY (UA4_LCR_PEN|UA4_LCR_EPS) +# define UA4_LCR_PARITY_LOGIC_1 (UA4_LCR_PEN|UA4_LCR_STKP) +# define UA4_LCR_PARITY_LOGIC_0 (UA4_LCR_PEN|UA4_LCR_EPS|UA4_LCR_STKP) + +#define UA4_LCR_SBRK 0x40 // Set Break +#define UA4_LCR_DLAB 0x80 // Divisor Latch select bit + +// aliases +# define UA4_LCR_STOP_BITS UA4_LCR_STB +# define UA4_LCR_PARITY_ENABLE UA4_LCR_PEN +# define UA4_LCR_SET_BREAK UA4_LCR_SBRK +# define UA4_LCR_BANK_SELECT_ENABLE UA4_LCR_BKSE + +/* +** Divisor Latch Registers +** Divisor Latch Least Significant (DLL) +** Divisor Latch Most Significant (DLM) +** +** These contain the lower and upper halves of the 16-bit divisor for +** baud rate generation. +** +** Accessing them requires sending a command to LCR with the most +** significant bit (0x80, the DLAB field) set. This "unlocks" the +** Divisor Latch registers, which are accessed at UA4_PORT+0 and +** UA4_PORT+1 (i.e., in place of the RXD/TXD and IE registers). To +** "re-lock" the Divisor Latch registers, write a command byte to +** LCR with 0 in the DLAB bit. +*/ +#define UA4_DLL (UA4_PORT+0) // Divisor Latch (least sig.) +#define UA4_DLM (UA4_PORT+1) // Divisor Latch (most sig.) + +// aliases +#define UA4_DIVISOR_LATCH_LS UA4_DLL +#define UA4_DIVISOR_LATCH_MS UA4_DLM + +// Baud rate divisor high and low bytes +#define BAUD_HIGH_BYTE(x) (((x) >> 8) & 0xff) +#define BAUD_LOW_BYTE(x) ((x) & 0xff) + +// Baud rate divisors +#define DL_BAUD_50 2304 +#define DL_BAUD_75 1536 +#define DL_BAUD_110 1047 +#define DL_BAUD_150 768 +#define DL_BAUD_300 384 +#define DL_BAUD_600 192 +#define DL_BAUD_1200 96 +#define DL_BAUD_1800 64 +#define DL_BAUD_2000 58 +#define DL_BAUD_2400 48 +#define DL_BAUD_3600 32 +#define DL_BAUD_4800 24 +#define DL_BAUD_7200 16 +#define DL_BAUD_9600 12 +#define DL_BAUD_14400 8 +#define DL_BAUD_19200 6 +#define DL_BAUD_28800 4 +#define DL_BAUD_38400 3 +#define DL_BAUD_57600 2 +#define DL_BAUD_115200 1 + +/* +** Modem Control Register +*/ +#define UA4_MCR (UA4_PORT+4) +# define UA4_MODEM_CTL UA4_MCR + +#define UA4_MCR_DTR 0x01 // Data Terminal Ready +#define UA4_MCR_RTS 0x02 // Ready to Send +#define UA4_MCR_RILP 0x04 // Loopback Interrupt Request +#define UA4_MCR_ISEN 0x08 // Interrupt Signal Enable +#define UA4_MCR_DCDLP 0x08 // DCD Loopback +#define UA4_MCR_LOOP 0x10 // Loopback Enable + +// aliases +#define UA4_MCR_DATA_TERMINAL_READY UA4_MCR_DTR +#define UA4_MCR_READY_TO_SEND UA4_MCR_RTS +#define UA4_MCR_LOOPBACK_INT_REQ UA4_MCR_RILP +#define UA4_MCR_INT_SIGNAL_ENABLE UA4_MCR_ISEN +#define UA4_MCR_LOOPBACK_DCD UA4_MCR_DCDLP +#define UA4_MCR_LOOPBACK_ENABLE UA4_MCR_LOOP + +/* +** Line Status Register +*/ +#define UA4_LSR (UA4_PORT+5) +# define UA4_LINE_STATUS UA4_LSR + +#define UA4_LSR_RXDA 0x01 // Receiver Data Available +#define UA4_LSR_OE 0x02 // Overrun Error +#define UA4_LSR_PE 0x04 // Parity Error +#define UA4_LSR_FE 0x08 // Framing Error +#define UA4_LSR_BRK 0x10 // Break Event Detected +#define UA4_LSR_TXRDY 0x20 // Transmitter Ready +#define UA4_LSR_TXEMP 0x40 // Transmitter Empty +#define UA4_LSR_ER_INF 0x80 // Error in RX_FIFO + +// aliases +#define UA4_LSR_RX_DATA_AVAILABLE UA4_LSR_RXDA +#define UA4_LSR_OVERRUN_ERROR UA4_LSR_OE +#define UA4_LSR_PARITY_ERROR UA4_LSR_PE +#define UA4_LSR_FRAMING_ERROR UA4_LSR_FE +#define UA4_LSR_BREAK_DETECTED UA4_LSR_BRK +#define UA4_LSR_TX_READY UA4_LSR_TXRDY +#define UA4_LSR_TX_EMPTY UA4_LSR_TXEMP +#define UA4_LSR_RX_FIFO_ERROR UA4_LSR_ER_INF + +/* +** Modem Status Register +*/ +#define UA4_MSR (UA4_PORT+6) +# define UA4_MODEM_STATUS UA4_MSR + +#define UA4_MSR_DCTS 0x01 // Delta Clear to Send +#define UA4_MSR_DDSR 0x02 // Delta Data Set Ready +#define UA4_MSR_TERI 0x04 // Trailing Edge Ring Indicate +#define UA4_MSR_DDCD 0x08 // Delta Data Carrier Detect +#define UA4_MSR_CTS 0x10 // Clear to Send +#define UA4_MSR_DSR 0x20 // Data Set Ready +#define UA4_MSR_RI 0x40 // Ring Indicate +#define UA4_MSR_DCD 0x80 // Data Carrier Detect + +// aliases +#define UA4_MSR_DELTA_CLEAR_TO_SEND UA4_MSR_DCTS +#define UA4_MSR_DELTA_DATA_SET_READY UA4_MSR_DDSR +#define UA4_MSR_TRAILING_EDGE_RING UA4_MSR_TERI +#define UA4_MSR_DELTA_DATA_CARRIER_DETECT UA4_MSR_DDCD +#define UA4_MSR_CLEAR_TO_SEND UA4_MSR_CTS +#define UA4_MSR_DATA_SET_READY UA4_MSR_DSR +#define UA4_MSR_RING_INDICATE UA4_MSR_RI +#define UA4_MSR_DATA_CARRIER_DETECT UA4_MSR_DCD + +/* +** Scratch Register +** +** Not used by the UART; usable as a "scratchpad" register for +** temporary storage. +*/ +#define UA4_SCR (UA4_PORT+7) +# define UA4_SCRATCH UA4_UA5_SCR + +#endif /* uart.h */ diff --git a/kernel/Make.mk b/kernel/Make.mk new file mode 100644 index 0000000..0c9b507 --- /dev/null +++ b/kernel/Make.mk @@ -0,0 +1,66 @@ +# +# Makefile fragment for the kernel components of the system. +# +# Makefile fragment for the kernel component of the system. +# +# THIS IS NOT A COMPLETE Makefile - run GNU make in the top-level +# directory, and this will be pulled in automatically. +# + +SUBDIRS += kernel + +################### +# FILES SECTION # +################### + +BOOT_OBJ := $(patsubst %.c, $(BUILDDIR)/%.o, $(BOOT_SRC)) + +KERN_SRC := kernel/startup.S kernel/isrs.S \ + kernel/cio.c kernel/clock.c kernel/kernel.c kernel/kmem.c \ + kernel/list.c kernel/procs.c kernel/sio.c kernel/support.c \ + kernel/syscalls.c kernel/user.c kernel/vm.c kernel/vmtables.c + +KERN_OBJ := $(patsubst %.c, $(BUILDDIR)/%.o, $(KERN_SRC)) +KERN_OBJ := $(patsubst %.S, $(BUILDDIR)/%.o, $(KERN_OBJ)) + +KCFLAGS := -ggdb +KLDFLAGS := -T kernel/kernel.ld +KLIBS := -lkernel -lcommon + +################### +# RULES SECTION # +################### + +kernel: $(BUILDDIR)/kernel/kernel.b + +$(BUILDDIR)/kernel/%.o: kernel/%.c $(BUILDDIR)/.vars.CFLAGS + @mkdir -p $(@D) + $(CC) $(CFLAGS) $(KCFLAGS) -c -o $@ $< + +$(BUILDDIR)/kernel/%.o: kernel/%.S $(BUILDDIR)/.vars.CFLAGS + @mkdir -p $(@D) + $(CPP) $(CPPFLAGS) -o $(@D)/$*.s $< + $(AS) $(ASFLAGS) $(KCFLAGS) -o $@ $(@D)/$*.s -a=$(@D)/$*.lst + $(RM) -f $(@D)/$*.s + +$(BUILDDIR)/kernel/kernel: $(KERN_OBJ) + @mkdir -p $(@D) + $(LD) $(KLDFLAGS) $(LDFLAGS) -o $@ $(KERN_OBJ) $(KLIBS) + $(OBJDUMP) -S $@ > $@.asm + $(NM) -n $@ > $@.sym + $(READELF) -a $@ > $@.info + +$(BUILDDIR)/kernel/kernel.b: $(BUILDDIR)/kernel/kernel + $(LD) $(LDFLAGS) -o $(BUILDDIR)/kernel/kernel.b -s \ + --oformat binary -Ttext 0x10000 $(BUILDDIR)/kernel/kernel + +# some debugging assist rules +$(BUILDDIR)/kernel/%.i: kernel/%.c $(BUILDDIR)/.vars.CFLAGS + @mkdir -p $(@D) + $(CC) $(CFLAGS) $(KCFLAGS) -E -c $< > $(@D)/$*.i + +$(BUILDDIR)/kernel/%.dat: $(BUILDDIR)/kernel/%.o + @mkdir -p $(@D) + $(OBJCOPY) -S -O binary -j .data $< $@ + hexdump -C $@ > $(@D)/$*.hex + diff --git a/kernel/cio.c b/kernel/cio.c new file mode 100644 index 0000000..cfff543 --- /dev/null +++ b/kernel/cio.c @@ -0,0 +1,796 @@ +/* +** SCCS ID: @(#)cio.c 2.10 1/22/25 +** +** @file cio.c +** +** @author Warren R. Carithers +** +** Based on: c_io.c 1.13 (Ken Reek, Jon Coles, Warren R. Carithers) +** +** Console I/O routines +** +** This module implements a simple set of input and output routines +** for the console screen and keyboard on the machines in the DSL. +** Refer to the header file comments for complete details. +** +** Naming conventions: +** +** Externally-visible functions have names beginning with the +** characters "cio_". +** +*/ + +#include <cio.h> +#include <lib.h> +#include <support.h> +#include <x86/arch.h> +#include <x86/pic.h> +#include <x86/ops.h> + +/* +** Bit masks for the lower five and eight bits of a value +*/ +#define BMASK5 0x1f +#define BMASK8 0xff + +/* +** Video parameters +*/ +#define SCREEN_MIN_X 0 +#define SCREEN_MIN_Y 0 +#define SCREEN_X_SIZE 80 +#define SCREEN_Y_SIZE 25 +#define SCREEN_MAX_X ( SCREEN_X_SIZE - 1 ) +#define SCREEN_MAX_Y ( SCREEN_Y_SIZE - 1 ) + +/* +** Video state +*/ +static unsigned int scroll_min_x, scroll_min_y; +static unsigned int scroll_max_x, scroll_max_y; +static unsigned int curr_x, curr_y; +static unsigned int min_x, min_y; +static unsigned int max_x, max_y; + +// pointer to input notification function +static void (*notify)(int); + +#ifdef SA_DEBUG +#include <stdio.h> +#define cio_putchar putchar +#define cio_puts(x) fputs( x, stdout ) +#endif + + +/* +** VGA definitions. +*/ + +// calculate the memory address of a specific character position +// within VGA memory +#define VIDEO_ADDR(x,y) ( unsigned short * ) \ + ( VID_BASE_ADDR + 2 * ( (y) * SCREEN_X_SIZE + (x) ) ) + +// port addresses +#define VGA_CTRL_IX_ADDR 0x3d4 +# define VGA_CTRL_CUR_HIGH 0x0e // cursor location, high byte +# define VGA_CTRL_CUR_LOW 0x0f // cursor location, low byte +#define VGA_CTRL_IX_DATA 0x3d5 + +// attribute bits +#define VGA_ATT_BBI 0x80 // blink, or background intensity +#define VGA_ATT_BGC 0x70 // background color +#define VGA_ATT_FICS 0x80 // foreground intensity or char font select +#define VGA_ATT_FGC 0x70 // foreground color + +// color selections +#define VGA_BG_BLACK 0x0000 // background colors +#define VGA_BG_BLUE 0x1000 +#define VGA_BG_GREEN 0x2000 +#define VGA_BG_CYAN 0x3000 +#define VGA_BG_RED 0x4000 +#define VGA_BG_MAGENTA 0x5000 +#define VGA_BG_BROWN 0x6000 +#define VGA_BG_WHITE 0x7000 + +#define VGA_FG_BLACK 0x0000 // foreground colors +#define VGA_FG_BLUE 0x0100 +#define VGA_FG_GREEN 0x0200 +#define VGA_FG_CYAN 0x0300 +#define VGA_FG_RED 0x0400 +#define VGA_FG_MAGENTA 0x0500 +#define VGA_FG_BROWN 0x0600 +#define VGA_FG_WHITE 0x0700 + +// color combinations +#define VGA_WHITE_ON_BLACK (VGA_FG_WHITE | VGA_BG_BLACK) +#define VGA_BLACK_ON_WHITE (VGA_FG_BLACK | VGA_BG_WHITE) + +/* +** Internal support routines. +*/ + +/* +** setcursor: set the cursor location (screen coordinates) +*/ +static void setcursor( void ) { + unsigned addr; + unsigned int y = curr_y; + + if( y > scroll_max_y ) { + y = scroll_max_y; + } + + addr = (unsigned)( y * SCREEN_X_SIZE + curr_x ); + + outb( VGA_CTRL_IX_ADDR, VGA_CTRL_CUR_HIGH ); + outb( VGA_CTRL_IX_DATA, ( addr >> 8 ) & BMASK8 ); + outb( VGA_CTRL_IX_ADDR, VGA_CTRL_CUR_LOW ); + outb( VGA_CTRL_IX_DATA, addr & BMASK8 ); +} + +/* +** putchar_at: physical output to the video memory +*/ +static void putchar_at( unsigned int x, unsigned int y, unsigned int c ) { + /* + ** If x or y is too big or small, don't do any output. + */ + if( x <= max_x && y <= max_y ) { + unsigned short *addr = VIDEO_ADDR( x, y ); + + /* + ** The character may have attributes associated with it; if + ** so, use those, otherwise use white on black. + */ + c &= 0xffff; // keep only the lower bytes + if( c > BMASK8 ) { + *addr = (unsigned short)c; + } else { + *addr = (unsigned short)c | VGA_WHITE_ON_BLACK; + } + } +} + +/* +** Globally-visible support routines. +*/ + +/* +** Set the scrolling region +*/ +void cio_setscroll( unsigned int s_min_x, unsigned int s_min_y, + unsigned int s_max_x, unsigned int s_max_y ) { + scroll_min_x = bound( min_x, s_min_x, max_x ); + scroll_min_y = bound( min_y, s_min_y, max_y ); + scroll_max_x = bound( scroll_min_x, s_max_x, max_x ); + scroll_max_y = bound( scroll_min_y, s_max_y, max_y ); + curr_x = scroll_min_x; + curr_y = scroll_min_y; + setcursor(); +} + +/* +** Cursor movement in the scroll region +*/ +void cio_moveto( unsigned int x, unsigned int y ) { + curr_x = bound( scroll_min_x, x + scroll_min_x, scroll_max_x ); + curr_y = bound( scroll_min_y, y + scroll_min_y, scroll_max_y ); + setcursor(); +} + +/* +** The putchar family +*/ +void cio_putchar_at( unsigned int x, unsigned int y, unsigned int c ) { + if( ( c & 0x7f ) == '\n' ) { + unsigned int limit; + + /* + ** If we're in the scroll region, don't let this loop + ** leave it. If we're not in the scroll region, don't + ** let this loop enter it. + */ + if( x > scroll_max_x ) { + limit = max_x; + } + else if( x >= scroll_min_x ) { + limit = scroll_max_x; + } + else { + limit = scroll_min_x - 1; + } + while( x <= limit ) { + putchar_at( x, y, ' ' ); + x += 1; + } + } + else { + putchar_at( x, y, c ); + } +} + +#ifndef SA_DEBUG +void cio_putchar( unsigned int c ) { + /* + ** If we're off the bottom of the screen, scroll the window. + */ + if( curr_y > scroll_max_y ) { + cio_scroll( curr_y - scroll_max_y ); + curr_y = scroll_max_y; + } + + switch( c & BMASK8 ) { + case '\n': + /* + ** Erase to the end of the line, then move to new line + ** (actual scroll is delayed until next output appears). + */ + while( curr_x <= scroll_max_x ) { + putchar_at( curr_x, curr_y, ' ' ); + curr_x += 1; + } + curr_x = scroll_min_x; + curr_y += 1; + break; + + case '\r': + curr_x = scroll_min_x; + break; + + default: + putchar_at( curr_x, curr_y, c ); + curr_x += 1; + if( curr_x > scroll_max_x ) { + curr_x = scroll_min_x; + curr_y += 1; + } + break; + } + setcursor(); +} +#endif + +/* +** The puts family +*/ +void cio_puts_at( unsigned int x, unsigned int y, const char *str ) { + unsigned int ch; + + while( (ch = *str++) != '\0' && x <= max_x ) { + cio_putchar_at( x, y, ch ); + x += 1; + } +} + +#ifndef SA_DEBUG +void cio_puts( const char *str ) { + unsigned int ch; + + while( (ch = *str++) != '\0' ) { + cio_putchar( ch ); + } +} +#endif + +/* +** Write a "sized" buffer (like cio_puts(), but no NUL) +*/ +void cio_write( const char *buf, int length ) { + for( int i = 0; i < length; ++i ) { + cio_putchar( buf[i] ); + } +} + +void cio_clearscroll( void ) { + unsigned int nchars = scroll_max_x - scroll_min_x + 1; + unsigned int l; + unsigned int c; + + for( l = scroll_min_y; l <= scroll_max_y; l += 1 ) { + unsigned short *to = VIDEO_ADDR( scroll_min_x, l ); + + for( c = 0; c < nchars; c += 1 ) { + *to++ = ' ' | 0x0700; + } + } +} + +void cio_clearscreen( void ) { + unsigned short *to = VIDEO_ADDR( min_x, min_y ); + unsigned int nchars = ( max_y - min_y + 1 ) * ( max_x - min_x + 1 ); + + while( nchars > 0 ) { + *to++ = ' ' | 0x0700; + nchars -= 1; + } +} + + +void cio_scroll( unsigned int lines ) { + unsigned short *from; + unsigned short *to; + int nchars = scroll_max_x - scroll_min_x + 1; + int line, c; + + /* + ** If # of lines is the whole scrolling region or more, just clear. + */ + if( lines > scroll_max_y - scroll_min_y ) { + cio_clearscroll(); + curr_x = scroll_min_x; + curr_y = scroll_min_y; + setcursor(); + return; + } + + /* + ** Must copy it line by line. + */ + for( line = scroll_min_y; line <= scroll_max_y - lines; line += 1 ) { + from = VIDEO_ADDR( scroll_min_x, line + lines ); + to = VIDEO_ADDR( scroll_min_x, line ); + for( c = 0; c < nchars; c += 1 ) { + *to++ = *from++; + } + } + + for( ; line <= scroll_max_y; line += 1 ) { + to = VIDEO_ADDR( scroll_min_x, line ); + for( c = 0; c < nchars; c += 1 ) { + *to++ = ' ' | 0x0700; + } + } +} + +static int mypad( int x, int y, int extra, int padchar ) { + while( extra > 0 ) { + if( x != -1 || y != -1 ) { + cio_putchar_at( x, y, padchar ); + x += 1; + } + else { + cio_putchar( padchar ); + } + extra -= 1; + } + return x; +} + +static int mypadstr( int x, int y, char *str, int len, int width, + int leftadjust, int padchar ) { + int extra; + + if( len < 0 ) { + len = strlen( str ); + } + extra = width - len; + if( extra > 0 && !leftadjust ) { + x = mypad( x, y, extra, padchar ); + } + if( x != -1 || y != -1 ) { + cio_puts_at( x, y, str ); + x += len; + } + else { + cio_puts( str ); + } + if( extra > 0 && leftadjust ) { + x = mypad( x, y, extra, padchar ); + } + return x; +} + +static void do_printf( int x, int y, char **f ) { + char *fmt = *f; + int *ap; + char buf[ 12 ]; + char ch; + char *str; + int leftadjust; + int width; + int len; + int padchar; + + /* + ** Get characters from the format string and process them + */ + + ap = (int *)( f + 1 ); + + while( (ch = *fmt++) != '\0' ) { + + /* + ** Is it the start of a format code? + */ + + if( ch == '%' ) { + + /* + ** Yes, get the padding and width options (if there). + ** Alignment must come at the beginning, then fill, + ** then width. + */ + + leftadjust = 0; + padchar = ' '; + width = 0; + + ch = *fmt++; + + if( ch == '-' ) { + leftadjust = 1; + ch = *fmt++; + } + + if( ch == '0' ) { + padchar = '0'; + ch = *fmt++; + } + + while( ch >= '0' && ch <= '9' ) { + width *= 10; + width += ch - '0'; + ch = *fmt++; + } + + /* + ** What data type do we have? + */ + switch( ch ) { + + case 'c': + // ch = *( (int *)ap )++; + ch = *ap++; + buf[ 0 ] = ch; + buf[ 1 ] = '\0'; + x = mypadstr( x, y, buf, 1, width, leftadjust, padchar ); + break; + + case 'd': + // len = cvtdec( buf, *( (int *)ap )++ ); + len = cvtdec( buf, *ap++ ); + x = mypadstr( x, y, buf, len, width, leftadjust, padchar ); + break; + + case 's': + // str = *( (char **)ap )++; + str = (char *) (*ap++); + x = mypadstr( x, y, str, -1, width, leftadjust, padchar ); + break; + + case 'x': + // len = cvthex( buf, *( (int *)ap )++ ); + len = cvthex( buf, *ap++ ); + x = mypadstr( x, y, buf, len, width, leftadjust, padchar ); + break; + + case 'o': + // len = cvtoct( buf, *( (int *)ap )++ ); + len = cvtoct( buf, *ap++ ); + x = mypadstr( x, y, buf, len, width, leftadjust, padchar ); + break; + + case 'u': + len = cvtuns( buf, *ap++ ); + x = mypadstr( x, y, buf, len, width, leftadjust, padchar ); + break; + + } + } else { + + /* + ** No - just print it normally. + */ + + if( x != -1 || y != -1 ) { + cio_putchar_at( x, y, ch ); + switch( ch ) { + case '\n': + y += 1; + /* FALL THRU */ + + case '\r': + x = scroll_min_x; + break; + + default: + x += 1; + } + } + else { + cio_putchar( ch ); + } + } + } +} + +void cio_printf_at( unsigned int x, unsigned int y, char *fmt, ... ) { + do_printf( x, y, &fmt ); +} + +void cio_printf( char *fmt, ... ) { + do_printf( -1, -1, &fmt ); +} + +/* +** These are the "standard" IBM AT "Set 1" keycodes. +*/ + +static unsigned char scan_code[ 2 ][ 128 ] = { + { // unshifted characters +/* 00-07 */ '\377', '\033', '1', '2', '3', '4', '5', '6', +/* 08-0f */ '7', '8', '9', '0', '-', '=', '\b', '\t', +/* 10-17 */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', +/* 18-1f */ 'o', 'p', '[', ']', '\n', '\377', 'a', 's', +/* 20-27 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', +/* 28-2f */ '\'', '`', '\377', '\\', 'z', 'x', 'c', 'v', +/* 30-37 */ 'b', 'n', 'm', ',', '.', '/', '\377', '*', +/* 38-3f */ '\377', ' ', '\377', '\377', '\377', '\377', '\377', '\377', +/* 40-47 */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '7', +/* 48-4f */ '8', '9', '-', '4', '5', '6', '+', '1', +/* 50-57 */ '2', '3', '0', '.', '\377', '\377', '\377', '\377', +/* 58-5f */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', +/* 60-67 */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', +/* 68-6f */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', +/* 70-77 */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', +/* 78-7f */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377' + }, + + { // shifted characters +/* 00-07 */ '\377', '\033', '!', '@', '#', '$', '%', '^', +/* 08-0f */ '&', '*', '(', ')', '_', '+', '\b', '\t', +/* 10-17 */ 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', +/* 18-1f */ 'O', 'P', '{', '}', '\n', '\377', 'A', 'S', +/* 20-27 */ 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', +/* 28-2f */ '"', '~', '\377', '|', 'Z', 'X', 'C', 'V', +/* 30-37 */ 'B', 'N', 'M', '<', '>', '?', '\377', '*', +/* 38-3f */ '\377', ' ', '\377', '\377', '\377', '\377', '\377', '\377', +/* 40-47 */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '7', +/* 48-4f */ '8', '9', '-', '4', '5', '6', '+', '1', +/* 50-57 */ '2', '3', '0', '.', '\377', '\377', '\377', '\377', +/* 58-5f */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', +/* 60-67 */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', +/* 68-6f */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', +/* 70-77 */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', +/* 78-7f */ '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377' + } +}; + +/* +** Scan code masks +*/ + +// 'release' bit +#define REL_BIT 0x80 +#define CODE_BITS 0x7f + +#define IS_PRESS(c) (((c) & REL_BIT) == 0) +#define IS_RELEASE(c) (((c) & REL_BIT) != 0) + +/* +** Scan codes for some special characters +*/ + +// escape code - followed by another code byte +#define SCAN_ESC 0xe0 + +// shift keys: press, release +#define L_SHIFT_DN 0x2a +#define R_SHIFT_DN 0x36 +#define L_SHIFT_UP 0xaa +#define R_SHIFT_UP 0xb6 + +// control keys +#define L_CTRL_DN 0x1d +#define L_CTRL_UP 0x9d + +/* +** I/O communication constants +*/ +#define KBD_DATA 0x60 +#define KBD_STATUS 0x64 +#define READY 0x1 + +/* +** Circular buffer for input characters. Characters are inserted at +** next_space, and are removed at next_char. Buffer is empty if +** these are equal. +*/ +#define C_BUFSIZE 200 + +static char input_buffer[ C_BUFSIZE ]; +static volatile char *next_char = input_buffer; +static volatile char *next_space = input_buffer; + +static volatile char *increment( volatile char *pointer ) { + if( ++pointer >= input_buffer + C_BUFSIZE ) { + pointer = input_buffer; + } + return pointer; +} + +static int input_scan_code( int code ) { + static int shift = 0; + static int ctrl_mask = BMASK8; + int rval = -1; + + /* + ** Do the shift processing + */ + code &= BMASK8; + switch( code ) { + case L_SHIFT_DN: + case R_SHIFT_DN: + shift = 1; + break; + + case L_SHIFT_UP: + case R_SHIFT_UP: + shift = 0; + break; + + case L_CTRL_DN: + ctrl_mask = BMASK5; + break; + + case L_CTRL_UP: + ctrl_mask = BMASK8; + break; + + default: + /* + ** Process ordinary characters only on the press (to handle + ** autorepeat). Ignore undefined scan codes. + */ + if( IS_PRESS(code) ) { + code = scan_code[ shift ][ (int)code ]; + if( code != '\377' ) { + volatile char *next = increment( next_space ); + + /* + ** Store character only if there's room + */ + rval = code & ctrl_mask; + if( next != next_char ) { + *next_space = code & ctrl_mask; + next_space = next; + } + } + } + } + return( rval ); +} + +static void keyboard_isr( int vector, int code ) { + + int data = inb( KBD_DATA ); + int val = input_scan_code( data ); + + // if there is a notification function, call it + if( val != -1 && notify ) + notify( val ); + + outb( PIC1_CMD, PIC_EOI ); +} + +int cio_getchar( void ) { + char c; + int interrupts_enabled = r_eflags() & EFL_IF; + + while( next_char == next_space ) { + if( !interrupts_enabled ) { + /* + ** Must read the next keystroke ourselves. + */ + while( ( inb( KBD_STATUS ) & READY ) == 0 ) { + ; + } + (void) input_scan_code( inb( KBD_DATA ) ); + } + } + + c = *next_char & BMASK8; + next_char = increment( next_char ); + if( c != EOT ) { + cio_putchar( c ); + } + return c; +} + +int cio_gets( char *buffer, unsigned int size ) { + char ch; + int count = 0; + + while( size > 1 ) { + ch = cio_getchar(); + if( ch == EOT ) { + break; + } + *buffer++ = ch; + count += 1; + size -= 1; + if( ch == '\n' ) { + break; + } + } + *buffer = '\0'; + return count; +} + +int cio_input_queue( void ) { + int n_chars = next_space - next_char; + + if( n_chars < 0 ) { + n_chars += C_BUFSIZE; + } + return n_chars; +} + +/* +** Initialization routines +*/ +void cio_init( void (*fcn)(int) ) { + /* + ** Screen dimensions + */ + min_x = SCREEN_MIN_X; + min_y = SCREEN_MIN_Y; + max_x = SCREEN_MAX_X; + max_y = SCREEN_MAX_Y; + + /* + ** Scrolling region + */ + scroll_min_x = SCREEN_MIN_X; + scroll_min_y = SCREEN_MIN_Y; + scroll_max_x = SCREEN_MAX_X; + scroll_max_y = SCREEN_MAX_Y; + + /* + ** Initial cursor location + */ + curr_y = min_y; + curr_x = min_x; + setcursor(); + + /* + ** Notification function (or NULL) + */ + notify = fcn; + + /* + ** Set up the interrupt handler for the keyboard + */ + install_isr( VEC_KBD, keyboard_isr ); +} + +#ifdef SA_DEBUG +int main() { + cio_printf( "%d\n", 123 ); + cio_printf( "%d\n", -123 ); + cio_printf( "%d\n", 0x7fffffff ); + cio_printf( "%d\n", 0x80000001 ); + cio_printf( "%d\n", 0x80000000 ); + cio_printf( "x%14dy\n", 0x80000000 ); + cio_printf( "x%-14dy\n", 0x80000000 ); + cio_printf( "x%014dy\n", 0x80000000 ); + cio_printf( "x%-014dy\n", 0x80000000 ); + cio_printf( "%s\n", "xyz" ); + cio_printf( "|%10s|\n", "xyz" ); + cio_printf( "|%-10s|\n", "xyz" ); + cio_printf( "%c\n", 'x' ); + cio_printf( "|%4c|\n", 'y' ); + cio_printf( "|%-4c|\n", 'y' ); + cio_printf( "|%04c|\n", 'y' ); + cio_printf( "|%-04c|\n", 'y' ); + cio_printf( "|%3d|\n", 5 ); + cio_printf( "|%3d|\n", 54321 ); + cio_printf( "%x\n", 0x123abc ); + cio_printf( "|%04x|\n", 20 ); + cio_printf( "|%012x|\n", 0xfedcba98 ); + cio_printf( "|%-012x|\n", 0x76543210 ); +} + +int curr_x, curr_y, max_x, max_y; +#endif diff --git a/kernel/clock.c b/kernel/clock.c new file mode 100644 index 0000000..96f71c4 --- /dev/null +++ b/kernel/clock.c @@ -0,0 +1,163 @@ +/** +** @file clock.c +** +** @author CSCI-452 class of 20245 +** +** @brief Clock module implementation +*/ + +#define KERNEL_SRC + +#include <common.h> + +#include <clock.h> +#include <procs.h> + +#include <x86/arch.h> +#include <x86/pic.h> +#include <x86/pit.h> + +/* +** PRIVATE DEFINITIONS +*/ + +/* +** PRIVATE DATA TYPES +*/ + +/* +** PRIVATE GLOBAL VARIABLES +*/ + +// pinwheel control variables +static uint32_t pinwheel; // pinwheel counter +static uint32_t pindex; // index into pinwheel string + +/* +** PUBLIC GLOBAL VARIABLES +*/ + +// current system time +uint32_t system_time; + +/* +** PRIVATE FUNCTIONS +*/ + +/** +** Name: clk_isr +** +** The ISR for the clock +** +** @param vector Vector number for the clock interrupt +** @param code Error code (0 for this interrupt) +*/ +static void clk_isr( int vector, int code ) { + + // spin the pinwheel + + ++pinwheel; + if( pinwheel == (CLOCK_FREQ / 10) ) { + pinwheel = 0; + ++pindex; + cio_putchar_at( 0, 0, "|/-\\"[ pindex & 3 ] ); + } + +#if defined(SYSTEM_STATUS) + // Periodically, dump the queue lengths and the SIO status (along + // with the SIO buffers, if non-empty). + // + // Define the symbol SYSTEM_STATUS with a value equal to the desired + // reporting frequency, in seconds. + + if( (system_time % SEC_TO_TICKS(SYSTEM_STATUS)) == 0 ) { + cio_printf_at( 1, 0, " queues: R[%u] W[%u] S[%u] Z[%u] I[%u] ", + pcb_queue_length(ready), + pcb_queue_length(waiting), + pcb_queue_length(sleeping), + pcb_queue_length(zombie), + pcb_queue_length(sioread) + ); + } +#endif + + // time marches on! + ++system_time; + + // wake up any sleeping processes whose time has come + // + // we give them preference over the current process when + // it is scheduled again + + do { + // if there isn't anyone in the sleep queue, we're done + if( pcb_queue_empty(sleeping) ) { + break; + } + + // peek at the first member of the queue + pcb_t *tmp = pcb_queue_peek( sleeping ); + assert( tmp != NULL ); + + // the sleep queue is sorted in ascending order by wakeup + // time, so we know that the retrieved PCB's wakeup time is + // the earliest of any process on the sleep queue; if that + // time hasn't arrived yet, there's nobody left to awaken + + if( tmp->wakeup > system_time ) { + break; + } + + // OK, we need to wake this process up + assert( pcb_queue_remove(sleeping,&tmp) == SUCCESS ); + schedule( tmp ); + } while( 1 ); + + // next, we decrement the current process' remaining time + current->ticks -= 1; + + // has it expired? + if( current->ticks < 1 ) { + // yes! reschedule it + schedule( current ); + current = NULL; + // and pick a new process + dispatch(); + } + + // tell the PIC we're done + outb( PIC1_CMD, PIC_EOI ); +} + +/* +** PUBLIC FUNCTIONS +*/ + +/** +** Name: clk_init +** +** Initializes the clock module +** +*/ +void clk_init( void ) { + +#if TRACING_INIT + cio_puts( " Clock" ); +#endif + + // start the pinwheel + pinwheel = (CLOCK_FREQ / 10) - 1; + pindex = 0; + + // return to the dawn of time + system_time = 0; + + // configure the clock + uint32_t divisor = PIT_FREQ / CLOCK_FREQ; + outb( PIT_CONTROL_PORT, PIT_0_LOAD | PIT_0_SQUARE ); + outb( PIT_0_PORT, divisor & 0xff ); // LSB of divisor + outb( PIT_0_PORT, (divisor >> 8) & 0xff ); // MSB of divisor + + // register the second-stage ISR + install_isr( VEC_TIMER, clk_isr ); +} diff --git a/kernel/isrs.S b/kernel/isrs.S new file mode 100644 index 0000000..421e6d2 --- /dev/null +++ b/kernel/isrs.S @@ -0,0 +1,374 @@ +/* +** @file isrs.S +** +** @author K. Reek +** @authors Jon Coles, Warren R. Carithers, Margaret Reek +** @author numerous Systems Programming classes +** +** Stubs for ISRs. +** +** This module provides the stubs needed for interrupts to save +** the machine state before calling the ISR. All interrupts have +** their own stub which pushes the interrupt number on the stack. +** This makes it possible for a common ISR to determine which +** interrupted occurred. +*/ + +#define ASM_SRC + + .arch i386 + +#include <bootstrap.h> + +/* +** Configuration options - define in Makefile +** +** TRACE_CX include context restore debugging code +*/ + + .text + +/* +** Macros for the isr stubs. Some interrupts push an error code on +** the stack and others don't; for those that don't we simply push +** a zero so that cleaning up from either type is identical. +** +** Note: these are not marked as global symbols, as they are never +** accessed directly outside of this file. This could be changed +** if need be by adding this line to each macro definition right +** after the #define line: +** +** .global isr_##vector +*/ + +#define ISR(vector) \ +isr_##vector: ; \ + pushl $0 ; \ + pushl $vector ; \ + jmp isr_save + +#define ERR_ISR(vector) \ +isr_##vector: ; \ + pushl $vector ; \ + jmp isr_save + + .globl isr_table + .globl isr_restore + +/* +** This routine saves the machine state, calls the ISR, and then +** restores the machine state and returns from the interrupt. +** +******************************************************************** +******************************************************************** +** NOTE: this code is highly application-specific, and will most ** +** probably require modification to tailor it. ** +** ** +** Examples of mods: switch to/from user stack, context switch ** +** changes, etc. ** +******************************************************************** +******************************************************************** +*/ + +isr_save: + +/* +** Begin by saving the CPU state (except for the FP context information). +** +** At this point, the stack looks like this: +** +** esp -> vector # saved by the entry macro +** error code, or 0 saved by the hardware, or the entry macro +** saved EIP saved by the hardware +** saved CS saved by the hardware +** saved EFLAGS saved by the hardware +*/ + pusha // save E*X, ESP, EBP, ESI, EDI + pushl %ds // save segment registers + pushl %es + pushl %fs + pushl %gs + pushl %ss + +/* +** Stack contents (all 32-bit longwords) and offsets from ESP: +** +** SS GS FS ES DS EDI ESI EBP ESP EBX EDX ECX EAX vec cod EIP CS EFL +** 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 +** +** Note that the saved ESP is the contents before the PUSHA. +** +** Set up parameters for the ISR call. +*/ + movl 52(%esp),%eax // get vector number and error code + movl 56(%esp),%ebx + +/* +*********************** +** MOD FOR 20245 ** +*********************** +*/ + +/* +** We need to switch to the system stack. This requires that we save +** the user context pointer into the current PCB, then load ESP with +** the initial system stack pointer. +*/ + + .globl current + .globl kernel_esp + + // save the context pointer + movl current, %edx + movl %esp, (%edx) + + // also save the page directory pointer + movl %cr3, %ecx + movl %ecx, 4(%edx) + + // switch to the system stack + // + // NOTE: this is inherently non-reentrant! If/when the OS + // is converted from monolithic to something that supports + // reentrant or interruptable ISRs, this code will need to + // be changed to support that! + + movl kernel_esp, %esp + + // we don't change CR3 because all the user PDIRs are + // set up with mappings for the OS in the upper half + +/* +*********************** +** END MOD FOR 20245 ** +*********************** +*/ + + pushl %ebx // put them on the top of the stack ... + pushl %eax // ... as parameters for the ISR + +/* +** Call the ISR +*/ + movl isr_table(,%eax,4),%ebx + call *%ebx + addl $8,%esp // pop the two parameters + +/* +** Context restore begins here +*/ + +isr_restore: + +/* +*********************** +** MOD FOR 20245 ** +*********************** +*/ + movl current, %ebx // return to the user stack + movl (%ebx), %esp // ESP --> context save area + movl 4(%ebx), %ecx // page directory pointer + movl %ecx, %cr3 + + // now we're operating with the user process' + // page directory and stack + +/* +*********************** +** END MOD FOR 20245 ** +*********************** +*/ + +#ifdef TRACE_CX +/* +** DEBUGGING CODE PART 1 +** +** This code will execute during each context restore, and +** should be modified to print out whatever debugging information +** is desired. +** +** By default, it prints out the CPU context being restored; it +** relies on the standard save sequence (see above). +*/ + .globl cio_printf_at + + pushl $fmt + pushl $1 + pushl $0 + call cio_printf_at + addl $12,%esp +/* +** END OF DEBUGGING CODE PART 1 +*/ +#endif + +/* +** Restore the context. +*/ + popl %ss // restore the segment registers + popl %gs + popl %fs + popl %es + popl %ds + popa // restore others + addl $8, %esp // discard the error code and vector + iret // and return + +#ifdef TRACE_CX +/* +** DEBUGGING CODE PART 2 +** +** This format string is arranged according to the ordering of values +** in the context save area on the stack. +*/ +fmt: .ascii " ss=%08x gs=%08x fs=%08x es=%08x ds=%08x\n" + .ascii "edi=%08x esi=%08x ebp=%08x esp=%08x ebx=%08x\n" + .ascii "edx=%08x ecx=%08x eax=%08x vec=%08x cod=%08x\n" + .string "eip=%08x cs=%08x efl=%08x\n" + +/* +** END OF DEBUGGING CODE PART 2 +*/ +#endif + +/* +** Here we generate the individual stubs for each interrupt. +*/ +ISR(0x00); ISR(0x01); ISR(0x02); ISR(0x03); +ISR(0x04); ISR(0x05); ISR(0x06); ISR(0x07); +ERR_ISR(0x08); ISR(0x09); ERR_ISR(0x0a); ERR_ISR(0x0b); +ERR_ISR(0x0c); ERR_ISR(0x0d); ERR_ISR(0x0e); ISR(0x0f); +ISR(0x10); ERR_ISR(0x11); ISR(0x12); ISR(0x13); +ISR(0x14); ERR_ISR(0x15); ISR(0x16); ISR(0x17); +ISR(0x18); ISR(0x19); ISR(0x1a); ISR(0x1b); +ISR(0x1c); ISR(0x1d); ISR(0x1e); ISR(0x1f); +ISR(0x20); ISR(0x21); ISR(0x22); ISR(0x23); +ISR(0x24); ISR(0x25); ISR(0x26); ISR(0x27); +ISR(0x28); ISR(0x29); ISR(0x2a); ISR(0x2b); +ISR(0x2c); ISR(0x2d); ISR(0x2e); ISR(0x2f); +ISR(0x30); ISR(0x31); ISR(0x32); ISR(0x33); +ISR(0x34); ISR(0x35); ISR(0x36); ISR(0x37); +ISR(0x38); ISR(0x39); ISR(0x3a); ISR(0x3b); +ISR(0x3c); ISR(0x3d); ISR(0x3e); ISR(0x3f); +ISR(0x40); ISR(0x41); ISR(0x42); ISR(0x43); +ISR(0x44); ISR(0x45); ISR(0x46); ISR(0x47); +ISR(0x48); ISR(0x49); ISR(0x4a); ISR(0x4b); +ISR(0x4c); ISR(0x4d); ISR(0x4e); ISR(0x4f); +ISR(0x50); ISR(0x51); ISR(0x52); ISR(0x53); +ISR(0x54); ISR(0x55); ISR(0x56); ISR(0x57); +ISR(0x58); ISR(0x59); ISR(0x5a); ISR(0x5b); +ISR(0x5c); ISR(0x5d); ISR(0x5e); ISR(0x5f); +ISR(0x60); ISR(0x61); ISR(0x62); ISR(0x63); +ISR(0x64); ISR(0x65); ISR(0x66); ISR(0x67); +ISR(0x68); ISR(0x69); ISR(0x6a); ISR(0x6b); +ISR(0x6c); ISR(0x6d); ISR(0x6e); ISR(0x6f); +ISR(0x70); ISR(0x71); ISR(0x72); ISR(0x73); +ISR(0x74); ISR(0x75); ISR(0x76); ISR(0x77); +ISR(0x78); ISR(0x79); ISR(0x7a); ISR(0x7b); +ISR(0x7c); ISR(0x7d); ISR(0x7e); ISR(0x7f); +ISR(0x80); ISR(0x81); ISR(0x82); ISR(0x83); +ISR(0x84); ISR(0x85); ISR(0x86); ISR(0x87); +ISR(0x88); ISR(0x89); ISR(0x8a); ISR(0x8b); +ISR(0x8c); ISR(0x8d); ISR(0x8e); ISR(0x8f); +ISR(0x90); ISR(0x91); ISR(0x92); ISR(0x93); +ISR(0x94); ISR(0x95); ISR(0x96); ISR(0x97); +ISR(0x98); ISR(0x99); ISR(0x9a); ISR(0x9b); +ISR(0x9c); ISR(0x9d); ISR(0x9e); ISR(0x9f); +ISR(0xa0); ISR(0xa1); ISR(0xa2); ISR(0xa3); +ISR(0xa4); ISR(0xa5); ISR(0xa6); ISR(0xa7); +ISR(0xa8); ISR(0xa9); ISR(0xaa); ISR(0xab); +ISR(0xac); ISR(0xad); ISR(0xae); ISR(0xaf); +ISR(0xb0); ISR(0xb1); ISR(0xb2); ISR(0xb3); +ISR(0xb4); ISR(0xb5); ISR(0xb6); ISR(0xb7); +ISR(0xb8); ISR(0xb9); ISR(0xba); ISR(0xbb); +ISR(0xbc); ISR(0xbd); ISR(0xbe); ISR(0xbf); +ISR(0xc0); ISR(0xc1); ISR(0xc2); ISR(0xc3); +ISR(0xc4); ISR(0xc5); ISR(0xc6); ISR(0xc7); +ISR(0xc8); ISR(0xc9); ISR(0xca); ISR(0xcb); +ISR(0xcc); ISR(0xcd); ISR(0xce); ISR(0xcf); +ISR(0xd0); ISR(0xd1); ISR(0xd2); ISR(0xd3); +ISR(0xd4); ISR(0xd5); ISR(0xd6); ISR(0xd7); +ISR(0xd8); ISR(0xd9); ISR(0xda); ISR(0xdb); +ISR(0xdc); ISR(0xdd); ISR(0xde); ISR(0xdf); +ISR(0xe0); ISR(0xe1); ISR(0xe2); ISR(0xe3); +ISR(0xe4); ISR(0xe5); ISR(0xe6); ISR(0xe7); +ISR(0xe8); ISR(0xe9); ISR(0xea); ISR(0xeb); +ISR(0xec); ISR(0xed); ISR(0xee); ISR(0xef); +ISR(0xf0); ISR(0xf1); ISR(0xf2); ISR(0xf3); +ISR(0xf4); ISR(0xf5); ISR(0xf6); ISR(0xf7); +ISR(0xf8); ISR(0xf9); ISR(0xfa); ISR(0xfb); +ISR(0xfc); ISR(0xfd); ISR(0xfe); ISR(0xff); + + .data + +/* +** This table contains the addresses where each of the preceding +** stubs begins. This information is needed to initialize the +** Interrupt Descriptor Table in support.c +*/ + .globl isr_stub_table +isr_stub_table: + .long isr_0x00, isr_0x01, isr_0x02, isr_0x03 + .long isr_0x04, isr_0x05, isr_0x06, isr_0x07 + .long isr_0x08, isr_0x09, isr_0x0a, isr_0x0b + .long isr_0x0c, isr_0x0d, isr_0x0e, isr_0x0f + .long isr_0x10, isr_0x11, isr_0x12, isr_0x13 + .long isr_0x14, isr_0x15, isr_0x16, isr_0x17 + .long isr_0x18, isr_0x19, isr_0x1a, isr_0x1b + .long isr_0x1c, isr_0x1d, isr_0x1e, isr_0x1f + .long isr_0x20, isr_0x21, isr_0x22, isr_0x23 + .long isr_0x24, isr_0x25, isr_0x26, isr_0x27 + .long isr_0x28, isr_0x29, isr_0x2a, isr_0x2b + .long isr_0x2c, isr_0x2d, isr_0x2e, isr_0x2f + .long isr_0x30, isr_0x31, isr_0x32, isr_0x33 + .long isr_0x34, isr_0x35, isr_0x36, isr_0x37 + .long isr_0x38, isr_0x39, isr_0x3a, isr_0x3b + .long isr_0x3c, isr_0x3d, isr_0x3e, isr_0x3f + .long isr_0x40, isr_0x41, isr_0x42, isr_0x43 + .long isr_0x44, isr_0x45, isr_0x46, isr_0x47 + .long isr_0x48, isr_0x49, isr_0x4a, isr_0x4b + .long isr_0x4c, isr_0x4d, isr_0x4e, isr_0x4f + .long isr_0x50, isr_0x51, isr_0x52, isr_0x53 + .long isr_0x54, isr_0x55, isr_0x56, isr_0x57 + .long isr_0x58, isr_0x59, isr_0x5a, isr_0x5b + .long isr_0x5c, isr_0x5d, isr_0x5e, isr_0x5f + .long isr_0x60, isr_0x61, isr_0x62, isr_0x63 + .long isr_0x64, isr_0x65, isr_0x66, isr_0x67 + .long isr_0x68, isr_0x69, isr_0x6a, isr_0x6b + .long isr_0x6c, isr_0x6d, isr_0x6e, isr_0x6f + .long isr_0x70, isr_0x71, isr_0x72, isr_0x73 + .long isr_0x74, isr_0x75, isr_0x76, isr_0x77 + .long isr_0x78, isr_0x79, isr_0x7a, isr_0x7b + .long isr_0x7c, isr_0x7d, isr_0x7e, isr_0x7f + .long isr_0x80, isr_0x81, isr_0x82, isr_0x83 + .long isr_0x84, isr_0x85, isr_0x86, isr_0x87 + .long isr_0x88, isr_0x89, isr_0x8a, isr_0x8b + .long isr_0x8c, isr_0x8d, isr_0x8e, isr_0x8f + .long isr_0x90, isr_0x91, isr_0x92, isr_0x93 + .long isr_0x94, isr_0x95, isr_0x96, isr_0x97 + .long isr_0x98, isr_0x99, isr_0x9a, isr_0x9b + .long isr_0x9c, isr_0x9d, isr_0x9e, isr_0x9f + .long isr_0xa0, isr_0xa1, isr_0xa2, isr_0xa3 + .long isr_0xa4, isr_0xa5, isr_0xa6, isr_0xa7 + .long isr_0xa8, isr_0xa9, isr_0xaa, isr_0xab + .long isr_0xac, isr_0xad, isr_0xae, isr_0xaf + .long isr_0xb0, isr_0xb1, isr_0xb2, isr_0xb3 + .long isr_0xb4, isr_0xb5, isr_0xb6, isr_0xb7 + .long isr_0xb8, isr_0xb9, isr_0xba, isr_0xbb + .long isr_0xbc, isr_0xbd, isr_0xbe, isr_0xbf + .long isr_0xc0, isr_0xc1, isr_0xc2, isr_0xc3 + .long isr_0xc4, isr_0xc5, isr_0xc6, isr_0xc7 + .long isr_0xc8, isr_0xc9, isr_0xca, isr_0xcb + .long isr_0xcc, isr_0xcd, isr_0xce, isr_0xcf + .long isr_0xd0, isr_0xd1, isr_0xd2, isr_0xd3 + .long isr_0xd4, isr_0xd5, isr_0xd6, isr_0xd7 + .long isr_0xd8, isr_0xd9, isr_0xda, isr_0xdb + .long isr_0xdc, isr_0xdd, isr_0xde, isr_0xdf + .long isr_0xe0, isr_0xe1, isr_0xe2, isr_0xe3 + .long isr_0xe4, isr_0xe5, isr_0xe6, isr_0xe7 + .long isr_0xe8, isr_0xe9, isr_0xea, isr_0xeb + .long isr_0xec, isr_0xed, isr_0xee, isr_0xef + .long isr_0xf0, isr_0xf1, isr_0xf2, isr_0xf3 + .long isr_0xf4, isr_0xf5, isr_0xf6, isr_0xf7 + .long isr_0xf8, isr_0xf9, isr_0xfa, isr_0xfb + .long isr_0xfc, isr_0xfd, isr_0xfe, isr_0xff diff --git a/kernel/kernel.c b/kernel/kernel.c new file mode 100644 index 0000000..53e50a7 --- /dev/null +++ b/kernel/kernel.c @@ -0,0 +1,381 @@ +/** +** @file kernel.c +** +** @author CSCI-452 class of 20245 +** +** @brief Kernel support routines +*/ + +#define KERNEL_SRC + +#include <common.h> +#include <cio.h> +#include <clock.h> +#include <kmem.h> +#include <procs.h> +#include <sio.h> +#include <syscalls.h> +#include <user.h> +#include <userids.h> +#include <vm.h> + +/* +** PRIVATE DEFINITIONS +*/ + +/* +** PRIVATE DATA TYPES +*/ + +/* +** PRIVATE GLOBAL VARIABLES +*/ + +/* +** PUBLIC GLOBAL VARIABLES +*/ + +// character buffers, usable throughout the OS +// nto guaranteed to retain their contents across an exception return +char b256[256]; // primarily used for message creation +char b512[512]; // used by PANIC macro + +/* +** PRIVATE FUNCTIONS +*/ + +/* +** PRIVATE FUNCTIONS +*/ + +/** +** report - report the system configuration +** +** Prints configuration information about the OS on the console monitor. +** +** @param dtrace Decode the TRACE options +*/ +static void kreport( bool_t dtrace ) { + + cio_puts( "\n-------------------------------\n" ); + cio_printf( "Config: N_PROCS = %d", N_PROCS ); + cio_printf( " N_PRIOS = %d", N_PRIOS ); + cio_printf( " N_STATES = %d", N_STATES ); + cio_printf( " CLOCK = %dHz\n", CLOCK_FREQ ); + + // This code is ugly, but it's the simplest way to + // print out the values of compile-time options + // without spending a lot of execution time at it. + + cio_puts( "Options: " +#ifdef RPT_INT_UNEXP + " R-uint" +#endif +#ifdef RPT_INT_MYSTERY + " R-mint" +#endif +#ifdef TRACE_CX + " CX" +#endif +#ifdef CONSOLE_STATS + " Cstats" +#endif + ); // end of cio_puts() call + +#ifdef SANITY + cio_printf( " SANITY = %d", SANITY ); +#endif +#ifdef STATUS + cio_printf( " STATUS = %d", STATUS ); +#endif + +#if TRACE > 0 + cio_printf( " TRACE = 0x%04x\n", TRACE ); + + // decode the trace settings if that was requested + if( TRACING_SOMETHING && dtrace ) { + + // this one is simpler - we rely on string literal + // concatenation in the C compiler to create one + // long string to print out + + cio_puts( "Tracing:" +#if TRACING_PCB + " PCB" +#endif +#if TRACING_STACK + " STK" +#endif +#if TRACING_QUEUE + " QUE" +#endif +#if TRACING_SCHED + " SCHED" +#endif +#if TRACING_SYSCALLS + " SCALL" +#endif +#if TRACING_SYSRETS + " SRET" +#endif +#if TRACING_EXIT + " EXIT" +#endif +#if TRACING_DISPATCH + " DISPATCH" +#endif +#if TRACING_INIT + " INIT" +#endif +#if TRACING_KMEM + " KM" +#endif +#if TRACING_KMEM_FREELIST + " KMFL" +#endif +#if TRACING_KMEM_INIT + " KMIN" +#endif +#if TRACING_SPAWN + " SPAWN" +#endif +#if TRACING_SIO_STAT + " S_STAT" +#endif +#if TRACING_SIO_ISR + " S_ISR" +#endif +#if TRACING_SIO_RD + " S_RD" +#endif +#if TRACING_SIO_WR + " S_WR" +#endif +#if TRACING_USER + " USER" +#endif +#if TRACING_ELF + " ELF" +#endif + ); // end of cio_puts() call + } +#endif /* TRACE > 0 */ + + cio_puts( "\n-------------------------------\n" ); +} + + +#if defined(CONSOLE_STATS) +/** +** stats - callback routine for console statistics +** +** Called by the CIO module when a key is pressed on the +** console keyboard. Depending on the key, it will print +** statistics on the console display, or will cause the +** user shell process to be dispatched. +** +** This code runs as part of the CIO ISR. +*/ +static void stats( int code ) { + + switch( code ) { + + case 'a': // dump the active table + ptable_dump( "\nActive processes", false ); + break; + + case 'c': // dump context info for all active PCBs + ctx_dump_all( "\nContext dump" ); + break; + + case 'p': // dump the active table and all PCBs + ptable_dump( "\nActive processes", true ); + break; + + case 'q': // dump the queues + // code to dump out any/all queues + pcb_queue_dump( "R", ready ); + pcb_queue_dump( "W", waiting ); + pcb_queue_dump( "S", sleeping ); + pcb_queue_dump( "Z", zombie ); + pcb_queue_dump( "I", sioread ); + break; + + case 'r': // print system configuration information + report( true ); + break; + + // ignore CR and LF + case '\r': // FALL THROUGH + case '\n': + break; + + default: + cio_printf( "console: unknown request '0x%02x'\n", code ); + // FALL THROUGH + + case 'h': // help message + cio_puts( "\nCommands:\n" + " a -- dump the active table\n" + " c -- dump contexts for active processes\n" + " h -- this message\n" + " p -- dump the active table and all PCBs\n" + " q -- dump the queues\n" + " r -- print system configuration\n" + ); + break; + } +} +#endif + +/* +** PUBLIC FUNCTIONS +*/ + +/** +** main - system initialization routine +** +** Called by the startup code immediately before returning into the +** first user process. +** +** Making this type 'int' keeps the compiler happy. +*/ +int main( void ) { + + /* + ** BOILERPLATE CODE - taken from basic framework + ** + ** Initialize interrupt stuff. + */ + + init_interrupts(); // IDT and PIC initialization + + /* + ** Console I/O system. + ** + ** Does not depend on the other kernel modules, so we can + ** initialize it before we initialize the kernel memory + ** and queue modules. + */ + +#if defined(CONSOLE_STATS) + cio_init( stats ); +#else + cio_init( NULL ); // no console callback routine +#endif + + cio_clearscreen(); // wipe out whatever is there + + /* + ** TERM-SPECIFIC CODE STARTS HERE + */ + + /* + ** Initialize various OS modules + ** + ** Other modules (clock, SIO, syscall, etc.) are expected to + ** install their own ISRs in their initialization routines. + */ + + cio_puts( "System initialization starting.\n" ); + cio_puts( "-------------------------------\n" ); + + cio_puts( "Modules:" ); + + // call the module initialization functions, being + // careful to follow any module precedence requirements + + km_init(); // MUST BE FIRST +#if TRACING_KMEM || TRACING_KMEM_FREE + delay( DELAY_2_SEC ); // approximately +#endif + + // other module initialization calls here + clk_init(); // clock + pcb_init(); // process (PCBs, queues, scheduler) +#if TRACING_PCB + delay( DELAY_2_SEC ); +#endif + sio_init(); // serial i/o + sys_init(); // system call +#if TRACING_SYSCALLS || TRACING_SYSRETS + delay( DELAY_2_SEC ); +#endif + vm_init(); // virtual memory + user_init(); // user code handling + + cio_puts( "\nModule initialization complete.\n" ); + cio_puts( "-------------------------------\n" ); + + // report our configuration options + kreport( true ); + + delay( DELAY_3_SEC ); + + /* + ** Other tasks typically performed here: + ** + ** Enabling any I/O devices (e.g., SIO xmit/rcv) + */ + + /* + ** Create the initial user process + ** + ** This code is largely stolen from the fork() and exec() + ** implementations in syscalls.c; if those change, this must + ** also change. + */ + + // if we can't get a PCB, there's no use continuing! + assert( pcb_alloc(&init_pcb) == SUCCESS ); + + // fill in the necessary details + init_pcb->pid = PID_INIT; + init_pcb->state = STATE_NEW; + init_pcb->priority = PRIO_HIGH; + + // find the 'init' program + prog_t *prog = user_locate( Init ); + assert( prog != NULL ); + + // command-line arguments for 'init' + const char *args[2] = { "init", NULL }; + + // load it + assert( user_load(prog,init_pcb,args) == SUCCESS ); + + // send it on its merry way + schedule( init_pcb ); + +#ifdef TRACE_CX + // if we're using a scrolling region, wait a bit more and then set it up + delay( DELAY_7_SEC ); + + // define a scrolling region in the top 7 lines of the screen + cio_setscroll( 0, 7, 99, 99 ); + + // clear it + cio_clearscroll(); + + // clear the top line + cio_puts_at( 0, 0, "* " ); + // separator + cio_puts_at( 0, 6, "================================================================================" ); +#endif + + // switch to the "real" kernel page directory + vm_set_kvm(); + + /* + ** END OF TERM-SPECIFIC CODE + ** + ** Finally, report that we're all done. + */ + + cio_puts( "System initialization complete.\n" ); + cio_puts( "-------------------------------\n" ); + + sio_enable( SIO_RX ); + + return 0; +} diff --git a/kernel/kernel.ld b/kernel/kernel.ld new file mode 100644 index 0000000..2007432 --- /dev/null +++ b/kernel/kernel.ld @@ -0,0 +1,57 @@ +/* +** Simple linker script for the 20245 kernel. +*/ + +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) + +SECTIONS +{ + /* Link the kernel at this address. */ + /* Must match what is defined in vm.h! */ + . = 0x80010000; + + .text : AT(0x10000) { + *(.text .stub .text.* .gnu.linkonce.t.*) + } + + /* standard symbols */ + PROVIDE(etext = .); + PROVIDE(_etext = .); + + /* put read-only data next */ + .rodata : { + *(.rodata .rodata.* .gnu.linkonce.r.*) + } + + /* Align the data segment at the next page boundary */ + /* . = ALIGN(0x1000); */ + + PROVIDE(data = .); + PROVIDE(_data = .); + + /* The data segment */ + .data : { + *(.data) + } + + PROVIDE(edata = .); + PROVIDE(_edata = .); + + /* page-align the BSS */ + . = ALIGN(0x1000); + + PROVIDE(__bss_start = .); + + .bss : { + *(.bss) + } + + PROVIDE(end = .); + PROVIDE(_end = .); + + /DISCARD/ : { + *(.stab .stab_info .stabstr .eh_frame .note.GNU-stack .note.gnu.property .comment) + } +} diff --git a/kernel/kmem.c b/kernel/kmem.c new file mode 100644 index 0000000..8777f49 --- /dev/null +++ b/kernel/kmem.c @@ -0,0 +1,681 @@ +/** +** @file kmem.c +** +** @author Warren R. Carithers +** @author Kenneth Reek +** @author 4003-506 class of 20013 +** +** @brief Functions to perform dynamic memory allocation in the OS. +** +** NOTE: these should NOT be called by user processes! +** +** This allocator functions as a simple "slab" allocator; it allows +** allocation of either 4096-byte ("page") or 1024-byte ("slice") +** chunks of memory from the free pool. The free pool is initialized +** using the memory map provided by the BIOS during the boot sequence, +** and contains a series of blocks which are each one page of memory +** (4KB, and aligned at 4KB boundaries); they are held in the free list +** in LIFO order, as all pages are created equal. +** +** Each allocator ("page" and "slice") allocates the first block from +** the appropriate free list. On deallocation, the block is added back +** to the free list. +** +** The "slice" allocator operates by taking blocks from the "page" +** allocator and splitting them into four 1K slices, which it then +** manages. Requests are made for slices one at a time. If the free +** list contains an available slice, it is unlinked and returned; +** otherwise, a page is requested from the page allocator, split into +** slices, and the slices are added to the free list, after which the +** first one is returned. The slice free list is a simple linked list +** of these 1K blocks; because they are all the same size, no ordering +** is done on the free list, and no coalescing is performed. +** +** This could be converted into a bitmap-based allocator pretty easily. +** A 4GB address space contains 2^20 (1,048,576) pages; at one bit per +** page frame, that's 131,072 (2^17) bytes to cover all of the address +** space, and that could be reduced by restricting allocatable space +** to a subset of the 4GB space. +** +** Compilation options: +** +** ALLOC_FAIL_PANIC if an internal slice allocation fails, panic +*/ + +#define KERNEL_SRC + +#include <common.h> + +// all other framework includes are next +#include <lib.h> + +#include <kmem.h> + +#include <list.h> +#include <x86/arch.h> +#include <x86/bios.h> +#include <bootstrap.h> +#include <cio.h> + +/* +** PRIVATE DEFINITIONS +*/ + +// parameters related to word and block sizes + +#define WORD_SIZE sizeof(int) +#define LOG2_OF_WORD_SIZE 2 + +#define LOG2_OF_PAGE_SIZE 12 + +#define LOG2_OF_SLICE_SIZE 10 + +// converters: pages to bytes, bytes to pages + +#define P2B(x) ((x) << LOG2_OF_PAGE_SIZE) +#define B2P(x) ((x) >> LOG2_OF_PAGE_SIZE) + +/* +** Name: adjacent +** +** Arguments: addresses of two blocks +** +** Description: Determines whether the second block immediately +** follows the first one. +*/ +#define adjacent(first,second) \ + ( (void *) (first) + P2B((first)->pages) == (void *) (second) ) + +/* +** PRIVATE DATA TYPES +*/ + +/* +** Memory region information returned by the BIOS +** +** This data consists of a 32-bit integer followed +** by an array of region descriptor structures. +*/ + +// a handy union for playing with 64-bit addresses +typedef union b64_u { + uint32_t part[2]; + uint64_t all; +} b64_t; + +// the halves of a 64-bit address +#define LOW part[0] +#define HIGH part[1] + +// memory region descriptor +typedef struct memregion_s { + b64_t base; // base address + b64_t length; // region length + uint32_t type; // type of region + uint32_t acpi; // ACPI 3.0 info +} __attribute__((__packed__)) region_t; + +/* +** Region types +*/ + +#define REGION_USABLE 1 +#define REGION_RESERVED 2 +#define REGION_ACPI_RECL 3 +#define REGION_ACPI_NVS 4 +#define REGION_BAD 5 + +/* +** ACPI 3.0 bit fields +*/ + +#define REGION_IGNORE 0x01 +#define REGION_NONVOL 0x02 + +/* +** 32-bit and 64-bit address values as 64-bit literals +*/ + +#define ADDR_BIT_32 0x0000000100000000LL +#define ADDR_LOW_HALF 0x00000000ffffffffLL +#define ADDR_HIGH_HALR 0xffffffff00000000LL + +#define ADDR_32_MAX ADDR_LOW_HALF +#define ADDR_64_FIRST ADDR_BIT_32 + +/* +** PRIVATE GLOBAL VARIABLES +*/ + +// freespace pools +static list_t free_pages; +static list_t free_slices; + +// block counts +static uint32_t n_pages; +static uint32_t n_slices; + +// initialization status +static int km_initialized; + +/* +** IMPORTED GLOBAL VARIABLES +*/ + +// this is no longer used; for simple situations, it can be used as +// the KM_LOW_CUTOFF value +// +// extern int _end; // end of the BSS section - provided by the linker + +/* +** FUNCTIONS +*/ + +/* +** FREE LIST MANAGEMENT +*/ + +/** +** Name: add_block +** +** Add a block to the free list. The block will be split into separate +** page-sized fragments which will each be added to the free_pages +** list; each of these will also be modified. +** +** @param[in] base Base address of the block +** @param[in] length Block length, in bytes +*/ +static void add_block( uint32_t base, uint32_t length ) { + + // don't add it if it isn't at least 4K + if( length < SZ_PAGE ) { + return; + } + +#if TRACING_KMEM | TRACING_KMEM_INIT + cio_printf( " add(%08x,%08x): ", base, length ); +#endif + + // verify that the base address is a 4K boundary + if( (base & MOD4K_BITS) != 0 ) { + // nope - how many bytes will we lose from the beginning + uint_t loss = base & MOD4K_BITS; + // adjust the starting address: (n + 4K - 1) / 4K + base = (base + MOD4K_BITS) & MOD4K_MASK; + // adjust the length + length -= loss; + } + + // only want to add multiples of 4K; check the lower bits + if( (length & MOD4K_BITS) != 0 ) { + // round it down to 4K + length &= MOD4K_MASK; + } + + // split the block into pages and add them to the free list + + void *block = (void *) base; + void *blend = (void *) (base + length); + int npages = 0; + +#if TRACING_KMEM | TRACING_KMEM_INIT + cio_printf( "-> base %08x len %08x: ", base, length ); +#endif + + while( block < blend ) { + + // just add to the front of the list + list_add( &free_pages, block ); + ++npages; + + // move to the next block + base += SZ_PAGE; + block = (void *) base; + } + + // add the count to our running total + n_pages += npages; + +#if TRACING_KMEM | TRACING_KMEM_INIT + cio_printf( " -> %d pages\n", npages ); +#endif +} + +/** +** Name: km_init +** +** Find what memory is present on the system and +** construct the list of free memory blocks. +** +** Dependencies: +** Must be called before any other init routine that uses +** dynamic storage is called. +*/ +void km_init( void ) { + int32_t entries; + region_t *region; + +#if TRACING_INIT + // announce that we're starting initialization + cio_puts( " Kmem" ); +#endif + + // initially, nothing in the free lists + free_slices.next = NULL; + free_pages.next = NULL; + n_pages = n_slices = 0; + km_initialized = 0; + + /* + ** We ignore anything below our KM_LOW_CUTOFF address. In theory, + ** we should be able to re-use much of that space; in practice, + ** this is safer. + */ + + // get the list length + entries = *((int32_t *) MMAP_ADDR); + +#if TRACING_KMEM | TRACING_KMEM_INIT + cio_printf( "\nKmem: %d regions\n", entries ); +#endif + + // if there are no entries, we have nothing to do! + if( entries < 1 ) { // note: entries == -1 could occur! + return; + } + + // iterate through the entries, adding things to the freelist + + region = ((region_t *) (MMAP_ADDR + 4)); + + for( int i = 0; i < entries; ++i, ++region ) { + +#if TRACING_KMEM | TRACING_KMEM_INIT + // report this region + cio_printf( "%3d: ", i ); + cio_printf( " B %08x%08x", + region->base.HIGH, region->base.LOW ); + cio_printf( " L %08x%08x", + region->length.HIGH, region->length.LOW ); + cio_printf( " T %08x A %08x", + region->type, region->acpi ); +#endif + + /* + ** Determine whether or not we should ignore this region. + ** + ** We ignore regions for several reasons: + ** + ** ACPI indicates it should be ignored + ** ACPI indicates it's non-volatile memory + ** Region type isn't "usable" + ** Region is above our address limit + ** + ** Currently, only "normal" (type 1) regions are considered + ** "usable" for our purposes. We could potentially expand + ** this to include ACPI "reclaimable" memory. + */ + + // first, check the ACPI one-bit flags + + if( ((region->acpi) & REGION_IGNORE) == 0 ) { +#if TRACING_KMEM | TRACING_KMEM_INIT + cio_puts( " IGN\n" ); +#endif + continue; + } + + if( ((region->acpi) & REGION_NONVOL) != 0 ) { +#if TRACING_KMEM | TRACING_KMEM_INIT + cio_puts( " NVOL\n" ); +#endif + continue; // we'll ignore this, too + } + + // next, the region type + + if( (region->type) != REGION_USABLE ) { +#if TRACING_KMEM | TRACING_KMEM_INIT + cio_puts( " RCLM\n" ); +#endif + continue; // we won't attempt to reclaim ACPI memory (yet) + } + + /* + ** We have a "normal" memory region. We need to verify + ** that it's within our constraints. We won't add anything + ** to the free list if it is: + ** + ** * below our KM_LOW_CUTOFF value + ** * above out KM_HIGH_CUTOFF value. + ** + ** For blocks which straddle one of those limits, we will + ** split it, and only use the portion that's within those + ** bounds. + */ + + // grab the two 64-bit values to simplify things + uint64_t base = region->base.all; + uint64_t length = region->length.all; + uint64_t endpt = base + length; + + // ignore it if it's above our high cutoff point + if( base >= KM_HIGH_CUTOFF || endpt >= KM_HIGH_CUTOFF ) { + + // is the whole thing too high, or just part? + if( base >= KM_HIGH_CUTOFF ) { + // it's all too high! +#if TRACING_KMEM | TRACING_KMEM_INIT + cio_puts( " HIGH\n" ); +#endif + continue; + } + + // some of it is usable - fix the end point + endpt = KM_HIGH_CUTOFF; + } + + // see if it's below our low cutoff point + if( base < KM_LOW_CUTOFF || endpt < KM_LOW_CUTOFF ) { + + // is the whole thing too low, or just part? + if( endpt < KM_LOW_CUTOFF ) { + // it's all below the cutoff! +#if TRACING_KMEM | TRACING_KMEM_INIT + cio_puts( " LOW\n" ); +#endif + continue; + } + + // some of it is usable - reset the base address + base = KM_LOW_CUTOFF; + + // recalculate the length + length = endpt - base; + } + + // we survived the gauntlet - add the new block + // + // we may have changed the base or endpoint, so + // we should recalculate the length + length = endpt - base; + +#if TRACING_KMEM | TRACING_KMEM_INIT + cio_puts( " OK\n" ); +#endif + + uint32_t b32 = base & ADDR_LOW_HALF; + uint32_t l32 = length & ADDR_LOW_HALF; + + add_block( b32, l32 ); + } + + // record the initialization + km_initialized = 1; + +#if TRACING_KMEM | TRACING_KMEM_INIT + delay( DELAY_3_SEC ); +#endif +} + +/** +** Name: km_dump +** +** Dump information about the free lists to the console. By default, +** prints only the list sizes; if 'addrs' is true, also dumps the list +** of page addresses; if 'all' is also true, dumps page addresses and +** slice addresses. +** +** @param addrs Also dump page addresses +** @param both Also dump slice addresses +*/ +void km_dump( bool_t addrs, bool_t both ) { + + // report the sizes + cio_printf( "&free_pages %08x, &free_slices %08x, %u pages, %u slices\n", + (uint32_t) &free_pages, (uint32_t) &free_slices, + n_pages, n_slices ); + + // was that all? + if( !addrs ) { + return; + } + + // dump the addresses of the pages in the free list + uint32_t n = 0; + list_t *block = free_pages.next; + while( block != NULL ) { + if( n && !(n & MOD4_BITS) ) { + // four per line + cio_putchar( '\n' ); + } + cio_printf( " page @ 0x%08x", (uint32_t) block ); + block = block->next; + ++n; + } + + // sanity check - verify that the counts match + if( n != n_pages ) { + sprint( b256, "km_dump: n_pages %u, counted %u!!!\n", + n_pages, n ); + WARNING( b256); + } + + if( !both ) { + return; + } + + // but wait - there's more! + + // also dump the addresses of slices in the slice free list + n = 0; + block = free_slices.next; + while( block != NULL ) { + if( n && !(n & MOD4_BITS) ) { + // four per line + cio_putchar( '\n' ); + } + cio_printf( " slc @ 0x%08x", (uint32_t) block ); + block = block->next; + ++n; + } + + // sanity check - verify that the counts match + if( n != n_slices ) { + sprint( b256, "km_dump: n_slices %u, counted %u!!!\n", + n_slices, n ); + WARNING( b256); + } +} + +/* +** PAGE MANAGEMENT +*/ + +/** +** Name: km_page_alloc +** +** Allocate a page of memory from the free list. +** +** @return a pointer to the beginning of the allocated page, +** or NULL if no memory is available +*/ +void *km_page_alloc( void ) { + + // if km_init() wasn't called first, stop us in our tracks + assert( km_initialized ); + +#if TRACING_KMEM_FREELIST + cio_puts( "KM: pg_alloc()" ); +#endif + + // pointer to the first block + void *page = list_remove( &free_pages ); + + // was a page available? + if( page == NULL ){ + // nope! +#if TRACING_KMEM_FREELIST + cio_puts( " FAIL\n" ); +#endif + return( NULL ); + } + + // fix the count of available pages + --n_pages; + +#if TRACING_KMEM_FREELIST + cio_printf( " -> %08x\n", (uint32_t) page ); +#endif + + return( page ); +} + +/** +** Name: km_page_free +** +** Returns a page to the list of available pages. +** +** @param[in] page Pointer to the page to be returned to the free list +*/ +void km_page_free( void *page ){ + + // verify that km_init() was called first + assert( km_initialized ); + + /* + ** Don't do anything if the address is NULL. + */ + if( page == NULL ){ + return; + } + +#if TRACING_KMEM_FREELIST + cio_printf( "KM: pg_free(%08x)", (uint32_t) page ); +#endif + + /* + ** CRITICAL ASSUMPTION + ** + ** We assume that the block pointer given to us points to a single + ** page-sized block of memory. We make this assumption because we + ** don't track allocation sizes. We can't use the simple "allocate + ** four extra bytes before the returned pointer" scheme to do this + ** because we're managing pages, and the pointers we return must point + ** to page boundaries, so we would wind up allocating an extra page + ** for each allocation. + ** + ** Alternatively, we could keep an array of addresses and block + ** sizes ourselves, but that feels clunky, and would risk running out + ** of table entries if there are lots of allocations (assuming we use + ** a 4KB page to hold the table, at eight bytes per entry we would have + ** 512 entries per page). + ** + ** IF THIS ASSUMPTION CHANGES, THIS CODE MUST BE FIXED!!! + */ + + // link this into the free list + list_add( &free_pages, page ); + + // one more in the pool + ++n_pages; +} + +/* +** SLICE MANAGEMENT +*/ + +/* +** Slices are 1024-byte fragments from pages. We maintain a free list of +** slices for those parts of the OS which don't need full 4096-byte chunks +** of space. +*/ + +/** +** Name: carve_slices +** +** Split an allocated page into four slices and add +** them to the "free slices" list. +** +** @param page Pointer to the page to be carved up +*/ +static void carve_slices( void *page ) { + + // sanity check + assert1( page != NULL ); + + // create the four slices from it + uint8_t *ptr = (uint8_t *) page; + for( int i = 0; i < 4; ++i ) { + km_slice_free( (void *) ptr ); + ptr += SZ_SLICE; + ++n_slices; + } +} + +/** +** Name: km_slice_alloc +** +** Dynamically allocates a slice (1/4 of a page). If no +** memory is available, we return NULL (unless ALLOC_FAIL_PANIC +** was defined, in which case we panic). +** +** @return a pointer to the allocated slice +*/ +void *km_slice_alloc( void ) { + + // verify that km_init() was called first + assert( km_initialized ); + +#if TRACING_KMEM_FREELIST + cio_printf( "KM: sl_alloc()\n" ); +#endif + + // if we are out of slices, create a few more + if( free_slices.next == NULL ) { + void *new = km_page_alloc(); + if( new == NULL ) { + // can't get any more space +#if ALLOC_FAIL_PANIC + PANIC( 0, "slice new alloc failed" ); +#else + return NULL; +#endif + } + carve_slices( new ); + } + + // take the first one from the free list + void *slice = list_remove( &free_slices ); + assert( slice != NULL ); + --n_slices; + + // make it nice and shiny for the caller + memclr( (void *) slice, SZ_SLICE ); + + return( slice ); +} + +/** +** Name: km_slice_free +** +** Returns a slice to the list of available slices. +** +** We make no attempt to merge slices, as we treat them as +** independent blocks of memory (like pages). +** +** @param[in] block Pointer to the slice (1/4 page) to be freed +*/ +void km_slice_free( void *block ) { + + // verify that km_init() was called first + assert( km_initialized ); + +#if TRACING_KMEM_FREELIST + cio_printf( "KM: sl_free(%08x)\n", (uint32_t) block ); +#endif + + // just add it to the front of the free list + list_add( &free_slices, block ); + --n_slices; +} diff --git a/kernel/list.c b/kernel/list.c new file mode 100644 index 0000000..084000a --- /dev/null +++ b/kernel/list.c @@ -0,0 +1,64 @@ +/** +** @file list.c +** +** @author Warren R. Carithers +** +** @brief Support for a basic linked list data type. +** +** This module provides a very basic linked list data structure. +** A list can contain anything that has a pointer field in the first +** four bytes; these routines assume those bytes contain a pointer to +** the following entry in the list, whatever that may be. +*/ + +#define KERNEL_SRC + +#include <common.h> + +#include <list.h> + +/* +** FUNCTIONS +*/ + +/** +** Name: list_add +** +** Add the supplied data to the beginning of the specified list. +** +** @param[in,out] list The address of a list_t variable +** @param[in] data The data to prepend to the list +*/ +void list_add( list_t *list, void *data ) { + + // sanity checks + assert1( list != NULL ); + assert1( data != NULL ); + + list_t *tmp = (list_t *)data; + tmp->next = list->next; + list->next = tmp; +} + +/** +** Name: list_remove +** +** Remove the first entry from a linked list. +** +** @param[in,out] list The address of a list_t variable +** +** @return a pointer to the removed data, or NULL if the list was empty +*/ +void *list_remove( list_t *list ) { + + assert1( list != NULL ); + + list_t *data = list->next; + if( data != NULL ) { + list->next = data->next; + data->next = NULL; + } + + return (void *)data; +} + diff --git a/kernel/procs.c b/kernel/procs.c new file mode 100644 index 0000000..96bb3fd --- /dev/null +++ b/kernel/procs.c @@ -0,0 +1,1136 @@ +/* +** @file procs.c +** +** @author CSCI-452 class of 20245 +** +** @brief Process-related implementations +*/ + +#define KERNEL_SRC + +#include <common.h> + +#include <procs.h> +#include <user.h> + +/* +** PRIVATE DEFINITIONS +*/ + +// determine if a queue is empty; assumes 'q' is a valid pointer +#define PCB_QUEUE_EMPTY(q) ((q)->head == NULL) + +/* +** PRIVATE DATA TYPES +*/ + +/* +** PCB Queue structure +** +** Opaque to the rest of the kernel +** +** Typedef'd in the header: typedef struct pcb_queue_s *pcb_queue_t; +*/ +struct pcb_queue_s { + pcb_t *head; + pcb_t *tail; + enum pcb_queue_order_e order; +}; + +/* +** PRIVATE GLOBAL VARIABLES +*/ + +// collection of queues +static struct pcb_queue_s pcb_freelist_queue; +static struct pcb_queue_s ready_queue; +static struct pcb_queue_s waiting_queue; +static struct pcb_queue_s sleeping_queue; +static struct pcb_queue_s zombie_queue; +static struct pcb_queue_s sioread_queue; + +/* +** PUBLIC GLOBAL VARIABLES +*/ + +// public-facing queue handles +pcb_queue_t pcb_freelist; +pcb_queue_t ready; +pcb_queue_t waiting; +pcb_queue_t sleeping; +pcb_queue_t zombie; +pcb_queue_t sioread; + +// pointer to the currently-running process +pcb_t *current; + +// the process table +pcb_t ptable[N_PROCS]; + +// next available PID +uint_t next_pid; + +// pointer to the PCB for the 'init' process +pcb_t *init_pcb; + +// table of state name strings +const char *state_str[N_STATES] = { + [ STATE_UNUSED ] = "Unu", // "Unused" + [ STATE_NEW ] = "New", + [ STATE_READY ] = "Rdy", // "Ready" + [ STATE_RUNNING ] = "Run", // "Running" + [ STATE_SLEEPING ] = "Slp", // "Sleeping" + [ STATE_BLOCKED ] = "Blk", // "Blocked" + [ STATE_WAITING ] = "Wat", // "Waiting" + [ STATE_KILLED ] = "Kil", // "Killed" + [ STATE_ZOMBIE ] = "Zom" // "Zombie" +}; + +// table of priority name strings +const char *prio_str[N_PRIOS] = { + [ PRIO_HIGH ] = "High", + [ PRIO_STD ] = "User", + [ PRIO_LOW ] = "Low ", + [ PRIO_DEFERRED ] = "Def " +}; + +// table of queue ordering name strings +const char *ord_str[N_PRIOS] = { + [ O_FIFO ] = "FIFO", + [ O_PRIO ] = "PRIO", + [ O_PID ] = "PID ", + [ O_WAKEUP ] = "WAKE" +}; + +/* +** PRIVATE FUNCTIONS +*/ + +/** +** Priority search functions. These are used to traverse a supplied +** queue looking for the queue entry that would precede the supplied +** PCB when that PCB is inserted into the queue. +** +** Variations: +** find_prev_wakeup() compares wakeup times +** find_prev_priority() compares process priorities +** find_prev_pid() compares PIDs +** +** Each assumes the queue should be in ascending order by the specified +** comparison value. +** +** @param[in] queue The queue to search +** @param[in] pcb The PCB to look for +** +** @return a pointer to the predecessor in the queue, or NULL if +** this PCB would be at the beginning of the queue. +*/ +static pcb_t *find_prev_wakeup( pcb_queue_t queue, pcb_t *pcb ) { + + // sanity checks! + assert1( queue != NULL ); + assert1( pcb != NULL ); + + pcb_t *prev = NULL; + pcb_t *curr = queue->head; + + while( curr != NULL && curr->wakeup <= pcb->wakeup ) { + prev = curr; + curr = curr->next; + } + + return prev; +} + +static pcb_t *find_prev_priority( pcb_queue_t queue, pcb_t *pcb ) { + + // sanity checks! + assert1( queue != NULL ); + assert1( pcb != NULL ); + + pcb_t *prev = NULL; + pcb_t *curr = queue->head; + + while( curr != NULL && curr->priority <= pcb->priority ) { + prev = curr; + curr = curr->next; + } + + return prev; +} + +static pcb_t *find_prev_pid( pcb_queue_t queue, pcb_t *pcb ) { + + // sanity checks! + assert1( queue != NULL ); + assert1( pcb != NULL ); + + pcb_t *prev = NULL; + pcb_t *curr = queue->head; + + while( curr != NULL && curr->pid <= pcb->pid ) { + prev = curr; + curr = curr->next; + } + + return prev; +} + +/* +** PUBLIC FUNCTIONS +*/ + +// a macro to simplify queue setup +#define QINIT(q,s) \ + q = &q##_queue; \ + if( pcb_queue_reset(q,s) != SUCCESS ) { \ + PANIC( 0, "pcb_init can't reset " # q ); \ + } + +/** +** Name: pcb_init +** +** Initialization for the Process module. +*/ +void pcb_init( void ) { + +#if TRACING_INIT + cio_puts( " Procs" ); +#endif + + // there is no current process + current = NULL; + + // set up the external links to the queues + QINIT( pcb_freelist, O_FIFO ); + QINIT( ready, O_PRIO ); + QINIT( waiting, O_PID ); + QINIT( sleeping, O_WAKEUP ); + QINIT( zombie, O_PID ); + QINIT( sioread, O_FIFO ); + + /* + ** We statically allocate our PCBs, so we need to add them + ** to the freelist before we can use them. If this changes + ** so that we dynamicallyl allocate PCBs, this step either + ** won't be required, or could be used to pre-allocate some + ** number of PCB structures for future use. + */ + + pcb_t *ptr = ptable; + for( int i = 0; i < N_PROCS; ++i ) { + pcb_free( ptr ); + ++ptr; + } +} + +/** +** Name: pcb_alloc +** +** Allocate a PCB from the list of free PCBs. +** +** @param pcb Pointer to a pcb_t * where the PCB pointer will be returned. +** +** @return status of the allocation attempt +*/ +int pcb_alloc( pcb_t **pcb ) { + + // sanity check! + assert1( pcb != NULL ); + + // remove the first PCB from the free list + pcb_t *tmp; + if( pcb_queue_remove(pcb_freelist,&tmp) != SUCCESS ) { + return E_NO_PCBS; + } + + *pcb = tmp; + return SUCCESS; +} + +/** +** Name: pcb_free +** +** Return a PCB to the list of free PCBs. +** +** @param pcb Pointer to the PCB to be deallocated. +*/ +void pcb_free( pcb_t *pcb ) { + + if( pcb != NULL ) { + // mark the PCB as available + pcb->state = STATE_UNUSED; + + // add it to the free list + int status = pcb_queue_insert( pcb_freelist, pcb ); + + // if that failed, we're in trouble + if( status != SUCCESS ) { + sprint( b256, "pcb_free(0x%08x) status %d", (uint32_t) pcb, + status ); + PANIC( 0, b256 ); + } + } +} + +/** +** Name: pcb_zombify +** +** Turn the indicated process into a Zombie. This function +** does most of the real work for exit() and kill() calls. +** Is also called from the scheduler and dispatcher. +** +** @param pcb Pointer to the newly-undead PCB +*/ +void pcb_zombify( register pcb_t *victim ) { + + // should this be an error? + if( victim == NULL ) { + return; + } + + // every process must have a parent, even if it's 'init' + assert( victim->parent != NULL ); + + /* + ** We need to locate the parent of this process. We also need + ** to reparent any children of this process. We do these in + ** a single loop. + */ + pcb_t *parent = victim->parent; + pcb_t *zchild = NULL; + + // two PIDs we will look for + uint_t vicpid = victim->pid; + + // speed up access to the process table entries + register pcb_t *curr = ptable; + + for( int i = 0; i < N_PROCS; ++i, ++curr ) { + + // make sure this is a valid entry + if( curr->state == STATE_UNUSED ) { + continue; + } + + // if this is our parent, just keep going - we continue + // iterating to find all the children of this process. + if( curr == parent ) { + continue; + } + + if( curr->parent == victim ) { + + // found a child - reparent it + curr->parent = init_pcb; + + // see if this child is already undead + if( curr->state == STATE_ZOMBIE ) { + // if it's already a zombie, remember it, so we + // can pass it on to 'init'; also, if there are + // two or more zombie children, it doesn't matter + // which one we pick here, as the others will be + // collected when 'init' loops + zchild = curr; + } + + } + } + + /* + ** If we found a child that was already terminated, we need to + ** wake up the init process if it's already waiting. + ** + ** Note: we only need to do this for one Zombie child process - + ** init will loop and collect the others after it finishes with + ** this one. + ** + ** Also note: it's possible that the exiting process' parent is + ** also init, which means we're letting one of zombie children + ** of the exiting process be cleaned up by init before the + ** existing process itself is cleaned up by init. This will work, + ** because after init cleans up the zombie, it will loop and + ** call waitpid() again, by which time this exiting process will + ** be marked as a zombie. + */ + if( zchild != NULL && init_pcb->state == STATE_WAITING ) { + + // dequeue the zombie + assert( pcb_queue_remove_this(zombie,zchild) == SUCCESS ); + + assert( pcb_queue_remove_this(waiting,init_pcb) == SUCCESS ); + + // intrinsic return value is the PID + RET(init_pcb) = zchild->pid; + + // may also want to return the exit status + int32_t *ptr = (int32_t *) ARG(init_pcb,2); + + if( ptr != NULL ) { + // ******************************************************** + // ** Potential VM issue here! This code assigns the exit + // ** status into a variable in the parent's address space. + // ** This works in the baseline because we aren't using + // ** any type of memory protection. If address space + // ** separation is implemented, this code will very likely + // ** STOP WORKING, and will need to be fixed. + // ******************************************************** + *ptr = zchild->exit_status; + } + + // all done - schedule 'init', and clean up the zombie + schedule( init_pcb ); + pcb_cleanup( zchild ); + } + + /* + ** Now, deal with the parent of this process. If the parent is + ** already waiting, just wake it up and clean up this process. + ** Otherwise, this process becomes a zombie. + ** + ** Note: if the exiting process' parent is init and we just woke + ** init up to deal with a zombie child of the exiting process, + ** init's status won't be Waiting any more, so we don't have to + ** worry about it being scheduled twice. + */ + + if( parent->state == STATE_WAITING ) { + + // verify that the parent is either waiting for this process + // or is waiting for any of its children + uint32_t target = ARG(parent,1); + + if( target == 0 || target == vicpid ) { + + // the parent is waiting for this child or is waiting + // for any of its children, so we can wake it up. + + // intrinsic return value is the PID + RET(parent) = vicpid; + + // may also want to return the exit status + int32_t *ptr = (int32_t *) ARG(parent,2); + + if( ptr != NULL ) { + // ******************************************************** + // ** Potential VM issue here! This code assigns the exit + // ** status into a variable in the parent's address space. + // ** This works in the baseline because we aren't using + // ** any type of memory protection. If address space + // ** separation is implemented, this code will very likely + // ** STOP WORKING, and will need to be fixed. + // ******************************************************** + *ptr = victim->exit_status; + } + + // all done - schedule the parent, and clean up the zombie + schedule( parent ); + pcb_cleanup( victim ); + + return; + } + } + + /* + ** The parent isn't waiting OR is waiting for a specific child + ** that isn't this exiting process, so we become a Zombie. + ** + ** This code assumes that Zombie processes are *not* in + ** a queue, but instead are just in the process table with + ** a state of 'Zombie'. This simplifies life immensely, + ** because we won't need to dequeue it when it is collected + ** by its parent. + */ + + victim->state = STATE_ZOMBIE; + assert( pcb_queue_insert(zombie,victim) == SUCCESS ); + + /* + ** Note: we don't call _dispatch() here - we leave that for + ** the calling routine, as it's possible we don't need to + ** choose a new current process. + */ +} + +/** +** Name: pcb_cleanup +** +** Reclaim a process' data structures +** +** @param pcb The PCB to reclaim +*/ +void pcb_cleanup( pcb_t *pcb ) { + +#if TRACING_PCB + cio_printf( "** pcb_cleanup(0x%08x)\n", (uint32_t) pcb ); +#endif + + // avoid deallocating a NULL pointer + if( pcb == NULL ) { + // should this be an error? + return; + } + + // we need to release all the VM data structures and frames + user_cleanup( pcb ); + + // release the PCB itself + pcb_free( pcb ); +} + +/** +** Name: pcb_find_pid +** +** Locate the PCB for the process with the specified PID +** +** @param pid The PID to be located +** +** @return Pointer to the PCB, or NULL +*/ +pcb_t *pcb_find_pid( uint_t pid ) { + + // must be a valid PID + if( pid < 1 ) { + return NULL; + } + + // scan the process table + pcb_t *p = ptable; + + for( int i = 0; i < N_PROCS; ++i, ++p ) { + if( p->pid == pid && p->state != STATE_UNUSED ) { + return p; + } + } + + // didn't find it! + return NULL; +} + +/** +** Name: pcb_find_ppid +** +** Locate the PCB for the process with the specified parent +** +** @param pid The PID to be located +** +** @return Pointer to the PCB, or NULL +*/ +pcb_t *pcb_find_ppid( uint_t pid ) { + + // must be a valid PID + if( pid < 1 ) { + return NULL; + } + + // scan the process table + pcb_t *p = ptable; + + for( int i = 0; i < N_PROCS; ++i, ++p ) { + assert1( p->parent != NULL ); + if( p->parent->pid == pid && p->parent->state != STATE_UNUSED ) { + return p; + } + } + + // didn't find it! + return NULL; +} + +/** +** Name: pcb_queue_reset +** +** Initialize a PCB queue. We assume that whatever data may be +** in the queue structure can be overwritten. +** +** @param queue[out] The queue to be initialized +** @param order[in] The desired ordering for the queue +** +** @return status of the init request +*/ +int pcb_queue_reset( pcb_queue_t queue, enum pcb_queue_order_e style ) { + + // sanity check + assert1( queue != NULL ); + + // make sure the style is valid + if( style < O_FIRST_STYLE || style > O_LAST_STYLE ) { + return E_BAD_PARAM; + } + + // reset the queue + queue->head = queue->tail = NULL; + queue->order = style; + + return SUCCESS; +} + +/** +** Name: pcb_queue_empty +** +** Determine whether a queue is empty. Essentially just a wrapper +** for the PCB_QUEUE_EMPTY() macro, for use outside this module. +** +** @param[in] queue The queue to check +** +** @return true if the queue is empty, else false +*/ +bool_t pcb_queue_empty( pcb_queue_t queue ) { + + // if there is no queue, blow up + assert1( queue != NULL ); + + return PCB_QUEUE_EMPTY(queue); +} + +/** +** Name: pcb_queue_length +** +** Return the count of elements in the specified queue. +** +** @param[in] queue The queue to check +** +** @return the count (0 if the queue is empty) +*/ +uint_t pcb_queue_length( const pcb_queue_t queue ) { + + // sanity check + assert1( queue != NULL ); + + // this is pretty simple + register pcb_t *tmp = queue->head; + register int num = 0; + + while( tmp != NULL ) { + ++num; + tmp = tmp->next; + } + + return num; +} + +/** +** Name: pcb_queue_insert +** +** Inserts a PCB into the indicated queue. +** +** @param queue[in,out] The queue to be used +** @param pcb[in] The PCB to be inserted +** +** @return status of the insertion request +*/ +int pcb_queue_insert( pcb_queue_t queue, pcb_t *pcb ) { + + // sanity checks + assert1( queue != NULL ); + assert1( pcb != NULL ); + + // if this PCB is already in a queue, we won't touch it + if( pcb->next != NULL ) { + // what to do? we let the caller decide + return E_BAD_PARAM; + } + + // is the queue empty? + if( queue->head == NULL ) { + queue->head = queue->tail = pcb; + return SUCCESS; + } + assert1( queue->tail != NULL ); + + // no, so we need to search it + pcb_t *prev = NULL; + + // find the predecessor node + switch( queue->order ) { + case O_FIFO: + prev = queue->tail; + break; + case O_PRIO: + prev = find_prev_priority(queue,pcb); + break; + case O_PID: + prev = find_prev_pid(queue,pcb); + break; + case O_WAKEUP: + prev = find_prev_wakeup(queue,pcb); + break; + default: + // do we need something more specific here? + return E_BAD_PARAM; + } + + // OK, we found the predecessor node; time to do the insertion + + if( prev == NULL ) { + + // there is no predecessor, so we're + // inserting at the front of the queue + pcb->next = queue->head; + if( queue->head == NULL ) { + // empty queue!?! - should we panic? + queue->tail = pcb; + } + queue->head = pcb; + + } else if( prev->next == NULL ) { + + // append at end + prev->next = pcb; + queue->tail = pcb; + + } else { + + // insert between prev & prev->next + pcb->next = prev->next; + prev->next = pcb; + + } + + return SUCCESS; +} + +/** +** Name: pcb_queue_remove +** +** Remove the first PCB from the indicated queue. +** +** @param queue[in,out] The queue to be used +** @param pcb[out] Pointer to where the PCB pointer will be saved +** +** @return status of the removal request +*/ +int pcb_queue_remove( pcb_queue_t queue, pcb_t **pcb ) { + + //sanity checks + assert1( queue != NULL ); + assert1( pcb != NULL ); + + // can't get anything if there's nothing to get! + if( PCB_QUEUE_EMPTY(queue) ) { + return E_EMPTY_QUEUE; + } + + // take the first entry from the queue + pcb_t *tmp = queue->head; + queue->head = tmp->next; + + // disconnect it completely + tmp->next = NULL; + + // was this the last thing in the queue? + if( queue->head == NULL ) { + // yes, so clear the tail pointer for consistency + queue->tail = NULL; + } + + // save the pointer + *pcb = tmp; + + return SUCCESS; +} + +/** +** Name: pcb_queue_remove_this +** +** Remove the specified PCB from the indicated queue. +** +** We don't return the removed pointer, because the calling +** routine must already have it (because it was supplied +** to us in the call). +** +** @param queue[in,out] The queue to be used +** @param pcb[in] Pointer to the PCB to be removed +** +** @return status of the removal request +*/ +int pcb_queue_remove_this( pcb_queue_t queue, pcb_t *pcb ) { + + //sanity checks + assert1( queue != NULL ); + assert1( pcb != NULL ); + + // can't get anything if there's nothing to get! + if( PCB_QUEUE_EMPTY(queue) ) { + return E_EMPTY_QUEUE; + } + + // iterate through the queue until we find the desired PCB + pcb_t *prev = NULL; + pcb_t *curr = queue->head; + + while( curr != NULL && curr != pcb ) { + prev = curr; + curr = curr->next; + } + + // case prev curr next interpretation + // ==== ==== ==== ==== ============================ + // 1. 0 0 -- *** CANNOT HAPPEN *** + // 2. 0 !0 0 removing only element + // 3. 0 !0 !0 removing first element + // 4. !0 0 -- *** NOT FOUND *** + // 5. !0 !0 0 removing from end + // 6. !0 !0 !0 removing from middle + + if( curr == NULL ) { + // case 1 + assert( prev != NULL ); + // case 4 + return E_NOT_FOUND; + } + + // connect predecessor to successor + if( prev != NULL ) { + // not the first element + // cases 5 and 6 + prev->next = curr->next; + } else { + // removing first element + // cases 2 and 3 + queue->head = curr->next; + } + + // if this was the last node (cases 2 and 5), + // also need to reset the tail pointer + if( curr->next == NULL ) { + // if this was the only entry (2), prev is NULL, + // so this works for that case, too + queue->tail = prev; + } + + // unlink current from queue + curr->next = NULL; + + // there's a possible consistancy problem here if somehow + // one of the queue pointers is NULL and the other one + // is not NULL + + assert1( + (queue->head == NULL && queue->tail == NULL) || + (queue->head != NULL && queue->tail != NULL) + ); + + return SUCCESS; +} + +/** +** Name: pcb_queue_peek +** +** Return the first PCB from the indicated queue, but don't +** remove it from the queue. +** +** @param queue[in] The queue to be used +** +** @return the PCB poiner, or NULL if the queue is empty +*/ +pcb_t *pcb_queue_peek( const pcb_queue_t queue ) { + + //sanity check + assert1( queue != NULL ); + + // can't get anything if there's nothing to get! + if( PCB_QUEUE_EMPTY(queue) ) { + return NULL; + } + + // just return the first entry from the queue + return queue->head; +} + +/* +** Scheduler routines +*/ + +/** +** schedule(pcb) +** +** Schedule the supplied process +** +** @param pcb Pointer to the PCB of the process to be scheduled +*/ +void schedule( pcb_t *pcb ) { + + // sanity check + assert1( pcb != NULL ); + + // check for a killed process + if( pcb->state == STATE_KILLED ) { + // TODO figure out what to do now + return; + } + + // mark it as ready + pcb->state = STATE_READY; + + // add it to the ready queue + if( pcb_queue_insert(ready,pcb) != SUCCESS ) { + PANIC( 0, "schedule insert fail" ); + } +} + +/** +** dispatch() +** +** Select the next process to receive the CPU +*/ +void dispatch( void ) { + + // verify that there is no current process + assert( current == NULL ); + + // grab whoever is at the head of the queue + int status = pcb_queue_remove( ready, ¤t ); + if( status != SUCCESS ) { + sprint( b256, "dispatch queue remove failed, code %d", status ); + PANIC( 0, b256 ); + } + + // set the process up for success + current->state = STATE_RUNNING; + current->ticks = QUANTUM_STANDARD; +} + + +/* +** Debugging/tracing routines +*/ + +/** +** ctx_dump(msg,context) +** +** Dumps the contents of this process context to the console +** +** @param msg[in] An optional message to print before the dump +** @param c[in] The context to dump out +*/ +void ctx_dump( const char *msg, register context_t *c ) { + + // first, the message (if there is one) + if( msg ) { + cio_puts( msg ); + } + + // the pointer + cio_printf( " @ %08x: ", (uint32_t) c ); + + // if it's NULL, why did you bother calling me? + if( c == NULL ) { + cio_puts( " NULL???\n" ); + return; + } + + // now, the contents + cio_printf( "ss %04x gs %04x fs %04x es %04x ds %04x cs %04x\n", + c->ss & 0xff, c->gs & 0xff, c->fs & 0xff, + c->es & 0xff, c->ds & 0xff, c->cs & 0xff ); + cio_printf( " edi %08x esi %08x ebp %08x esp %08x\n", + c->edi, c->esi, c->ebp, c->esp ); + cio_printf( " ebx %08x edx %08x ecx %08x eax %08x\n", + c->ebx, c->edx, c->ecx, c->eax ); + cio_printf( " vec %08x cod %08x eip %08x eflags %08x\n", + c->vector, c->code, c->eip, c->eflags ); +} + +/** +** ctx_dump_all(msg) +** +** dump the process context for all active processes +** +** @param msg[in] Optional message to print +*/ +void ctx_dump_all( const char *msg ) { + + if( msg != NULL ) { + cio_puts( msg ); + } + + int n = 0; + register pcb_t *pcb = ptable; + for( int i = 0; i < N_PROCS; ++i, ++pcb ) { + if( pcb->state != STATE_UNUSED ) { + ++n; + cio_printf( "%2d(%d): ", n, pcb->pid ); + ctx_dump( NULL, pcb->context ); + } + } +} + +/** +** _pcb_dump(msg,pcb) +** +** Dumps the contents of this PCB to the console +** +** @param msg[in] An optional message to print before the dump +** @param pcb[in] The PCB to dump +** @param all[in] Dump all the contents? +*/ +void pcb_dump( const char *msg, register pcb_t *pcb, bool_t all ) { + + // first, the message (if there is one) + if( msg ) { + cio_puts( msg ); + } + + // the pointer + cio_printf( " @ %08x:", (uint32_t) pcb ); + + // if it's NULL, why did you bother calling me? + if( pcb == NULL ) { + cio_puts( " NULL???\n" ); + return; + } + + cio_printf( " %d", pcb->pid ); + cio_printf( " %s", + pcb->state >= N_STATES ? "???" : state_str[pcb->state] ); + + if( !all ) { + // just printing IDs and states on one line + return; + } + + // now, the rest of the contents + cio_printf( " %s", + pcb->priority >= N_PRIOS ? "???" : prio_str[pcb->priority] ); + + cio_printf( " ticks %u xit %d wake %08x\n", + pcb->ticks, pcb->exit_status, pcb->wakeup ); + + cio_printf( " parent %08x", (uint32_t)pcb->parent ); + if( pcb->parent != NULL ) { + cio_printf( " (%u)", pcb->parent->pid ); + } + + cio_printf( " next %08x context %08x pde %08x", (uint32_t) pcb->next, + (uint32_t) pcb->context, (uint32_t) pcb->pdir ); + + cio_putchar( '\n' ); +} + +/** +** pcb_queue_dump(msg,queue,contents) +** +** Dump the contents of the specified queue to the console +** +** @param msg[in] Optional message to print +** @param queue[in] The queue to dump +** @param contents[in] Also dump (some) contents? +*/ +void pcb_queue_dump( const char *msg, pcb_queue_t queue, bool_t contents ) { + + // report on this queue + cio_printf( "%s: ", msg ); + if( queue == NULL ) { + cio_puts( "NULL???\n" ); + return; + } + + // first, the basic data + cio_printf( "head %08x tail %08x", + (uint32_t) queue->head, (uint32_t) queue->tail ); + + // next, how the queue is ordered + cio_printf( " order %s\n", + queue->order >= N_ORDERINGS ? "????" : ord_str[queue->order] ); + + // if there are members in the queue, dump the first few PIDs + if( contents && queue->head != NULL ) { + cio_puts( " PIDs: " ); + pcb_t *tmp = queue->head; + for( int i = 0; i < 5 && tmp != NULL; ++i, tmp = tmp->next ) { + cio_printf( " [%u]", tmp->pid ); + } + + if( tmp != NULL ) { + cio_puts( " ..." ); + } + + cio_putchar( '\n' ); + } +} + +/** +** ptable_dump(msg,all) +** +** dump the contents of the "active processes" table +** +** @param msg[in] Optional message to print +** @param all[in] Dump all or only part of the relevant data +*/ +void ptable_dump( const char *msg, bool_t all ) { + + if( msg ) { + cio_puts( msg ); + } + cio_putchar( ' ' ); + + int used = 0; + int empty = 0; + + register pcb_t *pcb = ptable; + for( int i = 0; i < N_PROCS; ++i ) { + if( pcb->state == STATE_UNUSED ) { + + // an empty slot + ++empty; + + } else { + + // a non-empty slot + ++used; + + // if not dumping everything, add commas if needed + if( !all && used ) { + cio_putchar( ',' ); + } + + // report the table slot # + cio_printf( " #%d:", i ); + + // and dump the contents + pcb_dump( NULL, pcb, all ); + } + } + + // only need this if we're doing one-line output + if( !all ) { + cio_putchar( '\n' ); + } + + // sanity check - make sure we saw the correct number of table slots + if( (used + empty) != N_PROCS ) { + cio_printf( "Table size %d, used %d + empty %d = %d???\n", + N_PROCS, used, empty, used + empty ); + } +} + +/** +** Name: ptable_dump_counts +** +** Prints basic information about the process table (number of +** entries, number with each process state, etc.). +*/ +void ptable_dump_counts( void ) { + uint_t nstate[N_STATES] = { 0 }; + uint_t unknown = 0; + + int n = 0; + pcb_t *ptr = ptable; + while( n < N_PROCS ) { + if( ptr->state < 0 || ptr->state >= N_STATES ) { + ++unknown; + } else { + ++nstate[ptr->state]; + } + ++n; + ++ptr; + } + + cio_printf( "Ptable: %u ***", unknown ); + for( n = 0; n < N_STATES; ++n ) { + cio_printf( " %u %s", nstate[n], + state_str[n] != NULL ? state_str[n] : "???" ); + } + cio_putchar( '\n' ); +} diff --git a/kernel/sio.c b/kernel/sio.c new file mode 100644 index 0000000..a5c7b75 --- /dev/null +++ b/kernel/sio.c @@ -0,0 +1,694 @@ +/** +** @file sio.c +** +** @author Warren R. Carithers +** +** @brief SIO module +** +** For maximum compatibility from semester to semester, this code uses +** several "stand-in" type names and macros which should be defined +** in the accompanying "compat.h" header file if they're not part of +** the baseline system: +** +** standard-sized integer types: intN_t, uintN_t +** other types: PCBTYPE, QTYPE +** scheduler functions: SCHED, DISPATCH +** queue functions: QCREATE, QLENGTH, QDEQUE +** other functions: SLENGTH +** sio read queue: QNAME +** +** Our SIO scheme is very simple: +** +** Input: We maintain a buffer of incoming characters that haven't +** yet been read by processes. When a character comes in, if +** there is no process waiting for it, it goes in the buffer; +** otherwise, the first waiting process is awakeneda and it +** gets the character. +** +** When a process invokes readch(), if there is a character in +** the input buffer, the process gets it; otherwise, it is +** blocked until input appears +** +** Communication with system calls is via two routines. +** sio_readc() returns the first available character (if +** there is one), resetting the input variables if this was +** the last character in the buffer. If there are no +** characters in the buffer, sio_read() returns a -1 +** (presumably so the requesting process can be blocked). +** +** sio_read() copies the contents of the input buffer into +** a user-supplied buffer. It returns the number of characters +** copied. If there are no characters available, return a -1. +** +** Output: We maintain a buffer of outgoing characters that haven't +** yet been sent to the device, and an indication of whether +** or not we are in the middle of a transmit sequence. When +** an interrupt comes in, if there is another character to +** send we copy it to the transmitter buffer; otherwise, we +** end the transmit sequence. +** +** Communication with user processes is via three functions. +** sio_writec() writes a single character; sio_write() +** writes a sized buffer full of characters; sio_puts() +** prints a NUL-terminated string. If we are in the middle +** of a transmit sequence, all characters will be added +** to the output buffer (from where they will be sent +** automatically); otherwise, we send the first character +** directly, add the rest of the characters (if there are +** any) to the output buffer, and set the "sending" flag +** to indicate that we're expecting a transmitter interrupt. +*/ + +#define KERNEL_SRC + +// this should do all includes required for this OS +#include <compat.h> + +// all other framework includes are next +#include <x86/uart.h> +#include <x86/arch.h> +#include <x86/pic.h> + +#include <sio.h> +#include <lib.h> + +/* +** PRIVATE DEFINITIONS +*/ + +#define BUF_SIZE 2048 + +/* +** PRIVATE GLOBALS +*/ + + // input character buffer +static char inbuffer[ BUF_SIZE ]; +static char *inlast; +static char *innext; +static uint32_t incount; + + // output character buffer +static char outbuffer[ BUF_SIZE ]; +static char *outlast; +static char *outnext; +static uint32_t outcount; + + // output control flag +static int sending; + + // interrupt register status +static uint8_t ier; + +/* +** PUBLIC GLOBAL VARIABLES +*/ + +// queue for read-blocked processes +#ifdef QNAME +QTYPE QNAME; +#endif + +/* +** PRIVATE FUNCTIONS +*/ + +/** +** sio_isr(vector,ecode) +** +** Interrupt handler for the SIO module. Handles all pending +** events (as described by the SIO controller). +** +** @param vector The interrupt vector number for this interrupt +** @param ecode The error code associated with this interrupt +*/ +static void sio_isr( int vector, int ecode ) { + int ch; + +#if TRACING_SIO_ISR + cio_puts( "SIO: int:" ); +#endif + // + // Must process all pending events; loop until the IRR + // says there's nothing else to do. + // + + for(;;) { + + // get the "pending event" indicator + int iir = inb( UA4_IIR ) & UA4_IIR_INT_PRI_MASK; + + // process this event + switch( iir ) { + + case UA4_IIR_LINE_STATUS: + // shouldn't happen, but just in case.... + cio_printf( "** SIO int, LSR = %02x\n", inb(UA4_LSR) ); + break; + + case UA4_IIR_RX: +#if TRACING_SIO_ISR + cio_puts( " RX" ); +#endif + // get the character + ch = inb( UA4_RXD ); + if( ch == '\r' ) { // map CR to LF + ch = '\n'; + } +#if TRACING_SIO_ISR + cio_printf( " ch %02x", ch ); +#endif + +#ifdef QNAME + // + // If there is a waiting process, this must be + // the first input character; give it to that + // process and awaken the process. + // + + if( !QEMPTY(QNAME) ) { + PCBTYPE *pcb; + + QDEQUE( QNAME, pcb ); + // make sure we got a non-NULL result + assert( pcb ); + + // return char via arg #2 and count in EAX + char *buf = (char *) ARG(pcb,2); + *buf = ch & 0xff; + RET(pcb) = 1; + SCHED( pcb ); + + } else { +#endif /* QNAME */ + + // + // Nobody waiting - add to the input buffer + // if there is room, otherwise just ignore it. + // + + if( incount < BUF_SIZE ) { + *inlast++ = ch; + ++incount; + } + +#ifdef QNAME + } +#endif /* QNAME */ + break; + + case UA5_IIR_RX_FIFO: + // shouldn't happen, but just in case.... + ch = inb( UA4_RXD ); + cio_printf( "** SIO FIFO timeout, RXD = %02x\n", ch ); + break; + + case UA4_IIR_TX: +#if TRACING_SIO_ISR + cio_puts( " TX" ); +#endif + // if there is another character, send it + if( sending && outcount > 0 ) { +#if TRACING_SIO_ISR + cio_printf( " ch %02x", *outnext ); +#endif + outb( UA4_TXD, *outnext ); + ++outnext; + // wrap around if necessary + if( outnext >= (outbuffer + BUF_SIZE) ) { + outnext = outbuffer; + } + --outcount; +#if TRACING_SIO_ISR + cio_printf( " (outcount %d)", outcount ); +#endif + } else { +#if TRACING_SIO_ISR + cio_puts( " EOS" ); +#endif + // no more data - reset the output vars + outcount = 0; + outlast = outnext = outbuffer; + sending = 0; + // disable TX interrupts + sio_disable( SIO_TX ); + } + break; + + case UA4_IIR_NO_INT: +#if TRACING_SIO_ISR + cio_puts( " EOI\n" ); +#endif + // nothing to do - tell the PIC we're done + outb( PIC1_CMD, PIC_EOI ); + return; + + case UA4_IIR_MODEM_STATUS: + // shouldn't happen, but just in case.... + cio_printf( "** SIO int, MSR = %02x\n", inb(UA4_MSR) ); + break; + + default: + // uh-oh.... + sprint( b256, "sio isr: IIR %02x\n", ((uint32_t) iir) & 0xff ); + PANIC( 0, b256 ); + } + + } + + // should never reach this point! + assert( false ); +} + +/* +** PUBLIC FUNCTIONS +*/ + +/** +** sio_init() +** +** Initialize the UART chip. +*/ +void sio_init( void ) { + +#if TRACING_INIT + cio_puts( " Sio" ); +#endif + + /* + ** Initialize SIO variables. + */ + + memclr( (void *) inbuffer, sizeof(inbuffer) ); + inlast = innext = inbuffer; + incount = 0; + + memclr( (void *) outbuffer, sizeof(outbuffer) ); + outlast = outnext = outbuffer; + outcount = 0; + sending = 0; + + // queue of read-blocked processes + QCREATE( QNAME ); + + /* + ** Next, initialize the UART. + ** + ** Initialize the FIFOs + ** + ** this is a bizarre little sequence of operations + */ + + outb( UA5_FCR, 0x20 ); + outb( UA5_FCR, UA5_FCR_FIFO_RESET ); // 0x00 + outb( UA5_FCR, UA5_FCR_FIFO_EN ); // 0x01 + outb( UA5_FCR, UA5_FCR_FIFO_EN | UA5_FCR_RXSR ); // 0x03 + outb( UA5_FCR, UA5_FCR_FIFO_EN | UA5_FCR_RXSR | UA5_FCR_TXSR ); // 0x07 + + /* + ** disable interrupts + ** + ** note that we leave them disabled; sio_enable() must be + ** called to switch them back on + */ + + outb( UA4_IER, 0 ); + ier = 0; + + /* + ** select the divisor latch registers and set the data rate + */ + + outb( UA4_LCR, UA4_LCR_DLAB ); + outb( UA4_DLL, BAUD_LOW_BYTE( DL_BAUD_9600 ) ); + outb( UA4_DLM, BAUD_HIGH_BYTE( DL_BAUD_9600 ) ); + + /* + ** deselect the latch registers, by setting the data + ** characteristics in the LCR + */ + + outb( UA4_LCR, UA4_LCR_WLS_8 | UA4_LCR_1_STOP_BIT | UA4_LCR_NO_PARITY ); + + /* + ** Set the ISEN bit to enable the interrupt request signal, + ** and the DTR and RTS bits to enable two-way communication. + */ + + outb( UA4_MCR, UA4_MCR_ISEN | UA4_MCR_DTR | UA4_MCR_RTS ); + + /* + ** Install our ISR + */ + + install_isr( VEC_COM1, sio_isr ); +} + +/** +** sio_enable() +** +** Enable SIO interrupts +** +** usage: uint8_t old = sio_enable( uint8_t which ) +** +** @param which Bit mask indicating which interrupt(s) to enable +** +** @return the prior IER setting +*/ +uint8_t sio_enable( uint8_t which ) { + uint8_t old; + + // remember the current status + + old = ier; + + // figure out what to enable + + if( which & SIO_TX ) { + ier |= UA4_IER_TX_IE; + } + + if( which & SIO_RX ) { + ier |= UA4_IER_RX_IE; + } + + // if there was a change, make it + + if( old != ier ) { + outb( UA4_IER, ier ); + } + + // return the prior settings + + return( old ); +} + +/** +** sio_disable() +** +** Disable SIO interrupts +** +** usage: uint8_t old = sio_disable( uint8_t which ) +** +** @param which Bit mask indicating which interrupt(s) to disable +** +** @return the prior IER setting +*/ +uint8_t sio_disable( uint8_t which ) { + uint8_t old; + + // remember the current status + + old = ier; + + // figure out what to disable + + if( which & SIO_TX ) { + ier &= ~UA4_IER_TX_IE; + } + + if( which & SIO_RX ) { + ier &= ~UA4_IER_RX_IE; + } + + // if there was a change, make it + + if( old != ier ) { + outb( UA4_IER, ier ); + } + + // return the prior settings + + return( old ); +} + +/** +** sio_inq_length() +** +** Get the input queue length +** +** usage: int num = sio_inq_length() +** +** @return the count of characters still in the input queue +*/ +int sio_inq_length( void ) { + return( incount ); +} + +/** +** sio_readc() +** +** Get the next input character +** +** usage: int ch = sio_readc() +** +** @return the next character, or -1 if no character is available +*/ +int sio_readc( void ) { + int ch; + + // assume there is no character available + ch = -1; + + // + // If there is a character, return it + // + + if( incount > 0 ) { + + // take it out of the input buffer + ch = ((int)(*innext++)) & 0xff; + --incount; + + // reset the buffer variables if this was the last one + if( incount < 1 ) { + inlast = innext = inbuffer; + } + + } + + return( ch ); + +} + +/** +** sio_read(buf,length) +** +** Read the entire input buffer into a user buffer of a specified size +** +** usage: int num = sio_read( char *buffer, int length ) +** +** @param buf The destination buffer +** @param length Length of the buffer +** +** @return the number of bytes copied, or 0 if no characters were available +*/ + +int sio_read( char *buf, int length ) { + char *ptr = buf; + int copied = 0; + + // if there are no characters, just return 0 + + if( incount < 1 ) { + return( 0 ); + } + + // + // We have characters. Copy as many of them into the user + // buffer as will fit. + // + + while( incount > 0 && copied < length ) { + *ptr++ = *innext++ & 0xff; + if( innext > (inbuffer + BUF_SIZE) ) { + innext = inbuffer; + } + --incount; + ++copied; + } + + // reset the input buffer if necessary + + if( incount < 1 ) { + inlast = innext = inbuffer; + } + + // return the copy count + + return( copied ); +} + + +/** +** sio_writec( ch ) +** +** Write a character to the serial output +** +** usage: sio_writec( int ch ) +** +** @param ch Character to be written (in the low-order 8 bits) +*/ +void sio_writec( int ch ){ + + + // + // Must do LF -> CRLF mapping + // + + if( ch == '\n' ) { + sio_writec( '\r' ); + } + + // + // If we're currently transmitting, just add this to the buffer + // + + if( sending ) { + *outlast++ = ch; + ++outcount; + return; + } + + // + // Not sending - must prime the pump + // + + sending = 1; + outb( UA4_TXD, ch ); + + // Also must enable transmitter interrupts + + sio_enable( SIO_TX ); + +} + +/** +** sio_write( buffer, length ) +** +** Write a buffer of characters to the serial output +** +** usage: int num = sio_write( const char *buffer, int length ) +** +** @param buffer Buffer containing characters to write +** @param length Number of characters to write +** +** @return the number of characters copied into the SIO output buffer +*/ +int sio_write( const char *buffer, int length ) { + int first = *buffer; + const char *ptr = buffer; + int copied = 0; + + // + // If we are currently sending, we want to append all + // the characters to the output buffer; else, we want + // to append all but the first character, and then use + // sio_writec() to send the first one out. + // + + if( !sending ) { + ptr += 1; + copied++; + } + + while( copied < length && outcount < BUF_SIZE ) { + *outlast++ = *ptr++; + // wrap around if necessary + if( outlast >= (outbuffer + BUF_SIZE) ) { + outlast = outbuffer; + } + ++outcount; + ++copied; + } + + // + // We use sio_writec() to send out the first character, + // as it will correctly set all the other necessary + // variables for us. + // + + if( !sending ) { + sio_writec( first ); + } + + // Return the transfer count + + + return( copied ); + +} + +/** +** sio_puts( buf ) +** +** Write a NUL-terminated buffer of characters to the serial output +** +** usage: int num = sio_puts( const char *buffer ) +** +** @param buffer The buffer containing a NUL-terminated string +** +** @return the count of bytes transferred +*/ +int sio_puts( const char *buffer ) { + int n; // must be outside the loop so we can return it + + n = SLENGTH( buffer ); + sio_write( buffer, n ); + + return( n ); +} + +/** +** sio_dump( full ) +** +** dump the contents of the SIO buffers to the console +** +** usage: sio_dump(true) or sio_dump(false) +** +** @param full Boolean indicating whether or not a "full" dump +** is being requested (which includes the contents +** of the queues) +*/ + +void sio_dump( bool_t full ) { + int n; + char *ptr; + + // dump basic info into the status region + + cio_printf_at( 48, 0, + "SIO: IER %02x (%c%c%c) in %d ot %d", + ((uint32_t)ier) & 0xff, sending ? '*' : '.', + (ier & UA4_IER_TX_IE) ? 'T' : 't', + (ier & UA4_IER_RX_IE) ? 'R' : 'r', + incount, outcount ); + + // if we're not doing a full dump, stop now + + if( !full ) { + return; + } + + // also want the queue contents, but we'll + // dump them into the scrolling region + + if( incount ) { + cio_puts( "SIO input queue: \"" ); + ptr = innext; + for( n = 0; n < incount; ++n ) { + put_char_or_code( *ptr++ ); + } + cio_puts( "\"\n" ); + } + + if( outcount ) { + cio_puts( "SIO output queue: \"" ); + cio_puts( " ot: \"" ); + ptr = outnext; + for( n = 0; n < outcount; ++n ) { + put_char_or_code( *ptr++ ); + } + cio_puts( "\"\n" ); + } +} diff --git a/kernel/startup.S b/kernel/startup.S new file mode 100644 index 0000000..1cae13c --- /dev/null +++ b/kernel/startup.S @@ -0,0 +1,153 @@ +/* +** @file startup.S +** +** @author Jon Coles +** @authors Warren R. Carithers, K. Reek +** +** SP startup code. +** +** This code prepares the various registers for execution of +** the program. It sets up all the segment registers and the +** runtime stack. By the time this code is running, we're in +** protected mode already. +*/ + +#define KERNEL_SRC +#define ASM_SRC + + .arch i386 + +#include <common.h> +#include <bootstrap.h> +#include <x86/arch.h> +#include <x86/bios.h> +#include <vm.h> + +/* +** Configuration options - define in Makefile +** +** CLEAR_BSS include code to clear all BSS space +** OS_CONFIG OS-related (vs. just standalone) variations +*/ + +/* +** A symbol for locating the beginning of the code. +*/ + .globl begtext + + .text +begtext: + +/* +** The entry point. When we get here, we have just entered protected +** mode, so all the segment registers are incorrect except for CS. +*/ + .globl _start + +_start: + cli /* seems to be reset on entry to p. mode */ + movb $NMI_ENABLE, %al /* re-enable NMIs (bootstrap */ + outb $CMOS_ADDR /* turned them off) */ + +/* +** Set the data and stack segment registers (code segment register +** was set by the long jump that switched us into protected mode). +*/ + xorl %eax, %eax /* clear EAX */ + movw $GDT_DATA, %ax /* GDT entry #3 - data segment */ + movw %ax, %ds /* for all four data segment registers */ + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + + movw $GDT_STACK, %ax /* entry #4 is the stack segment */ + movw %ax, %ss + + movl $TARGET_STACK, %esp /* set up the system stack pointer */ + +#ifdef CLEAR_BSS +/* +** Zero the BSS segment +** +** These symbols are defined automatically by the linker, but they're +** defined at their virtual addresses rather than their physical addresses, +** and we haven't enabled paging yet. +*/ + .globl __bss_start, _end + + movl $V2P(__bss_start), %edi +clearbss: + movl $0, (%edi) + addl $4, %edi + cmpl $V2P(_end), %edi + jb clearbss +#endif /* CLEAR_BSS */ + +/* +** Enable paging. We use "large" pages for the initial page directory +** so that a one-level hierarchy will work for us. Once we have set +** up our memory freelist, we'll create a two-level hierarchy using +** "normal" 4KB pages. +*/ + # enable large pages + movl %cr4, %eax + orl $(CR4_PSE), %eax + movl %eax, %cr4 + + # set the page directory + .globl firstpdir + movl $(V2P(firstpdir)+0x1000), %eax + movl %eax, %cr3 + + # turn on paging + movl %cr0, %eax + orl $(CR0_PG), %eax + movl %eax, %cr0 + + # reset our stack pointer + movl $(kstack + SZ_KSTACK), %esp + + # set the initial frame pointer + xorl %ebp, %ebp + +/* +** Call the system initialization routine, and switch to +** executing at high addresses. We use an indirect jump +** here to avoid getting a PC-relative 'jmp' instruction. +** +** Alternate idea: push the address of isr_restore +** and just do an indirect jump? +*/ + .globl main + + movl $main, %eax + call *%eax + +/* +** At this point, main() must have created the first user +** process, and we're ready to shift into user mode. The user +** stack for that process must have the initial context in it; +** we treat this as a "return from interrupt" event, and just +** transfer to the code that restores the user context. +*/ + + .globl isr_restore + jmp isr_restore + + .data + +/* +** Define the kernel stack here, at a multiple-of-16 address +*/ + .p2align 4 + .globl kstack +kstack: .space SZ_KSTACK, 0 + +/* +** Define the initial kernel ESP here, as well. It should point +** to the first byte after the stack. +*/ + + .globl kernel_esp +kernel_esp: + .long kstack + SZ_KSTACK diff --git a/kernel/support.c b/kernel/support.c new file mode 100644 index 0000000..d48ce59 --- /dev/null +++ b/kernel/support.c @@ -0,0 +1,279 @@ +/* +** SCCS ID: @(#)support.c 2.6 1/22/25 +** +** @file support.c +** +** @author 4003-506 class of 20003 +** @authors K. Reek, Warren R. Carithers +** +** Miscellaneous system initialization functions, interrupt +** support routines, and data structures. +*/ + +#include <common.h> + +#include <support.h> +#include <cio.h> +#include <x86/arch.h> +#include <x86/pic.h> +#include <x86/ops.h> +#include <bootstrap.h> +#include <syscalls.h> + +/* +** Global variables and local data types. +*/ + +/* +** This is the table that contains pointers to the C-language ISR for +** each interrupt. These functions are called from the isr stub based +** on the interrupt number. +*/ +void ( *isr_table[ 256 ] )( int vector, int code ); + +/* +** Format of an IDT entry. +*/ +typedef struct { + short offset_15_0; + short segment_selector; + short flags; + short offset_31_16; +} IDT_Gate; + +/* +** LOCAL ROUTINES - not intended to be used outside this module. +*/ + +/** +** unexpected_handler +** +** This routine catches interrupts that we do not expect to ever occur. +** It handles them by (optionally) reporting them and then calling panic(). +** +** @param vector vector number for the interrupt that occurred +** @param code error code, or a dummy value +** +** Does not return. +*/ +#ifdef RPT_INT_UNEXP +/* add any header includes you need here */ +#endif +static void unexpected_handler( int vector, int code ) { +#ifdef RPT_INT_UNEXP + cio_printf( "\n** UNEXPECTED vector %d code %d\n", vector, code ); +#endif + panic( "Unexpected interrupt" ); +} + +/** +** default_handler +** +** Default handler for interrupts we expect may occur but are not +** handling (yet). We just reset the PIC and return. +** +** @param vector vector number for the interrupt that occurred +** @param code error code, or a dummy value +*/ +static void default_handler( int vector, int code ) { +#ifdef RPT_INT_UNEXP + cio_printf( "\n** vector %d code %d\n", vector, code ); +#endif + if( vector >= 0x20 && vector < 0x30 ) { + if( vector > 0x27 ) { + // must also ACK the secondary PIC + outb( PIC2_CMD, PIC_EOI ); + } + outb( PIC1_CMD, PIC_EOI ); + } else { + /* + ** All the "expected" interrupts will be handled by the + ** code above. If we get down here, the isr table may + ** have been corrupted. Print a message and don't return. + */ + panic( "Unexpected \"expected\" interrupt!" ); + } +} + +/** +** mystery_handler +** +** Default handler for the "mystery" interrupt that comes through vector +** 0x27. This is a non-repeatable interrupt whose source has not been +** identified, but it appears to be the famous "spurious level 7 interrupt" +** source. +** +** @param vector vector number for the interrupt that occurred +** @param code error code, or a dummy value +*/ +static void mystery_handler( int vector, int code ) { +#if defined(RPT_INT_MYSTERY) || defined(RPT_INT_UNEXP) + cio_printf( "\nMystery interrupt!\nVector=0x%02x, code=%d\n", + vector, code ); +#endif + outb( PIC1_CMD, PIC_EOI ); +} + +/** +** init_pic +** +** Initialize the 8259 Programmable Interrupt Controller. +*/ +static void init_pic( void ) { + /* + ** ICW1: start the init sequence, update ICW4 + */ + outb( PIC1_CMD, PIC_CW1_INIT | PIC_CW1_NEED4 ); + outb( PIC2_CMD, PIC_CW1_INIT | PIC_CW1_NEED4 ); + + /* + ** ICW2: primary offset of 0x20 in the IDT, secondary offset of 0x28 + */ + outb( PIC1_DATA, PIC1_CW2_VECBASE ); + outb( PIC2_DATA, PIC2_CW2_VECBASE ); + + /* + ** ICW3: secondary attached to line 2 of primary, bit mask is 00000100 + ** secondary id is 2 + */ + outb( PIC1_DATA, PIC1_CW3_SEC_IRQ2 ); + outb( PIC2_DATA, PIC2_CW3_SEC_ID ); + + /* + ** ICW4: want 8086 mode, not 8080/8085 mode + */ + outb( PIC1_DATA, PIC_CW4_PM86 ); + outb( PIC2_DATA, PIC_CW4_PM86 ); + + /* + ** OCW1: allow interrupts on all lines + */ + outb( PIC1_DATA, PIC_MASK_NONE ); + outb( PIC2_DATA, PIC_MASK_NONE ); +} + +/** +** set_idt_entry +** +** Construct an entry in the IDT +** +** @param entry the vector number of the interrupt +** @param handler ISR address to be put into the IDT entry +** +** Note: generally, the handler invoked from the IDT will be a "stub" +** that calls the second-level C handler via the isr_table array. +*/ +static void set_idt_entry( int entry, void ( *handler )( void ) ) { + IDT_Gate *g = (IDT_Gate *)IDT_ADDR + entry; + + g->offset_15_0 = (int)handler & 0xffff; + g->segment_selector = 0x0010; + g->flags = IDT_PRESENT | IDT_DPL_0 | IDT_INT32_GATE; + g->offset_31_16 = (int)handler >> 16 & 0xffff; +} + +/** +** Name: init_idt +** +** Initialize the Interrupt Descriptor Table (IDT). This makes each of +** the entries in the IDT point to the isr stub for that entry, and +** installs a default handler in the handler table. Temporary handlers +** are then installed for those interrupts we may get before a real +** handler is set up. +*/ +static void init_idt( void ) { + int i; + extern void ( *isr_stub_table[ 256 ] )( void ); + + /* + ** Make each IDT entry point to the stub for that vector. Also + ** make each entry in the ISR table point to the default handler. + */ + for ( i=0; i < 256; i++ ) { + set_idt_entry( i, isr_stub_table[ i ] ); + install_isr( i, unexpected_handler ); + } + + /* + ** Install the handlers for interrupts that have (or will have) a + ** specific handler. Comments indicate which module init function + ** will eventually install the "real" handler. + */ + + install_isr( VEC_KBD, default_handler ); // cio_init() + install_isr( VEC_COM1, default_handler ); // sio_init() + install_isr( VEC_TIMER, default_handler ); // clk_init() + install_isr( VEC_SYSCALL, default_handler ); // sys_init() + install_isr( VEC_PAGE_FAULT, default_handler ); // vm_init() + + install_isr( VEC_MYSTERY, mystery_handler ); +} + +/* +** END OF LOCAL ROUTINES. +** +** Full documentation for globally-visible routines is in the corresponding +** header file. +*/ + +/* +** panic +** +** Called when we find an unrecoverable error. +*/ +void panic( char *reason ) { + __asm__( "cli" ); + cio_printf( "\nPANIC: %s\nHalting...", reason ); + for(;;) { + ; + } +} + +/* +** init_interrupts +** +** (Re)initilizes the interrupt system. +*/ +void init_interrupts( void ) { + init_idt(); + init_pic(); +} + +/* +** install_isr +** +** Installs a second-level handler for a specific interrupt. +*/ +void (*install_isr( int vector, + void (*handler)(int,int) ) ) ( int, int ) { + + void ( *old_handler )( int vector, int code ); + + old_handler = isr_table[ vector ]; + isr_table[ vector ] = handler; + return old_handler; +} + +/* +** Name: delay +** +** Notes: The parameter to the delay() function is ambiguous; it +** purports to indicate a delay length, but that isn't really tied +** to any real-world time measurement. +** +** On the original systems we used (dual 500MHz Intel P3 CPUs), each +** "unit" was approximately one tenth of a second, so delay(10) would +** delay for about one second. +** +** On the current machines (Intel Core i5-7500), delay(100) is about +** 2.5 seconds, so each "unit" is roughly 0.025 seconds. +** +** Ultimately, just remember that DELAY VALUES ARE APPROXIMATE AT BEST. +*/ +void delay( int length ) { + + while( --length >= 0 ) { + for( int i = 0; i < 10000000; ++i ) + ; + } +} diff --git a/kernel/syscalls.c b/kernel/syscalls.c new file mode 100644 index 0000000..7176cda --- /dev/null +++ b/kernel/syscalls.c @@ -0,0 +1,829 @@ +/** +** @file syscalls.c +** +** @author CSCI-452 class of 20245 +** +** @brief System call implementations +*/ + +#define KERNEL_SRC + +#include <common.h> + +#include <cio.h> +#include <clock.h> +#include <procs.h> +#include <sio.h> +#include <syscalls.h> +#include <user.h> +#include <vm.h> +#include <x86/pic.h> + +/* +** PRIVATE DEFINITIONS +*/ + +/* +** Macros to simplify tracing a bit +** +** TRACING_SYSCALLS and TRACING_SYSRETS are defined in debug.h, +** controlled by the TRACE ** macro. If not tracing these, SYSCALL_ENTER +** is a no-op, and SYSCALL_EXIT just does a return. +*/ + +#if TRACING_SYSCALLS + +#define SYSCALL_ENTER(x) do { \ + cio_printf( "--> %s, pid %08x", __func__, (uint32_t) (x) ); \ + } while(0) + +#else + +#define SYSCALL_ENTER(x) /* */ + +#endif /* TRACING_SYSCALLS */ + +#if TRACING_SYSRETS + +#define SYSCALL_EXIT(x) do { \ + cio_printf( "<-- %s %08x\n", __func__, (uint32_t) (x) ); \ + return; \ + } while(0) + +#else + +#define SYSCALL_EXIT(x) return + +#endif /* TRACING_SYSRETS */ + +/* +** PRIVATE DATA TYPES +*/ + +/* +** PUBLIC GLOBAL VARIABLES +*/ + +/* +** IMPLEMENTATION FUNCTIONS +*/ + +// a macro to simplify syscall entry point specification +// we don't declare these static because we may want to call +// some of them from other parts of the kernel +#define SYSIMPL(x) void sys_##x( pcb_t * pcb ) + +/* +** Second-level syscall handlers +** +** All have this prototype: +** +** static void sys_NAME( pcb_t *pcb ); +** +** where the parameter 'pcb' is a pointer to the PCB of the process +** making the system call. +** +** Values being returned to the user are placed into the EAX +** field in the context save area for that process. +*/ + +/** +** sys_exit - terminate the calling process +** +** Implements: +** void exit( int32_t status ); +** +** Does not return +*/ +SYSIMPL(exit) { + + // sanity check + assert( pcb != NULL ); + + SYSCALL_ENTER( pcb->pid ); + + // retrieve the exit status of this process + pcb->exit_status = (int32_t) ARG(pcb,1); + + // now, we need to do the following: + // reparent any children of this process and wake up init if need be + // find this process' parent and wake it up if it's waiting + + pcb_zombify( pcb ); + + // pick a new winner + dispatch(); + + SYSCALL_EXIT( 0 ); +} + +/** +** sys_waitpid - wait for a child process to terminate +** +** Implements: +** int waitpid( uint_t pid, int32_t *status ); +** +** Blocks the calling process until the specified child (or any child) +** of the caller terminates. Intrinsic return is the PID of the child that +** terminated, or an error code; on success, returns the child's termination +** status via 'status' if that pointer is non-NULL. +*/ +SYSIMPL(waitpid) { + + // sanity check + assert( pcb != NULL ); + + SYSCALL_ENTER( pcb->pid ); + + /* + ** We need to do two things here: (1) find out whether or + ** not this process has any children in the system, and (2) + ** find out whether the desired child (or any child, if the + ** target PID is 0) has terminated. + ** + ** To do this, we loop until we find a the requested PID or + ** a Zombie child process, or have gone through all of the + ** slots in the process table. + ** + ** If the target PID is 0, we don't care which child process + ** we reap here; there could be several, but we only need to + ** find one. + */ + + // verify that we aren't looking for ourselves! + uint_t target = ARG(pcb,1); + + if( target == pcb->pid ) { + RET(pcb) = E_BAD_PARAM; + SYSCALL_EXIT( E_BAD_PARAM ); + } + + // Good. Now, figure out what we're looking for. + + pcb_t *child = NULL; + + if( target != 0 ) { + + // we're looking for a specific child + child = pcb_find_pid( target ); + + if( child != NULL ) { + + // found the process; is it one of our children: + if( child->parent != pcb ) { + // NO, so we can't wait for it + RET(pcb) = E_BAD_PARAM; + SYSCALL_EXIT( E_BAD_PARAM ); + } + + // yes! is this one ready to be collected? + if( child->state != STATE_ZOMBIE ) { + // no, so we'll have to block for now + child = NULL; + } + + } else { + + // no such child + RET(pcb) = E_BAD_PARAM; + SYSCALL_EXIT( E_BAD_PARAM ); + + } + + } else { + + // looking for any child + + // we need to find a process that is our child + // and has already exited + + child = NULL; + bool_t found = false; + + // unfortunately, we can't stop at the first child, + // so we need to do the iteration ourselves + register pcb_t *curr = ptable; + + for( int i = 0; i < N_PROCS; ++i, ++curr ) { + + if( curr->parent == pcb ) { + + // found one! + found = true; + + // has it already exited? + if( curr->state == STATE_ZOMBIE ) { + // yes, so we're done here + child = curr; + break; + } + } + } + + if( !found ) { + // got through the loop without finding a child! + RET(pcb) = E_NO_CHILDREN; + SYSCALL_EXIT( E_NO_CHILDREN ); + } + + } + + /* + ** At this point, one of these situations is true: + ** + ** * we are looking for a specific child and found it + ** * we are looking for any child and found one + ** + ** Either way, 'child' will be non-NULL if the selected + ** process has already become a Zombie. If that's the + ** case, we collect its status and clean it up; otherwise, + ** we block this process. + */ + + // did we find one to collect? + if( child == NULL ) { + + // no - mark the parent as "Waiting" + pcb->state = STATE_WAITING; + assert( pcb_queue_insert(waiting,pcb) == SUCCESS ); + + // select a new current process + dispatch(); + SYSCALL_EXIT( (uint32_t) current ); + } + + // found a Zombie; collect its information and clean it up + RET(pcb) = child->pid; + + // get "status" pointer from parent + int32_t *stat = (int32_t *) ARG(pcb,2); + + // if stat is NULL, the parent doesn't want the status + if( stat != NULL ) { + // ******************************************************** + // ** Potential VM issue here! This code assigns the exit + // ** status into a variable in the parent's address space. + // ** This works in the baseline because we aren't using + // ** any type of memory protection. If address space + // ** separation is implemented, this code will very likely + // ** STOP WORKING, and will need to be fixed. + // ******************************************************** + *stat = child->exit_status; + } + + // clean up the child + pcb_cleanup( child ); + + SYSCALL_EXIT( RET(pcb) ); +} + +/** +** sys_fork - create a new process +** +** Implements: +** int fork( void ); +** +** Creates a new process that is a duplicate of the calling process. +** Returns the child's PID to the parent, and 0 to the child, on success; +** else, returns an error code to the parent. +*/ +SYSIMPL(fork) { + + // sanity check + assert( pcb != NULL ); + + SYSCALL_ENTER( pcb->pid ); + + // Make sure there's room for another process! + pcb_t *new; + if( pcb_alloc(&new) != SUCCESS || new == NULL ) { + RET(pcb) = E_NO_PROCS; + SYSCALL_EXIT( RET(pcb) ); + } + + // duplicate the memory image of the parent + int status = user_duplicate( new, pcb ); + if( status != SUCCESS ) { + pcb_free( new ); + RET(pcb) = status; + SYSCALL_EXIT( status ); + } + + // Set the child's identity. + new->pid = next_pid++; + new->parent = pcb; + new->state = STATE_NEW; + + // replicate other things inherited from the parent + new->priority = pcb->priority; + + // Set the return values for the two processes. + RET(pcb) = new->pid; + RET(new) = 0; + + // Schedule the child, and let the parent continue. + schedule( new ); + + SYSCALL_EXIT( new->pid ); +} + +/** +** sys_exec - replace the memory image of a process +** +** Implements: +** void exec( uint_t what, char **args ); +** +** Replaces the memory image of the calling process with that of the +** indicated program. +** +** Returns only on failure. +*/ +SYSIMPL(exec) +{ + // sanity check + assert( pcb != NULL ); + + uint_t what = ARG(pcb,1); + const char **args = (const char **) ARG(pcb,2); + + SYSCALL_ENTER( pcb->pid ); + + // locate the requested program + prog_t *prog = user_locate( what ); + if( prog == NULL ) { + RET(pcb) = E_NOT_FOUND; + SYSCALL_EXIT( E_NOT_FOUND ); + } + + // we have located the program, but before we can load it, + // we need to clean up the existing VM hierarchy + vm_free( pcb->pdir ); + pcb->pdir = NULL; + + // "load" it and set up the VM tables for this process + int status = user_load( prog, pcb, args ); + if( status != SUCCESS ) { + RET(pcb) = status; + SYSCALL_EXIT( status ); + } + + /* + ** Decision: + ** (A) schedule this process and dispatch another, + ** (B) let this one continue in its current time slice + ** (C) reset this one's time slice and let it continue + ** + ** We choose option A. + ** + ** If scheduling the process fails, the exec() has failed. However, + ** all trace of the old process is gone by now, so we can't return + ** an error status to it. + */ + + schedule( pcb ); + + dispatch(); +} + +/** +** sys_read - read into a buffer from an input channel +** +** Implements: +** int read( uint_t chan, void *buffer, uint_t length ); +** +** Reads up to 'length' bytes from 'chan' into 'buffer'. Returns the +** count of bytes actually transferred. +*/ +SYSIMPL(read) { + + // sanity check + assert( pcb != NULL ); + + SYSCALL_ENTER( pcb->pid ); + + // grab the arguments + uint_t chan = ARG(pcb,1); + char *buf = (char *) ARG(pcb,2); + uint_t len = ARG(pcb,3); + + // if the buffer is of length 0, we're done! + if( len == 0 ) { + RET(pcb) = 0; + SYSCALL_EXIT( 0 ); + } + + // try to get the next character(s) + int n = 0; + + if( chan == CHAN_CIO ) { + + // console input is non-blocking + if( cio_input_queue() < 1 ) { + RET(pcb) = 0; + SYSCALL_EXIT( 0 ); + } + // at least one character + n = cio_gets( buf, len ); + RET(pcb) = n; + SYSCALL_EXIT( n ); + + } else if( chan == CHAN_SIO ) { + + // SIO input is blocking, so if there are no characters + // available, we'll block this process + n = sio_read( buf, len ); + RET(pcb) = n; + SYSCALL_EXIT( n ); + + } + + // bad channel code + RET(pcb) = E_BAD_PARAM; + SYSCALL_EXIT( E_BAD_PARAM ); +} + +/** +** sys_write - write from a buffer to an output channel +** +** Implements: +** int write( uint_t chan, const void *buffer, uint_t length ); +** +** Writes 'length' bytes from 'buffer' to 'chan'. Returns the +** count of bytes actually transferred. +*/ +SYSIMPL(write) { + + // sanity check + assert( pcb != NULL ); + + SYSCALL_ENTER( pcb->pid ); + + // grab the parameters + uint_t chan = ARG(pcb,1); + char *buf = (char *) ARG(pcb,2); + uint_t length = ARG(pcb,3); + + // this is almost insanely simple, but it does separate the + // low-level device access fromm the higher-level syscall implementation + + // assume we write the indicated amount + int rval = length; + + // simplest case + if( length >= 0 ) { + + if( chan == CHAN_CIO ) { + + cio_write( buf, length ); + + } else if( chan == CHAN_SIO ) { + + sio_write( buf, length ); + + } else { + + rval = E_BAD_CHAN; + + } + + } + + RET(pcb) = rval; + + SYSCALL_EXIT( rval ); +} + +/** +** sys_getpid - returns the PID of the calling process +** +** Implements: +** uint_t getpid( void ); +*/ +SYSIMPL(getpid) { + + // sanity check! + assert( pcb != NULL ); + + SYSCALL_ENTER( pcb->pid ); + + // return the time + RET(pcb) = pcb->pid; +} + +/** +** sys_getppid - returns the PID of the parent of the calling process +** +** Implements: +** uint_t getppid( void ); +*/ +SYSIMPL(getppid) { + + // sanity check! + assert( pcb != NULL ); + assert( pcb->parent != NULL ); + + SYSCALL_ENTER( pcb->pid ); + + // return the time + RET(pcb) = pcb->parent->pid; +} + +/** +** sys_gettime - returns the current system time +** +** Implements: +** uint32_t gettime( void ); +*/ +SYSIMPL(gettime) { + + // sanity check! + assert( pcb != NULL ); + + SYSCALL_ENTER( pcb->pid ); + + // return the time + RET(pcb) = system_time; +} + +/** +** sys_getprio - the scheduling priority of the calling process +** +** Implements: +** int getprio( void ); +*/ +SYSIMPL(getprio) { + + // sanity check! + assert( pcb != NULL ); + + SYSCALL_ENTER( pcb->pid ); + + // return the time + RET(pcb) = pcb->priority; +} + +/** +** sys_setprio - sets the scheduling priority of the calling process +** +** Implements: +** int setprio( int new ); +*/ +SYSIMPL(setprio) { + + // sanity check! + assert( pcb != NULL ); + + SYSCALL_ENTER( pcb->pid ); + + // remember the old priority + int old = pcb->priority; + + // set the priority + pcb->priority = ARG(pcb,1); + + // return the old value + RET(pcb) = old; +} + +/** +** sys_kill - terminate a process with extreme prejudice +** +** Implements: +** int32_t kill( uint_t pid ); +** +** Marks the specified process (or the calling process, if PID is 0) +** as "killed". Returns 0 on success, else an error code. +*/ +SYSIMPL(kill) { + + // sanity check + assert( pcb != NULL ); + + SYSCALL_ENTER( pcb->pid ); + + // who is the victim? + uint_t pid = ARG(pcb,1); + + // if it's this process, convert this into a call to exit() + if( pid == pcb->pid ) { + pcb->exit_status = EXIT_KILLED; + pcb_zombify( pcb ); + dispatch(); + SYSCALL_EXIT( EXIT_KILLED ); + } + + // must be a valid "ordinary user" PID + // QUESTION: what if it's the idle process? + if( pid < FIRST_USER_PID ) { + RET(pcb) = E_FAILURE; + SYSCALL_EXIT( E_FAILURE ); + } + + // OK, this is an acceptable victim; see if it exists + pcb_t *victim = pcb_find_pid( pid ); + if( victim == NULL ) { + // nope! + RET(pcb) = E_NOT_FOUND; + SYSCALL_EXIT( E_NOT_FOUND ); + } + + // must have a state that is possible + assert( victim->state >= FIRST_VIABLE && victim->state < N_STATES ); + + // how we perform the kill depends on the victim's state + int32_t status = SUCCESS; + + switch( victim->state ) { + + case STATE_KILLED: // FALL THROUGH + case STATE_ZOMBIE: + // you can't kill it if it's already dead + RET(pcb) = SUCCESS; + break; + + case STATE_READY: // FALL THROUGH + case STATE_SLEEPING: // FALL THROUGH + case STATE_BLOCKED: // FALL THROUGH + // here, the process is on a queue somewhere; mark + // it as "killed", and let the scheduler deal with it + victim->state = STATE_KILLED; + RET(pcb) = SUCCESS; + break; + + case STATE_RUNNING: + // we have met the enemy, and it is us! + pcb->exit_status = EXIT_KILLED; + pcb_zombify( pcb ); + status = EXIT_KILLED; + // we need a new current process + dispatch(); + break; + + case STATE_WAITING: + // similar to the 'running' state, but we don't need + // to dispatch a new process + victim->exit_status = EXIT_KILLED; + status = pcb_queue_remove_this( waiting, victim ); + pcb_zombify( victim ); + RET(pcb) = status; + break; + + default: + // this is a really bad potential problem - we have an + // unexpected or bogus process state, but we didn't + // catch that earlier. + sprint( b256, "*** kill(): victim %d, odd state %d\n", + victim->pid, victim->state ); + PANIC( 0, b256 ); + } + + SYSCALL_EXIT( status ); +} + + +/** +** sys_sleep - put the calling process to sleep for some length of time +** +** Implements: +** uint_t sleep( uint_t ms ); +** +** Puts the calling process to sleep for 'ms' milliseconds (or just yields +** the CPU if 'ms' is 0). ** Returns the time the process spent sleeping. +*/ +SYSIMPL(sleep) { + + // sanity check + assert( pcb != NULL ); + + SYSCALL_ENTER( pcb->pid ); + + // get the desired duration + uint_t length = ARG( pcb, 1 ); + + if( length == 0 ) { + + // just yield the CPU + // sleep duration is 0 + RET(pcb) = 0; + + // back on the ready queue + schedule( pcb ); + + } else { + + // sleep for a while + pcb->wakeup = system_time + length; + + if( pcb_queue_insert(sleeping,pcb) != SUCCESS ) { + // something strange is happening + WARNING( "sleep pcb insert failed" ); + // if this is the current process, report an error + if( current == pcb ) { + RET(pcb) = -1; + } + // return without dispatching a new process + return; + } + } + + // only dispatch if the current process called us + if( pcb == current ) { + current = NULL; + dispatch(); + } +} + +/* +** PRIVATE FUNCTIONS GLOBAL VARIABLES +*/ + +/* +** The system call jump table +** +** Initialized using designated initializers to ensure the entries +** are correct even if the syscall code values should happen to change. +** This also makes it easy to add new system call entries, as their +** position in the initialization list is irrelevant. +*/ + +static void (* const syscalls[N_SYSCALLS])( pcb_t * ) = { + [ SYS_exit ] = sys_exit, + [ SYS_waitpid ] = sys_waitpid, + [ SYS_fork ] = sys_fork, + [ SYS_exec ] = sys_exec, + [ SYS_read ] = sys_read, + [ SYS_write ] = sys_write, + [ SYS_getpid ] = sys_getpid, + [ SYS_getppid ] = sys_getppid, + [ SYS_gettime ] = sys_gettime, + [ SYS_getprio ] = sys_getprio, + [ SYS_setprio ] = sys_setprio, + [ SYS_kill ] = sys_kill, + [ SYS_sleep ] = sys_sleep +}; + +/** +** Name: sys_isr +** +** System call ISR +** +** @param vector Vector number for this interrupt +** @param code Error code (0 for this interrupt) +*/ +static void sys_isr( int vector, int code ) { + + // keep the compiler happy + (void) vector; + (void) code; + + // sanity check! + assert( current != NULL ); + assert( current->context != NULL ); + + // retrieve the syscall code + int num = REG( current, eax ); + +#if TRACING_SYSCALLS + cio_printf( "** --> SYS pid %u code %u\n", current->pid, num ); +#endif + + // validate it + if( num < 0 || num >= N_SYSCALLS ) { + // bad syscall number + // could kill it, but we'll just force it to exit + num = SYS_exit; + ARG(current,1) = EXIT_BAD_SYSCALL; + } + + // call the handler + syscalls[num]( current ); + +#if TRACING_SYSCALLS + cio_printf( "** <-- SYS pid %u ret %u\n", current->pid, RET(current) ); +#endif + + // tell the PIC we're done + outb( PIC1_CMD, PIC_EOI ); +} + +/* +** PUBLIC FUNCTIONS +*/ + +/** +** Name: sys_init +** +** Syscall module initialization routine +** +** Dependencies: +** Must be called after cio_init() +*/ +void sys_init( void ) { + +#if TRACING_INIT + cio_puts( " Sys" ); +#endif + + // install the second-stage ISR + install_isr( VEC_SYSCALL, sys_isr ); +} diff --git a/kernel/user.c b/kernel/user.c new file mode 100644 index 0000000..2d32157 --- /dev/null +++ b/kernel/user.c @@ -0,0 +1,774 @@ +/** +** @file user.c +** +** @author CSCI-452 class of 20245 +** +** @brief User-level code manipulation routines +*/ + +#define KERNEL_SRC + +#include <common.h> + +#include <bootstrap.h> +#include <elf.h> +#include <user.h> +#include <vm.h> + +/* +** PRIVATE DEFINITIONS +*/ + +/* +** PRIVATE DATA TYPES +*/ + +/* +** PRIVATE GLOBAL VARIABLES +*/ + +/* +** PUBLIC GLOBAL VARIABLES +*/ + +/* +** Location of the "user blob" in memory. +** +** These variables are filled in by the code in startup.S using values +** passed to it from the bootstrap. +** +** These are visible so that the startup code can find them. +*/ +uint16_t user_offset; // byte offset from the segment base +uint16_t user_segment; // segment base address +uint16_t user_sectors; // number of 512-byte sectors it occupies + +header_t *user_header; // filled in by the user_init routine +prog_t *prog_table; // filled in by the user_init routine + +/* +** PRIVATE FUNCTIONS +*/ + +#if TRACING_ELF + +/* +** This is debugging support code; if not debugging the ELF +** handling code, it won't be compiled into the kernel. +*/ + +// buffer used by some of these functions +static char ebuf[16]; + +/* +** File header functions +*/ + +// interpret the file class +static const char *fh_eclass( e32_si class ) { + switch( class ) { + case ELF_CLASS_NONE: return( "None" ); break; + case ELF_CLASS_32: return( "EC32" ); break; + case ELF_CLASS_64: return( "EC64" ); break; + } + return( "????" ); +} + +// interpret the data encoding +static const char *fh_edata( e32_si data ) { + switch( data ) { + case ELF_DATA_NONE: return( "Invd" ); break; + case ELF_DATA_2LSB: return( "2CLE" ); break; + case ELF_DATA_2MSB: return( "2CBE" ); break; + } + return( "????" ); +} + +// interpret the file type +static const char *fh_htype( e32_h type ) { + switch( type ) { + case ET_NONE: return( "none" ); break; + case ET_REL: return( "rel" ); break; + case ET_EXEC: return( "exec" ); break; + case ET_DYN: return( "dyn" ); break; + case ET_CORE: return( "core" ); break; + default: + if( type >= ET_LO_OS && type <= ET_HI_OS ) + return( "OSsp" ); + else if( type >= ET_LO_CP && type <= ET_HI_CP ) + return( "CPsp" ); + } + sprint( ebuf, "0x%04x", type ); + return( (const char *) ebuf ); +} + +// interpret the machine type +static const char *fh_mtype( e32_h machine ) { + switch( machine ) { + case EM_NONE: return( "None" ); break; + case EM_386: return( "386" ); break; + case EM_ARM: return( "ARM" ); break; + case EM_X86_64: return( "AMD64" ); break; + case EM_AARCH64: return( "AARCH64" ); break; + case EM_RISCV: return( "RISC-V" ); break; + } + return( "Other" ); +} + +// dump the program header +static void dump_fhdr( elfhdr_t *hdr ) { + cio_puts( "File header: magic " ); + for( int i = EI_MAG0; i <= EI_MAG3; ++i ) + put_char_or_code( hdr->e_ident.bytes[i] ); + cio_printf( " class %s", fh_eclass(hdr->e_ident.f.class) ); + cio_printf( " enc %s", fh_edata(hdr->e_ident.f.data) ); + cio_printf( " ver %u\n", hdr->e_ident.f.version ); + cio_printf( " type %s", fh_htype(hdr->e_type) ); + cio_printf( " mach %s", fh_mtype(hdr->e_machine) ); + cio_printf( " vers %d", hdr->e_version ); + cio_printf( " entr %08x\n", hdr->e_entry ); + + cio_printf( " phoff %08x", hdr->e_phoff ); + cio_printf( " shoff %08x", hdr->e_shoff ); + cio_printf( " flags %08x", (uint32_t) hdr->e_flags ); + cio_printf( " ehsize %u\n", hdr->e_ehsize ); + cio_printf( " phentsize %u", hdr->e_phentsize ); + cio_printf( " phnum %u", hdr->e_phnum ); + cio_printf( " shentsize %u", hdr->e_shentsize ); + cio_printf( " shnum %u", hdr->e_shnum ); + cio_printf( " shstrndx %u\n", hdr->e_shstrndx ); +} + +/* +** Program header functions +*/ + +// categorize the header type +static const char *ph_type( e32_w type ) { + switch( type ) { + case PT_NULL: return( "Unused" ); break; + case PT_LOAD: return( "Load" ); break; + case PT_DYNAMIC: return( "DLI" ); break; + case PT_INTERP: return( "Interp" ); break; + case PT_NOTE: return( "Aux" ); break; + case PT_SHLIB: return( "RSVD" ); break; + case PT_PHDR: return( "PTentry" ); break; + case PT_TLS: return( "TLS" ); break; + default: + if( type >= PT_LO_OS && type <= PT_HI_OS ) + return( "OSsp" ); + else if( type >= PT_LO_CP && type <= PT_HI_CP ) + return( "CPsp" ); + } + sprint( ebuf, "0x%08x", type ); + return( (const char *) ebuf ); +} + +// report the individual flags +static void ph_flags( e32_w flags ) { + if( (flags & PF_R) != 0 ) cio_putchar( 'R' ); + if( (flags & PF_W) != 0 ) cio_putchar( 'W' ); + if( (flags & PF_E) != 0 ) cio_putchar( 'X' ); +} + +// dump a program header +static void dump_phdr( elfproghdr_t *hdr, int n ) { + cio_printf( "Prog header %d, type %s\n", n, ph_type(hdr->p_type) ); + cio_printf( " offset %08x", hdr->p_offset ); + cio_printf( " va %08x", hdr->p_va ); + cio_printf( " pa %08x\n", hdr->p_pa ); + cio_printf( " filesz %08x", hdr->p_filesz ); + cio_printf( " memsz %08x", hdr->p_memsz ); + cio_puts( " flags " ); + ph_flags( hdr->p_flags ); + cio_printf( " align %08x", hdr->p_align ); + cio_putchar( '\n' ); +} + +/* +** Section header functions +*/ + +// interpret the header type +static const char *sh_type( e32_w type ) { + switch( type ) { + case SHT_NULL: return( "Unused" ); break; + case SHT_PROGBITS: return( "Progbits" ); break; + case SHT_SYMTAB: return( "Symtab" ); break; + case SHT_STRTAB: return( "Strtab" ); break; + case SHT_RELA: return( "Rela" ); break; + case SHT_HASH: return( "Hash" ); break; + case SHT_DYNAMIC: return( "Dynamic" ); break; + case SHT_NOTE: return( "Note" ); break; + case SHT_NOBITS: return( "Nobits" ); break; + case SHT_REL: return( "Rel" ); break; + case SHT_SHLIB: return( "Shlib" ); break; + case SHT_DYNSYM: return( "Dynsym" ); break; + default: + if( type >= SHT_LO_CP && type <= SHT_HI_CP ) + return( "CCsp" ); + else if( type >= SHT_LO_US && type <= SHT_HI_US ) + return( "User" ); + } + sprint( ebuf, "0x%08x", type ); + return( (const char *) ebuf ); +} + +// report the various flags +static void sh_flags( unsigned int flags ) { + if( (flags & SHF_WRITE) != 0 ) cio_putchar( 'W' ); + if( (flags & SHF_ALLOC) != 0 ) cio_putchar( 'A' ); + if( (flags & SHF_EXECINSTR) != 0 ) cio_putchar( 'X' ); + if( (flags & SHF_MERGE) != 0 ) cio_putchar( 'M' ); + if( (flags & SHF_STRINGS) != 0 ) cio_putchar( 'S' ); + if( (flags & SHF_INFO_LINK) != 0 ) cio_putchar( 'L' ); + if( (flags & SHF_LINK_ORDER) != 0 ) cio_putchar( 'o' ); + if( (flags & SHF_OS_NONCON) != 0 ) cio_putchar( 'n' ); + if( (flags & SHF_GROUP) != 0 ) cio_putchar( 'g' ); + if( (flags & SHF_TLS) != 0 ) cio_putchar( 't' ); +} + +// dump a section header +__attribute__((__unused__)) +static void dump_shdr( elfsecthdr_t *hdr, int n ) { + cio_printf( "Sect header %d, type %d (%s), name %s\n", + n, hdr->sh_type, sh_type(hdr->sh_type) ); + cio_printf( " flags %08x ", (uint32_t) hdr->sh_flags ); + sh_flags( hdr->sh_flags ); + cio_printf( " addr %08x", hdr->sh_addr ); + cio_printf( " offset %08x", hdr->sh_offset ); + cio_printf( " size %08x\n", hdr->sh_size ); + cio_printf( " link %08x", hdr->sh_link ); + cio_printf( " info %08x", hdr->sh_info ); + cio_printf( " align %08x", hdr->sh_addralign ); + cio_printf( " entsz %08x\n", hdr->sh_entsize ); +} +#endif + +/** +** read_phdrs(addr,phoff,phentsize,phnum) +** +** Parses the ELF program headers and each segment described into memory. +** +** @param hdr Pointer to the program header +** @param pcb Pointer to the PCB (and its PDE) +** +** @return status of the attempt: +** SUCCESS everything loaded correctly +** E_LOAD_LIMIT more than N_LOADABLE PT_LOAD sections +** other status returned from vm_add() +*/ +static int read_phdrs( elfhdr_t *hdr, pcb_t *pcb ) { + + // sanity check + assert1( hdr != NULL ); + assert2( pcb != NULL ); + +#if TRACING_USER + cio_printf( "read_phdrs(%08x,%08x)\n", (uint32_t) hdr, (uint32_t) pcb ); +#endif + + // iterate through the program headers + uint_t nhdrs = hdr->e_phnum; + + // pointer to the first header table entry + elfproghdr_t *curr = (elfproghdr_t *) ((uint32_t) hdr + hdr->e_phoff); + + // process them all + int loaded = 0; + for( uint_t i = 0; i < nhdrs; ++i, ++curr ) { + +#if TRACING_ELF + dump_phdr( curr, i ); +#endif + if( curr->p_type != PT_LOAD ) { + // not loadable --> we'll skip it + continue; + } + + if( loaded >= N_LOADABLE ) { +#if TRACING_USER + cio_puts( " LIMIT\n" ); +#endif + return E_LOAD_LIMIT; + } + + // set a pointer to the bytes within the object file + char *data = (char *) (((uint32_t)hdr) + curr->p_offset); +#if TRACING_USER + cio_printf( " data @ %08x", (uint32_t) data ); +#endif + + // copy the pages into memory + int stat = vm_add( pcb->pdir, curr->p_flags & PF_W, false, + (char *) curr->p_va, curr->p_memsz, data, curr->p_filesz ); + if( stat != SUCCESS ) { + // TODO what else should we do here? check for memory leak? + return stat; + } + + // set the section table entry in the PCB + pcb->sects[loaded].length = curr->p_memsz; + pcb->sects[loaded].addr = curr->p_va; +#if TRACING_USER + cio_printf( " loaded %u @ %08x\n", + pcb->sects[loaded].length, pcb->sects[loaded].addr ); +#endif + ++loaded; + } + + return SUCCESS; +} + +/** +** Name: stack_setup +** +** Set up the stack for a new process +** +** @param pcb Pointer to the PCB for the process +** @param entry Entry point for the new process +** @param args Argument vector to be put in place +** +** @return A pointer to the context_t on the stack, or NULL +*/ +static context_t *stack_setup( pcb_t *pcb, uint32_t entry, const char **args ) { + + /* + ** First, we need to count the space we'll need for the argument + ** vector and strings. + */ + + int argbytes = 0; + int argc = 0; + + while( args[argc] != NULL ) { + int n = strlen( args[argc] ) + 1; + // can't go over one page in size + if( (argbytes + n) > SZ_PAGE ) { + // oops - ignore this and any others + break; + } + argbytes += n; + ++argc; + } + + // Round up the byte count to the next multiple of four. + argbytes = (argbytes + 3) & MOD4_MASK; + + /* + ** Allocate the arrays. We are safe using dynamic arrays here + ** because we're using the OS stack, not the user stack. + ** + ** We want the argstrings and argv arrays to contain all zeroes. + ** The C standard states, in section 6.7.8, that + ** + ** "21 If there are fewer initializers in a brace-enclosed list + ** than there are elements or members of an aggregate, or + ** fewer characters in a string literal used to initialize an + ** array of known size than there are elements in the array, + ** the remainder of the aggregate shall be initialized + ** implicitly the same as objects that have static storage + ** duration." + ** + ** Sadly, because we're using variable-sized arrays, we can't + ** rely on this, so we have to call memclr() instead. :-( In + ** truth, it doesn't really cost us much more time, but it's an + ** annoyance. + */ + + char argstrings[ argbytes ]; + char *argv[ argc + 1 ]; + + CLEAR( argstrings ); + CLEAR( argv ); + + // Next, duplicate the argument strings, and create pointers to + // each one in our argv. + char *tmp = argstrings; + for( int i = 0; i < argc; ++i ) { + int nb = strlen(args[i]) + 1; // bytes (incl. NUL) in this string + strcpy( tmp, args[i] ); // add to our buffer + argv[i] = tmp; // remember where it was + tmp += nb; // move on + } + + // trailing NULL pointer + argv[argc] = NULL; + + /* + ** The pages for the stack were cleared when they were allocated, + ** so we don't need to remember to do that. + ** + ** We reserve one longword at the bottom of the stack to hold a + ** pointer to where argv is on the stack. + ** + ** The user code was linked with a startup function that defines + ** the entry point (_start), calls main(), and then calls exit() + ** if main() returns. We need to set up the stack this way: + ** + ** esp -> context <- context save area + ** ... <- context save area + ** context <- context save area + ** entry_pt <- return address for the ISR + ** argc <- argument count for main() + ** /-> argv <- argv pointer for main() + ** | ... <- argv array w/trailing NULL + ** | ... <- argv character strings + ** \--- ptr <- last word in stack + ** + ** Stack alignment rules for the SysV ABI i386 supplement dictate that + ** the 'argc' parameter must be at an address that is a multiple of 16; + ** see below for more information. + */ + + // Pointer to the last word in stack. We get this from the + // VM hierarchy. Get the PDE entry for the user address space. + pde_t stack_pde = pcb->pdir[USER_PDE]; + + // The PDE entry points to the PT, which is an array of PTE. The last + // two entries are for the stack; pull out the last one. + pte_t stack_pte = ((pte_t *)(stack_pde & MOD4K_MASK))[USER_STK_PTE2]; + + // OK, now we have the PTE. The frame address of the last page is + // in this PTE. Find the address immediately after that. + uint32_t *ptr = (uint32_t *) + ((uint32_t)(stack_pte & MOD4K_MASK) + SZ_PAGE); + + // Pointer to where the arg strings should be filled in. + char *strings = (char *) ( (uint32_t) ptr - argbytes ); + + // back the pointer up to the nearest word boundary; because we're + // moving toward location 0, the nearest word boundary is just the + // next smaller address whose low-order two bits are zeroes + strings = (char *) ((uint32_t) strings & MOD4_MASK); + + // Copy over the argv strings. + memcpy( (void *)strings, argstrings, argbytes ); + + /* + ** Next, we need to copy over the argv pointers. Start by + ** determining where 'argc' should go. + ** + ** Stack alignment is controlled by the SysV ABI i386 supplement, + ** version 1.2 (June 23, 2016), which states in section 2.2.2: + ** + ** "The end of the input argument area shall be aligned on a 16 + ** (32 or 64, if __m256 or __m512 is passed on stack) byte boundary. + ** In other words, the value (%esp + 4) is always a multiple of 16 + ** (32 or 64) when control is transferred to the function entry + ** point. The stack pointer, %esp, always points to the end of the + ** latest allocated stack frame." + ** + ** Isn't technical documentation fun? Ultimately, this means that + ** the first parameter to main() should be on the stack at an address + ** that is a multiple of 16. + ** + ** The space needed for argc, argv, and the argv array itself is + ** argc + 3 words (argc+1 for the argv entries, plus one word each + ** for argc and argv). We back up that much from 'strings'. + */ + + int nwords = argc + 3; + uint32_t *acptr = ((uint32_t *) strings) - nwords; + + /* + ** Next, back up until we're at a multiple-of-16 address. Because we + ** are moving to a lower address, its upper 28 bits are identical to + ** the address we currently have, so we can do this with a bitwise + ** AND to just turn off the lower four bits. + */ + + acptr = (uint32_t *) ( ((uint32_t)acptr) & MOD16_MASK ); + + // copy in 'argc' + *acptr = argc; + + // next, 'argv', which follows 'argc'; 'argv' points to the + // word that follows it in the stack + uint32_t *avptr = acptr + 2; + *(acptr+1) = (uint32_t) avptr; + + /* + ** Next, we copy in all argc+1 pointers. + */ + + // Adjust and copy the string pointers. + for( int i = 0; i <= argc; ++i ) { + if( argv[i] != NULL ) { + // an actual pointer - adjust it and copy it in + *avptr = (uint32_t) strings; + // skip to the next entry in the array + strings += strlen(argv[i]) + 1; + } else { + // end of the line! + *avptr = NULL; + } + ++avptr; + } + + /* + ** Now, we need to set up the initial context for the executing + ** process. + ** + ** When this process is dispatched, the context restore code will + ** pop all the saved context information off the stack, including + ** the saved EIP, CS, and EFLAGS. We set those fields up so that + ** the interrupt "returns" to the entry point of the process. + */ + + // Locate the context save area on the stack. + context_t *ctx = ((context_t *) avptr) - 1; + + /* + ** We cleared the entire stack earlier, so all the context + ** fields currently contain zeroes. We now need to fill in + ** all the important fields. + */ + + ctx->eflags = DEFAULT_EFLAGS; // IE enabled, PPL 0 + ctx->eip = entry; // initial EIP + ctx->cs = GDT_CODE; // segment registers + ctx->ss = GDT_STACK; + ctx->ds = ctx->es = ctx->fs = ctx->gs = GDT_DATA; + + /* + ** Return the new context pointer to the caller. It will be our + ** caller's responsibility to schedule this process. + */ + + return( ctx ); +} + +/* +** PUBLIC FUNCTIONS +*/ + +/** +** Name: user_init +** +** Initializes the user support module. +*/ +void user_init( void ) { + +#if TRACING_INIT + cio_puts( " User" ); +#endif + + // This is gross, but we need to get this information somehow. + // Access the "user blob" data in the second bootstrap sector + uint16_t *blobdata = (uint16_t *) USER_BLOB_DATA; + user_offset = *blobdata++; + user_segment = *blobdata++; + user_sectors = *blobdata++; + +#if TRACING_USER + cio_printf( "\nUser blob: %u sectors @ %04x:%04x", user_sectors, + user_segment, user_offset ); +#endif + + // calculate the location of the user blob + if( user_sectors > 0 ) { + + // calculate the address of the header + user_header = (header_t *) + ( KERN_BASE + + ( (((uint_t)user_segment) << 4) + ((uint_t)user_offset) ) + ); + + // the program table immediate follows the blob header + prog_table = (prog_t *) (user_header + 1); + +#if TRACING_USER + cio_printf( ", hdr %08x, %u progs, tbl %08x\n", (uint32_t) user_header, + user_header->num, (uint32_t) prog_table ); +#endif + + } else { + // too bad, so sad! + user_header = NULL; + prog_table = NULL; +#if TRACING_USER + cio_putchar( '\n' ); +#endif + } +} + +/** +** Name: user_locate +** +** Locates a user program in the user code archive. +** +** @param what The ID of the user program to find +** +** @return pointer to the program table entry in the code archive, or NULL +*/ +prog_t *user_locate( uint_t what ) { + + // no programs if there is no blob! + if( user_header == NULL ) { + return NULL; + } + + // make sure this is a reasonable program to request + if( what >= user_header->num ) { + // no such program! + return NULL; + } + + // find the entry in the program table + prog_t *prog = &prog_table[what]; + + // if there are no bytes, it's useless + if( prog->size < 1 ) { + return NULL; + } + + // return the program table pointer + return prog; +} + +/** +** Name: user_duplicate +** +** Duplicates the memory setup for an existing process. +** +** @param new The PCB for the new copy of the program +** @param old The PCB for the existing the program +** +** @return the status of the duplicate attempt +*/ +int user_duplicate( pcb_t *new, pcb_t *old ) { + + // We need to do a recursive duplication of the process address + // space of the current process. First, we create a new user + // page directory. Next, we'll duplicate the USER_PDE page + // table. Finally, we'll go through that table and duplicate + // all the frames. + + // create the initial VM hierarchy + pde_t *pdir = vm_mkuvm(); + if( pdir == NULL ) { + return E_NO_MEMORY; + } + new->pdir = pdir; + + // next, add a USER_PDE page table that's a duplicate of the + // current process' page table + if( !vm_uvmdup(old->pdir,new->pdir) ) { + // check for memory leak? + return E_NO_MEMORY; + } + + // now, iterate through the entries, replacing the frame + // numbers with duplicate frames + // + // NOTE: we only deal with pdir[0] here, as we are limiting + // the user address space to the first 4MB + pte_t *pt = (pte_t *) (pdir[USER_PDE]); + + for( int i = 0; i < N_PTE; ++i ) { + + // if this entry is present, + if( IS_PRESENT(*pt) ) { + + // duplicate the page + void *tmp = vm_pagedup( (void *) (*pt & FRAME_MASK) ); + // replace the old frame number with the new one + *pt = (pte_t) (((uint32_t)tmp) | (*pt & PERM_MASK)); + + } else { + + *pt = 0; + + } + ++pt; + } + + return SUCCESS; +} + +/** +** Name: user_load +** +** Loads a user program from the user code archive into memory. +** Allocates all needed frames and sets up the VM tables. +** +** @param ptab A pointer to the program table entry to be loaded +** @param pcb The PCB for the program being loaded +** @param args The argument vector for the program +** +** @return the status of the load attempt +*/ +int user_load( prog_t *ptab, pcb_t *pcb, const char **args ) { + + // NULL pointers are bad! + assert1( ptab != NULL ); + assert1( pcb != NULL ); + assert1( args != NULL ); + + // locate the ELF binary + elfhdr_t *hdr = (elfhdr_t *) ((uint32_t)user_header + ptab->offset); + +#if TRACING_ELF + cio_printf( "Load: ptab %08x: '%s', off %08x, size %08x, flags %08x\n", + (uint32_t) ptab, ptab->name, ptab->offset, ptab->size, + ptab->flags ); + cio_printf( " args %08x:", (uint32_t) args ); + for( int i = 0; args[i] != NULL; ++i ) { + cio_printf( " [%d] %s", i, args[i] ); + } + cio_printf( "\n pcb %08x (pid %u)\n", (uint32_t) pcb, pcb->pid ); + dump_fhdr( hdr ); +#endif + + // verify the ELF header + if( hdr->e_ident.f.magic != ELF_MAGIC ) { + return E_BAD_PARAM; + } + + // allocate a page directory + pcb->pdir = vm_mkuvm(); + if( pcb->pdir == NULL ) { + return E_NO_MEMORY; + } + + // read all the program headers + int stat = read_phdrs( hdr, pcb ); + if( stat != SUCCESS ) { + // TODO figure out a better way to deal with this + PANIC( 0, "user_load: phdr read failed" ); + } + + // next, set up the runtime stack - just like setting up loadable + // sections, except nothing to copy + stat = vm_add( pcb->pdir, true, false, (void *) USER_STACK, + SZ_USTACK, NULL, 0 ); + if( stat != SUCCESS ) { + // TODO yadda yadda... + PANIC( 0, "user_load: vm_add failed" ); + } + + // set up the command-line arguments + pcb->context = stack_setup( pcb, hdr->e_entry, args ); + + return SUCCESS; +} + +/** +** Name: user_cleanup +** +** "Unloads" a user program. Deallocates all memory frames and +** cleans up the VM structures. +** +** @param pcb The PCB of the program to be unloaded +*/ +void user_cleanup( pcb_t *pcb ) { + + if( pcb == NULL ) { + // should this be an error? + return; + } + + vm_free( pcb->pdir ); + pcb->pdir = NULL; +} diff --git a/kernel/vm.c b/kernel/vm.c new file mode 100644 index 0000000..46c4eab --- /dev/null +++ b/kernel/vm.c @@ -0,0 +1,585 @@ +/** +** @file vm.c +** +** @author CSCI-452 class of 20245 +** +** @brief Kernel VM support +*/ + +#define KERNEL_SRC + +#include <common.h> + +#include <vm.h> +#include <vmtables.h> + +#include <kmem.h> +#include <procs.h> +#include <x86/arch.h> +#include <x86/ops.h> + +/* +** PRIVATE DEFINITIONS +*/ + +/* +** PRIVATE DATA TYPES +*/ + +/* +** PRIVATE GLOBAL VARIABLES +*/ + +/* +** PUBLIC GLOBAL VARIABLES +*/ + +// created page directory for the kernel +pde_t *kpdir; + +/* +** PRIVATE FUNCTIONS +*/ + +/** +** Name: vm_isr +** +** Description: Page fault handler +** +** @param vector Interrupt vector number +** @param code Error code pushed onto the stack +*/ +static void vm_isr( int vector, int code ) { + + // get whatever information we can from the fault + pfec_t fault; + fault.u = (uint32_t) code; + uint32_t addr = r_cr2(); + + // report what we found + sprint( b256, + "** page fault @ 0x%08x %cP %c %cM %cRSV %c %cPK %cSS %cHLAT %cSGZ", + addr, + fault.s.p ? ' ' : '!', + fault.s.w ? 'W' : 'R', + fault.s.us ? 'U' : 'S', + fault.s.rsvd ? ' ' : '!', + fault.s.id ? 'I' : 'D', + fault.s.pk ? ' ' : '!', + fault.s.ss ? ' ' : '!', + fault.s.hlat ? ' ' : '!', + fault.s.sgz ? ' ' : '!' + ); + + // and give up + PANIC( 0, b256 ); +} + +/** +** Name: uva2kva +** +** Convert a user VA into a kernel address +*/ +__attribute__((__unused__)) +static void *uva2kva( pde_t *pdir, void *va ) { + + // find the PMT entry for this address + pte_t *pte = vm_getpte( pdir, va, false ); + if( pte == NULL ) { + return NULL; + } + + // is this a valid address for the user? + if( IS_PRESENT(*pte) ) { + return 0; + } + + if( IS_LARGE(*pte) ) { + return 0; + } + + // get the physical address + uint32_t frame = *pte & FRAME_MASK; // keep the frame address + frame |= ((uint32_t) va) & PERM_MASK; // OR in the lower 12 bits + + return (void *) frame; +} + + +/* +** PUBLIC FUNCTIONS +*/ + +/** +** Name: vm_init +** +** Description: Initialize the VM module +*/ +void vm_init( void ) { + +#if TRACING_INIT + cio_puts( " VM" ); +#endif + + // set up the kernel's page directory + kpdir = vm_mkkvm(); + assert( kpdir != NULL ); + + // install the page fault handler + install_isr( VEC_PAGE_FAULT, vm_isr ); +} + +/** +** Name: vm_pagedup +** +** Duplicate a page of memory +** +** @param old Pointer to the first byte of a page +** +** @return a pointer to the new, duplicate page, or NULL +*/ +void *vm_pagedup( void *old ) { + void *new = (void *) km_page_alloc(); + if( new != NULL ) { + memcpy( new, old, SZ_PAGE ); + } + return new; +} + +/** +** Name: vm_ptdup +** +** Duplicate a page directory entry +** +** @param dst Pointer to where the duplicate should go +** @param curr Pointer to the entry to be duplicated +** +** @return true on success, else false +*/ +bool_t vm_ptdup( pde_t *dst, pde_t *curr ) { + +#if TRACING_VM + cio_printf( "vm_ptdup dst %08x curr %08x\n", + (uint32_t) dst, (uint32_t) curr ); +#endif + // simplest case + if( *curr == 0 ) { + *dst = 0; + return true; + } + + // OK, we have an entry; allocate a page table + pte_t *pt = (pte_t *) km_page_alloc(); + if( pt == NULL ) { + return false; + } + + // pointer to the first PTE in the current table + pte_t *old = (pte_t *) (((uint32_t) *curr) & FRAME_MASK); + // pointer to the first PTE in the new table + pte_t *new = pt; + + for( int i = 0 ; i < N_PTE; ++i ) { + if( IS_PRESENT(*old) ) { + *new = 0; + } else { + *new = *old; + } + ++old; + ++new; + } + + // assign the page table into the new page directory + // upper 22 bits from 'pt', lower 12 from '*curr' + *dst = (pde_t) ( + (((uint32_t)pt) & FRAME_MASK) | + (((uint32_t)(*curr)) & PERM_MASK ) + ); + + return true; +} + +/** +** Name: vm_getpte +** +** Return the address of the PTE corresponding to the virtual address +** 'va' within the address space controlled by 'pgdir'. If there is no +** page table for that VA and 'alloc' is true, create the necessary +** page table entries. +** +** @param pdir Pointer to the page directory to be searched +** @param va The virtual address we're looking for +** @param alloc Should we allocate a page table if there isn't one? +** +** @return A pointer to the page table entry for this VA, or NULL +*/ +pte_t *vm_getpte( pde_t *pdir, const void *va, bool_t alloc ) { + pte_t *ptab; + + // sanity check + assert1( pdir != NULL ); + + // get the PDIR entry for this virtual address + pde_t *pde = &pdir[ PDIX(va) ]; + + // is it already set up? + if( IS_PRESENT(*pde) ) { + + // yes! + ptab = (pte_t*)P2V(PTE_ADDR(*pde)); + + } else { + + // no - should we create it? + if( !alloc ) { + // nope, so just return + return NULL; + } + + // yes - try to allocate a page table + ptab = (pte_t *) km_page_alloc(); + if( ptab == NULL ) { + WARNING( "can't allocate page table" ); + return NULL; + } + + // who knows what was left in this page.... + memclr( ptab, SZ_PAGE ); + + // add this to the page directory + // + // we set this up to allow general access; this could be + // controlled by setting access control in the page table + // entries, if necessary. + *pde = V2P(ptab) | PDE_P | PDE_RW; + } + + // finally, return a pointer to the entry in the + // page table for this VA + return &ptab[ PTIX(va) ]; +} + +// Set up kernel part of a page table. +pde_t *vm_mkkvm( void ) +{ + mapping_t *k; + + // allocate the page directory + pde_t *pdir = km_page_alloc(); + if( pdir == NULL ) { + return NULL; + } + + // clear it out to disable all the entries + memclr( pdir, SZ_PAGE ); + + // map in all the page ranges + k = kmap; + for( int i = 0; i < n_kmap; ++i, ++k ) { + int stat = vm_map( pdir, ((void *)k->va_start), + k->pa_end - k->pa_start, + k->pa_start, k->perm ); + if( stat != SUCCESS ) { + vm_free( pdir ); + return 0; + } + } + + return pdir; +} + +/* +** Creates an initial user VM table hierarchy by copying the +** system entries into a new page directory. +** +** @return a pointer to the new page directory, or NULL +*/ +pde_t *vm_mkuvm( void ) { + + // allocate the directory + pde_t *new = (pde_t *) km_page_alloc(); + if( new == NULL ) { + return NULL; + } + + // iterate through the kernel page directory + pde_t *curr = kpdir; + pde_t *dst = new; + for( int i = 0; i < N_PDE; ++i ) { + + if( *curr != 0 ) { + // found an active one - duplicate it + if( !vm_ptdup(dst,curr) ) { + return NULL; + } + } + + ++curr; + ++dst; + } + + return new; + +} + +/** +** Name: vm_set_kvm +** +** Switch the page table register to the kernel's page directory. +*/ +void vm_set_kvm( void ) { + w_cr3( V2P(kpdir) ); // switch to the kernel page table +} + +/** +** Name: vm_set_uvm +** +** Switch the page table register to the page directory for a user process. +** +** @param p PCB of the process we're switching to +*/ +void vm_set_uvm( pcb_t *p ) { + assert( p != NULL ); + assert( p->pdir != NULL ); + + w_cr3( V2P(p->pdir) ); // switch to process's address space +} + +/** +** Name: vm_add +** +** Add pages to the page hierarchy for a process, copying data into +** them if necessary. +** +** @param pdir Pointer to the page directory to modify +** @param wr "Writable" flag for the PTE +** @param sys "System" flag for the PTE +** @param va Starting VA of the range +** @param size Amount of physical memory to allocate (bytes) +** @param data Pointer to data to copy, or NULL +** @param bytes Number of bytes to copy +** +** @return status of the allocation attempt +*/ +int vm_add( pde_t *pdir, bool_t wr, bool_t sys, + void *va, uint32_t size, char *data, uint32_t bytes ) { + + // how many pages do we need? + uint_t npages = ((size & MOD4K_BITS) ? PGUP(size) : size) >> MOD4K_SHIFT; + + // permission set for the PTEs + uint_t entrybase = PTE_P; + if( wr ) { + entrybase |= PTE_RW; + } + if( sys ) { + entrybase |= PTE_US; + } + +#if TRACING_VM + cio_printf( "vm_add: pdir %08x, %s, va %08x (%u, %u pgs)\n", + (uint32_t) pdir, wr ? "W" : "!W", (uint32_t) va, size ); + cio_printf( " from %08x, %u bytes, perms %08x\n", + (uint32_t) data, bytes, entrybase ); +#endif + + // iterate through the pages + + for( int i = 0; i < npages; ++i ) { + + // figure out where this page will go in the hierarchy + pte_t *pte = vm_getpte( pdir, va, true ); + if( pte == NULL ) { + // TODO if i > 0, this isn't the first frame - is + // there anything to do about other frames? + // POSSIBLE MEMORY LEAK? + return E_NO_MEMORY; + } + + // allocate the frame + void *page = km_page_alloc(); + if( page == NULL ) { + // TODO same question here + return E_NO_MEMORY; + } + + // clear it all out + memclr( page, SZ_PAGE ); + + // create the PTE for this frame + uint32_t entry = (uint32_t) (PTE_ADDR(page) | entrybase); + *pte = entry; + + // copy data if we need to + if( data != NULL && bytes > 0 ) { + // how much to copy + uint_t num = bytes > SZ_PAGE ? SZ_PAGE : bytes; + // do it! + memcpy( (void *)page, (void *)data, num ); + // adjust all the pointers + data += num; // where to continue + bytes -= num; // what's left to copy + } + + // bump the virtual address + va += SZ_PAGE; + } + + return SUCCESS; + +} + +/** +** Name: vm_free +** +** Deallocate a page table hierarchy and all physical memory frames +** in the user portion. +** +** @param pdir Pointer to the page directory +*/ +void vm_free( pde_t *pdir ) { + + // do we have anything to do? + if( pdir == NULL ) { + return; + } + + // iterate through the page directory entries, freeing the + // PMTS and the frames they point to + pde_t *curr = pdir; + for( int i = 0; i < N_PDE; ++i ) { + + // does this entry point to anything useful? + if( IS_PRESENT(*curr) ) { + + // yes - get the PMT pointer + pte_t *pte = (pte_t *) PTE_ADDR(*curr); + + // walk the PMT + for( int j = 0; j < N_PTE; ++j ) { + // does this entry point to a frame? + if( IS_PRESENT(*pte) ) { + // yes - free the frame + km_page_free( (void *) PTE_ADDR(*pte) ); + // mark it so we don't get surprised + *pte = 0; + } + // move on + ++pte; + } + // now, free the PMT itself + km_page_free( (void *) PDE_ADDR(*curr) ); + *curr = 0; + } + + // move to the next entry + ++curr; + } + + // finally, free the PDIR itself + km_page_free( (void *) pdir ); +} + +/* +** Name: vm_map +** +** Create PTEs for virtual addresses starting at 'va' that refer to +** physical addresses in the range [pa, pa+size-1]. We aren't guaranteed +** that va is page-aligned. +** +** @param pdir Page directory for this address space +** @param va The starting virtual address +** @param size Length of the range to be mapped +** @param pa The starting physical address +** @param perm Permission bits for the PTEs +*/ +int vm_map( pde_t *pdir, void *va, uint_t size, uint_t pa, int perm ) { + pte_t *pte; + + // round the VA down to its page boundary + char *addr = (char*)PGDOWN((uint_t)va); + + // round the end of the range down to its page boundary + char *last = (char*)PGDOWN(((uint_t)va) + size - 1); + + for(;;) { + + // get a pointer to the PTE for the current VA + if( (pte = vm_getpte(pdir, addr, 1)) == 0 ) { + // couldn't find it + return E_NO_PTE; + } + + // if this entry has already been mapped, we're in trouble + if( IS_PRESENT(*pte) ) { + PANIC( 0, "mapping an already-mapped address" ); + } + + // ok, set the PTE as requested + *pte = pa | perm | PTE_P; + + // are we done? + if( addr == last ) { + break; + } + + // nope - move to the next page + addr += SZ_PAGE; + pa += SZ_PAGE; + } + return 0; +} + +/** +** Name: vm_uvmdup +** +** Create a duplicate of the user portio of an existing page table +** hierarchy. We assume that the "new" page directory exists and +** the system portions of it should not be touched. +** +** Note: we do not duplicate the frames in the hierarchy - we just +** create a duplicate of the hierarchy itself. This means that we +** now have two sets of page tables that refer to the same user-level +** frames in memory. +** +** @param old Existing page directory +** @param new New page directory +** +** @return status of the duplication attempt +*/ +int vm_uvmdup( pde_t *old, pde_t *new ) { + + if( old == NULL || new == NULL ) { + return E_BAD_PARAM; + } + + // we only want to deal with the "user" half of the address space + for( int i = 0; i < (N_PDE >> 1); ++i ) { + + // is this entry in use? + if( IS_PRESENT(*old) ) { + + // yes. if it points to a 4MB page, we just copy it; + // otherwise, we must duplicate the next level PMT + + *new = *old; // copy the entry + + if( !IS_LARGE(*old) ) { + + // it's a 4KB page, so we need to duplicate the PMT + pte_t *newpmt = (pte_t *) vm_pagedup( (void *) (*old & FRAME_MASK) ); + if( newpmt == NULL ) { + return E_NO_MEMORY; + } + + // create the new PDE entry by replacing the frame # + *new = (pde_t) (((uint32_t)newpmt) | PERMS(*old)); + } + } + + ++old; + ++new; + } + + return SUCCESS; +} diff --git a/kernel/vmtables.c b/kernel/vmtables.c new file mode 100644 index 0000000..306b1f6 --- /dev/null +++ b/kernel/vmtables.c @@ -0,0 +1,270 @@ +/** +** @file vmtables.c +** +** @author CSCI-452 class of 20245 +** +** @brief Kernel VM tables +** +** Compilation options: +** +** MAKE_IDENTITY_MAP Creates a page table that identity-maps the first +** 4MB of main memory. +*/ + +#define KERNEL_SRC + +#include <common.h> + +#include <kmem.h> +#include <procs.h> +#include <vm.h> +#include <x86/arch.h> + +// defined for us by the linker +extern char _data[]; + +/* +** Initial page directory, for when the kernel is starting up +** +** we use large (4MB) pages here to allow us to use a one-level +** paging hierarchy; the kernel will create a new page table +** hierarchy once memory is initialized +** +** We only map the first 2GB of memory, plus a 4MB portion of +** the upper half, which we map to cover the first 4MB of +** memory. +*/ + +// identity-map 4MB page #n +#define L(n) [n] = (pde_t) ( (TO_4MFRAME((n))) | (PDE_P|PDE_RW|PDE_PS) ) + +ALIGN(SZ_PAGE) +pde_t firstpdir[N_PDE] = { + + // Map VA range [0, 2GB] to PA range [0, 2GB] +L(0x000), L(0x001), L(0x002), L(0x003), L(0x004), L(0x005), L(0x006), L(0x007), +L(0x008), L(0x009), L(0x00a), L(0x00b), L(0x00c), L(0x00d), L(0x00e), L(0x00f), +L(0x010), L(0x011), L(0x012), L(0x013), L(0x014), L(0x015), L(0x016), L(0x017), +L(0x018), L(0x019), L(0x01a), L(0x01b), L(0x01c), L(0x01d), L(0x01e), L(0x01f), +L(0x020), L(0x021), L(0x022), L(0x023), L(0x024), L(0x025), L(0x026), L(0x027), +L(0x028), L(0x029), L(0x02a), L(0x02b), L(0x02c), L(0x02d), L(0x02e), L(0x02f), +L(0x030), L(0x031), L(0x032), L(0x033), L(0x034), L(0x035), L(0x036), L(0x037), +L(0x038), L(0x039), L(0x03a), L(0x03b), L(0x03c), L(0x03d), L(0x03e), L(0x03f), +L(0x040), L(0x041), L(0x042), L(0x043), L(0x044), L(0x045), L(0x046), L(0x047), +L(0x048), L(0x049), L(0x04a), L(0x04b), L(0x04c), L(0x04d), L(0x04e), L(0x04f), +L(0x050), L(0x051), L(0x052), L(0x053), L(0x054), L(0x055), L(0x056), L(0x057), +L(0x058), L(0x059), L(0x05a), L(0x05b), L(0x05c), L(0x05d), L(0x05e), L(0x05f), +L(0x060), L(0x061), L(0x062), L(0x063), L(0x064), L(0x065), L(0x066), L(0x067), +L(0x068), L(0x069), L(0x06a), L(0x06b), L(0x06c), L(0x06d), L(0x06e), L(0x06f), +L(0x070), L(0x071), L(0x072), L(0x073), L(0x074), L(0x075), L(0x076), L(0x077), +L(0x078), L(0x079), L(0x07a), L(0x07b), L(0x07c), L(0x07d), L(0x07e), L(0x07f), +L(0x080), L(0x081), L(0x082), L(0x083), L(0x084), L(0x085), L(0x086), L(0x087), +L(0x088), L(0x089), L(0x08a), L(0x08b), L(0x08c), L(0x08d), L(0x08e), L(0x08f), +L(0x090), L(0x091), L(0x092), L(0x093), L(0x094), L(0x095), L(0x096), L(0x097), +L(0x098), L(0x099), L(0x09a), L(0x09b), L(0x09c), L(0x09d), L(0x09e), L(0x09f), +L(0x0a0), L(0x0a1), L(0x0a2), L(0x0a3), L(0x0a4), L(0x0a5), L(0x0a6), L(0x0a7), +L(0x0a8), L(0x0a9), L(0x0aa), L(0x0ab), L(0x0ac), L(0x0ad), L(0x0ae), L(0x0af), +L(0x0b0), L(0x0b1), L(0x0b2), L(0x0b3), L(0x0b4), L(0x0b5), L(0x0b6), L(0x0b7), +L(0x0b8), L(0x0b9), L(0x0ba), L(0x0bb), L(0x0bc), L(0x0bd), L(0x0be), L(0x0bf), +L(0x0c0), L(0x0c1), L(0x0c2), L(0x0c3), L(0x0c4), L(0x0c5), L(0x0c6), L(0x0c7), +L(0x0c8), L(0x0c9), L(0x0ca), L(0x0cb), L(0x0cc), L(0x0cd), L(0x0ce), L(0x0cf), +L(0x0d0), L(0x0d1), L(0x0d2), L(0x0d3), L(0x0d4), L(0x0d5), L(0x0d6), L(0x0d7), +L(0x0d8), L(0x0d9), L(0x0da), L(0x0db), L(0x0dc), L(0x0dd), L(0x0de), L(0x0df), +L(0x0e0), L(0x0e1), L(0x0e2), L(0x0e3), L(0x0e4), L(0x0e5), L(0x0e6), L(0x0e7), +L(0x0e8), L(0x0e9), L(0x0ea), L(0x0eb), L(0x0ec), L(0x0ed), L(0x0ee), L(0x0ef), +L(0x0f0), L(0x0f1), L(0x0f2), L(0x0f3), L(0x0f4), L(0x0f5), L(0x0f6), L(0x0f7), +L(0x0f8), L(0x0f9), L(0x0fa), L(0x0fb), L(0x0fc), L(0x0fd), L(0x0fe), L(0x0ff), +L(0x100), L(0x101), L(0x102), L(0x103), L(0x104), L(0x105), L(0x106), L(0x107), +L(0x108), L(0x109), L(0x10a), L(0x10b), L(0x10c), L(0x10d), L(0x10e), L(0x10f), +L(0x110), L(0x111), L(0x112), L(0x113), L(0x114), L(0x115), L(0x116), L(0x117), +L(0x118), L(0x119), L(0x11a), L(0x11b), L(0x11c), L(0x11d), L(0x11e), L(0x11f), +L(0x120), L(0x121), L(0x122), L(0x123), L(0x124), L(0x125), L(0x126), L(0x127), +L(0x128), L(0x129), L(0x12a), L(0x12b), L(0x12c), L(0x12d), L(0x12e), L(0x12f), +L(0x130), L(0x131), L(0x132), L(0x133), L(0x134), L(0x135), L(0x136), L(0x137), +L(0x138), L(0x139), L(0x13a), L(0x13b), L(0x13c), L(0x13d), L(0x13e), L(0x13f), +L(0x140), L(0x141), L(0x142), L(0x143), L(0x144), L(0x145), L(0x146), L(0x147), +L(0x148), L(0x149), L(0x14a), L(0x14b), L(0x14c), L(0x14d), L(0x14e), L(0x14f), +L(0x150), L(0x151), L(0x152), L(0x153), L(0x154), L(0x155), L(0x156), L(0x157), +L(0x158), L(0x159), L(0x15a), L(0x15b), L(0x15c), L(0x15d), L(0x15e), L(0x15f), +L(0x160), L(0x161), L(0x162), L(0x163), L(0x164), L(0x165), L(0x166), L(0x167), +L(0x168), L(0x169), L(0x16a), L(0x16b), L(0x16c), L(0x16d), L(0x16e), L(0x16f), +L(0x170), L(0x171), L(0x172), L(0x173), L(0x174), L(0x175), L(0x176), L(0x177), +L(0x178), L(0x179), L(0x17a), L(0x17b), L(0x17c), L(0x17d), L(0x17e), L(0x17f), +L(0x180), L(0x181), L(0x182), L(0x183), L(0x184), L(0x185), L(0x186), L(0x187), +L(0x188), L(0x189), L(0x18a), L(0x18b), L(0x18c), L(0x18d), L(0x18e), L(0x18f), +L(0x190), L(0x191), L(0x192), L(0x193), L(0x194), L(0x195), L(0x196), L(0x197), +L(0x198), L(0x199), L(0x19a), L(0x19b), L(0x19c), L(0x19d), L(0x19e), L(0x19f), +L(0x1a0), L(0x1a1), L(0x1a2), L(0x1a3), L(0x1a4), L(0x1a5), L(0x1a6), L(0x1a7), +L(0x1a8), L(0x1a9), L(0x1aa), L(0x1ab), L(0x1ac), L(0x1ad), L(0x1ae), L(0x1af), +L(0x1b0), L(0x1b1), L(0x1b2), L(0x1b3), L(0x1b4), L(0x1b5), L(0x1b6), L(0x1b7), +L(0x1b8), L(0x1b9), L(0x1ba), L(0x1bb), L(0x1bc), L(0x1bd), L(0x1be), L(0x1bf), +L(0x1c0), L(0x1c1), L(0x1c2), L(0x1c3), L(0x1c4), L(0x1c5), L(0x1c6), L(0x1c7), +L(0x1c8), L(0x1c9), L(0x1ca), L(0x1cb), L(0x1cc), L(0x1cd), L(0x1ce), L(0x1cf), +L(0x1d0), L(0x1d1), L(0x1d2), L(0x1d3), L(0x1d4), L(0x1d5), L(0x1d6), L(0x1d7), +L(0x1d8), L(0x1d9), L(0x1da), L(0x1db), L(0x1dc), L(0x1dd), L(0x1de), L(0x1df), +L(0x1e0), L(0x1e1), L(0x1e2), L(0x1e3), L(0x1e4), L(0x1e5), L(0x1e6), L(0x1e7), +L(0x1e8), L(0x1e9), L(0x1ea), L(0x1eb), L(0x1ec), L(0x1ed), L(0x1ee), L(0x1ef), +L(0x1f0), L(0x1f1), L(0x1f2), L(0x1f3), L(0x1f4), L(0x1f5), L(0x1f6), L(0x1f7), +L(0x1f8), L(0x1f9), L(0x1fa), L(0x1fb), L(0x1fc), L(0x1fd), L(0x1fe), L(0x1ff), + + // Map VA range [KERN_BASE, KERN_BASE+4MB] to PA range [0, 4MB] + [PDIX(KERN_BASE)] = (pde_t) (PDE_P | PDE_RW | PDE_PS) +}; + +#ifdef MAKE_IDENTITY_MAP +/* +** "Identity" page map table. +** +** This just maps the first 4MB of physical memory. It is initialized +** in vm_init(). +** +** This could be converted into a 4GB map of 4MB pages by turning on +** the PDE_PS bit in each entry. +*/ + +// identity-map 4KB page #n +#define S(n) [n] = (pte_t) ( (TO_4KFRAME((n))) | (PTE_P|PTE_RW) ) + +pte_t id_map[N_PTE] = { +S(0x000), S(0x001), S(0x002), S(0x003), S(0x004), S(0x005), S(0x006), S(0x007), +S(0x008), S(0x009), S(0x00a), S(0x00b), S(0x00c), S(0x00d), S(0x00e), S(0x00f), +S(0x010), S(0x011), S(0x012), S(0x013), S(0x014), S(0x015), S(0x016), S(0x017), +S(0x018), S(0x019), S(0x01a), S(0x01b), S(0x01c), S(0x01d), S(0x01e), S(0x01f), +S(0x020), S(0x021), S(0x022), S(0x023), S(0x024), S(0x025), S(0x026), S(0x027), +S(0x028), S(0x029), S(0x02a), S(0x02b), S(0x02c), S(0x02d), S(0x02e), S(0x02f), +S(0x030), S(0x031), S(0x032), S(0x033), S(0x034), S(0x035), S(0x036), S(0x037), +S(0x038), S(0x039), S(0x03a), S(0x03b), S(0x03c), S(0x03d), S(0x03e), S(0x03f), +S(0x040), S(0x041), S(0x042), S(0x043), S(0x044), S(0x045), S(0x046), S(0x047), +S(0x048), S(0x049), S(0x04a), S(0x04b), S(0x04c), S(0x04d), S(0x04e), S(0x04f), +S(0x050), S(0x051), S(0x052), S(0x053), S(0x054), S(0x055), S(0x056), S(0x057), +S(0x058), S(0x059), S(0x05a), S(0x05b), S(0x05c), S(0x05d), S(0x05e), S(0x05f), +S(0x060), S(0x061), S(0x062), S(0x063), S(0x064), S(0x065), S(0x066), S(0x067), +S(0x068), S(0x069), S(0x06a), S(0x06b), S(0x06c), S(0x06d), S(0x06e), S(0x06f), +S(0x070), S(0x071), S(0x072), S(0x073), S(0x074), S(0x075), S(0x076), S(0x077), +S(0x078), S(0x079), S(0x07a), S(0x07b), S(0x07c), S(0x07d), S(0x07e), S(0x07f), +S(0x080), S(0x081), S(0x082), S(0x083), S(0x084), S(0x085), S(0x086), S(0x087), +S(0x088), S(0x089), S(0x08a), S(0x08b), S(0x08c), S(0x08d), S(0x08e), S(0x08f), +S(0x090), S(0x091), S(0x092), S(0x093), S(0x094), S(0x095), S(0x096), S(0x097), +S(0x098), S(0x099), S(0x09a), S(0x09b), S(0x09c), S(0x09d), S(0x09e), S(0x09f), +S(0x0a0), S(0x0a1), S(0x0a2), S(0x0a3), S(0x0a4), S(0x0a5), S(0x0a6), S(0x0a7), +S(0x0a8), S(0x0a9), S(0x0aa), S(0x0ab), S(0x0ac), S(0x0ad), S(0x0ae), S(0x0af), +S(0x0b0), S(0x0b1), S(0x0b2), S(0x0b3), S(0x0b4), S(0x0b5), S(0x0b6), S(0x0b7), +S(0x0b8), S(0x0b9), S(0x0ba), S(0x0bb), S(0x0bc), S(0x0bd), S(0x0be), S(0x0bf), +S(0x0c0), S(0x0c1), S(0x0c2), S(0x0c3), S(0x0c4), S(0x0c5), S(0x0c6), S(0x0c7), +S(0x0c8), S(0x0c9), S(0x0ca), S(0x0cb), S(0x0cc), S(0x0cd), S(0x0ce), S(0x0cf), +S(0x0d0), S(0x0d1), S(0x0d2), S(0x0d3), S(0x0d4), S(0x0d5), S(0x0d6), S(0x0d7), +S(0x0d8), S(0x0d9), S(0x0da), S(0x0db), S(0x0dc), S(0x0dd), S(0x0de), S(0x0df), +S(0x0e0), S(0x0e1), S(0x0e2), S(0x0e3), S(0x0e4), S(0x0e5), S(0x0e6), S(0x0e7), +S(0x0e8), S(0x0e9), S(0x0ea), S(0x0eb), S(0x0ec), S(0x0ed), S(0x0ee), S(0x0ef), +S(0x0f0), S(0x0f1), S(0x0f2), S(0x0f3), S(0x0f4), S(0x0f5), S(0x0f6), S(0x0f7), +S(0x0f8), S(0x0f9), S(0x0fa), S(0x0fb), S(0x0fc), S(0x0fd), S(0x0fe), S(0x0ff), +S(0x100), S(0x101), S(0x102), S(0x103), S(0x104), S(0x105), S(0x106), S(0x107), +S(0x108), S(0x109), S(0x10a), S(0x10b), S(0x10c), S(0x10d), S(0x10e), S(0x10f), +S(0x110), S(0x111), S(0x112), S(0x113), S(0x114), S(0x115), S(0x116), S(0x117), +S(0x118), S(0x119), S(0x11a), S(0x11b), S(0x11c), S(0x11d), S(0x11e), S(0x11f), +S(0x120), S(0x121), S(0x122), S(0x123), S(0x124), S(0x125), S(0x126), S(0x127), +S(0x128), S(0x129), S(0x12a), S(0x12b), S(0x12c), S(0x12d), S(0x12e), S(0x12f), +S(0x130), S(0x131), S(0x132), S(0x133), S(0x134), S(0x135), S(0x136), S(0x137), +S(0x138), S(0x139), S(0x13a), S(0x13b), S(0x13c), S(0x13d), S(0x13e), S(0x13f), +S(0x140), S(0x141), S(0x142), S(0x143), S(0x144), S(0x145), S(0x146), S(0x147), +S(0x148), S(0x149), S(0x14a), S(0x14b), S(0x14c), S(0x14d), S(0x14e), S(0x14f), +S(0x150), S(0x151), S(0x152), S(0x153), S(0x154), S(0x155), S(0x156), S(0x157), +S(0x158), S(0x159), S(0x15a), S(0x15b), S(0x15c), S(0x15d), S(0x15e), S(0x15f), +S(0x160), S(0x161), S(0x162), S(0x163), S(0x164), S(0x165), S(0x166), S(0x167), +S(0x168), S(0x169), S(0x16a), S(0x16b), S(0x16c), S(0x16d), S(0x16e), S(0x16f), +S(0x170), S(0x171), S(0x172), S(0x173), S(0x174), S(0x175), S(0x176), S(0x177), +S(0x178), S(0x179), S(0x17a), S(0x17b), S(0x17c), S(0x17d), S(0x17e), S(0x17f), +S(0x180), S(0x181), S(0x182), S(0x183), S(0x184), S(0x185), S(0x186), S(0x187), +S(0x188), S(0x189), S(0x18a), S(0x18b), S(0x18c), S(0x18d), S(0x18e), S(0x18f), +S(0x190), S(0x191), S(0x192), S(0x193), S(0x194), S(0x195), S(0x196), S(0x197), +S(0x198), S(0x199), S(0x19a), S(0x19b), S(0x19c), S(0x19d), S(0x19e), S(0x19f), +S(0x1a0), S(0x1a1), S(0x1a2), S(0x1a3), S(0x1a4), S(0x1a5), S(0x1a6), S(0x1a7), +S(0x1a8), S(0x1a9), S(0x1aa), S(0x1ab), S(0x1ac), S(0x1ad), S(0x1ae), S(0x1af), +S(0x1b0), S(0x1b1), S(0x1b2), S(0x1b3), S(0x1b4), S(0x1b5), S(0x1b6), S(0x1b7), +S(0x1b8), S(0x1b9), S(0x1ba), S(0x1bb), S(0x1bc), S(0x1bd), S(0x1be), S(0x1bf), +S(0x1c0), S(0x1c1), S(0x1c2), S(0x1c3), S(0x1c4), S(0x1c5), S(0x1c6), S(0x1c7), +S(0x1c8), S(0x1c9), S(0x1ca), S(0x1cb), S(0x1cc), S(0x1cd), S(0x1ce), S(0x1cf), +S(0x1d0), S(0x1d1), S(0x1d2), S(0x1d3), S(0x1d4), S(0x1d5), S(0x1d6), S(0x1d7), +S(0x1d8), S(0x1d9), S(0x1da), S(0x1db), S(0x1dc), S(0x1dd), S(0x1de), S(0x1df), +S(0x1e0), S(0x1e1), S(0x1e2), S(0x1e3), S(0x1e4), S(0x1e5), S(0x1e6), S(0x1e7), +S(0x1e8), S(0x1e9), S(0x1ea), S(0x1eb), S(0x1ec), S(0x1ed), S(0x1ee), S(0x1ef), +S(0x1f0), S(0x1f1), S(0x1f2), S(0x1f3), S(0x1f4), S(0x1f5), S(0x1f6), S(0x1f7), +S(0x1f8), S(0x1f9), S(0x1fa), S(0x1fb), S(0x1fc), S(0x1fd), S(0x1fe), S(0x1ff), +S(0x200), S(0x201), S(0x202), S(0x203), S(0x204), S(0x205), S(0x206), S(0x207), +S(0x208), S(0x209), S(0x20a), S(0x20b), S(0x20c), S(0x20d), S(0x20e), S(0x20f), +S(0x210), S(0x211), S(0x212), S(0x213), S(0x214), S(0x215), S(0x216), S(0x217), +S(0x218), S(0x219), S(0x21a), S(0x21b), S(0x21c), S(0x21d), S(0x21e), S(0x21f), +S(0x220), S(0x221), S(0x222), S(0x223), S(0x224), S(0x225), S(0x226), S(0x227), +S(0x228), S(0x229), S(0x22a), S(0x22b), S(0x22c), S(0x22d), S(0x22e), S(0x22f), +S(0x230), S(0x231), S(0x232), S(0x233), S(0x234), S(0x235), S(0x236), S(0x237), +S(0x238), S(0x239), S(0x23a), S(0x23b), S(0x23c), S(0x23d), S(0x23e), S(0x23f), +S(0x240), S(0x241), S(0x242), S(0x243), S(0x244), S(0x245), S(0x246), S(0x247), +S(0x248), S(0x249), S(0x24a), S(0x24b), S(0x24c), S(0x24d), S(0x24e), S(0x24f), +S(0x250), S(0x251), S(0x252), S(0x253), S(0x254), S(0x255), S(0x256), S(0x257), +S(0x258), S(0x259), S(0x25a), S(0x25b), S(0x25c), S(0x25d), S(0x25e), S(0x25f), +S(0x260), S(0x261), S(0x262), S(0x263), S(0x264), S(0x265), S(0x266), S(0x267), +S(0x268), S(0x269), S(0x26a), S(0x26b), S(0x26c), S(0x26d), S(0x26e), S(0x26f), +S(0x270), S(0x271), S(0x272), S(0x273), S(0x274), S(0x275), S(0x276), S(0x277), +S(0x278), S(0x279), S(0x27a), S(0x27b), S(0x27c), S(0x27d), S(0x27e), S(0x27f), +S(0x280), S(0x281), S(0x282), S(0x283), S(0x284), S(0x285), S(0x286), S(0x287), +S(0x288), S(0x289), S(0x28a), S(0x28b), S(0x28c), S(0x28d), S(0x28e), S(0x28f), +S(0x290), S(0x291), S(0x292), S(0x293), S(0x294), S(0x295), S(0x296), S(0x297), +S(0x298), S(0x299), S(0x29a), S(0x29b), S(0x29c), S(0x29d), S(0x29e), S(0x29f), +S(0x2a0), S(0x2a1), S(0x2a2), S(0x2a3), S(0x2a4), S(0x2a5), S(0x2a6), S(0x2a7), +S(0x2a8), S(0x2a9), S(0x2aa), S(0x2ab), S(0x2ac), S(0x2ad), S(0x2ae), S(0x2af), +S(0x2b0), S(0x2b1), S(0x2b2), S(0x2b3), S(0x2b4), S(0x2b5), S(0x2b6), S(0x2b7), +S(0x2b8), S(0x2b9), S(0x2ba), S(0x2bb), S(0x2bc), S(0x2bd), S(0x2be), S(0x2bf), +S(0x2c0), S(0x2c1), S(0x2c2), S(0x2c3), S(0x2c4), S(0x2c5), S(0x2c6), S(0x2c7), +S(0x2c8), S(0x2c9), S(0x2ca), S(0x2cb), S(0x2cc), S(0x2cd), S(0x2ce), S(0x2cf), +S(0x2d0), S(0x2d1), S(0x2d2), S(0x2d3), S(0x2d4), S(0x2d5), S(0x2d6), S(0x2d7), +S(0x2d8), S(0x2d9), S(0x2da), S(0x2db), S(0x2dc), S(0x2dd), S(0x2de), S(0x2df), +S(0x2e0), S(0x2e1), S(0x2e2), S(0x2e3), S(0x2e4), S(0x2e5), S(0x2e6), S(0x2e7), +S(0x2e8), S(0x2e9), S(0x2ea), S(0x2eb), S(0x2ec), S(0x2ed), S(0x2ee), S(0x2ef), +S(0x2f0), S(0x2f1), S(0x2f2), S(0x2f3), S(0x2f4), S(0x2f5), S(0x2f6), S(0x2f7), +S(0x2f8), S(0x2f9), S(0x2fa), S(0x2fb), S(0x2fc), S(0x2fd), S(0x2fe), S(0x2ff), +S(0x300), S(0x301), S(0x302), S(0x303), S(0x304), S(0x305), S(0x306), S(0x307), +S(0x308), S(0x309), S(0x30a), S(0x30b), S(0x30c), S(0x30d), S(0x30e), S(0x30f), +S(0x310), S(0x311), S(0x312), S(0x313), S(0x314), S(0x315), S(0x316), S(0x317), +S(0x318), S(0x319), S(0x31a), S(0x31b), S(0x31c), S(0x31d), S(0x31e), S(0x31f), +S(0x320), S(0x321), S(0x322), S(0x323), S(0x324), S(0x325), S(0x326), S(0x327), +S(0x328), S(0x329), S(0x32a), S(0x32b), S(0x32c), S(0x32d), S(0x32e), S(0x32f), +S(0x330), S(0x331), S(0x332), S(0x333), S(0x334), S(0x335), S(0x336), S(0x337), +S(0x338), S(0x339), S(0x33a), S(0x33b), S(0x33c), S(0x33d), S(0x33e), S(0x33f), +S(0x340), S(0x341), S(0x342), S(0x343), S(0x344), S(0x345), S(0x346), S(0x347), +S(0x348), S(0x349), S(0x34a), S(0x34b), S(0x34c), S(0x34d), S(0x34e), S(0x34f), +S(0x350), S(0x351), S(0x352), S(0x353), S(0x354), S(0x355), S(0x356), S(0x357), +S(0x358), S(0x359), S(0x35a), S(0x35b), S(0x35c), S(0x35d), S(0x35e), S(0x35f), +S(0x360), S(0x361), S(0x362), S(0x363), S(0x364), S(0x365), S(0x366), S(0x367), +S(0x368), S(0x369), S(0x36a), S(0x36b), S(0x36c), S(0x36d), S(0x36e), S(0x36f), +S(0x370), S(0x371), S(0x372), S(0x373), S(0x374), S(0x375), S(0x376), S(0x377), +S(0x378), S(0x379), S(0x37a), S(0x37b), S(0x37c), S(0x37d), S(0x37e), S(0x37f), +S(0x380), S(0x381), S(0x382), S(0x383), S(0x384), S(0x385), S(0x386), S(0x387), +S(0x388), S(0x389), S(0x38a), S(0x38b), S(0x38c), S(0x38d), S(0x38e), S(0x38f), +S(0x390), S(0x391), S(0x392), S(0x393), S(0x394), S(0x395), S(0x396), S(0x397), +S(0x398), S(0x399), S(0x39a), S(0x39b), S(0x39c), S(0x39d), S(0x39e), S(0x39f), +S(0x3a0), S(0x3a1), S(0x3a2), S(0x3a3), S(0x3a4), S(0x3a5), S(0x3a6), S(0x3a7), +S(0x3a8), S(0x3a9), S(0x3aa), S(0x3ab), S(0x3ac), S(0x3ad), S(0x3ae), S(0x3af), +S(0x3b0), S(0x3b1), S(0x3b2), S(0x3b3), S(0x3b4), S(0x3b5), S(0x3b6), S(0x3b7), +S(0x3b8), S(0x3b9), S(0x3ba), S(0x3bb), S(0x3bc), S(0x3bd), S(0x3be), S(0x3bf), +S(0x3c0), S(0x3c1), S(0x3c2), S(0x3c3), S(0x3c4), S(0x3c5), S(0x3c6), S(0x3c7), +S(0x3c8), S(0x3c9), S(0x3ca), S(0x3cb), S(0x3cc), S(0x3cd), S(0x3ce), S(0x3cf), +S(0x3d0), S(0x3d1), S(0x3d2), S(0x3d3), S(0x3d4), S(0x3d5), S(0x3d6), S(0x3d7), +S(0x3d8), S(0x3d9), S(0x3da), S(0x3db), S(0x3dc), S(0x3dd), S(0x3de), S(0x3df), +S(0x3e0), S(0x3e1), S(0x3e2), S(0x3e3), S(0x3e4), S(0x3e5), S(0x3e6), S(0x3e7), +S(0x3e8), S(0x3e9), S(0x3ea), S(0x3eb), S(0x3ec), S(0x3ed), S(0x3ee), S(0x3ef), +S(0x3f0), S(0x3f1), S(0x3f2), S(0x3f3), S(0x3f4), S(0x3f5), S(0x3f6), S(0x3f7), +S(0x3f8), S(0x3f9), S(0x3fa), S(0x3fb), S(0x3fc), S(0x3fd), S(0x3fe), S(0x3ff) +}; +#endif /* MAKE_IDENTITY_MAP */ + +/* +** Kernel address mappings, present in every page table +*/ +mapping_t kmap[] = { + // va pa_start pa_end perms + { KERN_BASE, 0, EXT_BASE, PDE_RW }, + { KERN_VLINK, KERN_PLINK, V2P(_data), 0 }, + { (uint32_t) _data, V2P(_data), KERN_BASE, PDE_RW }, + { DEV_BASE, DEV_BASE, 0, PDE_RW } +}; +const uint_t n_kmap = sizeof(kmap) / sizeof(kmap[0]); diff --git a/lib/Make.mk b/lib/Make.mk new file mode 100644 index 0000000..2f8de2c --- /dev/null +++ b/lib/Make.mk @@ -0,0 +1,73 @@ +# +# Makefile fragment for the library components of the system. +# +# THIS IS NOT A COMPLETE Makefile - run GNU make in the top-level +# directory, and this will be pulled in automatically. +# + +SUBDIRS += lib + +################### +# FILES SECTION # +################### + +# +# library file lists +# + +# "common" library functions, used by kernel and users +CLIB_SRC := lib/bound.c lib/cvtdec.c lib/cvtdec0.c \ + lib/cvthex.c lib/cvtoct.c lib/cvtuns.c \ + lib/cvtuns0.c lib/memclr.c lib/memcpy.c \ + lib/memset.c lib/pad.c lib/padstr.c \ + lib/sprint.c lib/str2int.c lib/strcat.c \ + lib/strcmp.c lib/strcpy.c lib/strlen.c + +# user-only library functions +ULIB_SRC := lib/ulibc.c lib/ulibs.S lib/entry.S + +# kernel-only library functions +KLIB_SRC := lib/klibc.c + +# lists of object files +CLIB_OBJ:= $(patsubst lib/%.c, $(BUILDDIR)/lib/%.o, $(CLIB_SRC)) + +ULIB_OBJ:= $(patsubst lib/%.c, $(BUILDDIR)/lib/%.o, $(ULIB_SRC)) +ULIB_OBJ:= $(patsubst lib/%.S, $(BUILDDIR)/lib/%.o, $(ULIB_OBJ)) + +KLIB_OBJ := $(patsubst lib/%.c, $(BUILDDIR)/lib/%.o, $(KLIB_SRC)) +KLIB_OBJ := $(patsubst lib/%.S, $(BUILDDIR)/lib/%.o, $(KLIB_OBJ)) + +# library file names +CLIB_NAME := libcommon.a +ULIB_NAME := libuser.a +KLIB_NAME := libkernel.a + +################### +# RULES SECTION # +################### + +# how to make everything +lib: $(BUILDDIR)/lib/$(CLIB_NAME) \ + $(BUILDDIR)/lib/$(KLIB_NAME) \ + $(BUILDDIR)/lib/$(ULIB_NAME) + +$(BUILDDIR)/lib/%.o: lib/%.c $(BUILDDIR)/.vars.CFLAGS + @mkdir -p $(@D) + $(CC) $(CFLAGS) -c -o $@ $< + +$(BUILDDIR)/lib/%.o: lib/%.S $(BUILDDIR)/.vars.CFLAGS + @mkdir -p $(@D) + $(CPP) $(CPPFLAGS) -o $(@D)/$*.s $< + $(AS) $(ASFLAGS) -o $@ $(@D)/$*.s -a=$(@D)/$*.lst + $(RM) -f $(@D)/$*.s + $(NM) -n $@ > $(@D)/$*.sym + +$(BUILDDIR)/lib/$(CLIB_NAME): $(CLIB_OBJ) + $(AR) $(ARFLAGS) $@ $(CLIB_OBJ) + +$(BUILDDIR)/lib/$(ULIB_NAME): $(ULIB_OBJ) + $(AR) $(ARFLAGS) $@ $(ULIB_OBJ) + +$(BUILDDIR)/lib/$(KLIB_NAME): $(KLIB_OBJ) + $(AR) $(ARFLAGS) $@ $(KLIB_OBJ) diff --git a/lib/bound.c b/lib/bound.c new file mode 100644 index 0000000..f086473 --- /dev/null +++ b/lib/bound.c @@ -0,0 +1,37 @@ +/** +** @file bound.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +*/ + +#ifndef BOUND_SRC_INC +#define BOUND_SRC_INC + +#include <common.h> + +#include <lib.h> + +/** +** bound(min,value,max) +** +** This function confines an argument within specified bounds. +** +** @param min Lower bound +** @param value Value to be constrained +** @param max Upper bound +** +** @return The constrained value +*/ +uint32_t bound( uint32_t min, uint32_t value, uint32_t max ) { + if( value < min ){ + value = min; + } + if( value > max ){ + value = max; + } + return value; +} + +#endif diff --git a/lib/cvtdec.c b/lib/cvtdec.c new file mode 100644 index 0000000..216f147 --- /dev/null +++ b/lib/cvtdec.c @@ -0,0 +1,43 @@ +/** +** @file cvtdec.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +*/ + +#ifndef CVTDEC_SRC_INC +#define CVTDEC_SRC_INC + +#include <common.h> + +#include <lib.h> + +/** +** cvtdec(buf,value) +** +** convert a 32-bit signed value into a NUL-terminated character string +** +** @param buf Destination buffer +** @param value Value to convert +** +** @return The number of characters placed into the buffer +** (not including the NUL) +** +** NOTE: assumes buf is large enough to hold the resulting string +*/ +int cvtdec( char *buf, int32_t value ) { + char *bp = buf; + + if( value < 0 ) { + *bp++ = '-'; + value = -value; + } + + bp = cvtdec0( bp, value ); + *bp = '\0'; + + return( bp - buf ); +} + +#endif diff --git a/lib/cvtdec0.c b/lib/cvtdec0.c new file mode 100644 index 0000000..87792e0 --- /dev/null +++ b/lib/cvtdec0.c @@ -0,0 +1,44 @@ +/** +** @file cvtdec0.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +*/ + +#ifndef CVTDEC0_SRC_INC +#define CVTDEC0_SRC_INC + +#include <common.h> + +#include <lib.h> + +/** +** cvtdec0(buf,value) - local support routine for cvtdec() +** +** convert a 32-bit unsigned integer into a NUL-terminated character string +** +** @param buf Destination buffer +** @param value Value to convert +** +** @return The number of characters placed into the buffer +** (not including the NUL) +** +** NOTE: assumes buf is large enough to hold the resulting string +*/ +char *cvtdec0( char *buf, int value ) { + int quotient; + + quotient = value / 10; + if( quotient < 0 ) { + quotient = 214748364; + value = 8; + } + if( quotient != 0 ) { + buf = cvtdec0( buf, quotient ); + } + *buf++ = value % 10 + '0'; + return buf; +} + +#endif diff --git a/lib/cvthex.c b/lib/cvthex.c new file mode 100644 index 0000000..5f3da19 --- /dev/null +++ b/lib/cvthex.c @@ -0,0 +1,49 @@ +/** +** @file cvthex.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +*/ + +#ifndef CVTHEX_SRC_INC +#define CVTHEX_SRC_INC + +#include <common.h> + +#include <lib.h> + +/** +** cvthex(buf,value) +** +** convert a 32-bit unsigned value into a minimal-length (up to +** 8-character) NUL-terminated character string +** +** @param buf Destination buffer +** @param value Value to convert +** +** @return The number of characters placed into the buffer +** (not including the NUL) +** +** NOTE: assumes buf is large enough to hold the resulting string +*/ +int cvthex( char *buf, uint32_t value ) { + const char hexdigits[] = "0123456789ABCDEF"; + int chars_stored = 0; + + for( int i = 0; i < 8; i += 1 ) { + uint32_t val = value & 0xf0000000; + if( chars_stored || val != 0 || i == 7 ) { + ++chars_stored; + val = (val >> 28) & 0xf; + *buf++ = hexdigits[val]; + } + value <<= 4; + } + + *buf = '\0'; + + return( chars_stored ); +} + +#endif diff --git a/lib/cvtoct.c b/lib/cvtoct.c new file mode 100644 index 0000000..dafd8ff --- /dev/null +++ b/lib/cvtoct.c @@ -0,0 +1,54 @@ +/** +** @file cvtoct.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +*/ + +#ifndef CVTOCT_SRC_INC +#define CVTOCT_SRC_INC + +#include <common.h> + +#include <lib.h> + +/** +** cvtoct(buf,value) +** +** convert a 32-bit unsigned value into a mininal-length (up to +** 11-character) NUL-terminated character string +** +** @param buf Destination buffer +** @param value Value to convert +** +** @return The number of characters placed into the buffer +** (not including the NUL) +** +** NOTE: assumes buf is large enough to hold the resulting string +*/ +int cvtoct( char *buf, uint32_t value ) { + int i; + int chars_stored = 0; + char *bp = buf; + uint32_t val; + + val = ( value & 0xc0000000 ); + val >>= 30; + for( i = 0; i < 11; i += 1 ){ + + if( i == 10 || val != 0 || chars_stored ) { + chars_stored = 1; + val &= 0x7; + *bp++ = val + '0'; + } + value <<= 3; + val = ( value & 0xe0000000 ); + val >>= 29; + } + *bp = '\0'; + + return bp - buf; +} + +#endif diff --git a/lib/cvtuns.c b/lib/cvtuns.c new file mode 100644 index 0000000..a0a686a --- /dev/null +++ b/lib/cvtuns.c @@ -0,0 +1,37 @@ +/** +** @file cvtuns.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +*/ + +#ifndef CVTUNS_SRC_INC +#define CVTUNS_SRC_INC + +#include <common.h> + +#include <lib.h> + +/** +** cvtuns(buf,value) +** +** Convert a 32-bit unsigned value into a NUL-terminated character string +** +** @param buf Result buffer +** @param value Value to be converted +** +** @return Length of the resulting buffer +** +** NOTE: assumes buf is large enough to hold the resulting string +*/ +int cvtuns( char *buf, uint32_t value ) { + char *bp = buf; + + bp = cvtuns0( bp, value ); + *bp = '\0'; + + return bp - buf; +} + +#endif diff --git a/lib/cvtuns0.c b/lib/cvtuns0.c new file mode 100644 index 0000000..6a63573 --- /dev/null +++ b/lib/cvtuns0.c @@ -0,0 +1,39 @@ +/** +** @file cvtuns0.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +*/ + +#ifndef CVTUNS0_SRC_INC +#define CVTUNS0_SRC_INC + +#include <common.h> + +#include <lib.h> + +/** +** cvtuns0(buf,value) - local support routine for cvtuns() +** +** Convert a 32-bit unsigned value into a NUL-terminated character string +** +** @param buf Result buffer +** @param value Value to be converted +** +** @return Pointer to the first unused byte in the buffer +** +** NOTE: assumes buf is large enough to hold the resulting string +*/ +char *cvtuns0( char *buf, uint32_t value ) { + uint32_t quotient; + + quotient = value / 10; + if( quotient != 0 ){ + buf = cvtdec0( buf, quotient ); + } + *buf++ = value % 10 + '0'; + return buf; +} + +#endif diff --git a/lib/entry.S b/lib/entry.S new file mode 100644 index 0000000..87ad9c7 --- /dev/null +++ b/lib/entry.S @@ -0,0 +1,25 @@ +// +// user-level startup routine +// + .text + .globl _start + .globl main + .globl exit + +// entry point - this is where the kernel starts us running +_start: + // we immediately call main() + call main + + // if we come back from that, it means the user + // program didn't call exit(), in which case the + // value returned from main() is the exit status + + // push that value onto the stack and call exit() + subl $12, %esp + pushl %eax + call exit + + // if we come back from that, something bad has + // happened, so we just lock up +1: jmp 1b diff --git a/lib/klibc.c b/lib/klibc.c new file mode 100644 index 0000000..ded0c78 --- /dev/null +++ b/lib/klibc.c @@ -0,0 +1,112 @@ +/* +** @file klibc.c +** +** @author Warren R. Carithers +** +** Additional support functions for the kernel. +** +*/ + +#define KERNEL_SRC + +#include <klib.h> +#include <cio.h> +#include <procs.h> +#include <support.h> + +/** +** Name: put_char_or_code( ch ) +** +** Description: Prints a character on the console, unless it +** is a non-printing character, in which case its hex code +** is printed +** +** @param ch The character to be printed +*/ +void put_char_or_code( int ch ) { + + if( ch >= ' ' && ch < 0x7f ) { + cio_putchar( ch ); + } else { + cio_printf( "\\x%02x", ch ); + } +} + +/** +** Name: backtrace +** +** Perform a stack backtrace +** +** @param ebp Initial EBP to use +** @param args Number of function argument values to print +*/ +void backtrace( uint32_t *ebp, uint_t args ) { + + cio_puts( "Trace: " ); + if( ebp == NULL ) { + cio_puts( "NULL ebp, no trace possible\n" ); + return; + } else { + cio_putchar( '\n' ); + } + + while( ebp != NULL ){ + + // get return address and report it and EBP + uint32_t ret = ebp[1]; + cio_printf( " ebp %08x ret %08x args", (uint32_t) ebp, ret ); + + // print the requested number of function arguments + for( uint_t i = 0; i < args; ++i ) { + cio_printf( " [%u] %08x", i+1, ebp[2+i] ); + } + cio_putchar( '\n' ); + + // follow the chain + ebp = (uint32_t *) *ebp; + } +} + +/** +** kpanic - kernel-level panic routine +** +** usage: kpanic( msg ) +** +** Prefix routine for panic() - can be expanded to do other things +** (e.g., printing a stack traceback) +** +** @param msg[in] String containing a relevant message to be printed, +** or NULL +*/ +void kpanic( const char *msg ) { + + cio_puts( "\n\n***** KERNEL PANIC *****\n\n" ); + + if( msg ) { + cio_printf( "%s\n", msg ); + } + + delay( DELAY_5_SEC ); // approximately + + // dump a bunch of potentially useful information + + // dump the contents of the current PCB + pcb_dump( "Current", current, true ); + + // dump the basic info about what's in the process table + ptable_dump_counts(); + + // dump information about the queues + pcb_queue_dump( "R", ready, true ); + pcb_queue_dump( "W", waiting, true ); + pcb_queue_dump( "S", sleeping, true ); + pcb_queue_dump( "Z", zombie, true ); + pcb_queue_dump( "I", sioread, true ); + + // perform a stack backtrace + backtrace( (uint32_t *) r_ebp(), 3 ); + + // could dump other stuff here, too + + panic( "KERNEL PANIC" ); +} diff --git a/lib/memclr.c b/lib/memclr.c new file mode 100644 index 0000000..490fc6d --- /dev/null +++ b/lib/memclr.c @@ -0,0 +1,37 @@ +/** +** @file memclr.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +*/ + +#ifndef MEMCLR_SRC_INC +#define MEMCLR_SRC_INC + +#include <common.h> + +#include <lib.h> + +/** +** memclr(buf,len) +** +** Initialize all bytes of a block of memory to zero +** +** @param buf The buffer to initialize +** @param len Buffer size (in bytes) +*/ +void memclr( void *buf, register uint32_t len ) { + register uint8_t *dest = buf; + + /* + ** We could speed this up by unrolling it and clearing + ** words at a time (instead of bytes). + */ + + while( len-- ) { + *dest++ = 0; + } +} + +#endif diff --git a/lib/memcpy.c b/lib/memcpy.c new file mode 100644 index 0000000..e5add26 --- /dev/null +++ b/lib/memcpy.c @@ -0,0 +1,41 @@ +/** +** @file memcpy.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +*/ + +#ifndef MEMCPY_SRC_INC +#define MEMCPY_SRC_INC + +#include <common.h> + +#include <lib.h> + +/** +** memcpy(dst,src,len) +** +** Copy a block from one place to another +** +** May not correctly deal with overlapping buffers +** +** @param dst Destination buffer +** @param src Source buffer +** @param len Buffer size (in bytes) +*/ +void memcpy( void *dst, register const void *src, register uint32_t len ) { + register uint8_t *dest = dst; + register const uint8_t *source = src; + + /* + ** We could speed this up by unrolling it and copying + ** words at a time (instead of bytes). + */ + + while( len-- ) { + *dest++ = *source++; + } +} + +#endif diff --git a/lib/memset.c b/lib/memset.c new file mode 100644 index 0000000..a93815c --- /dev/null +++ b/lib/memset.c @@ -0,0 +1,38 @@ +/** +** @file memset.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +*/ + +#ifndef MEMSET_SRC_INC +#define MEMSET_SRC_INC + +#include <common.h> + +#include <lib.h> + +/** +** memset(buf,len,value) +** +** initialize all bytes of a block of memory to a specific value +** +** @param buf The buffer to initialize +** @param len Buffer size (in bytes) +** @param value Initialization value +*/ +void memset( void *buf, register uint32_t len, register uint32_t value ) { + register uint8_t *bp = buf; + + /* + ** We could speed this up by unrolling it and copying + ** words at a time (instead of bytes). + */ + + while( len-- ) { + *bp++ = value; + } +} + +#endif diff --git a/lib/pad.c b/lib/pad.c new file mode 100644 index 0000000..5220c99 --- /dev/null +++ b/lib/pad.c @@ -0,0 +1,35 @@ +/** +** @file pad.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +*/ + +#ifndef PAD_SRC_INC +#define PAD_SRC_INC + +#include <common.h> + +#include <lib.h> + +/** +** pad(dst,extra,padchar) - generate a padding string +** +** @param dst Pointer to where the padding should begin +** @param extra How many padding bytes to add +** @param padchar What character to pad with +** +** @return Pointer to the first byte after the padding +** +** NOTE: does NOT NUL-terminate the buffer +*/ +char *pad( char *dst, int extra, int padchar ) { + while( extra > 0 ){ + *dst++ = (char) padchar; + extra -= 1; + } + return dst; +} + +#endif diff --git a/lib/padstr.c b/lib/padstr.c new file mode 100644 index 0000000..b83229f --- /dev/null +++ b/lib/padstr.c @@ -0,0 +1,61 @@ +/** +** @file padstr.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +*/ + +#ifndef PADSTR_SRC_INC +#define PADSTR_SRC_INC + +#include <common.h> + +#include <lib.h> + +/** +** padstr(dst,str,len,width,leftadjust,padchar - add padding characters +** to a string +** +** @param dst The destination buffer +** @param str The string to be padded +** @param len The string length, or -1 +** @param width The desired final length of the string +** @param leftadjust Should the string be left-justified? +** @param padchar What character to pad with +** +** @return Pointer to the first byte after the padded string +** +** NOTE: does NOT NUL-terminate the buffer +*/ +char *padstr( char *dst, char *str, int len, int width, + int leftadjust, int padchar ) { + int extra; + + // determine the length of the string if we need to + if( len < 0 ){ + len = strlen( str ); + } + + // how much filler must we add? + extra = width - len; + + // add filler on the left if we're not left-justifying + if( extra > 0 && !leftadjust ){ + dst = pad( dst, extra, padchar ); + } + + // copy the string itself + for( int i = 0; i < len; ++i ) { + *dst++ = str[i]; + } + + // add filler on the right if we are left-justifying + if( extra > 0 && leftadjust ){ + dst = pad( dst, extra, padchar ); + } + + return dst; +} + +#endif diff --git a/lib/sprint.c b/lib/sprint.c new file mode 100644 index 0000000..d2e0a7e --- /dev/null +++ b/lib/sprint.c @@ -0,0 +1,133 @@ +/** +** @file sprint.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +*/ + +#ifndef SPRINT_SRC_INC +#define SPRINT_SRC_INC + +#include <common.h> + +#include <lib.h> + +/** +** sprint(dst,fmt,...) - formatted output into a string buffer +** +** @param dst The string buffer +** @param fmt Format string +** +** The format string parameter is followed by zero or more additional +** parameters which are interpreted according to the format string. +** +** NOTE: assumes the buffer is large enough to hold the result string +** +** NOTE: relies heavily on the x86 parameter passing convention +** (parameters are pushed onto the stack in reverse order as +** 32-bit values). +*/ +void sprint( char *dst, char *fmt, ... ) { + int32_t *ap; + char buf[ 12 ]; + char ch; + char *str; + int leftadjust; + int width; + int len; + int padchar; + + /* + ** Get characters from the format string and process them + ** + ** We use the "old-school" method of handling variable numbers + ** of parameters. We assume that parameters are passed on the + ** runtime stack in consecutive longwords; thus, if the first + ** parameter is at location 'x', the second is at 'x+4', the + ** third at 'x+8', etc. We use a pointer to a 32-bit thing + ** to point to the next "thing", and interpret it according + ** to the format string. + */ + + // get the pointer to the first "value" parameter + ap = (int *)(&fmt) + 1; + + // iterate through the format string + while( (ch = *fmt++) != '\0' ){ + /* + ** Is it the start of a format code? + */ + if( ch == '%' ){ + /* + ** Yes, get the padding and width options (if there). + ** Alignment must come at the beginning, then fill, + ** then width. + */ + leftadjust = 0; + padchar = ' '; + width = 0; + ch = *fmt++; + if( ch == '-' ){ + leftadjust = 1; + ch = *fmt++; + } + if( ch == '0' ){ + padchar = '0'; + ch = *fmt++; + } + while( ch >= '0' && ch <= '9' ){ + width *= 10; + width += ch - '0'; + ch = *fmt++; + } + + /* + ** What data type do we have? + */ + switch( ch ) { + + case 'c': // characters are passed as 32-bit values + ch = *ap++; + buf[ 0 ] = ch; + buf[ 1 ] = '\0'; + dst = padstr( dst, buf, 1, width, leftadjust, padchar ); + break; + + case 'd': + len = cvtdec( buf, *ap++ ); + dst = padstr( dst, buf, len, width, leftadjust, padchar ); + break; + + case 's': + str = (char *) (*ap++); + dst = padstr( dst, str, -1, width, leftadjust, padchar ); + break; + + case 'x': + len = cvthex( buf, *ap++ ); + dst = padstr( dst, buf, len, width, leftadjust, padchar ); + break; + + case 'o': + len = cvtoct( buf, *ap++ ); + dst = padstr( dst, buf, len, width, leftadjust, padchar ); + break; + + case 'u': + len = cvtuns( buf, *ap++ ); + dst = padstr( dst, buf, len, width, leftadjust, padchar ); + break; + + } + } else { + // no, it's just an ordinary character + *dst++ = ch; + } + } + + // NUL-terminate the result + *dst = '\0'; +} + +#endif diff --git a/lib/str2int.c b/lib/str2int.c new file mode 100644 index 0000000..c0f777d --- /dev/null +++ b/lib/str2int.c @@ -0,0 +1,51 @@ +/** +** @file str2int.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +*/ + +#ifndef STR2INT_SRC_INC +#define STR2INT_SRC_INC + +#include <common.h> + +#include <lib.h> + +/** +** str2int(str,base) - convert a string to a number in the specified base +** +** @param str The string to examine +** @param base The radix to use in the conversion +** +** @return The converted integer +*/ +int str2int( register const char *str, register int base ) { + register int num = 0; + register char bchar = '9'; + int sign = 1; + + // check for leading '-' + if( *str == '-' ) { + sign = -1; + ++str; + } + + if( base != 10 ) { + bchar = '0' + base - 1; + } + + // iterate through the characters + while( *str ) { + if( *str < '0' || *str > bchar ) + break; + num = num * base + *str - '0'; + ++str; + } + + // return the converted value + return( num * sign ); +} + +#endif diff --git a/lib/strcat.c b/lib/strcat.c new file mode 100644 index 0000000..b0a8726 --- /dev/null +++ b/lib/strcat.c @@ -0,0 +1,38 @@ +/** +** @file strcat.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +*/ + +#ifndef STRCAT_SRC_INC +#define STRCAT_SRC_INC + +#include <common.h> + +#include <lib.h> + +/** +** strcat(dst,src) - append one string to another +** +** @param dst The destination buffer +** @param src The source buffer +** +** @return The dst parameter +** +** NOTE: assumes dst is large enough to hold the resulting string +*/ +char *strcat( register char *dst, register const char *src ) { + register char *tmp = dst; + + while( *dst ) // find the NUL + ++dst; + + while( (*dst++ = *src++) ) // append the src string + ; + + return( tmp ); +} + +#endif diff --git a/lib/strcmp.c b/lib/strcmp.c new file mode 100644 index 0000000..c59f4f7 --- /dev/null +++ b/lib/strcmp.c @@ -0,0 +1,32 @@ +/** +** @file strcmp.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +*/ + +#ifndef STRCMP_SRC_INC +#define STRCMP_SRC_INC + +#include <common.h> + +#include <lib.h> + +/** +** strcmp(s1,s2) - compare two NUL-terminated strings +** +** @param s1 The first source string +** @param s2 The second source string +** +** @return negative if s1 < s2, zero if equal, and positive if s1 > s2 +*/ +int strcmp( register const char *s1, register const char *s2 ) { + + while( *s1 != 0 && (*s1 == *s2) ) + ++s1, ++s2; + + return( *s1 - *s2 ); +} + +#endif diff --git a/lib/strcpy.c b/lib/strcpy.c new file mode 100644 index 0000000..036e4be --- /dev/null +++ b/lib/strcpy.c @@ -0,0 +1,35 @@ +/** +** @file strcpy.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +*/ + +#ifndef STRCPY_SRC_INC +#define STRCPY_SRC_INC + +#include <common.h> + +#include <lib.h> + +/** +** strcpy(dst,src) - copy a NUL-terminated string +** +** @param dst The destination buffer +** @param src The source buffer +** +** @return The dst parameter +** +** NOTE: assumes dst is large enough to hold the copied string +*/ +char *strcpy( register char *dst, register const char *src ) { + register char *tmp = dst; + + while( (*dst++ = *src++) ) + ; + + return( tmp ); +} + +#endif diff --git a/lib/strlen.c b/lib/strlen.c new file mode 100644 index 0000000..b41fe69 --- /dev/null +++ b/lib/strlen.c @@ -0,0 +1,32 @@ +/** +** @file strlen.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +*/ + +#ifndef STRLEN_SRC_INC +#define STRLEN_SRC_INC + +#include <common.h> + +#include <lib.h> + +/** +** strlen(str) - return length of a NUL-terminated string +** +** @param str The string to examine +** +** @return The length of the string, or 0 +*/ +uint32_t strlen( register const char *str ) { + register uint32_t len = 0; + + while( *str++ ) { + ++len; + } + + return( len ); +} +#endif diff --git a/lib/ulibc.c b/lib/ulibc.c new file mode 100644 index 0000000..f3783a4 --- /dev/null +++ b/lib/ulibc.c @@ -0,0 +1,162 @@ +/** +** @file ulibc.c +** +** @author CSCI-452 class of 20245 +** +** @brief C implementations of user-level library functions +*/ + +#include <common.h> + +/* +** PRIVATE DEFINITIONS +*/ + +/* +** PRIVATE DATA TYPES +*/ + +/* +** PRIVATE GLOBAL VARIABLES +*/ + +/* +** PUBLIC GLOBAL VARIABLES +*/ + +/* +** PRIVATE FUNCTIONS +*/ + +/* +** PUBLIC FUNCTIONS +*/ + +/* +********************************************** +** CONVENIENT "SHORTHAND" VERSIONS OF SYSCALLS +********************************************** +*/ + +/** +** wait - wait for any child to exit +** +** usage: pid = wait(&status) +** +** Calls waitpid(0,status) +** +** @param status Pointer to int32_t into which the child's status is placed, +** or NULL +** +** @returns The PID of the terminated child, or an error code +*/ +int wait( int32_t *status ) { + return( waitpid(0,status) ); +} + +/** +** spawn - create a new process running a different program +** +** usage: pid = spawn(what,args); +** +** Creates a new process and then execs 'what' +** +** @param what The program table index of the program to spawn +** @param args The command-line argument vector for the new process +** +** @returns PID of the new process, or an error code +*/ +int32_t spawn( uint_t what, char **args ) { + int32_t pid; + char buf[256]; + + pid = fork(); + if( pid != 0 ) { + // failure, or we are the parent + return( pid ); + } + + // we are the child + pid = getpid(); + + // child inherits parent's priority level + + exec( what, args ); + + // uh-oh.... + + sprint( buf, "Child %d exec() #%u failed\n", pid, what ); + cwrites( buf ); + + exit( EXIT_FAILURE ); + return( 0 ); // shut the compiler up +} + +/** +** cwritech(ch) - write a single character to the console +** +** @param ch The character to write +** +** @returns The return value from calling write() +*/ +int cwritech( char ch ) { + return( write(CHAN_CIO,&ch,1) ); +} + +/** +** cwrites(str) - write a NUL-terminated string to the console +** +** @param str The string to write +** +*/ +int cwrites( const char *str ) { + int len = strlen(str); + return( write(CHAN_CIO,str,len) ); +} + +/** +** cwrite(buf,size) - write a sized buffer to the console +** +** @param buf The buffer to write +** @param size The number of bytes to write +** +** @returns The return value from calling write() +*/ +int cwrite( const char *buf, uint32_t size ) { + return( write(CHAN_CIO,buf,size) ); +} + +/** +** swritech(ch) - write a single character to the SIO +** +** @param ch The character to write +** +** @returns The return value from calling write() +*/ +int swritech( char ch ) { + return( write(CHAN_SIO,&ch,1) ); +} + +/** +** swrites(str) - write a NUL-terminated string to the SIO +** +** @param str The string to write +** +** @returns The return value from calling write() +*/ +int swrites( const char *str ) { + int len = strlen(str); + return( write(CHAN_SIO,str,len) ); +} + +/** +** swrite(buf,size) - write a sized buffer to the SIO +** +** @param buf The buffer to write +** @param size The number of bytes to write +** +** @returns The return value from calling write() +*/ +int swrite( const char *buf, uint32_t size ) { + return( write(CHAN_SIO,buf,size) ); +} diff --git a/lib/ulibs.S b/lib/ulibs.S new file mode 100644 index 0000000..46fcb89 --- /dev/null +++ b/lib/ulibs.S @@ -0,0 +1,93 @@ +/** +** @file ulibs.S +** +** @author CSCI-452 class of 20245 +** +** @brief assembly-language user-level library functions +*/ + +#define ASM_SRC + +// get the system call codes + +#include <syscalls.h> + +/** +** System call stubs +** +** All have the same structure: +** +** move a code into EAX +** generate the interrupt +** return to the caller +** +** As these are simple "leaf" routines, we don't use +** the standard enter/leave method to set up a stack +** frame - that takes time, and we don't really need it. +** +** Could be modified to use the UNIX/Linux convention of +** having the syscall code set the 'C' flag to indicate that +** the value being returned in %EAX is an error code: +** +** ... +** int $VEC_SYSCALL +** jc set_errno +** ret +** ... +** +** .globl errno +** set_errno: +** movl %eax, errno +** movl $-1, %eax +** ret +*/ + +#define SYSCALL(name) \ + .globl name ; \ +name: ; \ + movl $SYS_##name, %eax ; \ + int $VEC_SYSCALL ; \ + ret + +/* +** "real" system calls +*/ + +SYSCALL(exit) +SYSCALL(waitpid) +SYSCALL(fork) +SYSCALL(exec) +SYSCALL(read) +SYSCALL(write) +SYSCALL(getpid) +SYSCALL(getppid) +SYSCALL(gettime) +SYSCALL(getprio) +SYSCALL(setprio) +SYSCALL(kill) +SYSCALL(sleep) + +/* +** This is a bogus system call; it's here so that we can test +** our handling of out-of-range syscall codes in the syscall ISR. +*/ +SYSCALL(bogus) + +/* +** Other library functions +*/ + +/** +** fake_exit() +** +** Dummy "startup" function +** +** calls exit(%eax) - serves as the "return to" code for +** main() functions, in case they don't call exit() themselves +*/ + + .globl fake_exit +fake_exit: + // alternate: could push a "fake exit" status + pushl %eax // termination status returned by main() + call exit // terminate this process diff --git a/user/Make.mk b/user/Make.mk new file mode 100644 index 0000000..648de69 --- /dev/null +++ b/user/Make.mk @@ -0,0 +1,64 @@ +# +# Makefile fragment for the user components of the system. +# +# THIS IS NOT A COMPLETE Makefile - run GNU make in the top-level +# directory, and this will be pulled in automatically. +# + +SUBDIRS += user + +################### +# FILES SECTION # +################### + +# order here must match the order of program names in the +# 'user_e' enum defined in include/userids.h!!! +USER_SRC := user/init.c user/idle.c user/shell.c \ + user/progABC.c user/progDE.c user/progFG.c user/progH.c \ + user/progI.c user/progJ.c user/progKL.c user/progMN.c \ + user/progP.c user/progQ.c user/progR.c user/progS.c \ + user/progTUV.c user/progW.c user/progX.c user/progY.c \ + user/progZ.c + +USER_OBJ := $(patsubst %.c, $(BUILDDIR)/%.o, $(USER_SRC)) + +USER_BIN := $(basename $(USER_SRC)) +USER_BIN := $(addprefix $(BUILDDIR)/, $(USER_BIN)) + +ULDFLAGS := -T user/user.ld +ULIBS := -luser -lcommon + +################### +# RULES SECTION # +################### + +userland: $(USER_BIN) + +$(BUILDDIR)/user/%.o: user/%.c $(BUILDDIR)/.vars.CFLAGS + @mkdir -p $(@D) + $(CC) $(CFLAGS) -c -o $@ $< + +$(BUILDDIR)/user/%: $(BUILDDIR)/user/%.o + @mkdir -p $(@D) + $(LD) $(ULDFLAGS) $(LDFLAGS) -o $@ $@.o $(ULIBS) + $(OBJDUMP) -S $@ > $@.asm + $(NM) -n $@ > $@.sym + $(READELF) -a $@ > $@.info + +# +# Remake the "user blob". When this happens, we also generate a new +# version of the userids.h header file; we don't copy it over the +# previous version if it is the same, to avoid triggering remakes +# of the rest of the system. +# +user.img: $(USR_BIN) mkblob + ./mkblob $(USER_BIN) + @./listblob -e $@ > $(BUILDDIR)/new_userids.h + -@sh -c 'cmp -s include/userids.h $(BUILDDIR)/new_userids.h || \ + (cp $(BUILDDIR)/new_userids.h include/userids.h; \ + echo "\n*** NOTE - updated include/userids.h, rebuild\!" ; \ + rm -f $(BUILDDIR)/new_userids.h)' + +# some debugging assist rules +user.hex: user.img + hexdump -C $< > $@ diff --git a/user/README b/user/README new file mode 100644 index 0000000..548aac4 --- /dev/null +++ b/user/README @@ -0,0 +1,25 @@ +This directory contains the source code for all user-level processes, +split out by main function. + +Naming convention: + + idle() classic 'idle' process; ensures there is always a + runnable process to dispatch (vs., for instance, having + dispatch() pause when there is nothing to dispatch). + + init() classic 'init' process; starts the idle process, and + starts (and restarts) the user shell program. + + shell() "user shell" process, for spawning individual tests + + progN() program source code for user process(es) 'N' + +All of these expect at least one command-line argument. All are invoked +with command lines of this form: + + name x n + +Each of these is designed to be compiled and linked separately, with the +resulting load modules bundled into a blob for automatic loading by the +bootstrap. Each will typically use one or more library functions from the +../lib directory. diff --git a/user/idle.c b/user/idle.c new file mode 100644 index 0000000..dbce885 --- /dev/null +++ b/user/idle.c @@ -0,0 +1,51 @@ +#include <common.h> + +/** +** Idle process: write, getpid, gettime, exit +** +** Reports itself, then loops forever delaying and printing a character. +** MUST NOT SLEEP, as it must always be available in the ready queue +** when there is no other process to dispatch. +** +** Invoked as: idle +*/ + +USERMAIN( main ) { + // this is the character we will repeatedly print + char ch = '.'; + + // ignore the command-line arguments + (void) argc; + (void) argv; + + // get some current information + uint_t pid = getpid(); + uint32_t now = gettime(); + enum priority_e prio = getprio(); + + char buf[128]; + sprint( buf, "Idle [%d], started @ %u\n", pid, prio, now ); + cwrites( buf ); + + // report our presence on the console + cwrites( "Idle started\n" ); + + write( CHAN_SIO, &ch, 1 ); + + // idle() should never block - it must always be available + // for dispatching when we need to pick a new current process + + for(;;) { + DELAY(LONG); + write( CHAN_SIO, &ch, 1 ); + } + + // we should never reach this point! + now = gettime(); + sprint( buf, "Idle [%d] EXITING @ %u!?!?!\n", pid, now ); + cwrites( buf ); + + exit( 1 ); + + return( 42 ); +} diff --git a/user/init.c b/user/init.c new file mode 100644 index 0000000..56330b1 --- /dev/null +++ b/user/init.c @@ -0,0 +1,185 @@ +#include <common.h> + +/** +** Initial process; it starts the other top-level user processes. +** +** Prints a message at startup, '+' after each user process is spawned, +** and '!' before transitioning to wait() mode to the SIO, and +** startup and transition messages to the console. It also reports +** each child process it collects via wait() to the console along +** with that child's exit status. +*/ + +/* +** "Spawn table" process entry. Similar to the one in shell.c, but +** this version has a field to hold the PID of the spawned process +** to allow 'init' to respawn it when it terminates. +*/ +typedef struct proc_s { + uint_t index; // process table index + uint_t pid; // its PID (when spawned) + uint8_t e_prio; // process priority + char select[3]; // identifying character, NUL, extra + char *args[MAX_ARGS]; // argument vector strings +} proc_t; + +/* +** Create a spawn table entry for a process with a string literal +** as its argument buffer. We rely on the fact that the C standard +** ensures our array of pointers will be filled out with NULLs +*/ +#define PROCENT(e,p,s,...) { e, 0, p, s, { __VA_ARGS__ , NULL } } + +// sentinel value for the end of the table - must be updated +// if you have more than 90,210 user programs in the table +#define TBLEND 90210 + +/* +** This table contains one entry for each process that should be +** started by 'init'. Typically, this includes the 'idle' process +** and a 'shell' process. +*/ +static proc_t spawn_table[] = { + + // the idle process; it runs at Deferred priority, + // so it will only be dispatched when there is + // nothing else available to be dispatched + PROCENT( Idle, PRIO_DEFERRED, "!", "idle", "." ), + + // the user shell + PROCENT( Shell, PRIO_STD, "@", "shell" ), + + // PROCENT( 0, 0, 0, 0 ) + { TBLEND } +}; + +// character to be printed by init when it spawns a process +static char ch = '+'; + +/** +** process - spawn all user processes listed in the supplied table +** +** @param proc pointer to the spawn table entry to be used +*/ + +static void process( proc_t *proc ) +{ + char buf[128]; + + // kick off the process + int32_t p = fork(); + if( p < 0 ) { + + // error! + sprint( buf, "INIT: fork for #%d failed\n", + (uint32_t) (proc->index) ); + cwrites( buf ); + + } else if( p == 0 ) { + + // change child's priority + (void) setprio( proc->e_prio ); + + // now, send it on its way + exec( proc->index, proc->args ); + + // uh-oh - should never get here! + sprint( buf, "INIT: exec(0x%08x) failed\n", + (uint32_t) (proc->index) ); + cwrites( buf ); + + } else { + + // parent just reports that another one was started + swritech( ch ); + + proc->pid = p; + + } +} + +/* +** The initial user process. Should be invoked with zero or one +** argument; if provided, the first argument should be the ASCII +** character 'init' will print to indicate the spawning of a process. +*/ +USERMAIN( main ) { + char buf[128]; + + // check to see if we got a non-standard "spawn" character + if( argc > 1 ) { + // maybe - check it to be sure it's printable + uint_t i = argv[1][0]; + if( i > ' ' && i < 0x7f ) { + ch = argv[1][0]; + } + } + + cwrites( "Init started\n" ); + + // home up, clear on a TVI 925 + swritech( '\x1a' ); + + // wait a bit + DELAY(SHORT); + + // a bit of Dante to set the mood :-) + swrites( "\n\nSpem relinquunt qui huc intrasti!\n\n\r" ); + + /* + ** Start all the user processes + */ + + cwrites( "INIT: starting user processes\n" ); + + proc_t *next; + for( next = spawn_table; next->index != TBLEND; ++next ) { + process( next ); + } + + swrites( " !!!\r\n\n" ); + + /* + ** At this point, we go into an infinite loop waiting + ** for our children (direct, or inherited) to exit. + */ + + cwrites( "INIT: transitioning to wait() mode\n" ); + + for(;;) { + int32_t status; + int whom = waitpid( 0, &status ); + + // PIDs must be positive numbers! + if( whom <= 0 ) { + sprint( buf, "INIT: waitpid() returned %d???\n", whom ); + cwrites( buf ); + } else { + + // got one; report it + sprint( buf, "INIT: pid %d exit(%d)\n", whom, status ); + cwrites( buf ); + + // figure out if this is one of ours + for( next = spawn_table; next->index != TBLEND; ++next ) { + if( next->pid == whom ) { + // one of ours - reset the PID field + // (in case the spawn attempt fails) + next->pid = 0; + // and restart it + process( next ); + break; + } + } + } + } + + /* + ** SHOULD NEVER REACH HERE + */ + + cwrites( "*** INIT IS EXITING???\n" ); + exit( 1 ); + + return( 1 ); // shut the compiler up +} diff --git a/user/progABC.c b/user/progABC.c new file mode 100644 index 0000000..4f7b6e6 --- /dev/null +++ b/user/progABC.c @@ -0,0 +1,68 @@ +#include <common.h> + +/** +** User function main #1: exit, write +** +** Prints its ID, then loops N times delaying and printing, then exits. +** Verifies the return byte count from each call to write(). +** +** Invoked as: main1 x n +** where x is the ID character +** n is the iteration count +*/ + +USERMAIN( main ) { + int count = 30; // default iteration count + char ch = '1'; // default character to print + char buf[128]; // local char buffer + + // process the command-line arguments + switch( argc ) { + case 3: count = str2int( argv[2], 10 ); + // FALL THROUGH + case 2: ch = argv[1][0]; + break; + default: + sprint( buf, "%s: argc %d, args: ", argv[0], argc ); + cwrites( buf ); + for( int i = 0; i <= argc; ++i ) { + sprint( buf, " %s", argv[argc] ? argv[argc] : "(null)" ); + cwrites( buf ); + } + cwrites( "\n" ); + } + + // announce our presence + int n = swritech( ch ); + if( n != 1 ) { + sprint( buf, "== %c, write #1 returned %d\n", ch, n ); + cwrites( buf ); + } + + // iterate and print the required number of other characters + for( int i = 0; i < count; ++i ) { + DELAY(STD); + n = swritech( ch ); + if( n != 1 ) { + sprint( buf, "== %c, write #2 returned %d\n", ch, n ); + cwrites( buf ); + } + } + + // all done! + exit( 0 ); + + // should never reach this code; if we do, something is + // wrong with exit(), so we'll report it + + char msg[] = "*1*"; + msg[1] = ch; + n = write( CHAN_SIO, msg, 3 ); /* shouldn't happen! */ + if( n != 3 ) { + sprint( buf, "User %c, write #3 returned %d\n", ch, n ); + cwrites( buf ); + } + + // this should really get us out of here + return( 42 ); +} diff --git a/user/progDE.c b/user/progDE.c new file mode 100644 index 0000000..a1aa0b3 --- /dev/null +++ b/user/progDE.c @@ -0,0 +1,56 @@ +#include <common.h> + +/** +** User function main #2: write +** +** Prints its ID, then loops N times delaying and printing, then returns +** without calling exit(). Verifies the return byte count from each call +** to write(). +** +** Invoked as: main2 x n +** where x is the ID character +** n is the iteration count +*/ + +USERMAIN( main ) { + int n; + int count = 30; // default iteration count + char ch = '2'; // default character to print + char buf[128]; + + // process the command-line arguments + switch( argc ) { + case 3: count = str2int( argv[2], 10 ); + // FALL THROUGH + case 2: ch = argv[1][0]; + break; + default: + sprint( buf, "main2: argc %d, args: ", argc ); + cwrites( buf ); + for( int i = 0; i <= argc; ++i ) { + sprint( buf, " %s", argv[argc] ? argv[argc] : "(null)" ); + cwrites( buf ); + } + cwrites( "\n" ); + } + + // announce our presence + n = swritech( ch ); + if( n != 1 ) { + sprint( buf, "== %c, write #1 returned %d\n", ch, n ); + cwrites( buf ); + } + + // iterate and print the required number of other characters + for( int i = 0; i < count; ++i ) { + DELAY(STD); + n = swritech( ch ); + if( n != 1 ) { + sprint( buf, "== %c, write #2 returned %d\n", ch, n ); + cwrites( buf ); + } + } + + // all done! + return( 0 ); +} diff --git a/user/progFG.c b/user/progFG.c new file mode 100644 index 0000000..a43ca67 --- /dev/null +++ b/user/progFG.c @@ -0,0 +1,55 @@ +#include <common.h> + +/** +** User function main #3: exit, sleep, write +** +** Prints its ID, then loops N times sleeping and printing, then exits. +** +** Invoked as: main3 x n s +** where x is the ID character +** n is the iteration count +** s is the sleep time in seconds +*/ + +USERMAIN( main ) { + char ch = '3'; // default character to print + int nap = 10; // default sleep time + int count = 30; // iteration count + char buf[128]; + + // process the command-line arguments + switch( argc ) { + case 4: nap = str2int( argv[3], 10 ); + // FALL THROUGH + case 3: count = str2int( argv[2], 10 ); + // FALL THROUGH + case 2: ch = argv[1][0]; + break; + default: + sprint( buf, "main3: argc %d, args: ", argc ); + cwrites( buf ); + for( int i = 0; i <= argc; ++i ) { + sprint( buf, " %s", argv[argc] ? argv[argc] : "(null)" ); + cwrites( buf ); + } + cwrites( "\n" ); + } + + // announce our presence + int n = swritech( ch ); + if( n != 1 ) { + sprint( buf, "=== %c, write #1 returned %d\n", ch, n ); + cwrites( buf ); + } + + write( CHAN_SIO, &ch, 1 ); + + for( int i = 0; i < count ; ++i ) { + sleep( SEC_TO_MS(nap) ); + write( CHAN_SIO, &ch, 1 ); + } + + exit( 0 ); + + return( 42 ); // shut the compiler up! +} diff --git a/user/progH.c b/user/progH.c new file mode 100644 index 0000000..386144d --- /dev/null +++ b/user/progH.c @@ -0,0 +1,66 @@ +#include <common.h> + +/** +** User function H: exit, fork, exec, sleep, write +** +** Prints its ID, then spawns 'n' children; exits before they terminate. +** +** Invoked as: userH x n +** where x is the ID character +** n is the number of children to spawn +*/ + +USERMAIN( main ) { + int32_t ret = 0; // return value + int count = 5; // child count + char ch = 'h'; // default character to print + char buf[128]; + int whom; + + // process the argument(s) + switch( argc ) { + case 3: count = str2int( argv[2], 10 ); + // FALL THROUGH + case 2: ch = argv[1][0]; + break; + default: + sprint( buf, "userH: argc %d, args: ", argc ); + cwrites( buf ); + for( int i = 0; i <= argc; ++i ) { + sprint( buf, " %s", argv[argc] ? argv[argc] : "(null)" ); + cwrites( buf ); + } + cwrites( "\n" ); + } + + // announce our presence + swritech( ch ); + + // we spawn user Z and then exit before it can terminate + // userZ 'Z' 10 + + char *argsz[] = { "userZ", "Z", "10", NULL }; + + for( int i = 0; i < count; ++i ) { + + // spawn a child + whom = spawn( ProgZ, argsz ); + + // our exit status is the number of failed spawn() calls + if( whom < 0 ) { + sprint( buf, "!! %c spawn() failed, returned %d\n", ch, whom ); + cwrites( buf ); + ret += 1; + } + } + + // yield the CPU so that our child(ren) can run + sleep( 0 ); + + // announce our departure + swritech( ch ); + + exit( ret ); + + return( 42 ); // shut the compiler up! +} diff --git a/user/progI.c b/user/progI.c new file mode 100644 index 0000000..c37eddf --- /dev/null +++ b/user/progI.c @@ -0,0 +1,104 @@ +#include <common.h> + +#ifndef MAX_CHILDREN +#define MAX_CHILDREN 50 +#endif + +/** +** User function I: exit, fork, exec, kill, sleep, waitpid, write +** +** Reports, then loops spawing userW, sleeps, kills two children, then +** loops checking the status of all its children +** +** Invoked as: userI [ x [ n ] ] +** where x is the ID character (defaults to 'i') +** n is the number of children to spawn (defaults to 5) +*/ + +USERMAIN( main ) { + int count = 5; // default child count + char ch = 'i'; // default character to print + int nap = 5; // nap time + char buf[128]; + char ch2[] = "*?*"; + uint_t children[MAX_CHILDREN]; + int nkids = 0; + + // process the command-line arguments + switch( argc ) { + case 3: count = str2int( argv[2], 10 ); + // FALL THROUGH + case 2: ch = argv[1][0]; + break; + case 1: // just use the defaults + break; + default: + sprint( buf, "userI: argc %d, args: ", argc ); + cwrites( buf ); + for( int i = 0; i <= argc; ++i ) { + sprint( buf, " %s", argv[argc] ? argv[argc] : "(null)" ); + cwrites( buf ); + } + cwrites( "\n" ); + } + + // secondary output (for indicating errors) + ch2[1] = ch; + + // announce our presence + write( CHAN_SIO, &ch, 1 ); + + // set up the argument vector + // we run: userW 10 5 + + char *argsw[] = { "userW", "W", "10", "5", NULL }; + + for( int i = 0; i < count; ++i ) { + int whom = spawn( ProgW, argsw ); + if( whom < 0 ) { + swrites( ch2 ); + } else { + swritech( ch ); + children[nkids++] = whom; + } + } + + // let the children start + sleep( SEC_TO_MS(nap) ); + + // kill two of them + int32_t status = kill( children[1] ); + if( status ) { + sprint( buf, "!! %c: kill(%d) status %d\n", ch, children[1], status ); + cwrites( buf ); + children[1] = -42; + } + status = kill( children[3] ); + if( status ) { + sprint( buf, "!! %c: kill(%d) status %d\n", ch, children[3], status ); + cwrites( buf ); + children[3] = -42; + } + + // collect child information + while( 1 ) { + int n = waitpid( 0, NULL ); + if( n == E_NO_CHILDREN ) { + // all done! + break; + } + for( int i = 0; i < count; ++i ) { + if( children[i] == n ) { + sprint( buf, "== %c: child %d (%d)\n", ch, i, children[i] ); + cwrites( buf ); + } + } + sleep( SEC_TO_MS(nap) ); + }; + + // let init() clean up after us! + + exit( 0 ); + + return( 42 ); // shut the compiler up! +} diff --git a/user/progJ.c b/user/progJ.c new file mode 100644 index 0000000..6eb4464 --- /dev/null +++ b/user/progJ.c @@ -0,0 +1,52 @@ +#include <common.h> + +/** +** User function J: exit, fork, exec, write +** +** Reports, tries to spawn lots of children, then exits +** +** Invoked as: userJ x [ n ] +** where x is the ID character +** n is the number of children to spawn (defaults to 2 * N_PROCS) +*/ + +USERMAIN( main ) { + int count = 2 * N_PROCS; // number of children to spawn + char ch = 'j'; // default character to print + char buf[128]; + + // process the command-line arguments + switch( argc ) { + case 3: count = str2int( argv[2], 10 ); + // FALL THROUGH + case 2: ch = argv[1][0]; + break; + default: + sprint( buf, "userJ: argc %d, args: ", argc ); + cwrites( buf ); + for( int i = 0; i <= argc; ++i ) { + sprint( buf, " %s", argv[argc] ? argv[argc] : "(null)" ); + cwrites( buf ); + } + cwrites( "\n" ); + } + + // announce our presence + write( CHAN_SIO, &ch, 1 ); + + // set up the command-line arguments + char *argsy[] = { "userY", "Y", "10", NULL }; + + for( int i = 0; i < count ; ++i ) { + int whom = spawn( ProgY, argsy ); + if( whom < 0 ) { + write( CHAN_SIO, "!j!", 3 ); + } else { + write( CHAN_SIO, &ch, 1 ); + } + } + + exit( 0 ); + + return( 42 ); // shut the compiler up! +} diff --git a/user/progKL.c b/user/progKL.c new file mode 100644 index 0000000..6bfb987 --- /dev/null +++ b/user/progKL.c @@ -0,0 +1,61 @@ +#include <common.h> + +/** +** User function main #4: exit, fork, exec, sleep, write +** +** Loops, spawning N copies of userX and sleeping between spawns. +** +** Invoked as: main4 x n +** where x is the ID character +** n is the iteration count (defaults to 5) +*/ + +USERMAIN( main ) { + int count = 5; // default iteration count + char ch = '4'; // default character to print + int nap = 30; // nap time + char msg2[] = "*4*"; // "error" message to print + char buf[32]; + + // process the command-line arguments + switch( argc ) { + case 3: count = str2int( argv[2], 10 ); + // FALL THROUGH + case 2: ch = argv[1][0]; + break; + default: + sprint( buf, "main4: argc %d, args: ", argc ); + cwrites( buf ); + for( int i = 0; i <= argc; ++i ) { + sprint( buf, " %s", argv[argc] ? argv[argc] : "(null)" ); + cwrites( buf ); + } + cwrites( "\n" ); + } + + // announce our presence + write( CHAN_SIO, &ch, 1 ); + + // argument vector for the processes we will spawn + char *arglist[] = { "userX", "X", buf, NULL }; + + for( int i = 0; i < count ; ++i ) { + + write( CHAN_SIO, &ch, 1 ); + + // second argument to X is 100 plus the iteration number + sprint( buf, "%d", 100 + i ); + int whom = spawn( ProgX, arglist ); + if( whom < 0 ) { + swrites( msg2 ); + } else { + write( CHAN_SIO, &ch, 1 ); + } + + sleep( SEC_TO_MS(nap) ); + } + + exit( 0 ); + + return( 42 ); // shut the compiler up! +} diff --git a/user/progMN.c b/user/progMN.c new file mode 100644 index 0000000..38ccd31 --- /dev/null +++ b/user/progMN.c @@ -0,0 +1,72 @@ +#include <common.h> + +/** +** User function main #5: exit, fork, exec, write +** +** Iterates spawning copies of userW (and possibly userZ), reporting +** their PIDs as it goes. +** +** Invoked as: main5 x n b +** where x is the ID character +** n is the iteration count +** b is the w&z boolean +*/ + +USERMAIN( main ) { + int count = 5; // default iteration count + char ch = '5'; // default character to print + int alsoZ = 0; // also do userZ? + char msgw[] = "*5w*"; + char msgz[] = "*5z*"; + char buf[128]; + + // process the command-line arguments + switch( argc ) { + case 4: alsoZ = argv[3][0] == 't'; + // FALL THROUGH + case 3: count = str2int( argv[2], 10 ); + // FALL THROUGH + case 2: ch = argv[1][0]; + break; + default: + sprint( buf, "main5: argc %d, args: ", argc ); + cwrites( buf ); + for( int i = 0; i <= argc; ++i ) { + sprint( buf, " %s", argv[argc] ? argv[argc] : "(null)" ); + cwrites( buf ); + } + cwrites( "\n" ); + } + + // update the extra message strings + msgw[1] = msgz[1] = ch; + + // announce our presence + write( CHAN_SIO, &ch, 1 ); + + // set up the argument vector(s) + + // W: 15 iterations, 5-second sleep + char *argsw[] = { "userW", "W", "15", "5", NULL }; + + // Z: 15 iterations + char *argsz[] = { "userZ", "Z", "15", NULL }; + + for( int i = 0; i < count; ++i ) { + write( CHAN_SIO, &ch, 1 ); + int whom = spawn( ProgW, argsw ); + if( whom < 1 ) { + swrites( msgw ); + } + if( alsoZ ) { + whom = spawn( ProgZ, argsz ); + if( whom < 1 ) { + swrites( msgz ); + } + } + } + + exit( 0 ); + + return( 42 ); // shut the compiler up! +} diff --git a/user/progP.c b/user/progP.c new file mode 100644 index 0000000..5a264a5 --- /dev/null +++ b/user/progP.c @@ -0,0 +1,51 @@ +#include "common.h" + +/** +** User function P: exit, sleep, write, gettime +** +** Reports itself, then loops reporting itself +** +** Invoked as: userP x [ n [ t ] ] +** where x is the ID character +** n is the iteration count (defaults to 3) +** t is the sleep time (defaults to 2 seconds) +*/ + +USERMAIN( main ) { + int count = 3; // default iteration count + char ch = 'p'; // default character to print + int nap = 2; // nap time + char buf[128]; + + // process the command-line arguments + switch( argc ) { + case 4: nap = str2int( argv[3], 10 ); + // FALL THROUGH + case 3: count = str2int( argv[2], 10 ); + // FALL THROUGH + case 2: ch = argv[1][0]; + break; + default: + sprint( buf, "userP: argc %d, args: ", argc ); + cwrites( buf ); + for( int i = 0; i <= argc; ++i ) { + sprint( buf, " %s", argv[argc] ? argv[argc] : "(null)" ); + cwrites( buf ); + } + cwrites( "\n" ); + } + + // announce our presence + uint32_t now = gettime(); + sprint( buf, " P@%u", now ); + swrites( buf ); + + for( int i = 0; i < count; ++i ) { + sleep( SEC_TO_MS(nap) ); + write( CHAN_SIO, &ch, 1 ); + } + + exit( 0 ); + + return( 42 ); // shut the compiler up! +} diff --git a/user/progQ.c b/user/progQ.c new file mode 100644 index 0000000..ecfcffc --- /dev/null +++ b/user/progQ.c @@ -0,0 +1,43 @@ +#include <common.h> + +/** +** User function Q: exit, write, bogus +** +** Reports itself, then tries to execute a bogus system call +** +** Invoked as: userQ x +** where x is the ID character +*/ + +USERMAIN( main ) { + char ch = 'q'; // default character to print + char buf[128]; + + // process the command-line arguments + switch( argc ) { + case 2: ch = argv[1][0]; + break; + default: + sprint( buf, "userQ: argc %d, args: ", argc ); + cwrites( buf ); + for( int i = 0; i <= argc; ++i ) { + sprint( buf, " %s", argv[argc] ? argv[argc] : "(null)" ); + cwrites( buf ); + } + cwrites( "\n" ); + } + + // announce our presence + write( CHAN_SIO, &ch, 1 ); + + // try something weird + bogus(); + + // should not have come back here! + sprint( buf, "!!!!! %c returned from bogus syscall!?!?!\n", ch ); + cwrites( buf ); + + exit( 1 ); + + return( 42 ); // shut the compiler up! +} diff --git a/user/progR.c b/user/progR.c new file mode 100644 index 0000000..1d47f6b --- /dev/null +++ b/user/progR.c @@ -0,0 +1,99 @@ +#include <common.h> + +/** +** User function R: exit, sleep, write, fork, getpid, getppid, +** +** Reports itself and its sequence number, along with its PID and +** its parent's PID. It then delays, forks, delays, reports again, +** and exits. +** +** Invoked as: userR x n [ s ] +** where x is the ID character +** n is the sequence number of the initial incarnation +** s is the initial delay time (defaults to 10) +*/ + +USERMAIN( main ) { + char ch = 'r'; // default character to print + int delay = 10; // initial delay count + int seq = 99; // my sequence number + char buf[128]; + + // process the command-line arguments + switch( argc ) { + case 4: delay = str2int( argv[3], 10 ); + // FALL THROUGH + case 3: seq = str2int( argv[2], 10 ); + // FALL THROUGH + case 2: ch = argv[1][0]; + break; + default: + sprint( buf, "userR: argc %d, args: ", argc ); + cwrites( buf ); + for( int i = 0; i <= argc; ++i ) { + sprint( buf, " %s", argv[argc] ? argv[argc] : "(null)" ); + cwrites( buf ); + } + cwrites( "\n" ); + } + + /* + ** C oddity: a label cannot immediately precede a declaration. + ** + ** Declarations are not considered "statements" in C. Prior to + ** C99, all declarations had to precede any statements inside a + ** block. Labels can only appear before statements. C99 allowed + ** the mixing of declarations and statements, but did not relax + ** the requirement that labels precede only statements. + ** + ** That's why the declarations of these variables occur before the + ** label, but their initializations occur after the label. + ** + ** As the PSA says on TV, "The more you know..." :-) + */ + + int32_t pid; + int32_t ppid; + + restart: + + // announce our presence + pid = getpid(); + ppid = getppid(); + + sprint( buf, " %c[%d,%d,%d]", ch, seq, pid, ppid ); + swrites( buf ); + + sleep( SEC_TO_MS(delay) ); + + // create the next child in sequence + if( seq < 5 ) { + ++seq; + int32_t n = fork(); + switch( n ) { + case -1: + // failure? + sprint( buf, "** R[%d] fork code %d\n", pid, n ); + cwrites( buf ); + break; + case 0: + // child + goto restart; + default: + // parent + --seq; + sleep( SEC_TO_MS(delay) ); + } + } + + // final report - PPID may change, but PID and seq shouldn't + pid = getpid(); + ppid = getppid(); + sprint( buf, " %c[%d,%d,%d]", ch, seq, pid, ppid ); + swrites( buf ); + + exit( 0 ); + + return( 42 ); // shut the compiler up! + +} diff --git a/user/progS.c b/user/progS.c new file mode 100644 index 0000000..d220955 --- /dev/null +++ b/user/progS.c @@ -0,0 +1,50 @@ +#include <common.h> + +/** +** User function S: exit, sleep, write +** +** Reports itself, then loops forever, sleeping on each iteration +** +** Invoked as: userS x [ s ] +** where x is the ID character +** s is the sleep time (defaults to 20) +*/ + +USERMAIN( main ) { + char ch = 's'; // default character to print + int nap = 20; // nap time + char buf[128]; + + // process the command-line arguments + switch( argc ) { + case 3: nap = str2int( argv[2], 10 ); + // FALL THROUGH + case 2: ch = argv[1][0]; + break; + default: + sprint( buf, "userS: argc %d, args: ", argc ); + cwrites( buf ); + for( int i = 0; i <= argc; ++i ) { + sprint( buf, " %s", argv[argc] ? argv[argc] : "(null)" ); + cwrites( buf ); + } + cwrites( "\n" ); + } + + // announce our presence + write( CHAN_SIO, &ch, 1 ); + + sprint( buf, "userS sleeping %d(%d)\n", nap, SEC_TO_MS(nap) ); + cwrites( buf ); + + for(;;) { + sleep( SEC_TO_MS(nap) ); + write( CHAN_SIO, &ch, 1 ); + } + + sprint( buf, "!! %c exiting!?!?!?\n", ch ); + cwrites( buf ); + exit( 1 ); + + return( 42 ); // shut the compiler up! +} diff --git a/user/progTUV.c b/user/progTUV.c new file mode 100644 index 0000000..3d5ed49 --- /dev/null +++ b/user/progTUV.c @@ -0,0 +1,169 @@ +#include <common.h> + +/** +** User function main #6: exit, fork, exec, kill, waitpid, sleep, write +** +** Reports, then loops spawing userW, sleeps, then waits for or kills +** all its children. +** +** Invoked as: main6 x c b +** where x is the ID character +** c is the child count +** b is wait/kill indicator ('w', 'W', or 'k') +*/ + +#ifndef MAX_CHILDREN +#define MAX_CHILDREN 50 +#endif + +USERMAIN( main ) { + int count = 3; // default child count + char ch = '6'; // default character to print + int nap = 8; // nap time + bool_t waiting = true; // default is waiting by PID + bool_t bypid = true; + char buf[128]; + uint_t children[MAX_CHILDREN]; + int nkids = 0; + char ch2[] = "*?*"; + + // process the command-line arguments + switch( argc ) { + case 4: waiting = argv[3][0] != 'k'; // 'w'/'W' -> wait, else -> kill + bypid = argv[3][0] != 'w'; // 'W'/'k' -> by PID + // FALL THROUGH + case 3: count = str2int( argv[2], 10 ); + // FALL THROUGH + case 2: ch = argv[1][0]; + break; + default: + sprint( buf, "main6: argc %d, args: ", argc ); + cwrites( buf ); + for( int i = 0; i <= argc; ++i ) { + sprint( buf, " %s", argv[argc] ? argv[argc] : "(null)" ); + cwrites( buf ); + } + cwrites( "\n" ); + } + + // fix the secondary output message (for indicating errors) + ch2[1] = ch; + + // announce our presence + write( CHAN_SIO, &ch, 1 ); + + // set up the argument vector + char *argsw[] = { "userW", "W", "10", "5", NULL }; + + for( int i = 0; i < count; ++i ) { + int whom = spawn( ProgW, argsw ); + if( whom < 0 ) { + swrites( ch2 ); + } else { + children[nkids++] = whom; + } + } + + // let the children start + sleep( SEC_TO_MS(nap) ); + + // collect exit status information + + // current child index + int n = 0; + + do { + int this; + int32_t status; + + // are we waiting for or killing it? + if( waiting ) { + this = waitpid( bypid ? children[n] : 0, &status ); + } else { + // always by PID + this = kill( children[n] ); + } + + // what was the result? + if( this < SUCCESS ) { + + // uh-oh - something went wrong + + // "no children" means we're all done + if( this != E_NO_CHILDREN ) { + if( waiting ) { + sprint( buf, "!! %c: waitpid(%d) status %d\n", + ch, bypid ? children[n] : 0, this ); + } else { + sprint( buf, "!! %c: kill(%d) status %d\n", + ch, children[n], this ); + } + } else { + sprint( buf, "!! %c: no children\n", ch ); + } + + // regardless, we're outta here + break; + + } else { + + // locate the child + int ix = -1; + + // were we looking by PID? + if( bypid ) { + // we should have just gotten the one we were looking for + if( this != children[n] ) { + // uh-oh + sprint( buf, "** %c: wait/kill PID %d, got %d\n", + ch, children[n], this ); + cwrites( buf ); + } else { + ix = n; + } + } + + // either not looking by PID, or the lookup failed somehow + if( ix < 0 ) { + int i; + for( i = 0; i < nkids; ++i ) { + if( children[i] == this ) { + ix = i; + break; + } + } + } + + // if ix == -1, the PID we received isn't in our list of children + + if( ix < 0 ) { + + // didn't find an entry for this PID??? + sprint( buf, "!! %c: child PID %d term, NOT FOUND\n", + ch, this ); + + } else { + + // found this PID in our list of children + if( ix != n ) { + // ... but it's out of sequence + sprint( buf, "== %c: child %d (%d,%d) status %d\n", + ch, ix, n, this, status ); + } else { + sprint( buf, "== %c: child %d (%d) status %d\n", + ch, ix, this, status ); + } + } + + } + + cwrites( buf ); + + ++n; + + } while( n < nkids ); + + exit( 0 ); + + return( 42 ); // shut the compiler up! +} diff --git a/user/progW.c b/user/progW.c new file mode 100644 index 0000000..5903663 --- /dev/null +++ b/user/progW.c @@ -0,0 +1,57 @@ +#include <common.h> + +/** +** User function W: exit, sleep, write, getpid, gettime +** +** Reports its presence, then iterates 'n' times printing identifying +** information and sleeping, before exiting. +** +** Invoked as: userW x [ n [ s ] ] +** where x is the ID character +** n is the iteration count (defaults to 20) +** s is the sleep time (defaults to 3 seconds) +*/ + +USERMAIN( main ) { + int count = 20; // default iteration count + char ch = 'w'; // default character to print + int nap = 3; // nap length + char buf[128]; + + // process the command-line arguments + switch( argc ) { + case 4: nap = str2int( argv[3], 10 ); + // FALL THROUGH + case 3: count = str2int( argv[2], 10 ); + // FALL THROUGH + case 2: ch = argv[1][0]; + break; + default: + sprint( buf, "userW: argc %d, args: ", argc ); + cwrites( buf ); + for( int i = 0; i <= argc; ++i ) { + sprint( buf, " %s", argv[argc] ? argv[argc] : "(null)" ); + cwrites( buf ); + } + cwrites( "\n" ); + } + + // announce our presence + int pid = getpid(); + uint32_t now = gettime(); + sprint( buf, " %c[%d,%u]", ch, pid, now ); + swrites( buf ); + + write( CHAN_SIO, &ch, 1 ); + + for( int i = 0; i < count ; ++i ) { + now = gettime(); + sprint( buf, " %c[%d,%u] ", ch, pid, now ); + swrites( buf ); + sleep( SEC_TO_MS(nap) ); + } + + exit( 0 ); + + return( 42 ); // shut the compiler up! +} diff --git a/user/progX.c b/user/progX.c new file mode 100644 index 0000000..ed356b9 --- /dev/null +++ b/user/progX.c @@ -0,0 +1,48 @@ +#include <common.h> + +/** +** User function X: exit, write, getpid +** +** Prints its PID at start and exit, iterates printing its character +** N times, and exits with a status of 12. +** +** Invoked as: userX x n +** where x is the ID character +** n is the iteration count +*/ + +USERMAIN( main ) { + int count = 20; // iteration count + char ch = 'x'; // default character to print + char buf[128]; + + // process the command-line arguments + switch( argc ) { + case 3: count = str2int( argv[2], 10 ); + // FALL THROUGH + case 2: ch = argv[1][0]; + break; + default: + sprint( buf, "userX: argc %d, args: ", argc ); + cwrites( buf ); + for( int i = 0; i <= argc; ++i ) { + sprint( buf, " %s", argv[argc] ? argv[argc] : "(null)" ); + cwrites( buf ); + } + cwrites( "\n" ); + } + + // announce our presence + int pid = getpid(); + sprint( buf, " %c[%d]", ch, pid ); + swrites( buf ); + + for( int i = 0; i < count ; ++i ) { + swrites( buf ); + DELAY(STD); + } + + exit( 12 ); + + return( 42 ); // shut the compiler up! +} diff --git a/user/progY.c b/user/progY.c new file mode 100644 index 0000000..194f188 --- /dev/null +++ b/user/progY.c @@ -0,0 +1,49 @@ +#include <common.h> + +/** +** User function Y: exit, sleep, write, getpid +** +** Reports its PID, then iterates N times printing 'Yx' and +** sleeping for one second, then exits. +** +** Invoked as: userY x [ n ] +** where x is the ID character +** n is the iteration count (defaults to 10) +*/ + +USERMAIN( main ) { + int count = 10; // default iteration count + char ch = 'y'; // default character to print + char buf[128]; + + // process the command-line arguments + switch( argc ) { + case 3: count = str2int( argv[2], 10 ); + // FALL THROUGH + case 2: ch = argv[1][0]; + break; + default: + sprint( buf, "?: argc %d, args: ", argc ); + cwrites( buf ); + for( int i = 0; i <= argc; ++i ) { + sprint( buf, " %s", argv[argc] ? argv[argc] : "(null)" ); + cwrites( buf ); + } + cwrites( "\n" ); + } + + // report our presence + int pid = getpid(); + sprint( buf, " %c[%d]", ch, pid ); + swrites( buf ); + + for( int i = 0; i < count ; ++i ) { + swrites( buf ); + DELAY(STD); + sleep( SEC_TO_MS(1) ); + } + + exit( 0 ); + + return( 42 ); // shut the compiler up! +} diff --git a/user/progZ.c b/user/progZ.c new file mode 100644 index 0000000..cc394c4 --- /dev/null +++ b/user/progZ.c @@ -0,0 +1,57 @@ +#include <common.h> + +/** +** User function Z: exit, sleep, write, getpid +** +** Prints its ID, then records PID and PPID, loops printing its ID, +** and finally re-gets PPID for comparison. Yields after every second +** ID print in the loop. +** +** This code is used as a handy "spawn me" test routine; it is spawned +** by several of the standard test processes. +** +** Invoked as: userZ x [ n ] +** where x is the ID character +** n is the iteration count (defaults to 10) +*/ + +USERMAIN( main ) { + int count = 10; // default iteration count + char ch = 'z'; // default character to print + char buf[128]; + + // process the command-line arguments + switch( argc ) { + case 3: count = str2int( argv[2], 10 ); + // FALL THROUGH + case 2: ch = argv[1][0]; + break; + default: + sprint( buf, "?: argc %d, args: ", argc ); + cwrites( buf ); + for( int i = 0; i <= argc; ++i ) { + sprint( buf, " %s", argv[argc] ? argv[argc] : "(null)" ); + cwrites( buf ); + } + cwrites( "\n" ); + } + + // announce our presence + int pid = getpid(); + sprint( buf, " %c[%d]", ch, pid ); + swrites( buf ); + + // iterate for a while; occasionally yield the CPU + for( int i = 0; i < count ; ++i ) { + sprint( buf, " %c[%d]", ch, i ); + swrites( buf ); + DELAY(STD); + if( i & 1 ) { + sleep( 0 ); + } + } + + exit( 0 ); + + return( 42 ); // shut the compiler up! +} diff --git a/user/shell.c b/user/shell.c new file mode 100644 index 0000000..5412033 --- /dev/null +++ b/user/shell.c @@ -0,0 +1,343 @@ +#include <common.h> + +// should we keep going? +static bool_t time_to_stop = false; + +// number of spawned but uncollected children +static int children = 0; + +/* +** For the test programs in the baseline system, command-line arguments +** follow these rules. The first two entries are as follows: +** +** argv[0] the name used to "invoke" this process +** argv[1] the "character to print" (identifies the process) +** +** Most user programs have one or more additional arguments. +** +** See the comment at the beginning of each user-code source file for +** information on the argument list that code expects. +*/ + +/* +** "Spawn table" process entry. Similar to that in init.c, +** except this one has no place to store the PID of the child. +*/ +typedef struct proc_s { + uint_t index; // process table index + int8_t prio; // process priority + char select[3]; // identifying character, NUL, extra + char *args[MAX_ARGS]; // argument vector strings +} proc_t; + +/* +** Create a spawn table entry for a process with a string literal +** as its argument buffer. We rely on the fact that the C standard +** ensures our array of pointers will be filled out with NULLs +*/ +#define PROCENT(e, p, s, ...) { e, p, s, { __VA_ARGS__ , NULL } } + +// sentinel value for the end of the table - must be updated +// if you have more than 90,210 user programs in the table +#define TBLEND 90210 + +/* +** The spawn table contains entries for processes that are started +** by the shell. +*/ +static proc_t spawn_table[] = { + + // Users A-C each run ProgABC, which loops printing its character +#if defined(SPAWN_A) + PROCENT( ProgABC, PRIO_STD, "A", "userA", "A", "30" ), +#endif +#if defined(SPAWN_B) + PROCENT( ProgABC, PRIO_STD, "B", "userB", "B", "30" ), +#endif +#if defined(SPAWN_C) + PROCENT( ProgABC, PRIO_STD, "C", "userC", "C", "30" ), +#endif + + // Users D and E run ProgDE, which is like ProgABC but doesn't exit() +#if defined(SPAWN_D) + PROCENT( ProgDE, PRIO_STD, "D", "userD", "D", "20" ), +#endif +#if defined(SPAWN_E) + PROCENT( ProgDE, PRIO_STD, "E", "userE", "E", "20" ), +#endif + + // Users F and G run ProgFG, which sleeps between write() calls +#if defined(SPAWN_F) + PROCENT( ProgFG, PRIO_STD, "F", "userF", "F", "20" ), +#endif +#if defined(SPAWN_G) + PROCENT( ProgFG, PRIO_STD, "G", "userG", "G", "10" ), +#endif + + // User H tests reparenting of orphaned children +#if defined(SPAWN_H) + PROCENT( ProgH, PRIO_STD, "H", "userH", "H", "4" ), +#endif + + // User I spawns several children, kills one, and waits for all +#if defined(SPAWN_I) + PROCENT( ProgI, PRIO_STD, "I", "userI", "I" ), +#endif + + // User J tries to spawn 2 * N_PROCS children +#if defined(SPAWN_J) + PROCENT( ProgJ, PRIO_STD, "J", "userJ", "J" ), +#endif + + // Users K and L iterate spawning userX and sleeping +#if defined(SPAWN_K) + PROCENT( ProgKL, PRIO_STD, "K", "userK", "K", "8" ), +#endif +#if defined(SPAWN_L) + PROCENT( ProgKL, PRIO_STD, "L", "userL", "L", "5" ), +#endif + + // Users M and N spawn copies of userW and userZ via ProgMN +#if defined(SPAWN_M) + PROCENT( ProgMN, PRIO_STD, "M", "userM", "M", "5", "f" ), +#endif +#if defined(SPAWN_N) + PROCENT( ProgMN, PRIO_STD, "N", "userN", "N", "5", "t" ), +#endif + + // There is no user O + + // User P iterates, reporting system time and stats, and sleeping +#if defined(SPAWN_P) + PROCENT( ProgP, PRIO_STD, "P", "userP", "P", "3", "2" ), +#endif + + // User Q tries to execute a bad system call +#if defined(SPAWN_Q) + PROCENT( ProgQ, PRIO_STD, "Q", "userQ", "Q" ), +#endif + + // User R reports its PID, PPID, and sequence number; it + // calls fork() but not exec(), with each child getting the + // next sequence number, to a total of five copies +#if defined(SPAWN_R) + PROCENT( ProgR, PRIO_STD, "R", "userR", "R", "20", "1" ), +#endif + + // User S loops forever, sleeping 13 sec. on each iteration +#if defined(SPAWN_S) + PROCENT( ProgS, PRIO_STD, "S", "userS", "S", "13" ), +#endif + + // Users T-V run ProgTUV(); they spawn copies of userW + // User T waits for any child + // User U waits for each child by PID + // User V kills each child +#if defined(SPAWN_T) + PROCENT( ProgTUV, PRIO_STD, "T", "userT", "T", "6", "w" ), +#endif +#if defined(SPAWN_U) + PROCENT( ProgTUV, PRIO_STD, "U", "userU", "U", "6", "W" ), +#endif +#if defined(SPAWN_V) + PROCENT( ProgTUV, PRIO_STD, "V", "userV", "V", "6", "k" ), +#endif + + // a dummy entry to use as a sentinel + { TBLEND } + + // these processes are spawned by the ones above, and are never + // spawned directly. + + // PROCENT( ProgW, PRIO_STD, "?", "userW", "W", "20", "3" ), + // PROCENT( ProgX, PRIO_STD, "?", "userX", "X", "20" ), + // PROCENT( ProgY, PRIO_STD, "?", "userY", "Y", "10" ), + // PROCENT( ProgZ, PRIO_STD, "?", "userZ", "Z", "10" ) +}; + +/* +** usage function +*/ +static void usage( void ) { + swrites( "\nTests - run with '@x', where 'x' is one or more of:\n " ); + proc_t *p = spawn_table; + while( p->index != TBLEND ) { + swritech( ' ' ); + swritech( p->select[0] ); + } + swrites( "\nOther commands: @* (all), @h (help), @x (exit)\n" ); +} + +/* +** run a program from the program table, or a builtin command +*/ +static int run( char which ) { + char buf[128]; + register proc_t *p; + + if( which == 'h' ) { + + // builtin "help" command + usage(); + + } else if( which == 'x' ) { + + // builtin "exit" command + time_to_stop = true; + + } else if( which == '*' ) { + + // torture test! run everything! + for( p = spawn_table; p->index != TBLEND; ++p ) { + int status = spawn( p->index, p->args ); + if( status > 0 ) { + ++children; + } + } + + } else { + + // must be a single test; find and run it + for( p = spawn_table; p->index != TBLEND; ++p ) { + if( p->select[0] == which ) { + // found it! + int status = spawn( p->index, p->args ); + if( status > 0 ) { + ++children; + } + return status; + } + } + + // uh-oh, made it through the table without finding the program + sprint( buf, "shell: unknown cmd '%c'\n", which ); + swrites( buf ); + usage(); + } + + return 0; +} + +/** +** edit - perform any command-line editing we need to do +** +** @param line Input line buffer +** @param n Number of valid bytes in the buffer +*/ +static int edit( char line[], int n ) { + char *ptr = line + n - 1; // last char in buffer + + // strip the EOLN sequence + while( n > 0 ) { + if( *ptr == '\n' || *ptr == '\r' ) { + --n; + } else { + break; + } + } + + // add a trailing NUL byte + if( n > 0 ) { + line[n] = '\0'; + } + + return n; +} + +/** +** shell - extremely simple shell for spawning test programs +** +** Scheduled by _kshell() when the character 'u' is typed on +** the console keyboard. +*/ +USERMAIN( main ) { + + // keep the compiler happy + (void) argc; + (void) argv; + + // report that we're up and running + swrites( "Shell is ready\n" ); + + // print a summary of the commands we'll accept + usage(); + + // loop forever + while( !time_to_stop ) { + char line[128]; + char *ptr; + + // the shell reads one line from the keyboard, parses it, + // and performs whatever command it requests. + + swrites( "\n> " ); + int n = read( CHAN_SIO, line, sizeof(line) ); + + // shortest valid command is "@?", so must have 3+ chars here + if( n < 3 ) { + // ignore it + continue; + } + + // edit it as needed; new shortest command is 2+ chars + if( (n=edit(line,n)) < 2 ) { + continue; + } + + // find the '@' + int i = 0; + for( ptr = line; i < n; ++i, ++ptr ) { + if( *ptr == '@' ) { + break; + } + } + + // did we find an '@'? + if( i < n ) { + + // yes; process any commands that follow it + ++ptr; + + for( ; *ptr != '\0'; ++ptr ) { + char buf[128]; + int pid = run( *ptr ); + + if( pid < 0 ) { + // spawn() failed + sprint( buf, "+++ Shell spawn %c failed, code %d\n", + *ptr, pid ); + cwrites( buf ); + } + + // should we end it all? + if( time_to_stop ) { + break; + } + } // for + + // now, wait for all the spawned children + while( children > 0 ) { + // wait for the child + int32_t status; + char buf[128]; + int whom = waitpid( 0, &status ); + + // figure out the result + if( whom == E_NO_CHILDREN ) { + break; + } else if( whom < 1 ) { + sprint( buf, "shell: waitpid() returned %d\n", whom ); + } else { + --children; + sprint( buf, "shell: PID %d exit status %d\n", + whom, status ); + } + // report it + swrites( buf ); + } + } // if i < n + } // while + + cwrites( "!!! shell exited loop???\n" ); + exit( 1 ); +} diff --git a/user/user.ld b/user/user.ld new file mode 100644 index 0000000..9e31dff --- /dev/null +++ b/user/user.ld @@ -0,0 +1,51 @@ +/* +** Simple linker script for user-level programs. +*/ + +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) + +SECTIONS +{ + /* user text begins at the second page of the address space */ + . = 0x1000; + + .text : { + KEEP(*(.text .stub .text.* .gnu.linkonce.t.*)) + } + + /* define some standard symbols */ + PROVIDE(etext = .); + PROVIDE(_etext = .); + + /* read-only data will go at the end of the text section */ + .rodata : { + KEEP(*(.rodata .rodata.* .gnu.linkonce.r.*)) + } + + /* Align the data segment at the next page boundary */ + . = ALIGN(0x1000); + + .data : { + KEEP(*(.data)) + } + + PROVIDE(edata = .); + PROVIDE(_edata = .); + + /* Page-align the BSS segment */ + . = ALIGN(0x1000); + + PROVIDE(__bss_start = .); + + .bss : { + KEEP(*(.bss)) + } + + PROVIDE(_end = .); + + /DISCARD/ : { + *(.stab .stab_info .stabstr .eh_frame .note.GNU-stack .note.gnu.property .comment) + } +} diff --git a/util/BuildImage.c b/util/BuildImage.c new file mode 100644 index 0000000..2124c9d --- /dev/null +++ b/util/BuildImage.c @@ -0,0 +1,415 @@ +/** +** SCCS ID: @(#)BuildImage.c 2.2 1/16/25 +** +** @file BuildImage.c +** +** @author K. Reek +** @author Jon Coles +** @author Warren R. Carithers +** @author Garrett C. Smith +** +** Modify the bootstrap image to include the information +** on the programs to be loaded, and produce the file +** that contains the concatenation of these programs. +** +*/ + +#define _POSIX_C_SOURCE 200809L + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +#define TRUE 1 +#define FALSE 0 + +#define DRIVE_FLOPPY 0x00 +#define DRIVE_USB 0x80 + +#define SECT_SIZE 512 + +char *progname; /* invocation name of this program */ +char *bootstrap_filename; /* path of file holding bootstrap program */ +char *output_filename; /* path of disk image file */ +FILE *out; /* output stream for disk image file */ +short drive = DRIVE_USB; /* boot drive */ + +/* +** Array into which program information will be stored, starting at the +** end and moving back toward the front. The array is the same size as +** a sector, which is guaranteed to be larger than the maximum possible +** space available for this stuff in the bootstrap image. Thus, the +** bootstrap image itself (and the amount of space available on the +** device) are the only limiting factors on how many program sections +** can be loaded. +*/ + +#define N_INFO ( SECT_SIZE / sizeof( short ) ) + +short info[ N_INFO ]; +int n_info = N_INFO; + +/** +** quit with an appropriate message +** +** @param msg NULL, or a message to be printed to stderr +** @param call_perror non-zero if perror() should be used; else, +** fprintf() will be used +** +** does not return +*/ +void quit( char *msg, int call_perror ) { + if( msg != NULL ){ + // preserve the error code in case we need it + int err_num = errno; + fprintf( stderr, "%s: ", progname ); + errno = err_num; + if( call_perror ){ + perror( msg ); + } else { + fprintf( stderr, "%s\n", msg ); + } + } + if( output_filename != NULL ){ + unlink( output_filename ); + } + exit( EXIT_FAILURE ); + // NOTREACHED +} + +const char usage_error_msg[] = + "\nUsage: %s [ -d drive ] -b bootfile -o outfile { progfile loadpt } ...\n\n" + "\t'drive' is either 'floppy' or 'usb' (default 'usb')\n\n" + "\tThere must be at least one program file and load point.\n\n" + "\tLoad points may be specified either as 32-bit quantities in hex,\n" + "\tdecimal or octal (e.g. 0x10c00, 68608, 0206000 are all equivalent),\n" + "\tor as an explicit segment:offset pair whose digits are always\n" + "\tinterpreted as hexadecimal values (e.g. 10c0:0000, 1000:0c00 are\n" + "\tboth equivalent to the previous examples).\n\n"; + +/** +** print a usage message and then call quit() +** +** does not return +*/ +void usage_error( void ){ + fprintf( stderr, usage_error_msg, progname ); + quit( NULL, FALSE ); + // NOTREACHED +} + +/** +** copy the contents of a binary file into the output file, padding the +** last sector with NUL bytes +** +** @param in open FILE to be read +** @return the number of sectors copied from the file +*/ +int copy_file( FILE *in ){ + int n_sectors = 0; + char buf[ SECT_SIZE ]; + int n_bytes; + int i; + + /* + ** Copy the file to the output, being careful that the + ** last sector is padded with null bytes out to the + ** sector size. + */ + n_sectors = 0; + while( (n_bytes = fread( buf, 1, sizeof( buf ), in )) > 0 ){ + // pad this sector out to block size + if( n_bytes < sizeof( buf ) ){ + int i; + + for( i = n_bytes; i < sizeof( buf ); i += 1 ){ + buf[ i ] = '\0'; + } + } + if( fwrite( buf, 1, sizeof( buf ), out ) != sizeof( buf ) ){ + quit( "Write failed or was wrong size", FALSE ); + } + n_sectors += 1; + } + return n_sectors; +} + +/** +** process a file whose contents should be at a specific' +** address in memory when the program is loaded +** +** @param name path to the file to be copied +** @param addr string containing the load address +*/ +void process_file( char *name, char *addr ){ + long address; + short segment, offset; + int n_bytes; + + /* + ** Open the input file. + */ + FILE *in = fopen( name, "rb" ); + if( in == NULL ){ + quit( name, TRUE ); + } + + /* + ** Copy the file to the output, being careful that the + ** last block is padded with null bytes. + */ + int n_sectors = copy_file( in ); + fclose( in ); + + /* + ** Decode the address they gave us. We'll accept two forms: + ** "nnnn:nnnn" for a segment:offset value (assumed to be hex), + ** "nnnnnnn" for a decimal, hex, or octal value + */ + int valid_address = FALSE; + char *cp = strchr( addr, ':' ); + if( cp != NULL ){ + // must be in nnnn:nnnn form exactly + if( strlen( addr ) == 9 && cp == addr + 4 ){ + char *ep1, *ep2; + int a1, a2; + + segment = strtol( addr, &ep1, 16 ); + offset = strtol( addr + 5, &ep2, 16 ); + address = ( segment << 4 ) + offset; + valid_address = *ep1 == '\0' && *ep2 == '\0'; + } else { + fprintf( stderr, "Bad address format - '%s'\n", addr ); + quit( NULL, FALSE ); + } + } else { + // just a number, possibly hex or octal + char *ep; + + address = strtol( addr, &ep, 0 ); + segment = (short)( address >> 4 ); + offset = (short)( address & 0xf ); + valid_address = *ep == '\0' && address <= 0x0009ffff; + } + + if( !valid_address ){ + fprintf( stderr, "%s: Invalid address: %s\n", progname, addr ); + quit( NULL, FALSE ); + } + + /* + ** Make sure the program will fit! + */ + if( address + n_sectors * SECT_SIZE > 0x0009ffff ){ + fprintf( stderr, "Program %s too large to start at 0x%08x\n", + name, (unsigned int) address ); + quit( NULL, FALSE ); + } + + if( n_info < 3 ){ + quit( "Too many programs!", FALSE ); + } + + + /* + ** Looks good: report and store the information. + */ + fprintf( stderr, " %s: %d sectors, loaded at 0x%x\n", + name, n_sectors, (unsigned int) address ); + + info[ --n_info ] = n_sectors; + info[ --n_info ] = segment; + info[ --n_info ] = offset; +} + +/* +** Global variables set by getopt() +*/ + +extern int optind, optopt; +extern char *optarg; + +/** +** process the command-line arguments +** +** @param ac the count of entries in av +** @param av the argument vector +*/ +void process_args( int ac, char **av ) { + int c; + + while( (c=getopt(ac,av,":d:o:b:")) != EOF ) { + + switch( c ) { + + case ':': /* missing arg value */ + fprintf( stderr, "missing operand after -%c\n", optopt ); + /* FALL THROUGH */ + + case '?': /* error */ + usage_error(); + /* NOTREACHED */ + + case 'b': /* -b bootstrap_file */ + bootstrap_filename = optarg; + break; + + case 'd': /* -d drive */ + switch( *optarg ) { + case 'f': drive = DRIVE_FLOPPY; break; + case 'u': drive = DRIVE_USB; break; + default: usage_error(); + } + break; + + case 'o': /* -o output_file */ + output_filename = optarg; + break; + + default: + usage_error(); + + } + + } + + if( !bootstrap_filename ) { + fprintf( stderr, "%s: no bootstrap file specified\n", progname ); + exit( 2 ); + } + + if( !output_filename ) { + fprintf( stderr, "%s: no disk image file specified\n", progname ); + exit( 2 ); + } + + /* + ** Must have at least two remaining arguments (file to load, + ** address at which it should be loaded), and must have an + ** even number of remaining arguments. + */ + int remain = ac - optind; + if( remain < 2 || (remain & 1) != 0 ) { + usage_error(); + } + +} + +/** +** build a bootable image file from one or more binary files +** +** usage: +** BuildImage [ -d drive ] -b bootfile -o outfile { binfile1 loadpt1 } ... ] +** +** @param ac command-line argument count +** @param av command-line argument vector +** @return EXIT_SUCCESS or EXIT_FAILURE +*/ +int main( int ac, char **av ) { + FILE *bootimage; + int bootimage_size; + int n_bytes, n_words; + short existing_data[ N_INFO ]; + int i; + + /* + ** Save the program name for error messages + */ + progname = strrchr( av[ 0 ], '/' ); + if( progname != NULL ){ + progname++; + } else { + progname = av[ 0 ]; + } + + /* + ** Process arguments + */ + process_args( ac, av ); + + /* + ** Open the output file + */ + + out = fopen( output_filename, "wb+" ); + if( out == NULL ){ + quit( output_filename, TRUE ); + } + + /* + ** Open the bootstrap file and copy it to the output image. + */ + bootimage = fopen( bootstrap_filename, "rb" ); + if( bootimage == NULL ){ + quit( bootstrap_filename, TRUE ); + } + + /* + ** Remember the size of the bootstrap for later, as we + ** need to patch some things into it + */ + int n_sectors = copy_file( bootimage ); + fclose( bootimage ); + + bootimage_size = n_sectors * SECT_SIZE; + fprintf( stderr, " %s: %d sectors\n", bootstrap_filename, n_sectors ); + + /* + ** Process the programs one by one + */ + ac -= optind; + av += optind; + while( ac >= 2 ){ + process_file( av[ 0 ], av[ 1 ] ); + ac -= 2; av += 2; + } + + /* + ** Check for oddball leftover argument + */ + if( ac > 0 ){ + usage_error(); + } + + /* + ** Seek to where the array of module data must begin and read + ** what's already there. + */ + n_words = ( N_INFO - n_info ); + n_bytes = n_words * sizeof( info[ 0 ] ); + fseek( out, bootimage_size - n_bytes, SEEK_SET ); + if( fread( existing_data, sizeof(info[0]), n_words, out ) != n_words ){ + quit( "Read from boot image failed or was too short", FALSE ); + } + + /* + ** If that space is non-zero, we have a problem + */ + for( i = 0; i < n_words; i += 1 ){ + if( existing_data[ i ] != 0 ){ + quit( "Too many programs to load!", FALSE ); + } + } + + /* + ** We know that we're only overwriting zeros at the end of + ** the bootstrap image, so it is ok to go ahead and do it. + */ + fseek( out, bootimage_size - n_bytes, SEEK_SET ); + if( fwrite( info + n_info, sizeof( info[ 0 ] ), n_words, out ) != n_words ){ + quit( "Write to boot image failed or was too short", FALSE ); + } + + /* + ** Write the drive index to the image. + */ + fseek( out, 508, SEEK_SET ); + fwrite( (void *)&drive, sizeof(drive), 1, out ); + + fclose( out ); + + return EXIT_SUCCESS; + +} diff --git a/util/Make.mk b/util/Make.mk new file mode 100644 index 0000000..0f45625 --- /dev/null +++ b/util/Make.mk @@ -0,0 +1,59 @@ +# +# Makefile fragment for the utility programs +# +# THIS IS NOT A COMPLETE Makefile - run GNU make in the top-level +# directory, and this will be pulled in automatically. +# + +################### +# FILES SECTION # +################### + +UTIL_BIN := BuildImage Offsets mkblob listblob + +################### +# RULES SECTION # +################### + +# how to make everything +util: $(UTIL_BIN) + +# +# Special rules for creating the utility programs. These are required +# because we don't want to use the same options as for the standalone +# binaries - we want these to be compiled as "normal" programs. +# + +BuildImage: util/BuildImage.c + @mkdir -p $(@D) + $(CC) -std=c99 -ggdb -o BuildImage util/BuildImage.c + +mkblob: util/mkblob.c + @mkdir -p $(@D) + $(CC) -std=c99 -ggdb -o mkblob util/mkblob.c + +listblob: util/listblob.c + @mkdir -p $(@D) + $(CC) -std=c99 -ggdb -o listblob util/listblob.c + +# +# Offsets is compiled using -mx32 to force a 32-bit execution environment +# for a program that runs under a 64-bit operating system. This ensures +# that pointers and long ints are 32 bits rather than 64 bits, which is +# critical to correctly determining the size of types and byte offsets for +# fields in structs. We also compile with "-fno-builtin" to avoid signature +# clashes between declarations in our system and function declarations +# built into the C compiler. +# +# If compiled with the CPP macro CREATE_HEADER_FILE defined, Offsets +# accepts a command-line argument "-h". This causes it to write its +# output as a standard C header file into a file named "include/offsets.h" +# where it can be included into other source files (e.g., to provide +# sizes of structs in C and assembly, or to provide byte offsets into +# structures for use in assembly code). +# + +Offsets: util/Offsets.c + @mkdir -p $(@D) + $(CC) -mx32 -std=c99 $(INCLUDES) -fno-builtin \ + -o Offsets util/Offsets.c diff --git a/util/Offsets.c b/util/Offsets.c new file mode 100644 index 0000000..3cf5a46 --- /dev/null +++ b/util/Offsets.c @@ -0,0 +1,250 @@ +/* +** SCCS ID: @(#)Offsets.c 2.2 1/23/25 +** +** @file Offsets.c +** +** @author Warren R. Carithers +** +** Print byte offsets for fields in various structures. +** +** This program exists to simplify life. If/when fields in a structure +** are changed, this can be modified, recompiled and executed to come up with +** byte offsets for use in accessing structure fields from assembly language. +** It makes use of the C 'offsetof' macro (defined since C89). +** +** IMPORTANT NOTE: compiling this on a 64-bit architecture will yield +** incorrect results by default, as 64-bit GCC versions most often use +** the LP64 model (longs and pointers are 64 bits). Add the "-mx32" +** option to the compiler (compile for x86_64, but use 32-bit sizes), +** and make sure you have the 'libc6-dev-i386' package installed (for +** Ubuntu systems). +** +** WATCH FOR clashes with standard system functions; compile with the +** "-fno-builtin" option to avoid warnings about clashes with builtin +** function declarations. +** +** Writes to stdout. Output contains information about type sizes and +** byte offsets for fields within structures. If invoked with the -h +** option, the output takes the form of a standard C header file; +** otherwise, the information is printed in ordinary text form. +** +** If compiled with the CREATE_HEADER_FILE macro defined, when invoked +** with the -h option, writes the data directly into a file named +** "offsets.h". +*/ + +// make sure we get all the kernel stuff +#define KERNEL_SRC + +// include any of our headers that define data structures to be described +#include <common.h> +#include <procs.h> + +// avoid complaints about NULL from stdio.h +#ifdef NULL +#undef NULL +#endif + +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <unistd.h> + +/* +** We don't include <time.h> because of conflicts with a time_t data +** type we may be defining; instead, we provide our own prototypes for +** ctime() and time(). +*/ + +extern char *ctime( const __time_t *timep ); +extern __time_t time( __time_t *tloc ); + +/* +** Header comment, including header guard +** +** No newline on the "Creation date" line, because ctime() +** puts a newline at the end of the string it produces. +*/ +char h_prefix[] = "/**\n" +"** @file\toffsets.h\n" +"**\n" +"** GENERATED AUTOMATICALLY - DO NOT EDIT\n" +"**\n" +"** Creation date: %s" +"**\n" +"** This header file contains C Preprocessor macros which expand\n" +"** into the byte offsets needed to reach fields within structs\n" +"** used in the baseline system. Should those struct declarations\n" +"** change, the Offsets program should be modified (if needed),\n" +"** recompiled, and re-run to recreate this file.\n" +"*/\n" +"\n" +"#ifndef OFFSETS_H_\n" +"#define OFFSETS_H_\n"; + +/* +** Header guard suffix +*/ +char h_suffix[] = "\n" +"#endif\n"; + +// are we generating the .h file? +int genheader = 0; + +// header file stream +FILE *hfile; + +// prefix for header file lines + +// produce a report line +void process( const char *sname, const char *field, size_t bytes ) { + if( genheader ) { + char name[64]; + sprintf( name, "%s_%s", sname, field ); + fprintf( hfile, "#define\t%-23s\t%u\n", name, bytes ); + } else { + printf( " %-10s %u\n", field, bytes ); + } +} + +#ifdef CREATE_HEADER_FILE +// dump out the header +void setheader( void ) { + // trigger output into the header file + genheader = 1; + + hfile = fopen( "offsets.h", "w" ); + if( hfile == NULL ) { + perror( "offsets.h" ); + exit( 1 ); + } + + __time_t t; + (void) time( &t ); + + fprintf( hfile, h_prefix, ctime(&t) ); +} +#endif /* CREATE_HEADER_FILE */ + +// introduce an "offsets" section for structs +void hsection( const char *name, const char *typename, size_t size ) { + if( genheader ) { + fprintf( hfile, "\n// %s structure\n\n", typename ); + process( "SZ", name, size ); + fputc( '\n', hfile ); + } else { + printf( "Offsets into %s (%u bytes):\n", typename, size ); + } +} + +// introduce a "sizes" section for types +void tsection( const char *name, const char *typename ) { + if( genheader ) { + fprintf( hfile, "\n// Sizes of %s types\n\n", typename ); + } else { + printf( "Sizes of %s types:\n", typename ); + } +} + +int main( int argc, char *argv[] ) { + + hfile = stdout; + + if( argc > 1 ) { +#ifdef CREATE_HEADER_FILE + // only accept one argument + if( argc == 2 ) { + // -h: produce an offsets.h header file + if( argv[1][0] == '-' && argv[1][1] == '-h' ) { + setheader(); + } + } else { + fprintf( stderr, "usage: %s [-h]\n", argv[0] ); + exit( 1 ); + } +#else + // we accept no arguments + fprintf( stderr, "usage: %s\n", argv[0] ); + exit( 1 ); +#endif /* CREATE_HEADER_FILE */ + } + + /* + ** Basic and simple/opaque types + */ + + tsection( "SZ", "basic" ); + process( "SZ", "char", sizeof(char) ); + process( "SZ", "short", sizeof(short) ); + process( "SZ", "int", sizeof(int) ); + process( "SZ", "long", sizeof(long) ); + process( "SZ", "long_long", sizeof(long long) ); + process( "SZ", "pointer", sizeof(void *) ); + fputc( '\n', hfile ); + + tsection( "SZ", "our" ); + process( "SZ", "int8_t", sizeof(int8_t) ); + process( "SZ", "uint8_t", sizeof(uint8_t) ); + process( "SZ", "int16_t", sizeof(int16_t) ); + process( "SZ", "uint16_t", sizeof(uint16_t) ); + process( "SZ", "int32_t", sizeof(int32_t) ); + process( "SZ", "uint32_t", sizeof(uint32_t) ); + process( "SZ", "int64_t", sizeof(int64_t) ); + process( "SZ", "uint64_t", sizeof(uint64_t) ); + process( "SZ", "bool_t", sizeof(bool_t) ); + fputc( '\n', hfile ); + + /* + ** Structured types whose fields we are describing + */ + + // add entries for each type here, as needed + + hsection( "CTX", "context_t", sizeof(context_t) ); + process( "CTX", "ss", offsetof(context_t,ss) ); + process( "CTX", "gs", offsetof(context_t,gs) ); + process( "CTX", "fs", offsetof(context_t,fs) ); + process( "CTX", "es", offsetof(context_t,es) ); + process( "CTX", "ds", offsetof(context_t,ds) ); + process( "CTX", "edi", offsetof(context_t,edi) ); + process( "CTX", "esi", offsetof(context_t,esi) ); + process( "CTX", "ebp", offsetof(context_t,ebp) ); + process( "CTX", "esp", offsetof(context_t,esp) ); + process( "CTX", "ebx", offsetof(context_t,ebx) ); + process( "CTX", "edx", offsetof(context_t,edx) ); + process( "CTX", "ecx", offsetof(context_t,ecx) ); + process( "CTX", "eax", offsetof(context_t,eax) ); + process( "CTX", "vector", offsetof(context_t,vector) ); + process( "CTX", "code", offsetof(context_t,code) ); + process( "CTX", "eip", offsetof(context_t,eip) ); + process( "CTX", "cs", offsetof(context_t,cs) ); + process( "CTX", "eflags", offsetof(context_t,eflags) ); + fputc( '\n', hfile ); + + hsection( "SCT", "section_t", sizeof(section_t) ); + process( "SCT", "length", offsetof(section_t,length) ); + process( "SCT", "addr", offsetof(section_t,addr) ); + fputc( '\n', hfile ); + + hsection( "PCB", "pcb_t", sizeof(pcb_t) ); + process( "PCB", "context", offsetof(pcb_t,context) ); + process( "PCB", "next", offsetof(pcb_t,next) ); + process( "PCB", "parent", offsetof(pcb_t,parent) ); + process( "PCB", "wakeup", offsetof(pcb_t,wakeup) ); + process( "PCB", "exit_status", offsetof(pcb_t,exit_status) ); + process( "PCB", "pdir", offsetof(pcb_t,pdir) ); + process( "PCB", "sects", offsetof(pcb_t,sects) ); + process( "PCB", "pid", offsetof(pcb_t,pid) ); + process( "PCB", "state", offsetof(pcb_t,state) ); + process( "PCB", "priority", offsetof(pcb_t,priority) ); + process( "PCB", "ticks", offsetof(pcb_t,ticks) ); + fputc( '\n', hfile ); + + // finish up the offsets.h file if we need to + if( genheader ) { + fputs( h_suffix, hfile ); + fclose( hfile ); + } + + return( 0 ); +} diff --git a/util/alternatives/Make.mk b/util/alternatives/Make.mk new file mode 100644 index 0000000..d5703e8 --- /dev/null +++ b/util/alternatives/Make.mk @@ -0,0 +1,56 @@ +# +# Makefile fragment for the utility programs +# +# THIS IS NOT A COMPLETE Makefile - run GNU make in the top-level +# directory, and this will be pulled in automatically. +# + +SUBDIRS += util + +################### +# RULES SECTION # +################### + +# how to make everything +util: $(BUILDDIR)/util/BuildImage $(BUILDDIR)/util/Offsets \ + $(BUILDDIR)/util/mkblob $(BUILDDIR)/util/listblob + +# +# Special rules for creating the utility programs. These are required +# because we don't want to use the same options as for the standalone +# binaries - we want these to be compiled as "normal" programs. +# + +$(BUILDDIR)/util/BuildImage: util/BuildImage.c + @mkdir -p $(@D) + $(CC) -std=c99 -o $(BUILDDIR)/util/BuildImage util/BuildImage.c + +$(BUILDDIR)/util/mkblob: util/mkblob.c + @mkdir -p $(@D) + $(CC) -std=c99 -o $(BUILDDIR)/util/mkblob util/mkblob.c + +$(BUILDDIR)/util/listblob: util/listblob.c + @mkdir -p $(@D) + $(CC) -std=c99 -o $(BUILDDIR)/util/listblob util/listblob.c + +# +# Offsets is compiled using -mx32 to force a 32-bit execution environment +# for a program that runs under a 64-bit operating system. This ensures +# that pointers and long ints are 32 bits rather than 64 bits, which is +# critical to correctly determining the size of types and byte offsets for +# fields in structs. We also compile with "-fno-builtin" to avoid signature +# clashes between declarations in our system and function declarations +# built into the C compiler. +# +# If compiled with the CPP macro CREATE_HEADER_FILE defined, Offsets +# accepts a command-line argument "-h". This causes it to write its +# output as a standard C header file into a file named "include/offsets.h" +# where it can be included into other source files (e.g., to provide +# sizes of structs in C and assembly, or to provide byte offsets into +# structures for use in assembly code). +# + +$(BUILDDIR)/util/Offsets: util/Offsets.c + @mkdir -p $(@D) + $(CC) -mx32 -std=c99 $(INCLUDES) -fno-builtin \ + -o $(BUILDDIR)/util/Offsets util/Offsets.c diff --git a/util/alternatives/README b/util/alternatives/README new file mode 100644 index 0000000..ae4dfbe --- /dev/null +++ b/util/alternatives/README @@ -0,0 +1,31 @@ +This directory contains "alternative" versions of some pieces of the system. + +Things included here: + + Make.mk + This version of the Makefile fragment puts the utility programs + in build/util instead of in the top-level directory. + + kmem.c + A version of the memory allocator that works with blocks of memory + that aren't exactly one page in length. During initialilzation, it + just adds each memory region identified during the boot process by + calls to the BIOS; as pages are requested, they are carved out of + these large blocks. The freelist is ordered by starting block + address, and allocation uses a first-fit strateby. + + The allocation function has this prototype: + + void *km_page_alloc( unsigned int count ); + + This allows the allocation of multiple contiguous pages. As pages + are freed, they are merged back into the freelist, and adjacent + free pages are coalesced into single, larger blocks. + + lib.c + This file pulls in all the individual .c files for the common + library functions in the lib/ directory. It is intended as an + alternative to having the libk.a archive file for the kernel; + instead of linking against that library, the lib.o file can + just be provided to the linker when the kernel is created, + and all the common library functions will be available. diff --git a/util/alternatives/kmem.c b/util/alternatives/kmem.c new file mode 100644 index 0000000..f1abf02 --- /dev/null +++ b/util/alternatives/kmem.c @@ -0,0 +1,749 @@ +/** +** @file kmem.c +** +** @author Warren R. Carithers +** @author Kenneth Reek +** @author 4003-506 class of 20013 +** +** @brief Functions to perform dynamic memory allocation in the OS. +** +** NOTE: these should NOT be called by user processes! +** +** This allocator functions as a simple "slab" allocator; it allows +** allocation of either 4096-byte ("page") or 1024-byte ("slice") +** chunks of memory from the free pool. The free pool is initialized +** using the memory map provided by the BIOS during the boot sequence, +** and contains a series of blocks which are multiples of 4K bytes and +** which are aligned at 4K boundaries; they are held in the free list +** in order by base address. +** +** The "page" allocator allows allocation of one or more 4K blocks +** at a time. Requests are made for a specific number of 4K pages; +** the allocator locates the first free list entry that contains at +** least the requested amount of space. If that entry is the exact +** size requested, it is unlinked and returned; otherwise, the entry +** is split into a chunk of the requested size and the remainder. +** The chunk is returned, and the remainder replaces the original +** block in the free list. On deallocation, the block is inserted +** at the appropriate place in the free list, and physically adjacent +** blocks are coalesced into single, larger blocks. If a multi-page +** block is allocated, it should be deallocated one page at a time, +** because there is no record of the size of the original allocation - +** all we know is that it is N*4K bytes in length, so it's up to the +** requesting code to figure this out. +** +** The "slice" allocator operates by taking blocks from the "page" +** allocator and splitting them into four 1K slices, which it then +** manages. Requests are made for slices one at a time. If the free +** list contains an available slice, it is unlinked and returned; +** otherwise, a page is requested from the page allocator, split into +** slices, and the slices are added to the free list, after which the +** first one is returned. The slice free list is a simple linked list +** of these 1K blocks; because they are all the same size, no ordering +** is done on the free list, and no coalescing is performed. +** +*/ + +#define KERNEL_SRC + +#include <common.h> + +// all other framework includes are next +#include <lib.h> + +#include <x86/arch.h> +#include <x86/bios.h> +#include <bootstrap.h> +#include <cio.h> + +#include <kmem.h> + +/* +** PRIVATE DEFINITIONS +*/ + +// parameters related to word and block sizes + +#define WORD_SIZE sizeof(int) +#define LOG2_OF_WORD_SIZE 2 + +#define LOG2_OF_PAGE_SIZE 12 + +#define LOG2_OF_SLICE_SIZE 10 + +// converters: pages to bytes, bytes to pages + +#define P2B(x) ((x) << LOG2_OF_PAGE_SIZE) +#define B2P(x) ((x) >> LOG2_OF_PAGE_SIZE) + +/* +** Name: adjacent +** +** Arguments: addresses of two blocks +** +** Description: Determines whether the second block immediately +** follows the first one. +*/ +#define adjacent(first,second) \ + ( (void *) (first) + P2B((first)->pages) == (void *) (second) ) + +/* +** PRIVATE DATA TYPES +*/ + +/* +** This structure keeps track of a single block of memory. All blocks +** are multiples of the base size (currently, 4KB). +*/ + +typedef struct block_s { + uint32_t pages; // length of this block, in pages + struct block_s *next; // pointer to the next free block +} block_t; + +/* +** Memory region information returned by the BIOS +** +** This data consists of a 32-bit integer followed +** by an array of region descriptor structures. +*/ + +// a handy union for playing with 64-bit addresses +typedef union b64_u { + uint32_t part[2]; + uint64_t all; +} b64_t; + +// the halves of a 64-bit address +#define LOW part[0] +#define HIGH part[1] + +// memory region descriptor +typedef struct memregion_s { + b64_t base; // base address + b64_t length; // region length + uint32_t type; // type of region + uint32_t acpi; // ACPI 3.0 info +} __attribute__((packed)) region_t; + +/* +** Region types +*/ + +#define REGION_USABLE 1 +#define REGION_RESERVED 2 +#define REGION_ACPI_RECL 3 +#define REGION_ACPI_NVS 4 +#define REGION_BAD 5 + +/* +** ACPI 3.0 bit fields +*/ + +#define REGION_IGNORE 0x01 +#define REGION_NONVOL 0x02 + +/* +** 32-bit and 64-bit address values as 64-bit literals +*/ + +#define ADDR_BIT_32 0x0000000100000000LL +#define ADDR_LOW_HALF 0x00000000ffffffffLL +#define ADDR_HIGH_HALR 0xffffffff00000000LL + +#define ADDR_32_MAX ADDR_LOW_HALF +#define ADDR_64_FIRST ADDR_BIT_32 + +/* +** PRIVATE GLOBAL VARIABLES +*/ + +// freespace pools +static block_t *free_pages; +static block_t *free_slices; + +// initialization status +static int km_initialized = 0; + +/* +** IMPORTED GLOBAL VARIABLES +*/ + +extern int _end; // end of the BSS section - provided by the linker + +/* +** FUNCTIONS +*/ + +/* +** FREE LIST MANAGEMENT +*/ + +/** +** Name: add_block +** +** Add a block to the free list. The contents of the block +** will be modified. +** +** @param[in] base Base address of the block +** @param[in] length Block length, in bytes +*/ +static void add_block( uint32_t base, uint32_t length ) { + block_t *block; + + // don't add it if it isn't at least 4K + if( length < SZ_PAGE ) { + return; + } + + // only want to add multiples of 4K; check the lower bits + if( (length & 0xfff) != 0 ) { + // round it down to 4K + length &= 0xfffff000; + } + + // create the "block" + + block = (block_t *) base; + block->pages = B2P(length); + block->next = NULL; + +#if TRACING_KMEM_FREE + cio_printf( "KM: add(%08x,%u): addr %08x len %u\n", + base, length, (uint32_t)block, block->length ); +#endif + + /* + ** We maintain the free list in order by address, to simplify + ** coalescing adjacent free blocks. + ** + ** Handle the easiest case first. + */ + + if( free_pages == NULL ) { + free_pages = block; + return; + } + + /* + ** Unfortunately, it's not always that easy.... + ** + ** Find the correct insertion spot. + */ + + block_t *prev, *curr; + + prev = NULL; + curr = free_pages; + + while( curr && curr < block ) { + prev = curr; + curr = curr->next; + } + + // the new block always points to its successor + block->next = curr; + + /* + ** If prev is NULL, we're adding at the front; otherwise, + ** we're adding after some other entry (middle or end). + */ + + if( prev == NULL ) { + // sanity check - both pointers can't be NULL + assert( curr ); + // add at the beginning + free_pages = block; + } else { + // inserting in the middle or at the end + prev->next = block; + } +} + +/** +** Name: km_init +** +** Find what memory is present on the system and +** construct the list of free memory blocks. +** +** Dependencies: +** Must be called before any other init routine that uses +** dynamic storage is called. +*/ +void km_init( void ) { + int32_t entries; + region_t *region; + uint64_t cutoff; + +#if TRACING_INIT + // announce that we're starting initialization + cio_puts( " Kmem" ); +#endif + + // initially, nothing in the free lists + free_slices = NULL; + free_pages = NULL; + + /* + ** We ignore all memory below the end of our OS. In theory, + ** we should be able to re-use much of that space; in practice, + ** this is safer. + */ + + // set our cutoff point as the end of the BSS section + cutoff = (uint32_t) &_end; + + // round it up to the next multiple of 4K (0x1000) + if( cutoff & 0xfffLL ) { + cutoff &= 0xfffff000LL; + cutoff += 0x1000LL; + } + + // get the list length + entries = *((int32_t *) MMAP_ADDRESS); + +#if TRACING_KEMEM + cio_printf( "\nKmem: %d regions\n", entries ); +#endif + + // if there are no entries, we have nothing to do! + if( entries < 1 ) { // note: entries == -1 could occur! + return; + } + + // iterate through the entries, adding things to the freelist + + region = ((region_t *) (MMAP_ADDRESS + 4)); + + for( int i = 0; i < entries; ++i, ++region ) { + +#if TRACING_KMEM + // report this region + cio_printf( "%3d: ", i ); + cio_printf( " base %08x%08x", + region->base.HIGH, region->base.LOW ); + cio_printf( " len %08x%08x", + region->length.HIGH, region->length.LOW ); + cio_printf( " type %08x acpi %08x", + region->type, region->acpi ); +#endif + + /* + ** Determine whether or not we should ignore this region. + ** + ** We ignore regions for several reasons: + ** + ** ACPI indicates it should be ignored + ** ACPI indicates it's non-volatile memory + ** Region type isn't "usable" + ** Region is above the 4GB address limit + ** + ** Currently, only "normal" (type 1) regions are considered + ** "usable" for our purposes. We could potentially expand + ** this to include ACPI "reclaimable" memory. + */ + + // first, check the ACPI one-bit flags + + if( ((region->acpi) & REGION_IGNORE) == 0 ) { + cio_puts( " IGN\n" ); + continue; + } + + if( ((region->acpi) & REGION_NONVOL) != 0 ) { + cio_puts( " NVOL\n" ); + continue; // we'll ignore this, too + } + + // next, the region type + + if( (region->type) != REGION_USABLE ) { + cio_puts( " RCLM\n" ); + continue; // we won't attempt to reclaim ACPI memory (yet) + } + + // OK, we have a "normal" memory region - verify that it's usable + + // ignore it if it's above 4GB + if( region->base.HIGH != 0 ) { + cio_puts( " 4GB+\n" ); + continue; + } + + // grab the two 64-bit values to simplify things + uint64_t base = region->base.all; + uint64_t length = region->length.all; + + // see if it's below our arbitrary cutoff point + if( base < cutoff ) { + + // is the whole thing too low, or just part? + if( (base + length) < cutoff ) { + // it's all below the cutoff! + cio_puts( " LOW\n" ); + continue; + } + + // recalculate the length, starting at our cutoff point + uint64_t loss = cutoff - base; + + // reset the length and the base address + length -= loss; + base = cutoff; + } + + // see if it extends beyond the 4GB boundary + + if( (base + length) > ADDR_32_MAX ) { + + // OK, it extends beyond the 32-bit limit; figure out + // how far over it goes, and lop off that portion + + uint64_t loss = (base + length) - ADDR_64_FIRST; + length -= loss; + } + + // we survived the gauntlet - add the new block + + cio_puts( " OK\n" ); + + uint32_t b32 = base & ADDR_LOW_HALF; + uint32_t l32 = length & ADDR_LOW_HALF; + + add_block( b32, l32 ); + } + + // record the initialization + km_initialized = 1; +} + +/** +** Name: km_dump +** +** Dump the current contents of the free list to the console +*/ +void km_dump( void ) { + block_t *block; + + cio_printf( "&_free_pages=%08x\n", &_free_pages ); + + for( block = _free_pages; block != NULL; block = block->next ) { + cio_printf( + "block @ 0x%08x 0x%08x pages (ends at 0x%08x) next @ 0x%08x\n", + block, block->pages, P2B(block->pages) + (uint32_t) block, + block->next ); + } + +} + +/* +** PAGE MANAGEMENT +*/ + +/** +** Name: km_page_alloc +** +** Allocate a page of memory from the free list. +** +** @param[in] count Number of contiguous pages desired +** +** @return a pointer to the beginning of the first allocated page, +** or NULL if no memory is available +*/ +void *km_page_alloc( unsigned int count ) { + + assert( km_initialized ); + + // make sure we actually need to do something! + if( count < 1 ) { + return( NULL ); + } + +#if TRACING_KMEM_FREE + cio_printf( "KM: pg_alloc(%u)", count ); +#endif + + /* + ** Look for the first entry that is large enough. + */ + + // pointer to the current block + block_t *block = free_pages; + + // pointer to where the pointer to the current block is + block_t **pointer = &free_pages; + + while( block != NULL && block->pages < count ){ + pointer = &block->next; + block = *pointer; + } + + // did we find a big enough block? + if( block == NULL ){ + // nope! +#if TRACING_KMEM_FREE + cio_puts( " FAIL\n" ); +#endif + return( NULL ); + } + + // found one! check the length + + if( block->pages == count ) { + + // exactly the right size - unlink it from the list + + *pointer = block->next; + + } else { + + // bigger than we need - carve the amount we need off + // the beginning of this block + + // remember where this chunk begins + block_t *chunk = block; + + // how much space will be left over? + int excess = block->pages - count; + + // find the start of the new fragment + block_t *fragment = (block_t *) ( (uint8_t *) block + P2B(count) ); + + // set the length and link for the new fragment + fragment->pages = excess; + fragment->next = block->next; + + // replace this chunk with the fragment + *pointer = fragment; + + // return this chunk + block = chunk; + } + +#if TRACING_KMEM_FREE + cio_printf( " -> %08x\n", (uint32_t) block ); +#endif + + return( block ); +} + +/** +** Name: km_page_free +** +** Returns a memory block to the list of available blocks, +** combining it with adjacent blocks if they're present. +** +** CRITICAL ASSUMPTION: multi-page blocks will be freed one page +** at a time! +** +** @param[in] block Pointer to the page to be returned to the free list +*/ +void km_page_free( void *block ){ + block_t *used; + block_t *prev; + block_t *curr; + + assert( km_initialized ); + + /* + ** Don't do anything if the address is NULL. + */ + if( block == NULL ){ + return; + } + +#if TRACING_KMEM_FREE + cio_printf( "KM: pg_free(%08x)", (uint32_t) block ); +#endif + + used = (block_t *) block; + + /* + ** CRITICAL ASSUMPTION + ** + ** We assume that any multi-page block that is being freed will + ** be freed one page at a time. We make this assumption because we + ** don't track allocation sizes. We can't use the simple "allocate + ** four extra bytes before the returned pointer" scheme to do this + ** because we're managing pages, and the pointers we return must point + ** to page boundaries, so we would wind up allocating an extra page + ** for each allocation. + ** + ** Alternatively, we could keep an array of addresses and block + ** sizes ourselves, but that feels clunky, and would risk running out + ** of table entries if there are lots of allocations (assuming we use + ** a 4KB page to hold the table, at eight bytes per entry we would have + ** 512 entries per page). + ** + ** IF THIS ASSUMPTION CHANGES, THIS CODE MUST BE FIXED!!! + */ + + used->pages = 1; + + /* + ** Advance through the list until current and previous + ** straddle the place where the new block should be inserted. + */ + prev = NULL; + curr = free_pages; + + while( curr != NULL && curr < used ){ + prev = curr; + curr = curr->next; + } + + /* + ** At this point, we have the following list structure: + ** + ** .... BLOCK BLOCK .... + ** (*prev) ^ (*curr) + ** | + ** "used" goes here + ** + ** We may need to merge the inserted block with either its + ** predecessor or its successor (or both). + */ + + /* + ** If this is not the first block in the resulting list, + ** we may need to merge it with its predecessor. + */ + if( prev != NULL ){ + + // There is a predecessor. Check to see if we need to merge. + if( adjacent( prev, used ) ){ + + // yes - merge them + prev->pages += used->pages; + + // the predecessor becomes the "newly inserted" block, + // because we still need to check to see if we should + // merge with the successor + used = prev; + + } else { + + // Not adjacent - just insert the new block + // between the predecessor and the successor. + used->next = prev->next; + prev->next = used; + + } + + } else { + + // Yes, it is first. Update the list pointer to insert it. + used->next = free_pages; + free_pages = used; + + } + + /* + ** If this is not the last block in the resulting list, + ** we may (also) need to merge it with its successor. + */ + if( curr != NULL ){ + + // No. Check to see if it should be merged with the successor. + if( adjacent( used, curr ) ){ + + // Yes, combine them. + used->next = curr->next; + used->pages += curr->pages; + + } + } +} + +/* +** SLICE MANAGEMENT +*/ + +/* +** Slices are 1024-byte fragments from pages. We maintain a free list of +** slices for those parts of the OS which don't need full 4096-byte chunks +** of space (e.g., the QNode and Queue allocators). +*/ + +/** +** Name: carve_slices +** +** Allocate a page and split it into four slices; If no +** memory is available, we panic. +*/ +static void carve_slices( void ) { + void *page; + + // get a page + page = km_page_alloc( 1 ); + + // allocation failure is a show-stopping problem + assert( page ); + + // we have the page; create the four slices from it + uint8_t *ptr = (uint8_t *) page; + for( int i = 0; i < 4; ++i ) { + km_slice_free( (void *) ptr ); + ptr += SZ_SLICE; + } +} + +/** +** Name: km_slice_alloc +** +** Dynamically allocates a slice (1/4 of a page). If no +** memory is available, we panic. +** +** @return a pointer to the allocated slice +*/ +void *km_slice_alloc( void ) { + block_t *slice; + + assert( km_initialized ); + +#if TRACING_KMEM_FREE + cio_printf( "KM: sl_alloc()\n" ); +#endif + + // if we are out of slices, create a few more + if( free_slices == NULL ) { + carve_slices(); + } + + // take the first one from the free list + slice = free_slices; + assert( slice != NULL ); + + // unlink it + free_slices = slice->next; + + // make it nice and shiny for the caller + memclr( (void *) slice, SZ_SLICE ); + + return( slice ); +} + +/** +** Name: km_slice_free +** +** Returns a slice to the list of available slices. +** +** We make no attempt to merge slices, as they are independent +** blocks of memory (unlike pages). +** +** @param[in] block Pointer to the slice (1/4 page) to be freed +*/ +void km_slice_free( void *block ) { + block_t *slice = (block_t *) block; + + assert( km_initialized ); + +#if TRACING_KMEM_FREE + cio_printf( "KM: sl_free(%08x)\n", (uint32_t) block ); +#endif + + // just add it to the front of the free list + slice->pages = SZ_SLICE; + slice->next = free_slices; + free_slices = slice; +} diff --git a/util/alternatives/lib.c b/util/alternatives/lib.c new file mode 100644 index 0000000..4b7a9ed --- /dev/null +++ b/util/alternatives/lib.c @@ -0,0 +1,56 @@ +/** +** @file lib.c +** +** @author Numerous CSCI-452 classes +** +** @brief C implementations of common library functions +** +** These are callable from either kernel or user code. Care should be taken +** that user code is linked against these separately from kernel code, to +** ensure separation of the address spaces. +** +** This file exists to pull them all in as a single object file. +*/ + +#include <common.h> + +#include <lib.h> + +/* +********************************************** +** MEMORY MANIPULATION FUNCTIONS +********************************************** +*/ + +#include "common/memset.c" +#include "common/memclr.c" +#include "common/memcpy.c" + +/* +********************************************** +** STRING MANIPULATION FUNCTIONS +********************************************** +*/ + +#include "common/str2int.c" +#include "common/strlen.c" +#include "common/strcmp.c" +#include "common/strcpy.c" +#include "common/strcat.c" +#include "common/pad.c" +#include "common/padstr.c" +#include "common/sprint.c" + +/* +********************************************** +** CONVERSION FUNCTIONS +********************************************** +*/ + +#include "common/cvtuns0.c" +#include "common/cvtuns.c" +#include "common/cvtdec0.c" +#include "common/cvtdec.c" +#include "common/cvthex.c" +#include "common/cvtoct.c" +#include "common/bound.c" diff --git a/util/gdbinit.tmpl b/util/gdbinit.tmpl new file mode 100644 index 0000000..d9a981d --- /dev/null +++ b/util/gdbinit.tmpl @@ -0,0 +1,31 @@ +# adapted from the xv6 .gdbinit.tmpl file +set $lastcs = -1 + +define hook-stop + # There doesn't seem to be a good way to detect if we're in 16- or + # 32-bit mode, but we always run with CS == 8 in 32-bit mode. + if $cs == 8 || $cs == 27 + if $lastcs != 8 && $lastcs != 27 + set architecture i386 + end + x/i $pc + else + if $lastcs == -1 || $lastcs == 8 || $lastcs == 27 + set architecture i8086 + end + # Translate the segment:offset into a physical address + printf "[%4x:%4x] ", $cs, $eip + x/i $cs*16+$eip + end + set $lastcs = $cs +end + +echo + target remote localhost:1234\n +target remote localhost:1234 + +# If this fails, it's probably because your GDB doesn't support ELF. +# Look at the tools page at +# http://pdos.csail.mit.edu/6.828/2009/tools.html +# for instructions on building GDB with ELF support. +echo + symbol-file build/kernel/kernel\n +symbol-file build/kernel/kernel diff --git a/util/listblob.c b/util/listblob.c new file mode 100644 index 0000000..07523a6 --- /dev/null +++ b/util/listblob.c @@ -0,0 +1,248 @@ +/** +** @file listblob.c +** +** @author Warren R. Carithers +** +** Examine a binary blob of ELF files. +*/ +#define _DEFAULT_SOURCE +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <elf.h> +#include <ctype.h> + +/* +** Blob file organization +** +** The file begins with a four-byte magic number and a four-byte integer +** indicating the number of ELF files contained in the blob. This is +** followed by an array of 32-byte file entries, and then the contents +** of the ELF files in the order they appear in the program file table. +** +** Bytes Contents +** ----- ---------------------------- +** 0 - 3 File magic number ("BLB\0") +** 4 - 7 Number of ELF files in blob ("n") +** 8 - n*32+8 Program file table +** n*32+9 - ? ELF file contents +** +** Each program file table entry contains the following information: +** +** name File name (up to 19 characters long) +** offset Byte offset to the ELF header for this file +** size Size of this ELF file, in bytes +** flags Flags related to this file +*/ + +// blob header: 8 bytes +typedef struct header_s { + char magic[4]; + uint32_t num; +} header_t; + +// The program table entry is 32 bytes long. To accomplish this, the +// name field is 20 bytes long, which allows file names of 19 characters +// (followed by a trailing NUL byte). +// +// If that field is made longer, it should be incremented in multiples +// of four to avoid the insertion of padding bytes. +#define NAMELEN 20 + +// program descriptor: 32 bytes +typedef struct prog_s { + char name[NAMELEN]; // truncated name (19 chars plus NUL) + uint32_t offset; // offset from the beginning of the blob + uint32_t size; // size of this ELF module + uint32_t flags; // miscellaneous flags +} prog_t; + +// modules must be written as multiples of eight bytes +#define FL_ROUNDUP 0x00000001 + +// mask for mod 8 checking +#define FSIZE_MASK 0x00000007 + +// program list entry +typedef struct node_s { + prog_t *data; + struct node_s *next; +} node_t; + +node_t *progs, *last_prog; // list pointers +uint32_t n_progs; // number of files being copied +uint32_t offset; // current file area offset +bool defs = false; // print CPP #defines? +bool enums = false; // print C enums? + +// header string for the userids.h file +const char header[] = +"/**\n" +"** @file userids.h\n" +"**\n" +"** @author Warren R. Carithers\n" +"**\n" +"** @brief IDs for user-level programs\n" +"**\n" +"** NOTE: this file is automatically generated when the user.img file\n" +"** is created. Do not edit this manually!\n" +"*/\n" +"\n" +"#ifndef USERIDS_H_\n" +"#define USERIDS_H_\n" +"\n" +"#ifndef ASM_SRC\n" +"/*\n" +"** These IDs are used to identify the various user programs.\n" +"** Each call to exec() will provide one of these as the first\n" +"** argument.\n" +"**\n" +"** This list should be updated if/when the collection of\n" +"** user processes changes.\n" +"*/\n" +"enum users_e {" +; + +// trailer string for the userids.h file +const char trailer[] = +"\n\t// sentinel\n\t, N_USERS\n" +"};\n" +"#endif /* !ASM_SRC */\n" +"\n" +"#endif" +; + +/** +** Name: process +** +** Process a program list entry +** +** @param num Program list index +** @param prog Pointer to the program list entry +*/ +void process( uint32_t num, prog_t *prog ) { + + if( defs || enums ) { + + char *slash = strrchr( prog->name, '/' ); + if( slash == NULL ) { + slash = prog->name; + } else { + ++slash; + } + + slash[0] = toupper(slash[0]); + + if( defs ) { + + // just printing #define statements + printf( "#define %-15s %2d\n", prog->name, num ); + + } else { + + // printing a new userids.h file + if( num == 0 ) { + // first one, so print the file header + puts( header ); + putchar( '\t' ); + } else { + // second or later entry; limit to 8 per line + fputs( ((num & 0x7) == 0 ) ? ",\n\t" : ", ", stdout ); + } + printf( "%s", prog->name ); + } + + } else { + + // just printing information + printf( "Entry %2d: ", num ); + printf( "%-s,", prog->name ); + printf( " offset 0x%x, size 0x%x, flags %08x\n", + prog->offset, prog->size, prog->flags ); + } +} + +void usage( char *name ) { + fprintf( stderr, "usage: %s [-d | -e] blob_name\n", name ); +} + +int main( int argc, char *argv[] ) { + + if( argc < 2 || argc > 3) { + usage( argv[0] ); + exit( 1 ); + } + + int nameix = 1; + + // could use getopt() for this, but this is easy enough + if( argc == 3 ) { + if( strcmp(argv[1],"-d") == 0 ) { + defs = true; + } else if( strcmp(argv[1],"-e") == 0 ) { + enums = true; + } else { + usage( argv[0] ); + exit( 1 ); + } + nameix = 2; + } + + char *name = argv[nameix]; + + int fd = open( name, O_RDONLY ); + if( fd < 0 ) { + perror( name ); + exit( 1 ); + } + + header_t hdr; + + int n = read( fd, &hdr, sizeof(header_t) ); + if( n != sizeof(header_t) ) { + fprintf( stderr, "%s: header read returned only %d bytes\n", name, n ); + close( fd ); + exit( 1 ); + } + + if( strcmp(hdr.magic,"BLB") != 0 ) { + fprintf( stderr, "%s: bad magic number\n", name ); + close( fd ); + exit( 1 ); + } + + if( hdr.num < 1 ) { + fprintf( stderr, "%s: no programs in blob?\n", name ); + close( fd ); + exit( 1 ); + } + + prog_t progs[hdr.num]; + + n = read( fd, progs, hdr.num * sizeof(prog_t) ); + if( n != (int) (hdr.num * sizeof(prog_t)) ) { + + fprintf( stderr, "%s: prog table only %d bytes, expected %lu\n", + name, n, hdr.num * sizeof(prog_t) ); + close( fd ); + exit( 1 ); + } + + for( uint32_t i = 0; i < hdr.num; ++i ) { + process( i, &progs[i] ); + } + + if( enums ) { + // print the file trailer + puts( trailer ); + } + + close( fd ); + return 0; + +} diff --git a/util/mergedep.pl b/util/mergedep.pl new file mode 100644 index 0000000..1730d53 --- /dev/null +++ b/util/mergedep.pl @@ -0,0 +1,86 @@ +#!/usr/bin/perl +# Copyright 2003 Bryan Ford +# Distributed under the GNU General Public License. +# +# Usage: mergedep <main-depfile> [<new-depfiles> ...] +# +# This script merges the contents of all <new-depfiles> specified +# on the command line into the single file <main-depfile>, +# which may or may not previously exist. +# Dependencies in the <new-depfiles> will override +# any existing dependencies for the same targets in <main-depfile>. +# The <new-depfiles> are deleted after <main-depfile> is updated. +# +# The <new-depfiles> are typically generated by GCC with the -MD option, +# and the <main-depfile> is typically included from a Makefile, +# as shown here for GNU 'make': +# +# .deps: $(wildcard *.d) +# perl mergedep $@ $^ +# -include .deps +# +# This script properly handles multiple dependencies per <new-depfile>, +# including dependencies having no target, +# so it is compatible with GCC3's -MP option. +# + +sub readdeps { + my $filename = shift; + + open(DEPFILE, $filename) or return 0; + while (<DEPFILE>) { + if (/([^:]*):([^\\:]*)([\\]?)$/) { + my $target = $1; + my $deplines = $2; + my $slash = $3; + while ($slash ne '') { + $_ = <DEPFILE>; + defined($_) or die + "Unterminated dependency in $filename"; + /(^[ \t][^\\]*)([\\]?)$/ or die + "Bad continuation line in $filename"; + $deplines = "$deplines\\\n$1"; + $slash = $2; + } + #print "DEPENDENCY [[$target]]: [[$deplines]]\n"; + $dephash{$target} = $deplines; + } elsif (/^[#]?[ \t]*$/) { + # ignore blank lines and comments + } else { + die "Bad dependency line in $filename: $_"; + } + } + close DEPFILE; + return 1; +} + + +if ($#ARGV < 0) { + print "Usage: mergedep <main-depfile> [<new-depfiles> ..]\n"; + exit(1); +} + +%dephash = (); + +# Read the main dependency file +$maindeps = $ARGV[0]; +readdeps($maindeps); + +# Read and merge in the new dependency files +foreach $i (1 .. $#ARGV) { + readdeps($ARGV[$i]) or die "Can't open $ARGV[$i]"; +} + +# Update the main dependency file +open(DEPFILE, ">$maindeps.tmp") or die "Can't open output file $maindeps.tmp"; +foreach $target (keys %dephash) { + print DEPFILE "$target:$dephash{$target}"; +} +close DEPFILE; +rename("$maindeps.tmp", "$maindeps") or die "Can't overwrite $maindeps"; + +# Finally, delete the new dependency files +foreach $i (1 .. $#ARGV) { + unlink($ARGV[$i]) or print "Error removing $ARGV[$i]\n"; +} + diff --git a/util/mkblob.c b/util/mkblob.c new file mode 100644 index 0000000..32c67dd --- /dev/null +++ b/util/mkblob.c @@ -0,0 +1,324 @@ +/** +** @file mkblob.c +** +** @author Warren R. Carithers +** +** Create a binary blob from a collection of ELF files. +*/ +#define _DEFAULT_SOURCE + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <elf.h> + +/* +** Blob file organization +** +** The file begins with a four-byte magic number and a four-byte integer +** indicating the number of ELF files contained in the blob. This is +** followed by an array of 32-byte file table entries, and then the contents +** of the ELF files in the order they appear in the program file table. +** +** Bytes Contents +** ----- ---------------------------- +** 0 - 3 File magic number ("BLB\0") +** 4 - 7 Number of ELF files in blob ("n") +** 8 - n*32+8 Program file table +** n*32+9 - ? ELF file contents +** +** Each program file table entry contains the following information: +** +** name File name (up to 19 characters long) +** offset Byte offset to the ELF header for this file +** size Size of this ELF file, in bytes +** flags Flags related to this file +*/ + +// blob header +typedef struct header_s { + char magic[4]; + uint32_t num; +} header_t; + +// length of the file name field +#define NAMELEN 20 + +// program descriptor +typedef struct prog_s { + char name[NAMELEN]; // truncated name (15 chars) + uint32_t offset; // offset from the beginning of the blob + uint32_t size; // size of this ELF module + uint32_t flags; // miscellaneous flags +} prog_t; + +// modules must be written as multiples of eight bytes +#define FL_ROUNDUP 0x00000001 + +// mask for mod 8 checking +#define FSIZE_MASK 0x00000007 + +// program list entry +typedef struct node_s { + prog_t *data; + char *fullname; + struct node_s *next; +} node_t; + +node_t *progs, *last_prog; // list pointers +uint32_t n_progs; // number of files being copied +uint32_t offset; // current file area offset + +/** +** Name: process +** +** Do the initial processing for an ELF file +** +** @param name The name of the file +*/ +void process( const char *name ) { + struct stat info; + + // check the name length + if( strlen(name) >= NAMELEN ) { + fprintf( stderr, "%s: name exceeds length limit (%d)\n", + name, NAMELEN-1 ); + return; + } + + // does it exist? + if( stat(name,&info) < 0 ) { + perror( name ); + return; + } + + // is it a regular file? + if( !S_ISREG(info.st_mode) ) { + fprintf( stderr, "%s: not a regular file\n", name ); + return; + } + + // open it and check the file header + int fd = open( name, O_RDONLY ); + if( fd < 0 ) { + perror( name ); + return; + } + + // read and check the ELF header + Elf32_Ehdr hdr; + int n = read( fd, &hdr, sizeof(Elf32_Ehdr) ); + close( fd ); + + if( n != sizeof(Elf32_Ehdr) ) { + fprintf( stderr, "%s: header read was short - only %d\n", name, n ); + return; + } + + if( hdr.e_ident[EI_MAG0] != ELFMAG0 || + hdr.e_ident[EI_MAG1] != ELFMAG1 || + hdr.e_ident[EI_MAG2] != ELFMAG2 || + hdr.e_ident[EI_MAG3] != ELFMAG3 ) { + fprintf( stderr, "%s: bad ELF magic number\n", name ); + return; + } + + // ok, it's a valid ELF file - create the prog list entry + prog_t *new = calloc( 1, sizeof(prog_t) ); + if( new == NULL ) { + fprintf( stderr, "%s: calloc prog returned NULL\n", name ); + return; + } + + node_t *node = calloc( 1, sizeof(node_t) ); + if( node == NULL ) { + free( new ); + fprintf( stderr, "%s: calloc node returned NULL\n", name ); + return; + } + + node->data = new; + node->fullname = strdup( name ); + + // copy in the name + + // only want the last component + const char *slash = strrchr( name, '/' ); + if( slash == NULL ) { + // only the file name + slash = name; + } else { + // skip the slash + ++slash; + } + + strncpy( new->name, slash, sizeof(new->name)-1 ); + new->offset = offset; + new->size = info.st_size; + + // bump our counters + ++n_progs; + offset += info.st_size; + + // make sure it's a multiple of eight bytes long + if( (info.st_size & FSIZE_MASK) != 0 ) { + // nope, so we must round it up when we write it out + new->flags |= FL_ROUNDUP; + // increases the offset to the next file + offset += 8 - (info.st_size & FSIZE_MASK); + } + + // add to the list + if( progs == NULL ) { + // first entry + progs = node; + } else { + // add to the end + if( last_prog == NULL ) { + fprintf( stderr, "%s: progs ! NULL, last_prog is NULL\n", name ); + free( new ); + free( node->fullname ); + free( node ); + return; + } + last_prog->next = node; + } + last_prog = node; +} + +/** +** Name: copy +** +** Copy the contents of a program list entry into the blob +** +** @param ofd The output FILE* to be written +** @param prog Pointer to the program list entry for the file +*/ +void copy( FILE *ofd, node_t *node ) { + + prog_t *prog = node->data; + + // open it so we can copy it + int fd = open( node->fullname, O_RDONLY ); + if( fd < 0 ) { + perror( node->fullname ); + return; + } + + uint8_t buf[512]; + + // copy it block-by-block + do { + int n = read( fd, buf, 512); + // no bytes --> we're done + if( n < 1 ) { + break; + } + // copy it, and verify the copy count + int k = fwrite( buf, 1, n, ofd ); + if( k != n ) { + fprintf( stderr, "%s: write of %d returned %d\n", + prog->name, n, k ); + } + } while( 1 ); + + printf( "%s: copied %d", prog->name, prog->size ); + + // do we need to round up? + if( (prog->flags & FL_ROUNDUP) != 0 ) { + + // we'll fill with NUL bytes + uint64_t filler = 0; + + // how many filler bytes do we need? + int nbytes = 8 - (prog->size & FSIZE_MASK); + + // do it, and check the transfer count to be sure + int n = fwrite( &filler, 1, nbytes, ofd ); + if( n != nbytes ) { + fprintf( stderr, "%s: fill write of %d returned %d\n", + prog->name, nbytes, n ); + } + + // report that we added some filler bytes + printf( "(+%d)", n ); + } + puts( " bytes" ); + + // all done! + close( fd ); +} + +int main( int argc, char *argv[] ) { + + // construct program list + for( int i = 1; i < argc; ++i ) { + process( argv[i] ); + } + + if( n_progs < 1 ) { + fputs( "Nothing to do... exiting.", stderr ); + exit( 0 ); + } + + // create the output file + FILE *ofd; + ofd = fopen( "user.img", "wb" ); + if( ofd == NULL ) { + perror( "user.img" ); + exit( 1 ); + } + + printf( "Processing %d ELF files\n", n_progs ); + + // we need to adjust the offset values so they are relative to the + // start of the blob, not relative to the start of the file area. + // do this by adding the sum of the file header and program entries + // to each offset field. + + uint32_t hlen = sizeof(header_t) + n_progs * sizeof(prog_t); + node_t *curr = progs; + while( curr != NULL ) { + curr->data->offset += hlen; + curr = curr->next; + } + + // write out the blob header + header_t hdr = { "BLB", n_progs }; + if( fwrite(&hdr,sizeof(header_t),1,ofd) != 1 ) { + perror( "blob header" ); + fclose( ofd ); + exit( 1 ); + } + + // next, the program entries + curr = progs; + while( curr != NULL ) { + if( fwrite(curr->data,sizeof(prog_t),1,ofd) != 1 ) { + perror( "blob prog entry write" ); + fclose( ofd ); + exit( 1 ); + } + curr = curr->next; + } + + // finally, copy the files + curr = progs; + while( curr != NULL ) { + prog_t *prog = curr->data; + copy( ofd, curr ); + node_t *tmp = curr; + curr = curr->next; + free( tmp->data ); + free( tmp->fullname ); + free( tmp ); + } + + fclose( ofd ); + + return 0; +} diff --git a/vmtables.d b/vmtables.d new file mode 100644 index 0000000..6fbb02c --- /dev/null +++ b/vmtables.d @@ -0,0 +1,5 @@ +vmtables.o: kernel/vmtables.c include/common.h include/types.h \ + include/params.h include/defs.h include/kdefs.h include/debug.h \ + include/cio.h include/support.h include/lib.h include/klib.h \ + include/x86/ops.h include/kmem.h include/procs.h include/vm.h \ + include/x86/arch.h |