Adding usermode tree
authorJohn Hodge <tpg@portege.(none)>
Mon, 21 Sep 2009 10:02:09 +0000 (18:02 +0800)
committerJohn Hodge <tpg@portege.(none)>
Mon, 21 Sep 2009 10:02:09 +0000 (18:02 +0800)
37 files changed:
Usermode/Applications/CLIShell_src/Makefile [new file with mode: 0644]
Usermode/Applications/CLIShell_src/header.h [new file with mode: 0644]
Usermode/Applications/CLIShell_src/lib.c [new file with mode: 0644]
Usermode/Applications/CLIShell_src/main.c [new file with mode: 0644]
Usermode/Applications/init_src/Makefile [new file with mode: 0644]
Usermode/Applications/init_src/main.c [new file with mode: 0644]
Usermode/Libraries/acess.ld [new file with mode: 0644]
Usermode/Libraries/crt0.o_src/Makefile [new file with mode: 0644]
Usermode/Libraries/crt0.o_src/crt0.asm [new file with mode: 0644]
Usermode/Libraries/ld-acess.so_src/Makefile [new file with mode: 0644]
Usermode/Libraries/ld-acess.so_src/common.h [new file with mode: 0644]
Usermode/Libraries/ld-acess.so_src/elf.c [new file with mode: 0644]
Usermode/Libraries/ld-acess.so_src/elf32.h [new file with mode: 0644]
Usermode/Libraries/ld-acess.so_src/lib.c [new file with mode: 0644]
Usermode/Libraries/ld-acess.so_src/loadlib.c [new file with mode: 0644]
Usermode/Libraries/ld-acess.so_src/main.c [new file with mode: 0644]
Usermode/Libraries/ld-acess.so_src/pe.c [new file with mode: 0644]
Usermode/Libraries/ld-acess.so_src/pe.h [new file with mode: 0644]
Usermode/Libraries/libacess.so_src/Makefile [new file with mode: 0644]
Usermode/Libraries/libacess.so_src/core.asm [new file with mode: 0644]
Usermode/Libraries/libacess.so_src/mm.asm [new file with mode: 0644]
Usermode/Libraries/libacess.so_src/syscalls.inc.asm [new file with mode: 0644]
Usermode/Libraries/libacess.so_src/vfs.asm [new file with mode: 0644]
Usermode/Libraries/libc.so_src/Makefile [new file with mode: 0644]
Usermode/Libraries/libc.so_src/env.c [new file with mode: 0644]
Usermode/Libraries/libc.so_src/fileIO.c [new file with mode: 0644]
Usermode/Libraries/libc.so_src/heap.c [new file with mode: 0644]
Usermode/Libraries/libc.so_src/signals.c [new file with mode: 0644]
Usermode/Libraries/libc.so_src/stdlib.c [new file with mode: 0644]
Usermode/Libraries/libc.so_src/stub.c [new file with mode: 0644]
Usermode/include/acess/sys.h [new file with mode: 0644]
Usermode/include/stdint.h [new file with mode: 0644]
Usermode/include/stdio.h [new file with mode: 0644]
Usermode/include/stdlib.h [new file with mode: 0644]
Usermode/include/sys/basic_drivers.h [new file with mode: 0644]
Usermode/include/sys/sys.h [new file with mode: 0644]
Usermode/include/sys/types.h [new file with mode: 0644]

diff --git a/Usermode/Applications/CLIShell_src/Makefile b/Usermode/Applications/CLIShell_src/Makefile
new file mode 100644 (file)
index 0000000..2d0d8f3
--- /dev/null
@@ -0,0 +1,36 @@
+# Project: Acess Shell\r
+\r
+CC = gcc\r
+AS = nasm\r
+LD = ld\r
+RM = @rm -f\r
+\r
+COBJ = main.o lib.o\r
+BIN = ../CLIShell\r
+ACESSDIR = /home/hodgeja/Projects/Acess2/Usermode\r
+\r
+INCS = -I$(ACESSDIR)/include -I./include\r
+CFLAGS = -Wall -fno-builtin -fno-stack-protector $(INCS)\r
+ASFLAGS = -felf\r
+LDFLAGS = -T $(ACESSDIR)/Libraries/acess.ld -I /Acess/Libs/ld-acess.so -lc\r
+\r
+.PHONY : all clean\r
+\r
+all: $(BIN)\r
+\r
+$(BIN): $(AOBJ) $(COBJ)\r
+       @echo --- $(LD) -o $@\r
+       @$(LD) $(LDFLAGS) -o $@ $(AOBJ) $(COBJ) -Map Map.txt\r
+       objdump -d $(BIN) > $(BIN).dsm\r
+       cp $(BIN) /mnt/AcessHDD/Acess2/\r
+\r
+clean:\r
+       $(RM) $(AOBJ) $(COBJ) $(BIN)\r
+\r
+$(COBJ): %.o: %.c\r
+       @echo --- GCC -o $@\r
+       @$(CC) $(CFLAGS) -c $? -o $@\r
+\r
+$(AOBJ): %.ao: %.asm\r
+       @echo --- $(AS) -o $@\r
+       @$(AS) $(ASFLAGS) -o $@ $<\r
diff --git a/Usermode/Applications/CLIShell_src/header.h b/Usermode/Applications/CLIShell_src/header.h
new file mode 100644 (file)
index 0000000..f90e651
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+ Acess Shell Version 2\r
+- Based on IOOS CLI Shell\r
+*/\r
+#ifndef _HEADER_H\r
+#define _HEADER_H\r
+\r
+#define NULL   ((void*)0)\r
+\r
+#define Print(str)     do{char*s=(str);write(_stdout,strlen(s)+1,s);}while(0)\r
+\r
+extern int _stdout;\r
+extern int _stdin;\r
+\r
+extern int     GeneratePath(char *file, char *base, char *tmpPath);\r
+\r
+\r
+#endif\r
diff --git a/Usermode/Applications/CLIShell_src/lib.c b/Usermode/Applications/CLIShell_src/lib.c
new file mode 100644 (file)
index 0000000..b807dd6
--- /dev/null
@@ -0,0 +1,102 @@
+/*\r
+ * AcessOS Shell Version 2\r
+ *\r
+ * See file COPYING for \r
+ */\r
+#include "header.h"\r
+\r
+// === CODE ===\r
+/**\r
+ * \fn int GeneratePath(char *file, char *base, char *Dest)\r
+ * \brief Generates a path given a base and a filename\r
+ * \param \r
+ */\r
+int GeneratePath(char *file, char *base, char *Dest)\r
+{\r
+       char    *pathComps[64];\r
+       char    *tmpStr;\r
+       int             iPos = 0;\r
+       int             iPos2 = 0;\r
+       \r
+       // Parse Base Path\r
+       if(file[0] != '/')\r
+       {\r
+               pathComps[iPos++] = tmpStr = base+1;\r
+               while(*tmpStr)\r
+               {\r
+                       if(*tmpStr++ == '/')\r
+                       {\r
+                               pathComps[iPos] = tmpStr;\r
+                               iPos ++;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       //Print(" GeneratePath: Base Done\n");\r
+       \r
+       // Parse Argument Path\r
+       pathComps[iPos++] = tmpStr = file;\r
+       while(*tmpStr)\r
+       {\r
+               if(*tmpStr++ == '/')\r
+               {\r
+                       pathComps[iPos] = tmpStr;\r
+                       iPos ++;\r
+               }\r
+       }\r
+       pathComps[iPos] = NULL;\r
+       \r
+       //Print(" GeneratePath: Path Done\n");\r
+       \r
+       // Cleanup\r
+       iPos2 = iPos = 0;\r
+       while(pathComps[iPos])\r
+       {\r
+               tmpStr = pathComps[iPos];\r
+               // Always Increment iPos\r
+               iPos++;\r
+               // ..\r
+               if(tmpStr[0] == '.' && tmpStr[1] == '.' && (tmpStr[2] == '/' || tmpStr[2] == '\0') )\r
+               {\r
+                       if(iPos2 != 0)\r
+                               iPos2 --;\r
+                       continue;\r
+               }\r
+               // .\r
+               if(tmpStr[0] == '.' && (tmpStr[1] == '/' || tmpStr[1] == '\0') )\r
+               {\r
+                       continue;\r
+               }\r
+               // Empty\r
+               if(tmpStr[0] == '/' || tmpStr[0] == '\0')\r
+               {\r
+                       continue;\r
+               }\r
+               \r
+               // Set New Position\r
+               pathComps[iPos2] = tmpStr;\r
+               iPos2++;\r
+       }\r
+       pathComps[iPos2] = NULL;\r
+       \r
+       // Build New Path\r
+       iPos2 = 1;      iPos = 0;\r
+       Dest[0] = '/';\r
+       while(pathComps[iPos])\r
+       {\r
+               tmpStr = pathComps[iPos];\r
+               while(*tmpStr && *tmpStr != '/')\r
+               {\r
+                       Dest[iPos2++] = *tmpStr;\r
+                       tmpStr++;\r
+               }\r
+               Dest[iPos2++] = '/';\r
+               iPos++;\r
+       }\r
+       if(iPos2 > 1)\r
+               Dest[iPos2-1] = 0;\r
+       else\r
+               Dest[iPos2] = 0;\r
+       \r
+       return iPos2;   //Length\r
+}\r
diff --git a/Usermode/Applications/CLIShell_src/main.c b/Usermode/Applications/CLIShell_src/main.c
new file mode 100644 (file)
index 0000000..28d476f
--- /dev/null
@@ -0,0 +1,323 @@
+/*\r
+ AcessOS Shell Version 2\r
+- Based on IOOS CLI Shell\r
+*/\r
+#include <acess/sys.h>\r
+#include <stdlib.h>\r
+#include "header.h"\r
+\r
+#define _stdin 0\r
+#define _stdout        1\r
+#define _stderr        2\r
+\r
+// ==== PROTOTYPES ====\r
+char   *ReadCommandLine(int *Length);\r
+void   Parse_Args(char *str, char **dest);\r
+void   Command_Colour(int argc, char **argv);\r
+void   Command_Clear(int argc, char **argv);\r
+//void Command_Ls(int argc, char **argv);\r
+void   Command_Cd(int argc, char **argv);\r
+//void Command_Cat(int argc, char **argv);\r
+\r
+// ==== CONSTANT GLOBALS ====\r
+char   *cCOLOUR_NAMES[8] = {"black", "red", "green", "yellow", "blue", "magenta", "cyan", "white"};\r
+struct {\r
+       char    *name;\r
+       void    (*fcn)(int argc, char **argv);\r
+}      cBUILTINS[] = {\r
+       {"colour", Command_Colour}, {"clear", Command_Clear}, {"cd", Command_Cd}\r
+};\r
+#define        BUILTIN_COUNT   (sizeof(cBUILTINS)/sizeof(cBUILTINS[0]))\r
+\r
+// ==== LOCAL VARIABLES ====\r
+char   gsCommandBuffer[1024];\r
+char   *gsCurrentDirectory = "/";\r
+char   gsTmpBuffer[1024];\r
+char   **gasCommandHistory;\r
+ int   giLastCommand = 0;\r
+ int   giCommandSpace = 0;\r
+\r
+// ==== CODE ====\r
+int main(int argc, char *argv[], char *envp[])\r
+{\r
+       char    *sCommandStr;\r
+       char    *saArgs[32];\r
+        int    length = 0;\r
+        int    pid = -1;\r
+        int    iArgCount = 0;\r
+        int    bCached = 1;\r
+       t_sysFInfo      info;\r
+       \r
+       //Command_Clear(0, NULL);\r
+       \r
+       write(_stdout, 36, "AcessOS/AcessBasic Shell Version 2\n");\r
+       write(_stdout, 30, " Based on CLI Shell for IOOS\n");\r
+       write(_stdout,  2, "\n");\r
+       for(;;)\r
+       {\r
+               // Free last command & arguments\r
+               if(saArgs[0])   free(saArgs);\r
+               if(!bCached)    free(sCommandStr);\r
+               bCached = 0;\r
+               write(_stdout, strlen(gsCurrentDirectory), gsCurrentDirectory);\r
+               write(_stdout, 3, "$ ");\r
+               \r
+               // Read Command line\r
+               sCommandStr = ReadCommandLine( &length );\r
+               \r
+               // Check if the command should be cached\r
+               if(gasCommandHistory == NULL || strcmp(sCommandStr, gasCommandHistory[giLastCommand]) != 0)\r
+               {\r
+                       if(giLastCommand >= giCommandSpace) {\r
+                               giCommandSpace += 12;\r
+                               gasCommandHistory = realloc(gasCommandHistory, giCommandSpace*sizeof(char*));\r
+                       }\r
+                       giLastCommand ++;\r
+                       gasCommandHistory[ giLastCommand ] = sCommandStr;\r
+                       bCached = 1;\r
+               }\r
+               \r
+               // Parse Command Line into arguments\r
+               Parse_Args(sCommandStr, saArgs);\r
+               \r
+               // Count Arguments\r
+               iArgCount = 0;\r
+               while(saArgs[iArgCount])        iArgCount++;\r
+               \r
+               // Silently Ignore all empty commands\r
+               if(saArgs[1][0] == '\0')        continue;\r
+               \r
+               // Check Built-In Commands\r
+               //  [HACK] Mem Usage - Use Length in place of `i'\r
+               for(length=0;length<BUILTIN_COUNT;length++)\r
+               {\r
+                       if(strcmp(saArgs[1], cBUILTINS[length].name) == 0)\r
+                       {\r
+                               cBUILTINS[length].fcn(iArgCount-1, &saArgs[1]);\r
+                               break;\r
+                       }\r
+               }
+               // Calling a file\r
+               if(length == BUILTIN_COUNT)\r
+               {\r
+                       GeneratePath(saArgs[1], gsCurrentDirectory, gsTmpBuffer);\r
+                       // Use length in place of fp\r
+                       length = open(gsTmpBuffer, 0);\r
+                       // Check file existence\r
+                       if(length == -1) {\r
+                               Print("Unknown Command: `");Print(saArgs[1]);Print("'\n");      // Error Message\r
+                               continue;\r
+                       }\r
+                       // Check if the file is a directory\r
+                       finfo( length, &info );
+                       close( length );\r
+                       if(info.flags & FILEFLAG_DIRECTORY) {\r
+                               Print("`");Print(saArgs[1]);    // Error Message\r
+                               Print("' is a directory.\n");\r
+                               continue;\r
+                       }\r
+                       pid = clone(CLONE_VM, 0);\r
+                       if(pid == 0)    execve(gsTmpBuffer, &saArgs[1], NULL);\r
+                       if(pid <= 0) {\r
+                               Print("Unablt to create process: `");Print(gsTmpBuffer);Print("'\n");   // Error Message
+                               //SysDebug("pid = %i\n", pid);\r
+                       }\r
+                       else {\r
+                               //waitpid(pid, K_WAITPID_DIE);\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+/**\r
+ * \fn char *ReadCommandLine(int *Length)\r
+ * \brief Read from the command line\r
+ */\r
+char *ReadCommandLine(int *Length)\r
+{\r
+       char    *ret;\r
+        int    len, pos, space = 1023;\r
+       char    ch;\r
+        \r
+       // Preset Variables\r
+       ret = malloc( space+1 );\r
+       len = 0;\r
+       pos = 0;\r
+               \r
+       // Read In Command Line\r
+       do {\r
+               read(_stdin, 1, &ch);   // Read Character from stdin (read is a blocking call)\r
+               // Ignore control characters\r
+               if(ch < 0)      continue;\r
+               // Backspace\r
+               if(ch == '\b') {\r
+                       if(len <= 0)            continue;       // Protect against underflows\r
+                       if(pos == len) {        // Simple case of end of string\r
+                               len --; pos--;\r
+                       } else {\r
+                               memmove(&ret[pos-1], &ret[pos], len-pos);\r
+                               pos --;\r
+                               len --;\r
+                       }\r
+                       write(_stdout, 1, &ch);\r
+                       continue;\r
+               }\r
+               // Expand Buffer\r
+               if(len > space) {\r
+                       space += 256;\r
+                       ret = realloc(ret, space+1);\r
+                       if(!ret)        return NULL;\r
+               }\r
+               \r
+               write(_stdout, 1, &ch);\r
+               ret[pos++] = ch;\r
+               len ++;\r
+       } while(ch != '\n');\r
+       \r
+       // Remove newline\r
+       pos --;\r
+       ret[pos] = '\0';\r
+       \r
+       // Return length\r
+       if(Length)      *Length = len;\r
+       \r
+       return ret;\r
+}\r
+\r
+/**\r
+ * \fn void Parse_Args(char *str, char **dest)\r
+ * \brief Parse a string into an argument array\r
+ */\r
+void Parse_Args(char *str, char **dest)\r
+{\r
+        int    i = 1;\r
+       char    *buf = malloc( strlen(str) + 1 );\r
+       \r
+       strcpy(buf, str);\r
+       dest[0] = buf;\r
+       \r
+       // Trim leading whitespace\r
+       while(*buf == ' ' && *buf)      buf++;\r
+       \r
+       for(;;)\r
+       {\r
+               dest[i] = buf;  // Save start of string\r
+               i++;\r
+               while(*buf && *buf != ' ')\r
+               {\r
+                       if(*buf++ == '"')\r
+                       {\r
+                               while(*buf && !(*buf == '"' && buf[-1] != '\\'))\r
+                                       buf++;\r
+                       }\r
+               }\r
+               if(*buf == '\0')        break;\r
+               *buf = '\0';\r
+               while(*++buf == ' ' && *buf);\r
+               if(*buf == '\0')        break;\r
+       }\r
+       dest[i] = NULL;\r
+       if(i == 1) {\r
+               free(buf);\r
+               dest[0] = NULL;\r
+       }\r
+}\r
+\r
+/**\r
+ * \fn void Command_Colour(int argc, char **argv)\r
+ * \brief \r
+ */\r
+void Command_Colour(int argc, char **argv)\r
+{\r
+       int fg, bg;\r
+       char    clrStr[6] = "\x1B[37m";\r
+       \r
+       // Verify Arg Count\r
+       if(argc < 2)\r
+       {\r
+               Print("Please specify a colour\n");\r
+               goto usage;\r
+       }\r
+       \r
+       // Check Colour\r
+       for(fg=0;fg<8;fg++)\r
+               if(strcmp(cCOLOUR_NAMES[fg], argv[1]) == 0)\r
+                       break;\r
+\r
+       // Foreground a valid colour\r
+       if(fg == 8) {\r
+               Print("Unknown Colour '");Print(argv[1]);Print("'\n");\r
+               goto usage;\r
+       }\r
+       // Set Foreground\r
+       clrStr[3] = '0' + fg;\r
+       write(_stdout, 6, clrStr);\r
+       \r
+       // Need to Set Background?\r
+       if(argc > 2)\r
+       {\r
+               for(bg=0;bg<8;bg++)\r
+                       if(strcmp(cCOLOUR_NAMES[bg], argv[2]) == 0)\r
+                               break;\r
+       \r
+               // Valid colour\r
+               if(bg == 8)\r
+               {\r
+                       Print("Unknown Colour '");Print(argv[2]);Print("'\n");\r
+                       goto usage;\r
+               }\r
+       \r
+               clrStr[2] = '4';\r
+               clrStr[3] = '0' + bg;\r
+               write(_stdout, 6, clrStr);\r
+       }\r
+       // Return\r
+       return;\r
+\r
+       // Function Usage (Requested via a Goto (I know it's ugly))\r
+usage:\r
+       Print("Valid Colours are ");\r
+       for(fg=0;fg<8;fg++)\r
+       {\r
+               Print(cCOLOUR_NAMES[fg]);\r
+               write(_stdout, 3, ", ");\r
+       }\r
+       write(_stdout, 4, "\b\b\n");\r
+       return;\r
+}\r
+\r
+void Command_Clear(int argc, char **argv)\r
+{\r
+       write(_stdout, 4, "\x1B[2J");   //Clear Screen\r
+}\r
+\r
+void Command_Cd(int argc, char **argv)\r
+{\r
+       char    tmpPath[1024];\r
+       int             fp;\r
+       t_sysFInfo      stats;\r
+       \r
+       if(argc < 2)\r
+       {\r
+               Print(gsCurrentDirectory);Print("\n");\r
+               return;\r
+       }\r
+       \r
+       GeneratePath(argv[1], gsCurrentDirectory, tmpPath);\r
+       \r
+       fp = open(tmpPath, 0);\r
+       if(fp == -1) {\r
+               write(_stdout, 26, "Directory does not exist\n");\r
+               return;\r
+       }\r
+       finfo(fp, &stats);\r
+       close(fp);\r
+       \r
+       if(!(stats.flags & FILEFLAG_DIRECTORY)) {\r
+               write(_stdout, 17, "Not a Directory\n");\r
+               return;\r
+       }\r
+       \r
+       strcpy(gsCurrentDirectory, tmpPath);\r
+}\r
+\r
diff --git a/Usermode/Applications/init_src/Makefile b/Usermode/Applications/init_src/Makefile
new file mode 100644 (file)
index 0000000..a51f61b
--- /dev/null
@@ -0,0 +1,27 @@
+#
+#
+#
+
+CC = gcc
+AS = nasm
+LD = ld
+RM = rm -f
+
+ASFLAGS = -felf
+CPPFLAGS = -nostdinc -I../../include
+CFLAGS = -Wall -Werror -O3 $(CPPFLAGS)
+LDFLAGS = -I/Acess/Libs/ld-acess.so -L../../Libraries ../../Libraries/crt0.o -lacess
+
+OBJ = main.o
+BIN = ../init
+
+.PHONY: all clean
+
+all: $(BIN)
+
+$(BIN): $(OBJ) Makefile
+       $(LD) $(LDFLAGS) $(OBJ) -o $(BIN)
+       cp $(BIN) /mnt/AcessHDD/Acess2/
+
+%.o: %.c
+       $(CC) $(CFLAGS) -c $< -o $@
diff --git a/Usermode/Applications/init_src/main.c b/Usermode/Applications/init_src/main.c
new file mode 100644 (file)
index 0000000..e701b44
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Acess2 System Init Task
+ */
+#include <acess/sys.h>
+
+// === CONSTANTS ===
+#define NULL   ((void*)0)
+#define        DEFAULT_TERMINAL        "/Devices/VTerm/0"
+#define DEFAULT_SHELL  "/Acess/CLIShell"
+
+// === CODE ===
+/**
+ * \fn int main(int argc, char *argv[])
+ */
+int main(int argc, char *argv[])
+{
+       open(DEFAULT_TERMINAL, OPENFLAG_READ);  // Stdin
+       open(DEFAULT_TERMINAL, OPENFLAG_WRITE); // Stdout
+       open(DEFAULT_TERMINAL, OPENFLAG_WRITE); // Stderr
+       
+       write(1, 13, "Hello, World!");
+       
+       if(clone(CLONE_VM, 0) == 0)
+       {
+               execve(DEFAULT_SHELL, NULL, NULL);
+       }
+       
+       for(;;) sleep();
+       
+       return 42;
+}
diff --git a/Usermode/Libraries/acess.ld b/Usermode/Libraries/acess.ld
new file mode 100644 (file)
index 0000000..adf7b2a
--- /dev/null
@@ -0,0 +1,199 @@
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")\r
+OUTPUT_ARCH(i386)\r
+ENTRY(start)\r
+SEARCH_DIR(/home/hodgeja/Projects/Acess2/Usermode/Libraries)\r
+INPUT(-lacess crt0.o)\r
+SECTIONS\r
+{\r
+  /* Read-only sections, merged into text segment: */\r
+  PROVIDE (__executable_start = 0x08048000); . = 0x08048000 + SIZEOF_HEADERS;\r
+  .interp         : { *(.interp) }\r
+  .note.gnu.build-id : { *(.note.gnu.build-id) }\r
+  .hash           : { *(.hash) }\r
+  .gnu.hash       : { *(.gnu.hash) }\r
+  .dynsym         : { *(.dynsym) }\r
+  .dynstr         : { *(.dynstr) }\r
+  .gnu.version    : { *(.gnu.version) }\r
+  .gnu.version_d  : { *(.gnu.version_d) }\r
+  .gnu.version_r  : { *(.gnu.version_r) }\r
+  .rel.dyn        :\r
+    {\r
+      *(.rel.init)\r
+      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)\r
+      *(.rel.fini)\r
+      *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)\r
+      *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)\r
+      *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)\r
+      *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)\r
+      *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)\r
+      *(.rel.ctors)\r
+      *(.rel.dtors)\r
+      *(.rel.got)\r
+      *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)\r
+    }\r
+  .rela.dyn       :\r
+    {\r
+      *(.rela.init)\r
+      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)\r
+      *(.rela.fini)\r
+      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)\r
+      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)\r
+      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)\r
+      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)\r
+      *(.rela.ctors)\r
+      *(.rela.dtors)\r
+      *(.rela.got)\r
+      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)\r
+    }\r
+  .rel.plt        : { *(.rel.plt) }\r
+  .rela.plt       : { *(.rela.plt) }\r
+  .init           :\r
+  {\r
+    KEEP (*(.init))\r
+  } =0x90909090\r
+  .plt            : { *(.plt) }\r
+  .text           :\r
+  {\r
+    *(.text .stub .text.* .gnu.linkonce.t.*)\r
+    /* .gnu.warning sections are handled specially by elf32.em.  */\r
+    *(.gnu.warning)\r
+  } =0x90909090\r
+  .fini           :\r
+  {\r
+    KEEP (*(.fini))\r
+  } =0x90909090\r
+  PROVIDE (__etext = .);\r
+  PROVIDE (_etext = .);\r
+  PROVIDE (etext = .);\r
+  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }\r
+  .rodata1        : { *(.rodata1) }\r
+  .eh_frame_hdr : { *(.eh_frame_hdr) }\r
+  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }\r
+  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }\r
+  /* Adjust the address for the data segment.  We want to adjust up to\r
+     the same address within the page on the next page up.  */\r
+  . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));\r
+  /* Exception handling  */\r
+  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }\r
+  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }\r
+  /* Thread Local Storage sections  */\r
+  .tdata         : { *(.tdata .tdata.* .gnu.linkonce.td.*) }\r
+  .tbss                  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }\r
+  .preinit_array     :\r
+  {\r
+    PROVIDE_HIDDEN (__preinit_array_start = .);\r
+    KEEP (*(.preinit_array))\r
+    PROVIDE_HIDDEN (__preinit_array_end = .);\r
+  }\r
+  .init_array     :\r
+  {\r
+     PROVIDE_HIDDEN (__init_array_start = .);\r
+     KEEP (*(SORT(.init_array.*)))\r
+     KEEP (*(.init_array))\r
+     PROVIDE_HIDDEN (__init_array_end = .);\r
+  }\r
+  .fini_array     :\r
+  {\r
+    PROVIDE_HIDDEN (__fini_array_start = .);\r
+    KEEP (*(.fini_array))\r
+    KEEP (*(SORT(.fini_array.*)))\r
+    PROVIDE_HIDDEN (__fini_array_end = .);\r
+  }\r
+  .ctors          :\r
+  {\r
+    /* gcc uses crtbegin.o to find the start of\r
+       the constructors, so we make sure it is\r
+       first.  Because this is a wildcard, it\r
+       doesn't matter if the user does not\r
+       actually link against crtbegin.o; the\r
+       linker won't look for a file to match a\r
+       wildcard.  The wildcard also means that it\r
+       doesn't matter which directory crtbegin.o\r
+       is in.  */\r
+    KEEP (*crtbegin.o(.ctors))\r
+    KEEP (*crtbegin?.o(.ctors))\r
+    /* We don't want to include the .ctor section from\r
+       the crtend.o file until after the sorted ctors.\r
+       The .ctor section from the crtend file contains the\r
+       end of ctors marker and it must be last */\r
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))\r
+    KEEP (*(SORT(.ctors.*)))\r
+    KEEP (*(.ctors))\r
+  }\r
+  .dtors          :\r
+  {\r
+    KEEP (*crtbegin.o(.dtors))\r
+    KEEP (*crtbegin?.o(.dtors))\r
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))\r
+    KEEP (*(SORT(.dtors.*)))\r
+    KEEP (*(.dtors))\r
+  }\r
+  .jcr            : { KEEP (*(.jcr)) }\r
+  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }\r
+  .dynamic        : { *(.dynamic) }\r
+  .got            : { *(.got) }\r
+  . = DATA_SEGMENT_RELRO_END (12, .);\r
+  .got.plt        : { *(.got.plt) }\r
+  .data           :\r
+  {\r
+    *(.data .data.* .gnu.linkonce.d.*)\r
+    SORT(CONSTRUCTORS)\r
+  }\r
+  .data1          : { *(.data1) }\r
+  _edata = .; PROVIDE (edata = .);\r
+  __bss_start = .;\r
+  .bss            :\r
+  {\r
+   *(.dynbss)\r
+   *(.bss .bss.* .gnu.linkonce.b.*)\r
+   *(COMMON)\r
+   /* Align here to ensure that the .bss section occupies space up to\r
+      _end.  Align after .bss to ensure correct alignment even if the\r
+      .bss section disappears because there are no input sections.\r
+      FIXME: Why do we need it? When there is no .bss section, we don't\r
+      pad the .data section.  */\r
+   . = ALIGN(. != 0 ? 32 / 8 : 1);\r
+  }\r
+  . = ALIGN(32 / 8);\r
+  . = ALIGN(32 / 8);\r
+  _end = .; PROVIDE (end = .);\r
+  . = DATA_SEGMENT_END (.);\r
+  /* Stabs debugging sections.  */\r
+  .stab          0 : { *(.stab) }\r
+  .stabstr       0 : { *(.stabstr) }\r
+  .stab.excl     0 : { *(.stab.excl) }\r
+  .stab.exclstr  0 : { *(.stab.exclstr) }\r
+  .stab.index    0 : { *(.stab.index) }\r
+  .stab.indexstr 0 : { *(.stab.indexstr) }\r
+  .comment       0 : { *(.comment) }\r
+  /* DWARF debug sections.\r
+     Symbols in the DWARF debugging sections are relative to the beginning\r
+     of the section so we begin them at 0.  */\r
+  /* DWARF 1 */\r
+  .debug          0 : { *(.debug) }\r
+  .line           0 : { *(.line) }\r
+  /* GNU DWARF 1 extensions */\r
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }\r
+  .debug_sfnames  0 : { *(.debug_sfnames) }\r
+  /* DWARF 1.1 and DWARF 2 */\r
+  .debug_aranges  0 : { *(.debug_aranges) }\r
+  .debug_pubnames 0 : { *(.debug_pubnames) }\r
+  /* DWARF 2 */\r
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }\r
+  .debug_abbrev   0 : { *(.debug_abbrev) }\r
+  .debug_line     0 : { *(.debug_line) }\r
+  .debug_frame    0 : { *(.debug_frame) }\r
+  .debug_str      0 : { *(.debug_str) }\r
+  .debug_loc      0 : { *(.debug_loc) }\r
+  .debug_macinfo  0 : { *(.debug_macinfo) }\r
+  /* SGI/MIPS DWARF 2 extensions */\r
+  .debug_weaknames 0 : { *(.debug_weaknames) }\r
+  .debug_funcnames 0 : { *(.debug_funcnames) }\r
+  .debug_typenames 0 : { *(.debug_typenames) }\r
+  .debug_varnames  0 : { *(.debug_varnames) }\r
+  /* DWARF 3 */\r
+  .debug_pubtypes 0 : { *(.debug_pubtypes) }\r
+  .debug_ranges   0 : { *(.debug_ranges) }\r
+  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }\r
+  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) }\r
+}\r
diff --git a/Usermode/Libraries/crt0.o_src/Makefile b/Usermode/Libraries/crt0.o_src/Makefile
new file mode 100644 (file)
index 0000000..c039e72
--- /dev/null
@@ -0,0 +1,15 @@
+#
+#
+#
+
+AS = nasm
+RM = rm -f
+
+ASFLAGS = -felf
+
+.PHONY: all clean
+
+all: ../crt0.o
+
+../crt0.o: crt0.asm
+       $(AS) $(ASFLAGS) $< -o $@
diff --git a/Usermode/Libraries/crt0.o_src/crt0.asm b/Usermode/Libraries/crt0.o_src/crt0.asm
new file mode 100644 (file)
index 0000000..07db9de
--- /dev/null
@@ -0,0 +1,19 @@
+;
+; Acess2
+; C Runtime 0
+; - crt0.asm
+
+[BITS 32]
+[section .text]
+
+
+[global _start]
+[global start]
+[extern main]
+_start:
+start:
+       call main
+       mov eax, ebx    ; Set Argument 1 to Return Value
+       xor eax, eax    ; Set EAX to SYS_EXIT (0)
+       int     0xAC
+       jmp $   ; This should never be reached
diff --git a/Usermode/Libraries/ld-acess.so_src/Makefile b/Usermode/Libraries/ld-acess.so_src/Makefile
new file mode 100644 (file)
index 0000000..2d00516
--- /dev/null
@@ -0,0 +1,41 @@
+# Acess Dynamic Linker (ELF) Version 1\r
+#  LD-ACESS.SO\r
+#  Makefile\r
+\r
+CC = gcc\r
+AS = nasm\r
+RM = @rm -f\r
+LD = ld\r
+OBJDUMP = objdump\r
+\r
+COBJ = main.o lib.o loadlib.o elf.o pe.o\r
+AOBJ = helpers.ao\r
+BIN = ../ld-acess.so\r
+\r
+CPPFLAGS = -I../../include\r
+CFLAGS = -Wall -fno-builtin -fleading-underscore -fno-stack-protector\r
+ASFLAGS = -felf\r
+#LDFLAGS = --oformat elf32-i386 -Map map.txt -Bstatic -e _SoMain -shared\r
+#LDFLAGS = --oformat elf32-i386 -Map map.txt -Bstatic -e _SoMain -Ttext 0xBFFFE000\r
+LDFLAGS = -T link.ld -Map map.txt -Bstatic\r
+\r
+\r
+.PHONY: all clean\r
+\r
+all:   $(BIN)\r
+\r
+clean:\r
+       $(RM) $(BIN) $(AOBJ) $(COBJ)\r
+\r
+$(BIN): $(AOBJ) $(COBJ)\r
+       $(LD) $(LDFLAGS) -o $(BIN) $(AOBJ) $(COBJ) > link.txt\r
+       $(OBJDUMP) -x $(BIN) > ld-acess.dmp\r
+       $(OBJDUMP) -d $(BIN) > ld-acess.dsm\r
+       cp $(BIN) /mnt/AcessHDD/Acess2/Libs\r
+\r
+$(COBJ): %.o: %.c\r
+       $(CC) $(CFLAGS) -o $@ -c $<\r
+\r
+$(AOBJ): %.ao: %.asm\r
+       $(AS) $(ASFLAGS) -o $@ $<\r
+       
diff --git a/Usermode/Libraries/ld-acess.so_src/common.h b/Usermode/Libraries/ld-acess.so_src/common.h
new file mode 100644 (file)
index 0000000..22066f9
--- /dev/null
@@ -0,0 +1,50 @@
+/*\r
+ AcessOS v1\r
+ By thePowersGang\r
+ ld-acess.so\r
+ COMMON.H\r
+*/\r
+#ifndef _COMMON_H\r
+#define _COMMON_H\r
+\r
+#define        NULL    ((void*)0)\r
+\r
+#include <stdarg.h>\r
+\r
+// === Types ===\r
+typedef unsigned int   Uint;\r
+typedef unsigned char  Uint8;\r
+typedef unsigned short Uint16;\r
+typedef unsigned long  Uint32;\r
+typedef signed char            Sint8;\r
+typedef signed short   Sint16;\r
+typedef signed long            Sint32;\r
+
+// === Main ===
+extern int     DoRelocate( Uint base, char **envp, char *Filename );
+\r
+// === Library/Symbol Manipulation ==\r
+extern Uint    LoadLibrary(char *filename, char *SearchDir, char **envp);
+extern void    AddLoaded(char *File, Uint base);
+extern Uint    GetSymbol(char *name);\r
+extern int     GetSymbolFromBase(Uint base, char *name, Uint *ret);\r
+\r
+// === Library Functions ===\r
+extern void    strcpy(char *dest, char *src);
+extern int     strcmp(char *s1, char *s2);\r
+extern int     strlen(char *str);\r
+\r
+// === System Calls ===\r
+extern void    SysExit();\r
+extern void    SysDebug(char *fmt, ...);       //!< Now implemented in main.c\r
+extern void    SysDebugV(char *fmt, ...);\r
+extern Uint    SysLoadBin(char *path, Uint *entry);\r
+extern Uint    SysUnloadBin(Uint Base);\r
+
+// === ELF Loader ===
+extern int     ElfGetSymbol(Uint Base, char *name, Uint *ret);\r
+\r
+// === PE Loader ===\r
+extern int     PE_GetSymbol(Uint Base, char *Name, Uint *ret);\r
+\r
+#endif\r
diff --git a/Usermode/Libraries/ld-acess.so_src/elf.c b/Usermode/Libraries/ld-acess.so_src/elf.c
new file mode 100644 (file)
index 0000000..56f75e2
--- /dev/null
@@ -0,0 +1,379 @@
+/*\r
+ AcessOS 1 - Dynamic Loader\r
+ By thePowersGang\r
+*/\r
+#include "common.h"\r
+#include "elf32.h"\r
+
+#define DEBUG  0
+
+#if DEBUG\r
+# define       DEBUGS(v...)    SysDebug(v)\r
+#else
+# define       DEBUGS(...)     
+#endif
+\r
+// === CONSTANTS ===
+#if DEBUG\r
+//static const char    *csaDT_NAMES[] = {"DT_NULL", "DT_NEEDED", "DT_PLTRELSZ", "DT_PLTGOT", "DT_HASH", "DT_STRTAB", "DT_SYMTAB", "DT_RELA", "DT_RELASZ", "DT_RELAENT", "DT_STRSZ", "DT_SYMENT", "DT_INIT", "DT_FINI", "DT_SONAME", "DT_RPATH", "DT_SYMBOLIC", "DT_REL", "DT_RELSZ", "DT_RELENT", "DT_PLTREL", "DT_DEBUG", "DT_TEXTREL", "DT_JMPREL"};\r
+static const char      *csaR_NAMES[] = {"R_386_NONE", "R_386_32", "R_386_PC32", "R_386_GOT32", "R_386_PLT32", "R_386_COPY", "R_386_GLOB_DAT", "R_386_JMP_SLOT", "R_386_RELATIVE", "R_386_GOTOFF", "R_386_GOTPC", "R_386_LAST"};
+#endif\r
+\r
+// === PROTOTYPES ===\r
+void elf_doRelocate(Uint r_info, Uint32 *ptr, Uint32 addend, Elf32_Sym *symtab, Uint base);\r
+Uint ElfHashString(char *name);\r
+\r
+// === CODE ===\r
+/**\r
+ \fn int ElfRelocate(void *Base, char **envp, char *Filename)\r
+ \brief Relocates a loaded ELF Executable\r
+*/\r
+int ElfRelocate(void *Base, char **envp, char *Filename)\r
+{\r
+       Elf32_Ehdr      *hdr = Base;\r
+       Elf32_Phdr      *phtab;\r
+        int    i, j;   // Counters\r
+       char    *libPath;\r
+       Uint    iRealBase = -1;\r
+       Uint    iBaseDiff;\r
+        int    iSegmentCount;\r
+        int    iSymCount;\r
+       Elf32_Rel       *rel = NULL;\r
+       Elf32_Rela      *rela = NULL;\r
+       Uint32  *pltgot = NULL;\r
+       void    *plt = NULL;\r
+        int    relSz=0, relEntSz=8;\r
+        int    relaSz=0, relaEntSz=8;\r
+        int    pltSz=0, pltType=0;\r
+       Elf32_Dyn       *dynamicTab = NULL;     // Dynamic Table Pointer\r
+       char    *dynstrtab = NULL;      // .dynamic String Table\r
+       Elf32_Sym       *dynsymtab;\r
+       \r
+       DEBUGS("ElfRelocate: (Base=0x%x)\n", Base);\r
+       \r
+       // Parse Program Header to get Dynamic Table\r
+       phtab = Base + hdr->phoff;\r
+       iSegmentCount = hdr->phentcount;\r
+       for(i=0;i<iSegmentCount;i++)\r
+       {\r
+               // Determine linked base address\r
+               if(phtab[i].Type == PT_LOAD && iRealBase > phtab[i].VAddr)\r
+                       iRealBase = phtab[i].VAddr;\r
+               \r
+               // Find Dynamic Section\r
+               if(phtab[i].Type == PT_DYNAMIC) {\r
+                       if(dynamicTab) {\r
+                               DEBUGS(" WARNING - elf_relocate: Multiple PT_DYNAMIC segments\n");\r
+                               continue;\r
+                       }\r
+                       dynamicTab = (void *) phtab[i].VAddr;\r
+                       j = i;  // Save Dynamic Table ID\r
+               }\r
+       }\r
+       \r
+       // Page Align real base\r
+       iRealBase &= ~0xFFF;\r
+       DEBUGS(" elf_relocate: True Base = 0x%x, Compiled Base = 0x%x\n", Base, iRealBase);\r
+       \r
+       // Adjust "Real" Base\r
+       iBaseDiff = (Uint)Base - iRealBase;\r
+       \r
+       hdr->entrypoint += iBaseDiff;   // Adjust Entrypoint\r
+       \r
+       // Check if a PT_DYNAMIC segement was found\r
+       if(!dynamicTab) {\r
+               SysDebug(" elf_relocate: No PT_DYNAMIC segment in image, returning\n");\r
+               return hdr->entrypoint;\r
+       }\r
+       \r
+       // Adjust Dynamic Table\r
+       dynamicTab = (void *) ((Uint)dynamicTab + iBaseDiff);\r
+       
+       // === Get Symbol table and String Table ===\r
+       for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++)\r
+       {
+               switch(dynamicTab[j].d_tag)
+               {
+               // --- Symbol Table ---\r
+               case DT_SYMTAB:\r
+                       DEBUGS(" elf_relocate: DYNAMIC Symbol Table 0x%x (0x%x)\n",\r
+                               dynamicTab[j].d_val, dynamicTab[j].d_val + iBaseDiff);\r
+                       dynamicTab[j].d_val += iBaseDiff;\r
+                       dynsymtab = (void*)(dynamicTab[j].d_val);\r
+                       hdr->misc.SymTable = dynamicTab[j].d_val;       // Saved in unused bytes of ident\r
+                       break;\r
+               // --- String Table ---\r
+               case DT_STRTAB:\r
+                       DEBUGS(" elf_relocate: DYNAMIC String Table 0x%x (0x%x)\n",\r
+                               dynamicTab[j].d_val, dynamicTab[j].d_val + iBaseDiff);\r
+                       dynamicTab[j].d_val += iBaseDiff;\r
+                       dynstrtab = (void*)(dynamicTab[j].d_val);\r
+                       break;\r
+               // --- Hash Table --\r
+               case DT_HASH:\r
+                       dynamicTab[j].d_val += iBaseDiff;\r
+                       iSymCount = ((Uint*)(dynamicTab[j].d_val))[1];\r
+                       hdr->misc.HashTable = dynamicTab[j].d_val;      // Saved in unused bytes of ident\r
+                       break;
+               }
+       }
+\r
+       if(dynsymtab == NULL) {\r
+               SysDebug("WARNING: No Dynamic Symbol table, returning\n");\r
+               return hdr->entrypoint;\r
+       }\r
+       \r
+       // Alter Symbols to true base\r
+       for(i=0;i<iSymCount;i++)\r
+       {\r
+               dynsymtab[i].value += iBaseDiff;
+               dynsymtab[i].nameOfs += (Uint)dynstrtab;\r
+               //DEBUGS("elf_relocate: Sym '%s' = 0x%x (relocated)\n", dynsymtab[i].name, dynsymtab[i].value);\r
+       }\r
+       
+       // === Add to loaded list (can be imported now) ===
+       AddLoaded( Filename, (Uint)Base );
+
+       // === Parse Relocation Data ===\r
+       DEBUGS(" elf_relocate: dynamicTab = 0x%x\n", dynamicTab);\r
+       for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++)\r
+       {\r
+               switch(dynamicTab[j].d_tag)\r
+               {\r
+               // --- Shared Library Name ---\r
+               case DT_SONAME:\r
+                       DEBUGS(" elf_relocate: .so Name '%s'\n", dynstrtab+dynamicTab[j].d_val);\r
+                       break;\r
+               // --- Needed Library ---\r
+               case DT_NEEDED:\r
+                       libPath = dynstrtab + dynamicTab[j].d_val;\r
+                       DEBUGS(" Required Library '%s'\n", libPath);\r
+                       if(LoadLibrary(libPath, NULL, envp) == 0) {\r
+                               #if DEBUG\r
+                                       DEBUGS(" elf_relocate: Unable to load '%s'\n", libPath);\r
+                               #else\r
+                               SysDebug("Unable to load required library '%s'\n", libPath);\r
+                               #endif\r
+                               return 0;\r
+                       }\r
+                       break;\r
+               // --- PLT/GOT ---\r
+               case DT_PLTGOT: pltgot = (void*)iBaseDiff+(dynamicTab[j].d_val);        break;\r
+               case DT_JMPREL: plt = (void*)(iBaseDiff+dynamicTab[j].d_val);   break;\r
+               case DT_PLTREL: pltType = dynamicTab[j].d_val;  break;\r
+               case DT_PLTRELSZ:       pltSz = dynamicTab[j].d_val;    break;\r
+               \r
+               // --- Relocation ---\r
+               case DT_REL:    rel = (void*)(iBaseDiff + dynamicTab[j].d_val); break;\r
+               case DT_RELSZ:  relSz = dynamicTab[j].d_val;    break;\r
+               case DT_RELENT: relEntSz = dynamicTab[j].d_val; break;\r
+               case DT_RELA:   rela = (void*)(iBaseDiff + dynamicTab[j].d_val);        break;\r
+               case DT_RELASZ: relaSz = dynamicTab[j].d_val;   break;\r
+               case DT_RELAENT:        relaEntSz = dynamicTab[j].d_val;        break;\r
+               \r
+               // --- Symbol Table ---\r
+               case DT_SYMTAB:\r
+               // --- Hash Table ---\r
+               case DT_HASH:\r
+               // --- String Table ---\r
+               case DT_STRTAB:\r
+                       break;\r
+               \r
+               // --- Unknown ---\r
+               default:\r
+                       if(dynamicTab[j].d_tag > DT_JMPREL)     continue;\r
+                       //DEBUGS(" elf_relocate: %i-%i = %s,0x%x\n",\r
+                       //      i,j, csaDT_NAMES[dynamicTab[j].d_tag],dynamicTab[j].d_val);\r
+                       break;\r
+               }\r
+       }\r
+       \r
+       DEBUGS(" elf_relocate: Beginning Relocation\n");\r
+       \r
+       // Parse Relocation Entries\r
+       if(rel && relSz)\r
+       {\r
+               Uint32  *ptr;\r
+               DEBUGS(" elf_relocate: rel=0x%x, relSz=0x%x, relEntSz=0x%x\n", rel, relSz, relEntSz);\r
+               j = relSz / relEntSz;\r
+               for( i = 0; i < j; i++ )\r
+               {
+                       //DEBUGS("  Rel %i: 0x%x+0x%x\n", i, iBaseDiff, rel[i].r_offset);\r
+                       ptr = (void*)(iBaseDiff + rel[i].r_offset);\r
+                       elf_doRelocate(rel[i].r_info, ptr, *ptr, dynsymtab, iBaseDiff);\r
+               }\r
+       }\r
+       // Parse Relocation Entries\r
+       if(rela && relaSz)\r
+       {\r
+               Uint32  *ptr;\r
+               DEBUGS(" elf_relocate: rela=0x%x, relaSz=0x%x, relaEntSz=0x%x\n", rela, relaSz, relaEntSz);\r
+               j = relaSz / relaEntSz;\r
+               for( i = 0; i < j; i++ )\r
+               {\r
+                       ptr = (void*)(iBaseDiff + rela[i].r_offset);\r
+                       elf_doRelocate(rel[i].r_info, ptr, rela[i].r_addend, dynsymtab, iBaseDiff);\r
+               }\r
+       }\r
+       \r
+       // === Process PLT (Procedure Linkage Table) ===\r
+       if(plt && pltSz)\r
+       {\r
+               Uint32  *ptr;\r
+               DEBUGS(" elf_relocate: Relocate PLT, plt=0x%x\n", plt);\r
+               if(pltType == DT_REL)\r
+               {\r
+                       Elf32_Rel       *pltRel = plt;\r
+                       j = pltSz / sizeof(Elf32_Rel);\r
+                       DEBUGS(" elf_relocate: PLT Reloc Type = Rel, %i entries\n", j);\r
+                       for(i=0;i<j;i++)\r
+                       {\r
+                               ptr = (void*)(iBaseDiff + pltRel[i].r_offset);\r
+                               elf_doRelocate(pltRel[i].r_info, ptr, *ptr, dynsymtab, iRealBase);\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       Elf32_Rela      *pltRela = plt;\r
+                       j = pltSz / sizeof(Elf32_Rela);\r
+                       DEBUGS(" elf_relocate: PLT Reloc Type = Rela, %i entries\n", j);\r
+                       for(i=0;i<j;i++)\r
+                       {\r
+                               ptr = (void*)(iRealBase + pltRela[i].r_offset);\r
+                               elf_doRelocate(pltRela[i].r_info, ptr, pltRela[i].r_addend, dynsymtab, iRealBase);\r
+                       }\r
+               }\r
+       }\r
+       \r
+       DEBUGS("ElfRelocate: RETURN 0x%x", hdr->entrypoint);\r
+       return hdr->entrypoint;\r
+}\r
+\r
+void elf_doRelocate(Uint r_info, Uint32 *ptr, Uint32 addend, Elf32_Sym *symtab, Uint base)\r
+{\r
+        int    type = ELF32_R_TYPE(r_info);\r
+        int    sym = ELF32_R_SYM(r_info);\r
+       Uint32  val;\r
+       switch( type )\r
+       {\r
+       // Standard 32 Bit Relocation (S+A)\r
+       case R_386_32:\r
+               val = GetSymbol( symtab[sym].name );\r
+               DEBUGS(" elf_doRelocate: R_386_32 *0x%x += 0x%x('%s')\n",\r
+                       ptr, val, symtab[sym].name);\r
+               *ptr = val + addend;\r
+               break;\r
+               \r
+       // 32 Bit Relocation wrt. Offset (S+A-P)\r
+       case R_386_PC32:\r
+               DEBUGS(" elf_doRelocate: #%i: '%s'\n", sym, symtab[sym].name);\r
+               val = GetSymbol( symtab[sym].name );\r
+               DEBUGS(" elf_doRelocate: R_386_PC32 *0x%x = 0x%x + 0x%x - 0x%x\n",\r
+                       ptr, *ptr, val, (Uint)ptr );\r
+               *ptr = val + addend - (Uint)ptr;\r
+               //*ptr = val + addend - ((Uint)ptr - base);\r
+               break;
+\r
+       // Absolute Value of a symbol (S)\r
+       case R_386_GLOB_DAT:\r
+       case R_386_JMP_SLOT:
+               DEBUGS(" elf_doRelocate: #%i: '%s'\n", sym, symtab[sym].name);\r
+               val = GetSymbol( symtab[sym].name );\r
+               DEBUGS(" elf_doRelocate: %s *0x%x = 0x%x\n", csaR_NAMES[type], ptr, val);\r
+               *ptr = val;\r
+               break;\r
+\r
+       // Base Address (B+A)\r
+       case R_386_RELATIVE:\r
+               DEBUGS(" elf_doRelocate: R_386_RELATIVE *0x%x = 0x%x + 0x%x\n", ptr, base, addend);\r
+               *ptr = base + addend;\r
+               break;\r
+               \r
+       default:\r
+               DEBUGS(" elf_doRelocate: Rel 0x%x: 0x%x,%s\n", ptr, sym, csaR_NAMES[type]);\r
+               break;\r
+       }\r
+       \r
+}
+\r
+/**\r
+ * \fn int ElfGetSymbol(Uint Base, char *name, Uint *ret)\r
+ */
+int ElfGetSymbol(Uint Base, char *Name, Uint *ret)
+{
+       Elf32_Ehdr      *hdr = (void*)Base;\r
+       Elf32_Sym       *symtab;
+        int    nbuckets = 0;\r
+        int    iSymCount = 0;
+        int    i;\r
+       Uint    *pBuckets;\r
+       Uint    *pChains;\r
+       Uint    iNameHash;
+\r
+       //DEBUGS("ElfGetSymbol: (Base=0x%x, Name='%s')\n", Base, Name);\r
+\r
+       pBuckets = (void *) hdr->misc.HashTable;\r
+       symtab = (void *) hdr->misc.SymTable;\r
+       
+       nbuckets = pBuckets[0];\r
+       iSymCount = pBuckets[1];\r
+       pBuckets = &pBuckets[2];\r
+       pChains = &pBuckets[ nbuckets ];\r
+       \r
+       // Get hash
+       iNameHash = ElfHashString(Name);\r
+       iNameHash %= nbuckets;\r
+       //DEBUGS(" ElfGetSymbol: iNameHash = 0x%x\n", iNameHash);\r
+
+       // Walk Chain\r
+       i = pBuckets[ iNameHash ];\r
+       //DEBUGS(" ElfGetSymbol: strcmp(Name, \"%s\")\n", symtab[i].name);\r
+       if(symtab[i].shndx != SHN_UNDEF && strcmp(symtab[i].name, Name) == 0) {\r
+               *ret = symtab[ i ].value;\r
+               return 1;\r
+       }\r
+       \r
+       //DEBUGS(" ElfGetSymbol: Hash of first = 0x%x\n", ElfHashString( symtab[i].name ) % nbuckets);\r
+       while(pChains[i] != STN_UNDEF)\r
+       {\r
+               //DEBUGS(" pChains[%i] = %i\n", i, pChains[i]);\r
+               i = pChains[i];\r
+               //DEBUGS(" ElfGetSymbol: strcmp(Name, \"%s\")\n", symtab[ i ].name);\r
+               if(symtab[i].shndx != SHN_UNDEF && strcmp(symtab[ i ].name, Name) == 0) {\r
+                       //DEBUGS("ElfGetSymbol: RETURN 1, '%s' = 0x%x\n", symtab[ i ].name, symtab[ i ].value);\r
+                       *ret = symtab[ i ].value;\r
+                       return 1;\r
+               }\r
+       }\r
+       \r
+       //DEBUGS("ElfGetSymbol: RETURN 0, Symbol '%s' not found\n", Name);
+       return 0;
+}\r
+\r
+Uint ElfHashString(char *name)\r
+{\r
+       Uint    h = 0, g;\r
+       while(*name)\r
+       {\r
+               h = (h << 4) + *name++;\r
+               if( (g = h & 0xf0000000) )\r
+                       h ^= g >> 24;\r
+               h &= ~g;\r
+       }\r
+       return h;\r
+}\r
+\r
+#if 0\r
+unsigned long elf_hash(const unsigned char *name)\r
+{\r
+       unsigned long   h = 0, g;\r
+       while (*name)\r
+       {\r
+               h = (h << 4) + *name++;\r
+               if (g = h & 0xf0000000)\r
+                       h ^= g >> 24;\r
+               h &= ~g;\r
+       }\r
+       return h;\r
+}\r
+#endif\r
diff --git a/Usermode/Libraries/ld-acess.so_src/elf32.h b/Usermode/Libraries/ld-acess.so_src/elf32.h
new file mode 100644 (file)
index 0000000..eededf4
--- /dev/null
@@ -0,0 +1,215 @@
+/**\r
+ Acess v1\r
+ \file elf32.h\r
+ \brief ELF Exeutable Loader\r
+*/\r
+#ifndef _ELF32_H\r
+#define _ELF32_H\r
+\r
+/**\r
+ \struct elf_header_s\r
+ \brief ELF File Header\r
+*/\r
+struct sElf32_Ehdr {\r
+       union {\r
+               char    ident[16];      //!< Identifier Bytes\r
+               struct {\r
+                       Uint    Ident1;\r
+                       Uint    Ident2;\r
+                       Uint    HashTable;\r
+                       Uint    SymTable;\r
+               } misc;\r
+       };\r
+       Uint16  filetype;       //!< File Type\r
+       Uint16  machine;        //!< Machine / Arch\r
+       Uint32  version;        //!< Version (File?)\r
+       Uint32  entrypoint;     //!< Entry Point\r
+       Uint32  phoff;  //!< Program Header Offset\r
+       Uint32  shoff;  //!< Section Header Offset\r
+       Uint32  flags;  //!< Flags\r
+       Uint16  headersize;     //!< Header Size\r
+       Uint16  phentsize;      //!< Program Header Entry Size\r
+       Uint16  phentcount;     //!< Program Header Entry Count\r
+       Uint16  shentsize;      //!< Section Header Entry Size\r
+       Uint16  shentcount;     //!< Section Header Entry Count\r
+       Uint16  shstrindex;     //!< Section Header String Table Index\r
+};\r
+\r
+/**\r
+ \name Executable Types\r
+ \{\r
+*/\r
+#define        ET_NONE         0       //!< NULL Type\r
+#define        ET_REL          1       //!< Relocatable (Object)\r
+#define ET_EXEC                2       //!< Executable\r
+#define ET_DYN         3       //!< Dynamic Library\r
+#define ET_CORE                4       //!< Core?\r
+#define ET_LOPROC      0xFF00  //!< Low Impl Defined\r
+#define ET_HIPROC      0xFFFF  //!< High Impl Defined\r
+//! \}\r
+\r
+/**\r
+ \name Section IDs\r
+ \{\r
+*/\r
+#define SHN_UNDEF              0       //!< Undefined Section\r
+#define SHN_LORESERVE  0xFF00  //!< Low Reserved\r
+#define SHN_LOPROC             0xFF00  //!< Low Impl Defined\r
+#define SHN_HIPROC             0xFF1F  //!< High Impl Defined\r
+#define SHN_ABS                        0xFFF1  //!< Absolute Address (Base: 0, Size: -1)\r
+#define SHN_COMMON             0xFFF2  //!< Common\r
+#define SHN_HIRESERVE  0xFFFF  //!< High Reserved\r
+//! \}\r
+\r
+/**\r
+ \enum eElfSectionTypes\r
+ \brief ELF Section Types\r
+*/\r
+enum eElfSectionTypes {\r
+       SHT_NULL,       //0\r
+       SHT_PROGBITS,   //1\r
+       SHT_SYMTAB,     //2\r
+       SHT_STRTAB,     //3\r
+       SHT_RELA,       //4\r
+       SHT_HASH,       //5\r
+       SHT_DYNAMIC,    //6\r
+       SHT_NOTE,       //7\r
+       SHT_NOBITS,     //8\r
+       SHT_REL,        //9\r
+       SHT_SHLIB,      //A\r
+       SHT_DYNSYM,     //B\r
+       SHT_LAST,       //C\r
+       SHT_LOPROC = 0x70000000,\r
+       SHT_HIPROC = 0x7fffffff,\r
+       SHT_LOUSER = 0x80000000,\r
+       SHT_HIUSER = 0xffffffff\r
+};\r
+\r
+#define SHF_WRITE      0x1\r
+#define SHF_ALLOC      0x2\r
+#define SHF_EXECINSTR  0x4\r
+#define SHF_MASKPROC   0xf0000000\r
+\r
+struct sElf32_Shent {\r
+       Uint32  name;\r
+       Uint32  type;\r
+       Uint32  flags;\r
+       Uint32  address;\r
+       Uint32  offset;\r
+       Uint32  size;\r
+       Uint32  link;\r
+       Uint32  info;\r
+       Uint32  addralign;\r
+       Uint32  entsize;\r
+};     //sizeof = 40\r
+\r
+struct elf_sym_s {
+       union {\r
+               Uint32  nameOfs;
+               char    *name;
+       };\r
+       Uint32  value;  //Address\r
+       Uint32  size;\r
+       Uint8   info;\r
+       Uint8   other;\r
+       Uint16  shndx;\r
+};\r
+#define        STN_UNDEF       0       // Undefined Symbol\r
+\r
+enum {\r
+       PT_NULL,        //0\r
+       PT_LOAD,        //1\r
+       PT_DYNAMIC,     //2\r
+       PT_INTERP,      //3\r
+       PT_NOTE,        //4\r
+       PT_SHLIB,       //5\r
+       PT_PHDR,        //6\r
+       PT_LOPROC = 0x70000000,\r
+       PT_HIPROC = 0x7fffffff\r
+};\r
+\r
+struct sElf32_Phdr {\r
+       Uint32  Type;\r
+       Uint    Offset;\r
+       Uint    VAddr;\r
+       Uint    PAddr;\r
+       Uint32  FileSize;\r
+       Uint32  MemSize;\r
+       Uint32  Flags;\r
+       Uint32  Align;\r
+};\r
+\r
+struct elf32_rel_s {\r
+       Uint32  r_offset;\r
+       Uint32  r_info;\r
+};\r
+\r
+struct elf32_rela_s {\r
+       Uint32  r_offset;\r
+       Uint32  r_info;\r
+       Sint32  r_addend;\r
+};\r
+\r
+enum {\r
+       R_386_NONE=0,   // none\r
+       R_386_32,       // S+A\r
+       R_386_PC32,     // S+A-P\r
+       R_386_GOT32,    // G+A-P\r
+       R_386_PLT32,    // L+A-P\r
+       R_386_COPY,     // none\r
+       R_386_GLOB_DAT, // S\r
+       R_386_JMP_SLOT, // S\r
+       R_386_RELATIVE, // B+A\r
+       R_386_GOTOFF,   // S+A-GOT\r
+       R_386_GOTPC,    // GOT+A-P\r
+       R_386_LAST      // none\r
+};\r
+\r
+#define        ELF32_R_SYM(i)  ((i)>>8)        // Takes an info value and returns a symbol index\r
+#define        ELF32_R_TYPE(i) ((i)&0xFF)      // Takes an info value and returns a type\r
+#define        ELF32_R_INFO(s,t)       (((s)<<8)+((t)&0xFF))   // Takes a type and symbol index and returns an info value\r
+\r
+struct elf32_dyn_s {\r
+       Uint16  d_tag;\r
+       Uint32  d_val;  //Also d_ptr\r
+};\r
+\r
+enum {\r
+       DT_NULL,        //!< Marks End of list\r
+       DT_NEEDED,      //!< Offset in strtab to needed library\r
+       DT_PLTRELSZ,    //!< Size in bytes of PLT\r
+       DT_PLTGOT,      //!< Address of PLT/GOT\r
+       DT_HASH,        //!< Address of symbol hash table\r
+       DT_STRTAB,      //!< String Table address\r
+       DT_SYMTAB,      //!< Symbol Table address\r
+       DT_RELA,        //!< Relocation table address\r
+       DT_RELASZ,      //!< Size of relocation table\r
+       DT_RELAENT,     //!< Size of entry in relocation table\r
+       DT_STRSZ,       //!< Size of string table\r
+       DT_SYMENT,      //!< Size of symbol table entry\r
+       DT_INIT,        //!< Address of initialisation function\r
+       DT_FINI,        //!< Address of termination function\r
+       DT_SONAME,      //!< String table offset of so name\r
+       DT_RPATH,       //!< String table offset of library path\r
+       DT_SYMBOLIC,//!< Reverse order of symbol searching for library, search libs first then executable\r
+       DT_REL,         //!< Relocation Entries (Elf32_Rel instead of Elf32_Rela)\r
+       DT_RELSZ,       //!< Size of above table (bytes)\r
+       DT_RELENT,      //!< Size of entry in above table\r
+       DT_PLTREL,      //!< Relocation entry of PLT\r
+       DT_DEBUG,       //!< Debugging Entry - Unknown contents\r
+       DT_TEXTREL,     //!< Indicates that modifcations to a non-writeable segment may occur\r
+       DT_JMPREL,      //!< Address of PLT only relocation entries\r
+       DT_LOPROC = 0x70000000, //!< Low Definable\r
+       DT_HIPROC = 0x7FFFFFFF  //!< High Definable\r
+};\r
+\r
+typedef struct sElf32_Ehdr     Elf32_Ehdr;\r
+typedef struct sElf32_Phdr     Elf32_Phdr;\r
+typedef struct sElf32_Shent    Elf32_Shent;\r
+typedef struct elf_sym_s       elf_symtab;\r
+typedef struct elf_sym_s       Elf32_Sym;\r
+typedef struct elf32_rel_s     Elf32_Rel;\r
+typedef struct elf32_rela_s    Elf32_Rela;\r
+typedef struct elf32_dyn_s     Elf32_Dyn;\r
+\r
+#endif // defined(_EXE_ELF_H)\r
diff --git a/Usermode/Libraries/ld-acess.so_src/lib.c b/Usermode/Libraries/ld-acess.so_src/lib.c
new file mode 100644 (file)
index 0000000..d327213
--- /dev/null
@@ -0,0 +1,30 @@
+/*\r
+ AcessOS 1\r
+ Dynamic Loader\r
+ By thePowersGang\r
+*/\r
+#include "common.h"\r
+\r
+// === CODE ===\r
+void strcpy(char *dest, char *src)\r
+{\r
+       while(*src) {\r
+               *dest = *src;\r
+               src ++; dest ++;\r
+       }\r
+       *dest = '\0';\r
+}
+
+int strcmp(char *s1, char *s2)
+{
+       while(*s1 == *s2 && *s1 != 0) s1++,s2++;
+       return *s1-*s2;
+}\r
+\r
+int strlen(char *str)\r
+{\r
+        int    len = 0;\r
+       while(*str)     len++,str++;\r
+       return len;\r
+}
+
diff --git a/Usermode/Libraries/ld-acess.so_src/loadlib.c b/Usermode/Libraries/ld-acess.so_src/loadlib.c
new file mode 100644 (file)
index 0000000..267555d
--- /dev/null
@@ -0,0 +1,192 @@
+/*\r
+ AcessOS 1 - Dynamic Loader\r
+ By thePowersGang\r
+*/\r
+#include "common.h"\r
+\r
+#define DEBUG  0\r
+\r
+#if DEBUG\r
+# define DEBUGS(v...)  SysDebug(v)\r
+#else\r
+# define DEBUGS(v...)  \r
+#endif\r
+\r
+// === PROTOTYPES ===\r
+Uint   IsFileLoaded(char *file);
+ int   GetSymbolFromBase(Uint base, char *name, Uint *ret);\r
+\r
+// === GLOABLS ===\r
+#define        MAX_LOADED_LIBRARIES    64\r
+#define        MAX_STRINGS_BYTES       4096\r
+struct {\r
+       Uint    Base;\r
+       char    *Name;\r
+}      gLoadedLibraries[MAX_LOADED_LIBRARIES];\r
+char   gsLoadedStrings[MAX_STRINGS_BYTES];\r
+char   *gsNextAvailString = gsLoadedStrings;\r
+//tLoadLib     *gpLoadedLibraries = NULL;\r
+\r
+// === CODE ===\r
+Uint LoadLibrary(char *filename, char *SearchDir, char **envp)\r
+{\r
+       char    sTmpName[1024] = "/Acess/Libs/";\r
+       Uint    iArg;\r
+       void    (*fEntry)(int, int, char *[], char**);\r
+       \r
+       DEBUGS("LoadLibrary: (filename='%s', envp=0x%x)\n", filename, envp);\r
+       \r
+       // Create Temp Name\r
+       strcpy(&sTmpName[12], filename);\r
+       DEBUGS(" LoadLibrary: sTmpName='%s'\n", sTmpName);\r
+       \r
+       if( (iArg = IsFileLoaded(sTmpName)) )\r
+               return iArg;\r
+       \r
+       // Load Library\r
+       iArg = SysLoadBin(sTmpName, (Uint*)&fEntry);\r
+       if(iArg == 0) {\r
+               DEBUGS("LoadLibrary: RETURN 0\n");\r
+               return 0;\r
+       }\r
+       \r
+       DEBUGS(" LoadLibrary: iArg=0x%x, iEntry=0x%x\n", iArg, fEntry);\r
+       \r
+       // Load Symbols\r
+       fEntry = (void*)DoRelocate( iArg, envp, sTmpName );\r
+       \r
+       // Call Entrypoint\r
+       DEBUGS(" LoadLibrary: '%s' Entry 0x%x\n", filename, fEntry);\r
+       fEntry(iArg, 0, NULL, envp);\r
+       \r
+       DEBUGS("LoadLibrary: RETURN 1\n");\r
+       return iArg;\r
+}
+\r
+/**\r
+ * \fn Uint IsFileLoaded(char *file)\r
+ * \brief Determine if a file is already loaded\r
+ */\r
+Uint IsFileLoaded(char *file)\r
+{\r
+        int    i;\r
+       DEBUGS("IsFileLoaded: (file='%s')\n", file);\r
+       for( i = 0; i < MAX_LOADED_LIBRARIES; i++ )\r
+       {\r
+               if(gLoadedLibraries[i].Base == 0)       break;  // Last entry has Base set to NULL\r
+               if(strcmp(gLoadedLibraries[i].Name, file) == 0) {\r
+                       DEBUGS("IsFileLoaded: Found %i (0x%x)\n", i, gLoadedLibraries[i].Base);\r
+                       return gLoadedLibraries[i].Base;\r
+               }\r
+       }\r
+       DEBUGS("IsFileLoaded: Not Found\n");\r
+       return 0;\r
+}\r
+\r
+/**\r
+ * \fn void AddLoaded(char *File, Uint base)\r
+ * \brief Add a file to the loaded list\r
+ */
+void AddLoaded(char *File, Uint base)
+{\r
+        int    i, length;\r
+       char    *name = gsNextAvailString;\r
+       \r
+       DEBUGS("AddLoaded: (File='%s', base=0x%x)", File, base);\r
+       \r
+       // Find a free slot\r
+       for( i = 0; i < MAX_LOADED_LIBRARIES; i ++ )\r
+       {\r
+               if(gLoadedLibraries[i].Base == 0)       break;\r
+       }\r
+       if(i == MAX_LOADED_LIBRARIES) {\r
+               SysDebug("ERROR - ld-acess.so has run out of load slots!");\r
+               return;\r
+       }\r
+       \r
+       // Check space in string buffer\r
+       length = strlen(File);\r
+       if(&name[length+1] >= &gsLoadedStrings[MAX_STRINGS_BYTES]) {\r
+               SysDebug("ERROR - ld-acess.so has run out of string buffer memory!");\r
+               return;\r
+       }\r
+       \r
+       // Set information\r
+       gLoadedLibraries[i].Base = base;\r
+       strcpy(name, File);\r
+       gLoadedLibraries[i].Name = name;\r
+       gsNextAvailString = &name[length+1];\r
+       DEBUGS("'%s' (0x%x) loaded as %i\n", name, base, i);\r
+       return;
+}\r
+\r
+/**\r
+ * \fn void Unload(Uint Base)\r
+ */\r
+void Unload(Uint Base)\r
+{      \r
+        int    i, j;\r
+        int    id;\r
+       char    *str;\r
+       for( id = 0; id < MAX_LOADED_LIBRARIES; id++ )\r
+       {\r
+               if(gLoadedLibraries[id].Base == Base)   break;\r
+       }\r
+       if(id == MAX_LOADED_LIBRARIES)  return;\r
+       \r
+       // Unload Binary\r
+       SysUnloadBin( Base );\r
+       // Save String Pointer\r
+       str = gLoadedLibraries[id].Name;\r
+       \r
+       // Compact Loaded List\r
+       j = id;\r
+       for( i = j + 1; i < MAX_LOADED_LIBRARIES; i++, j++ )\r
+       {\r
+               if(gLoadedLibraries[i].Base == 0)       break;\r
+               // Compact String\r
+               strcpy(str, gLoadedLibraries[i].Name);\r
+               str += strlen(str)+1;\r
+               // Compact Entry\r
+               gLoadedLibraries[j].Base = gLoadedLibraries[i].Base;\r
+               gLoadedLibraries[j].Name = str;\r
+       }\r
+       \r
+       // NULL Last Entry\r
+       gLoadedLibraries[j].Base = 0;\r
+       gLoadedLibraries[j].Name = NULL;\r
+       // Save next string\r
+       gsNextAvailString = str;\r
+}\r
+\r
+/**
+ \fn Uint GetSymbol(char *name)
+ \brief Gets a symbol value from a loaded library
+*/
+Uint GetSymbol(char *name)
+{\r
+        int    i;
+       Uint    ret;\r
+       for(i=0;i<sizeof(gLoadedLibraries)/sizeof(gLoadedLibraries[0]);i++)\r
+       {\r
+               if(gLoadedLibraries[i].Base == 0)       break;
+//             SysDebug(" GetSymbol: Trying 0x%x\n", gLoadedLibraries[i]);
+               if(GetSymbolFromBase(gLoadedLibraries[i].Base, name, &ret))     return ret;\r
+       }\r
+       SysDebug("GetSymbol: === Symbol '%s' not found ===\n", name);\r
+       return 0;
+}
+
+/**
+ \fn int GetSymbolFromBase(Uint base, char *name, Uint *ret)
+ \breif Gets a symbol from a specified library
+*/
+int GetSymbolFromBase(Uint base, char *name, Uint *ret)
+{
+       if(*(Uint32*)base == (0x7F|('E'<<8)|('L'<<16)|('F'<<24)))
+               return ElfGetSymbol(base, name, ret);
+       if(*(Uint16*)base == ('M'|('Z'<<8)))
+               return PE_GetSymbol(base, name, ret);
+       return 0;
+}
+
diff --git a/Usermode/Libraries/ld-acess.so_src/main.c b/Usermode/Libraries/ld-acess.so_src/main.c
new file mode 100644 (file)
index 0000000..fb9cd35
--- /dev/null
@@ -0,0 +1,89 @@
+/*\r
+ AcessOS 1 - Dynamic Loader\r
+ By thePowersGang\r
+*/\r
+#include "common.h"\r
+\r
+// === PROTOTYPES ===\r
+ int   DoRelocate( Uint base, char **envp, char *Filename );\r
+ int   CallUser(Uint entry, Uint SP);\r
+ int   ElfRelocate(void *Base, char *envp[], char *Filename);\r
+ int   PE_Relocate(void *Base, char *envp[], char *Filename);\r
+\r
+// === Imports ===\r
+extern void    gLinkedBase;\r
\r
+// === CODE ===\r
+/**\r
+ \fn int SoMain(Uint base, int argc, char *argv[], char **envp)\r
+ \brief Library entry point\r
+ \note This is the entrypoint for the library\r
+*/\r
+int SoMain(Uint base, int arg1)\r
+{\r
+        int    ret;\r
+       \r
+       SysDebug("SoMain: base = 0x%x", base);\r
+       SysDebug("SoMain: arg1 = 0x%x", arg1);\r
+        \r
+       // - Assume that the file pointer will be less than 4096\r
+       if(base < 0x1000) {\r
+               SysDebug("ld-acess - SoMain: Passed file pointer %i\n", base);\r
+               SysExit();\r
+               for(;;);\r
+       }\r
+       // Check if we are being called directly\r
+       if(base == (Uint)&gLinkedBase) {\r
+               SysDebug("ld-acess should not be directly called\n");\r
+               SysExit();\r
+               for(;;);\r
+       }\r
+       \r
+       // Otherwise do relocations\r
+       //ret = DoRelocate( base, envp, "Executable" );\r
+       ret = DoRelocate( base, NULL, "Executable" );\r
+       if( ret == 0 ) {\r
+               SysDebug("ld-acess - SoMain: Relocate failed, base=0x%x\n", base);\r
+               SysExit();\r
+               for(;;);\r
+       }\r
+       \r
+       // And call user\r
+       //SysDebug("Calling User at 0x%x\n", ret);\r
+       CallUser( ret, (Uint)&arg1 );\r
+       \r
+       return 0;\r
+}\r
+\r
+/**\r
+ \fn int DoRelocate(Uint base, char **envp)\r
+ \brief Relocates an in-memory image\r
+*/\r
+int DoRelocate( Uint base, char **envp, char *Filename )\r
+{\r
+       // Load Executable\r
+       if(*(Uint*)base == (0x7F|('E'<<8)|('L'<<16)|('F'<<24)))\r
+               return ElfRelocate((void*)base, envp, Filename);\r
+       if(*(Uint16*)base == ('M'|('Z'<<8)))\r
+               return PE_Relocate((void*)base, envp, Filename);\r
+       \r
+       SysDebug("ld-acess - DoRelocate: Unkown file format '0x%x 0x%x 0x%x 0x%x'\n",\r
+               *(Uint8*)(base), *(Uint8*)(base+1), *(Uint8*)(base+2), *(Uint8*)(base+3) );\r
+       SysDebug("ld-acess - DoRelocate: File '%s'\n", Filename);\r
+       SysExit();\r
+       for(;;);\r
+}\r
+\r
+/**\r
+ \fn int CallUser(Uint entry, Uint sp)\r
+*/\r
+int CallUser(Uint entry, Uint sp)\r
+{\r
+       SysDebug("CallUser: (entry=0x%x, sp=0x%x)", entry, sp);\r
+       *(Uint*)(sp-4) = 0;     // Clear return address\r
+       __asm__ __volatile__ (\r
+       "mov %%eax, %%esp;\n\t"\r
+       "jmp *%%ecx"\r
+       : : "a"(sp-4), "c"(entry));\r
+       for(;;);\r
+}\r
diff --git a/Usermode/Libraries/ld-acess.so_src/pe.c b/Usermode/Libraries/ld-acess.so_src/pe.c
new file mode 100644 (file)
index 0000000..ec3b6b8
--- /dev/null
@@ -0,0 +1,180 @@
+/*\r
+ * Acess v1\r
+ * Portable Executable Loader\r
+ */\r
+#include "common.h"\r
+#include "pe.h"\r
+\r
+#define PE_DEBUG       0\r
+#define DEBUG  (ACESS_DEBUG|PE_DEBUG)\r
+\r
+//#define DLL_BASE_PATH        "/Acess/Windows/"\r
+#define DLL_BASE_PATH  NULL\r
+\r
+#if DEBUG\r
+# define DEBUGS(v...)  SysDebug(v)\r
+#else\r
+# define DEBUGS(v...)\r
+#endif\r
+\r
+// === PROTOTYPES ===\r
+ int   PE_Relocate(void *Base, char **envp, char *Filename);\r
+char   *PE_int_GetTrueFile(char *file);\r
+ int   PE_int_GetForwardSymbol(char *Fwd, Uint *Value);\r
+\r
+// === CODE ===\r
+int PE_Relocate(void *Base, char *envp[], char *Filename)\r
+{\r
+       tPE_DOS_HEADER          *dosHdr = Base;\r
+       tPE_IMAGE_HEADERS       *peHeaders;\r
+       tPE_DATA_DIR    *directory;\r
+       tPE_IMPORT_DIR  *impDir;\r
+       tPE_HINT_NAME   *name;\r
+       Uint32  *importTab, *aIAT;\r
+        int    i, j;\r
+       Uint    iBase = (Uint)Base;\r
+       Uint    iLibBase;\r
+       \r
+       DEBUGS("PE_Relocate: (Base=0x%x)\n", Base);\r
+       \r
+       peHeaders = Base + dosHdr->PeHdrOffs;\r
+       \r
+       directory = peHeaders->OptHeader.Directory;\r
+       \r
+       // === Load Import Tables\r
+       impDir = Base + directory[PE_DIR_IMPORT].RVA;\r
+       for( i = 0; impDir[i].DLLName != NULL; i++ )\r
+       {\r
+               impDir[i].DLLName += iBase;\r
+               impDir[i].ImportLookupTable += iBase/4;\r
+               impDir[i].ImportAddressTable += iBase/4;\r
+               DEBUGS(" PE_Relocate: DLL Required '%s'(0x%x)\n", impDir[i].DLLName, impDir[i].DLLName);\r
+               iLibBase = LoadLibrary(PE_int_GetTrueFile(impDir[i].DLLName), DLL_BASE_PATH, envp);\r
+               if(iLibBase == 0) {\r
+                       SysDebug("Unable to load required library '%s'\n", impDir[i].DLLName);\r
+                       return 0;\r
+               }\r
+               DEBUGS(" PE_Relocate: Loaded as 0x%x\n", iLibBase);\r
+               importTab = impDir[i].ImportLookupTable;\r
+               aIAT = impDir[i].ImportAddressTable;\r
+               for( j = 0; importTab[j] != 0; j++ )\r
+               {\r
+                       if( importTab[j] & 0x80000000 )\r
+                               DEBUGS(" PE_Relocate: Import Ordinal %i\n", importTab[j] & 0x7FFFFFFF);\r
+                       else\r
+                       {\r
+                               name = (void*)( iBase + importTab[j] );\r
+                               DEBUGS(" PE_Relocate: Import Name '%s', Hint 0x%x\n", name->Name, name->Hint);\r
+                               if( GetSymbolFromBase(iLibBase, name->Name, (Uint*)&aIAT[j]) == 0 ) {\r
+                                       SysDebug("Unable to find symbol '%s' in library '%s'\n", name->Name, impDir[i].DLLName);\r
+                                       return 0;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       \r
+       #if DEBUG\r
+       for(i=0;i<PE_DIR_LAST;i++) {\r
+               if(directory[i].RVA == 0)       continue;\r
+               SysDebug("directory[%i] = {RVA=0x%x,Size=0x%x}\n", i, directory[i].RVA, directory[i].Size);\r
+       }\r
+       #endif\r
+       \r
+       DEBUGS("PE_Relocate: RETURN 0x%x\n", iBase + peHeaders->OptHeader.EntryPoint);\r
+       \r
+       return iBase + peHeaders->OptHeader.EntryPoint;\r
+}\r
+\r
+/**\r
+ * \fn int PE_GetSymbol(Uint Base, char *Name, Uint *Ret)\r
+ */\r
+int PE_GetSymbol(Uint Base, char *Name, Uint *Ret)\r
+{\r
+       tPE_DOS_HEADER          *dosHdr = (void*)Base;\r
+       tPE_IMAGE_HEADERS       *peHeaders;\r
+       tPE_DATA_DIR    *directory;\r
+       tPE_EXPORT_DIR  *expDir;\r
+       Uint32  *nameTable, *addrTable;\r
+       Uint16  *ordTable;\r
+        int    i;\r
+        int    symbolCount;\r
+       char    *name;\r
+       Uint    retVal;\r
+       Uint    expLen;\r
+       \r
+       peHeaders = (void*)( Base + dosHdr->PeHdrOffs );\r
+       directory = peHeaders->OptHeader.Directory;\r
+       \r
+       expDir = (void*)( Base + directory[PE_DIR_EXPORT].RVA );\r
+       expLen = directory[PE_DIR_EXPORT].Size;\r
+       symbolCount = expDir->NumNamePointers;\r
+       nameTable = (void*)( Base + expDir->NamePointerRVA );\r
+       ordTable = (void*)( Base + expDir->OrdinalTableRVA );\r
+       addrTable = (void*)( Base + expDir->AddressRVA );\r
+       //DEBUGS(" PE_GetSymbol: %i Symbols\n", symbolCount);\r
+       for(i=0;i<symbolCount;i++)\r
+       {\r
+               name = (char*)( Base + nameTable[i] );\r
+               //DEBUGS(" PE_GetSymbol: '%s' = 0x%x\n", name, Base + addrTable[ ordTable[i] ]);\r
+               if(strcmp(name, Name) == 0)\r
+               {\r
+                       retVal = Base + addrTable[ ordTable[i] ];\r
+                       // Check for forwarding\r
+                       if((Uint)expDir < retVal && retVal < (Uint)expDir + expLen) {\r
+                               char *fwd = (char*)retVal;\r
+                               DEBUGS(" PE_GetSymbol: '%s' forwards to '%s'\n", name, fwd);\r
+                               return PE_int_GetForwardSymbol(fwd, Ret);\r
+                       }\r
+                       *Ret = retVal;\r
+                       return 1;\r
+               }\r
+       }\r
+       return 0;\r
+}\r
+\r
+/**\r
+ * \fn char *PE_int_GetTrueFile(char *file)\r
+ * \brief Get the true file name\r
+ */\r
+char *PE_int_GetTrueFile(char *file)\r
+{\r
+        int    i;\r
+       if(file[0] != ':')      return file;\r
+\r
+       // Translate name\r
+       for(i=1;file[i];i++)\r
+               if(file[i] == '_')\r
+                       file[i] = '.';\r
+       \r
+       return &file[1];\r
+}\r
+\r
+int PE_int_GetForwardSymbol(char *Fwd, Uint *Value)\r
+{\r
+       char    *libname;\r
+       char    *sym;\r
+        int    i;\r
+       Uint    libbase;\r
+        int    ret;\r
+       \r
+       // -- Find seperator\r
+       // PE spec says that there sould only be one, but the string may\r
+       // be mutilated in the loader\r
+       for(i=0;Fwd[i]!='\0';i++);\r
+       for(;i&&Fwd[i]!='.';i--);\r
+       \r
+       Fwd[i] = '\0';\r
+       sym = &Fwd[i+1];\r
+       \r
+       libname = PE_int_GetTrueFile(Fwd);\r
+       \r
+       DEBUGS(" PE_int_GetForwardSymbol: Get '%s' from '%s'\n", sym, libname);\r
+       \r
+       libbase = LoadLibrary(libname, DLL_BASE_PATH, NULL);\r
+       ret = GetSymbolFromBase(libbase, sym, Value);\r
+       if(!ret) {\r
+               SysDebug(" PE_int_GetForwardSymbol: Unable to find '%s' in '%s'\n", sym, libname);\r
+       }\r
+       Fwd[i] = '.';\r
+       return ret;\r
+}\r
diff --git a/Usermode/Libraries/ld-acess.so_src/pe.h b/Usermode/Libraries/ld-acess.so_src/pe.h
new file mode 100644 (file)
index 0000000..5221f3a
--- /dev/null
@@ -0,0 +1,150 @@
+/*\r
+AcessOS/AcessBasic v1\r
+PE Loader\r
+HEADER\r
+*/\r
+#ifndef _EXE_PE_H\r
+#define _EXE_PE_H\r
+\r
+enum ePE_MACHINES {\r
+       PE_MACHINE_I386 = 0x14c,        // Intel 386+\r
+       PE_MACHINE_IA64 = 0x200         // Intel-64\r
+};\r
+\r
+enum ePE_DIR_INDX {\r
+       PE_DIR_EXPORT,          // 0\r
+       PE_DIR_IMPORT,          // 1\r
+       PE_DIR_RESOURCE,        // 2\r
+       PE_DIR_EXCEPTION,       // 3\r
+       PE_DIR_SECRURITY,       // 4\r
+       PE_DIR_RELOC,           // 5\r
+       PE_DIR_DEBUG,           // 6\r
+       PE_DIR_COPYRIGHT,       // 7\r
+       PE_DIR_ARCHITECTURE,// 8\r
+       PE_DIR_GLOBALPTR,       // 9\r
+       PE_DIR_TLS,                     // 10\r
+       PE_DIR_LOAD_CFG,        // 11\r
+       PE_DIR_BOUND_IMPORT,// 12\r
+       PE_DIR_IAT,                     // 13\r
+       PE_DIR_DELAY_IMPORT,// 14\r
+       PE_DIR_COM_DESCRIPTOR,  //15\r
+       PE_DIR_LAST\r
+};\r
+\r
+typedef struct {\r
+       Uint32  RVA;\r
+       Uint32  Size;\r
+} tPE_DATA_DIR;\r
+\r
+typedef struct {\r
+       Uint32  *ImportLookupTable;     //0x80000000 is Ordninal Flag\r
+       Uint32  TimeStamp;\r
+       Uint32  FowarderChain;\r
+       char    *DLLName;\r
+       Uint32  *ImportAddressTable;    // Array of Addresses - To be edited by loader\r
+} tPE_IMPORT_DIR;\r
+\r
+typedef struct {\r
+       Uint32  Flags;\r
+       Uint32  Timestamp;\r
+       Uint16  MajorVer;\r
+       Uint16  MinorVer;\r
+       Uint32  NameRVA;        // DLL Name\r
+       Uint32  OrdinalBase;\r
+       Uint32  NumAddresses;\r
+       Uint32  NumNamePointers;\r
+       Uint32  AddressRVA;\r
+       Uint32  NamePointerRVA;\r
+       Uint32  OrdinalTableRVA;\r
+} tPE_EXPORT_DIR;\r
+\r
+typedef struct {\r
+       Uint16  Hint;\r
+       char    Name[]; // Zero Terminated String\r
+} tPE_HINT_NAME;\r
+\r
+typedef struct {\r
+       char    Name[8];\r
+       Uint32  VirtualSize;\r
+       Uint32  RVA;\r
+       Uint32  RawSize;\r
+       Uint32  RawOffs;\r
+       Uint32  RelocationsPtr; //Set to 0 in executables\r
+       Uint32  LineNumberPtr;  //Pointer to Line Numbers\r
+       Uint16  RelocationCount;        // Set to 0 in executables\r
+       Uint16  LineNumberCount;\r
+       Uint32  Flags;\r
+} tPE_SECTION_HEADER;\r
+\r
+#define PE_SECTION_FLAG_CODE   0x00000020      // Section contains executable code.\r
+#define PE_SECTION_FLAG_IDATA  0x00000040      // Section contains initialized data.\r
+#define PE_SECTION_FLAG_UDATA  0x00000080      // Section contains uninitialized data.\r
+#define PE_SECTION_FLAG_DISCARDABLE    0x02000000      // Section can be discarded as needed.\r
+#define PE_SECTION_FLAG_MEM_NOT_CACHED 0x04000000      // Section cannot be cached.\r
+#define PE_SECTION_FLAG_MEM_NOT_PAGED  0x08000000      // Section is not pageable.\r
+#define PE_SECTION_FLAG_MEM_SHARED     0x10000000      // Section can be shared in memory.\r
+#define PE_SECTION_FLAG_MEM_EXECUTE    0x20000000      // Section can be executed as code.\r
+#define PE_SECTION_FLAG_MEM_READ       0x40000000      // Section can be read.\r
+#define PE_SECTION_FLAG_MEM_WRITE      0x80000000      // Section can be written to.\r
+\r
+typedef struct {\r
+       Uint32  page;\r
+       Uint32  size;\r
+       Uint16  ents[];\r
+} tPE_FIXUP_BLOCK;\r
+\r
+//File Header\r
+typedef struct {\r
+       Uint16  Machine;\r
+       Uint16  SectionCount;\r
+       Uint32  CreationTimestamp;\r
+       Uint32  SymbolTableOffs;\r
+       Uint32  SymbolCount;\r
+       Uint16  OptHeaderSize;\r
+       Uint16  Flags;\r
+} tPE_FILE_HEADER;\r
+\r
+typedef struct {\r
+       Uint16  Magic;  //0x10b: 32Bit, 0x20b: 64Bit\r
+       Uint16  LinkerVersion;\r
+       Uint32  CodeSize;       //Sum of all Code Segment Sizes\r
+       Uint32  DataSize;       //Sum of all Intialised Data Segments\r
+       Uint32  BssSize;        //Sum of all Unintialised Data Segments\r
+       Uint32  EntryPoint;\r
+       Uint32  CodeRVA;\r
+       Uint32  DataRVA;\r
+       Uint32  ImageBase;      //Prefered Base Address\r
+       Uint32  SectionAlignment;\r
+       Uint32  FileAlignment;\r
+       Uint32  WindowsVersion; //Unused/Irrelevent\r
+       Uint32  ImageVersion;   //Unused/Irrelevent\r
+       Uint32  SubsystemVersion;       //Unused, Set to 4\r
+       Uint32  Win32Version;   //Unused\r
+       Uint32  ImageSize;\r
+       Uint32  HeaderSize;\r
+       Uint32  Checksum;       //Unknown Method, Can be set to 0\r
+       Uint16  Subsystem;      //Required Windows Subsystem (None, GUI, Console)\r
+       Uint16  DllFlags;\r
+       Uint32  MaxStackSize;           //Reserved Stack Size\r
+       Uint32  InitialStackSize;       //Commited Stack Size\r
+       Uint32  InitialReservedHeap;    // Reserved Heap Size\r
+       Uint32  InitialCommitedHeap;    // Commited Heap Size\r
+       Uint32  LoaderFlags;    // Obselete\r
+       Uint32  NumberOfDirEntries;\r
+       tPE_DATA_DIR    Directory[16];\r
+} tPE_OPT_HEADER;\r
+\r
+// Root Header\r
+typedef struct {\r
+       Uint32  Signature;\r
+       tPE_FILE_HEADER FileHeader;\r
+       tPE_OPT_HEADER  OptHeader;\r
+} tPE_IMAGE_HEADERS;\r
+\r
+typedef struct {\r
+       Uint16  Ident;\r
+       Uint16  Resvd[29];\r
+       Uint32  PeHdrOffs;              // File address of new exe header\r
+} tPE_DOS_HEADER;\r
+\r
+#endif\r
diff --git a/Usermode/Libraries/libacess.so_src/Makefile b/Usermode/Libraries/libacess.so_src/Makefile
new file mode 100644 (file)
index 0000000..7b320b9
--- /dev/null
@@ -0,0 +1,29 @@
+#
+#
+#
+
+AS = nasm
+LD = ld
+STRIP = strip
+RM = rm -f
+
+ASFLAGS = -felf
+LDFLAGS = -nostdlib -shared -I/Acess/Libs/ld-acess.so -e SoMain
+
+OBJ = core.ao vfs.ao mm.ao
+BIN = ../libacess.so
+
+.PHONY: all clean
+
+all: $(BIN)
+
+clean:
+       $(RM) $(BIN) $(OBJ)
+
+$(BIN): $(OBJ)
+       $(LD) $(LDFLAGS) -o $(BIN) $(OBJ)
+       $(STRIP) $(BIN)
+       cp $(BIN) /mnt/AcessHDD/Acess2/Libs
+       
+%.ao: %.asm syscalls.inc.asm
+       $(AS) $(ASFLAGS) -o $@ $<
diff --git a/Usermode/Libraries/libacess.so_src/core.asm b/Usermode/Libraries/libacess.so_src/core.asm
new file mode 100644 (file)
index 0000000..22a2aa0
--- /dev/null
@@ -0,0 +1,45 @@
+;
+; Acess2 System Interface
+;
+%include "syscalls.inc.asm"
+
+[BITS 32]
+[section .data]
+[global _errno]
+_errno:
+       dd      0
+
+[section .text]
+[global SoMain:func]
+SoMain:
+       ret
+
+; --- Process Controll ---
+SYSCALL1       _exit, SYS_EXIT
+SYSCALL2       clone, SYS_CLONE
+SYSCALL2       kill, SYS_KILL
+SYSCALL2       signal, SYS_SIGNAL
+SYSCALL0       yield, SYS_YIELD
+SYSCALL0       sleep, SYS_SLEEP
+SYSCALL1       wait, SYS_WAIT
+
+SYSCALL0       gettid, SYS_GETTID
+SYSCALL0       getpid, SYS_GETPID
+SYSCALL0       getuid, SYS_GETUID
+SYSCALL0       getgid, SYS_GETGID
+
+SYSCALL0       setuid, SYS_SETUID
+SYSCALL0       setgid, SYS_SETGID
+
+SYSCALL1       SysSetName, SYS_SETNAME
+SYSCALL2       SysGetName, SYS_GETNAME
+
+SYSCALL1       SysSetPri, SYS_SETPRI
+
+SYSCALL3       SysSendMessage, SYS_SENDMSG
+SYSCALL3       SysGetMessage, SYS_GETMSG
+
+SYSCALL3       SysSpawn, SYS_SPAWN
+SYSCALL3       execve, SYS_EXECVE
+SYSCALL2       SysLoadBin, SYS_LOADBIN
+
diff --git a/Usermode/Libraries/libacess.so_src/mm.asm b/Usermode/Libraries/libacess.so_src/mm.asm
new file mode 100644 (file)
index 0000000..e16ef18
--- /dev/null
@@ -0,0 +1,11 @@
+;
+; Acess2 System Interface
+;
+%include "syscalls.inc.asm"
+
+[BITS 32]
+[extern _errno]
+
+[section .text]
+SYSCALL0       _SysGetPhys, SYS_GETPHYS        ; uint64_t _SysGetPhys(uint addr)
+SYSCALL1       _SysAllocate, SYS_ALLOCATE      ; uint64_t _SysAllocate(uint addr)
diff --git a/Usermode/Libraries/libacess.so_src/syscalls.inc.asm b/Usermode/Libraries/libacess.so_src/syscalls.inc.asm
new file mode 100644 (file)
index 0000000..fc0b9c0
--- /dev/null
@@ -0,0 +1,89 @@
+; ========================
+; AcssMicro - System Calls
+; ========================
+
+%include "../../../Kernel/include/syscalls.inc.asm"
+
+; System Call - No Arguments
+%macro SYSCALL0        2
+[global %1:func]
+%1:
+       push ebx
+       mov eax, %2
+       int 0xAC
+       mov [_errno], ebx
+       pop ebx
+       ret
+%endmacro
+
+; System Call - 1 Argument
+%macro SYSCALL1        2
+[global %1:func]
+%1:
+       push ebp
+       mov ebp, esp
+       push ebx
+       mov eax, %2
+       mov ebx, [ebp+8]
+       int 0xAC
+       mov [_errno], ebx
+       pop ebx
+       pop ebp
+       ret
+%endmacro
+
+; System Call - 2 Arguments
+%macro SYSCALL2        2
+[global %1:func]
+%1:
+       push ebp
+       mov ebp, esp
+       push ebx
+       mov eax, %2
+       mov ebx, [ebp+8]
+       mov ecx, [ebp+12]
+       int 0xAC
+       mov [_errno], ebx
+       pop ebx
+       pop ebp
+       ret
+%endmacro
+
+; System Call - 3 Arguments
+%macro SYSCALL3        2
+[global %1:func]
+%1:
+       push ebp
+       mov ebp, esp
+       push ebx
+       mov eax, %2
+       mov ebx, [ebp+8]
+       mov ecx, [ebp+12]
+       mov edx, [ebp+16]
+       int 0xAC
+       mov [_errno], ebx
+       pop ebx
+       pop ebp
+       ret
+%endmacro
+
+; System Call - 4 Arguments
+%macro SYSCALL4        2
+[global %1:func]
+%1:
+       push ebp
+       mov ebp, esp
+       push ebx
+       push edi
+       mov eax, %2
+       mov ebx, [ebp+8]
+       mov ecx, [ebp+12]
+       mov edx, [ebp+16]
+       mov edi, [ebp+20]
+       int 0xAC
+       mov [_errno], ebx
+       pop edi
+       pop ebx
+       pop ebp
+       ret
+%endmacro
diff --git a/Usermode/Libraries/libacess.so_src/vfs.asm b/Usermode/Libraries/libacess.so_src/vfs.asm
new file mode 100644 (file)
index 0000000..cfc26d4
--- /dev/null
@@ -0,0 +1,16 @@
+;
+; Acess2 System Interface
+;
+%include "syscalls.inc.asm"
+
+[BITS 32]
+[extern _errno]
+
+[section .text]
+SYSCALL2       open, SYS_OPEN
+SYSCALL3       reopen, SYS_REOPEN
+SYSCALL1       close, SYS_CLOSE
+SYSCALL3       read, SYS_READ
+SYSCALL4       write, SYS_WRITE        ; int, int64_t, void*
+SYSCALL4       seek, SYS_SEEK          ; int, int64_t, int
+SYSCALL2       finfo, SYS_FINFO
diff --git a/Usermode/Libraries/libc.so_src/Makefile b/Usermode/Libraries/libc.so_src/Makefile
new file mode 100644 (file)
index 0000000..293f783
--- /dev/null
@@ -0,0 +1,46 @@
+# AcessOS Basic C Library\r
+# Makefile\r
+\r
+CC = gcc\r
+AS = nasm\r
+RM = @rm -f\r
+LD = ld\r
+OBJDUMP = objdump\r
+ACESSDIR = /home/hodgeja/Projects/Acess2\r
+\r
+CPPFLAGS = -I$(ACESSDIR)/Usermode/include\r
+CFLAGS = -Wall -fPIC -fno-builtin -fno-stack-protector $(CPPFLAGS)\r
+ASFLAGS = -felf\r
+LDFLAGS = -x -shared -soname libc.so.1 -Map map.txt -e SoMain -L$(ACESSDIR)/Usermode/Libraries -lacess\r
+\r
+OBJ_LIBC = heap.o stdlib.o stub.o env.o fileIO.o signals.o\r
+BIN = ../libc.so.1\r
+\r
+.PHONY:        all clean\r
+\r
+all: $(BIN) $(OBJ_LIBC)\r
+\r
+clean:\r
+       $(RM) $(BIN) $(OBJ_LIBC)\r
+\r
+# Core C Library\r
+$(BIN): $(OBJ_LIBC)\r
+       @echo --- ld -shared -o $@\r
+       @$(LD) $(LDFLAGS) $(OBJ_LIBC) -o $@\r
+       $(OBJDUMP) -d $@ > libc.so.1.dsm\r
+       $(OBJDUMP) -x -r -R $@ > libc.so.1.dmp\r
+       cp ../libc.so.1 ../libc.so\r
+       cp ../libc.so.1 /mnt/AcessHDD/Acess2/Libs/\r
+\r
+# C Runtime 0\r
+../crt0.o: crt0.asm\r
+       @echo --- $(AS) -o $@\r
+       @$(AS) $(ASFLAGS) -o $@ $<\r
+\r
+$(filter %.o, $(OBJ_LIBC)): %.o: %.c config.h\r
+       @echo --- $(CC) -o $@\r
+       @$(CC) $(CFLAGS) -DBUILD_SO -o $@ -c $<\r
+\r
+$(filter %.ao, $(OBJ_LIBC)): %.ao: %.asm\r
+       @echo --- $(AS) -o $@\r
+       @$(AS) $(ASFLAGS) -o $@ $<\r
diff --git a/Usermode/Libraries/libc.so_src/env.c b/Usermode/Libraries/libc.so_src/env.c
new file mode 100644 (file)
index 0000000..c0f8ea3
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+AcessOS C Library
+- Environment Handler
+*/
+#include <stdlib.h>
+
+// === GLOBALS ===
+char **_envp = NULL;
+
+// === CODE ===
+char *getenv(const char *name)
+{
+       char    **env;
+       char    *str;
+        int    len;
+       
+       if(!_envp)      return NULL;
+       if(!name)       return NULL;
+       
+       
+       len = strlen((char*)name);
+       
+       env = _envp;
+       while(*env) {
+               str = *env;
+               if(str[len] == '=' && strncmp((char*)name, str, len) == 0) {
+                       return str+len+1;
+               }
+               env ++;
+       }
+       
+       return NULL;
+}
diff --git a/Usermode/Libraries/libc.so_src/fileIO.c b/Usermode/Libraries/libc.so_src/fileIO.c
new file mode 100644 (file)
index 0000000..be6f80b
--- /dev/null
@@ -0,0 +1,166 @@
+/*\r
+AcessOS Basic C Library\r
+*/\r
+#include "config.h"\r
+#include <acess/sys.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include "stdio_int.h"\r
+\r
+#define DEBUG_BUILD    0\r
+\r
+// === CONSTANTS ===\r
+\r
+// === PROTOTYPES ===\r
+struct sFILE   *get_file_struct();\r
+\r
+// === GLOBALS ===\r
+struct sFILE   _iob[STDIO_MAX_STREAMS];        // IO Buffer\r
+\r
+// === CODE ===\r
+/**\r
+ * \fn FILE *freopen(FILE *fp, char *file, char *mode)\r
+ */\r
+FILE *freopen(FILE *fp, char *file, char *mode)\r
+{\r
+        int    openFlags = 0;\r
+        int    i;\r
+       \r
+       // Sanity Check Arguments\r
+       if(!fp || !file || !mode)       return NULL;\r
+       \r
+       if(fp->Flags) {\r
+               fflush(fp);\r
+               close(fp->FD);\r
+       }\r
+       \r
+       // Get main mode\r
+       switch(mode[0])\r
+       {\r
+       case 'r':       fp->Flags = FILE_FLAG_MODE_READ;        break;\r
+       case 'w':       fp->Flags = FILE_FLAG_MODE_WRITE;       break;\r
+       case 'a':       fp->Flags = FILE_FLAG_MODE_APPEND;      break;\r
+       case 'x':       fp->Flags = FILE_FLAG_MODE_EXEC;        break;\r
+       default:\r
+               return NULL;\r
+       }\r
+       // Get Modifiers\r
+       for(i=1;mode[i];i++)\r
+       {\r
+               switch(mode[i])\r
+               {\r
+               case '+':       fp->Flags |= FILE_FLAG_M_EXT;\r
+               }\r
+       }\r
+       \r
+       // Get Open Flags\r
+       switch(mode[0])\r
+       {\r
+       // Read\r
+       case 'r':       openFlags = OPENFLAG_READ;\r
+               if(fp->Flags & FILE_FLAG_M_EXT)\r
+                       openFlags |= OPENFLAG_WRITE;\r
+               break;\r
+       // Write\r
+       case 'w':       openFlags = OPENFLAG_WRITE;\r
+               if(fp->Flags & FILE_FLAG_M_EXT)\r
+                       openFlags |= OPENFLAG_READ;\r
+               break;\r
+       // Execute\r
+       case 'x':       openFlags = OPENFLAG_EXEC;\r
+               break;\r
+       }\r
+       \r
+       //Open File\r
+       fp->FD = reopen(fp->FD, file, openFlags);\r
+       if(fp->FD == -1) {\r
+               fp->Flags = 0;\r
+               return NULL;\r
+       }\r
+       \r
+       if(mode[0] == 'a') {\r
+               seek(fp->FD, 0, SEEK_END);      //SEEK_END\r
+       }\r
+       \r
+       return fp;\r
+}\r
+/**\r
+ \fn FILE *fopen(char *file, char *mode)\r
+ \brief Opens a file and returns the pointer\r
+ \param file   String - Filename to open\r
+ \param mode   Mode to open in\r
+*/\r
+FILE *fopen(char *file, char *mode)\r
+{\r
+       FILE    *retFile;\r
+       \r
+       // Sanity Check Arguments\r
+       if(!file || !mode)      return NULL;\r
+       \r
+       // Create Return Structure\r
+       retFile = get_file_struct();\r
+       \r
+       return freopen(retFile, file, mode);\r
+}\r
+\r
+void fclose(FILE *fp)\r
+{\r
+       close(fp->FD);\r
+       free(fp);\r
+}\r
+\r
+void fflush(FILE *fp)\r
+{\r
+       ///\todo Implement\r
+}\r
+\r
+/**\r
+ * \fn int fprintf(FILE *fp, const char *format, ...)\r
+ * \brief Print a formatted string to a stream\r
+ */\r
+int fprintf(FILE *fp, const char *format, ...)\r
+{\r
+        int    size;\r
+       char    *buf;\r
+       va_list args;\r
+       \r
+       if(!fp || !format)      return -1;\r
+       \r
+       // Get Size\r
+       va_start(args, format);\r
+       size = ssprintfv((char*)format, args);\r
+       va_end(args);\r
+       \r
+       // Allocate buffer\r
+       buf = (char*)malloc(size+1);\r
+       buf[size] = '\0';\r
+       \r
+       // Print\r
+       va_start(args, format);\r
+       sprintfv(buf, (char*)format, args);\r
+       va_end(args);\r
+       \r
+       // Write to stream\r
+       write(fp->FD, size+1, buf);\r
+       \r
+       // Free buffer\r
+       free(buf);\r
+       \r
+       // Return written byte count\r
+       return size;\r
+}\r
+\r
+// --- INTERNAL ---\r
+/**\r
+ * \fn FILE *get_file_struct()\r
+ * \brief Returns a file descriptor structure\r
+ */\r
+FILE *get_file_struct()\r
+{\r
+        int    i;\r
+       for(i=0;i<STDIO_MAX_STREAMS;i++)\r
+       {\r
+               if(_iob[i].Flags == 0)  return &_iob[i];\r
+       }\r
+       return NULL;\r
+}\r
diff --git a/Usermode/Libraries/libc.so_src/heap.c b/Usermode/Libraries/libc.so_src/heap.c
new file mode 100644 (file)
index 0000000..23df92a
--- /dev/null
@@ -0,0 +1,367 @@
+/*\r
+AcessOS Basic LibC\r
+heap.c - Heap Manager\r
+*/\r
+#include <acess/sys.h>\r
+#include <stdlib.h>\r
+#include "lib.h"\r
+\r
+// === Constants ===\r
+#define MAGIC  0xACE55051      //AcessOS1\r
+#define MAGIC_FREE     (~MAGIC)\r
+#define BLOCK_SIZE     16      //Minimum\r
+#define HEAP_INIT_SIZE 0x10000\r
+\r
+typedef unsigned int Uint;\r
+\r
+//Typedefs\r
+typedef struct {\r
+       Uint    magic;\r
+       Uint    size;\r
+}      heap_head;\r
+typedef struct {\r
+       heap_head       *header;\r
+       Uint    magic;\r
+}      heap_foot;\r
+\r
+//Globals\r
+void   *_heap_start = NULL;\r
+void   *_heap_end = NULL;\r
+\r
+//Prototypes\r
+EXPORT void    *malloc(Uint bytes);\r
+EXPORT void    free(void *mem);\r
+EXPORT void    *realloc(void *mem, Uint bytes);\r
+EXPORT void    *sbrk(int increment);\r
+LOCAL void     *extendHeap(int bytes);\r
+LOCAL uint     brk(int delta);\r
+\r
+//Code\r
+\r
+/**\r
+ \fn EXPORT void *malloc(size_t bytes)\r
+ \brief Allocates memory from the heap space\r
+ \param bytes  Integer - Size of buffer to return\r
+ \return Pointer to buffer\r
+*/\r
+EXPORT void *malloc(size_t bytes)\r
+{\r
+       Uint    bestSize;\r
+       Uint    closestMatch = 0;\r
+       Uint    bestMatchAddr = 0;\r
+       heap_head       *curBlock;\r
+       \r
+       // Initialise Heap\r
+       if(_heap_start == NULL)\r
+       {LOCAL void     *sbrk(int delta);\r
+               _heap_start = sbrk(0);\r
+               _heap_end = _heap_start;\r
+               extendHeap(HEAP_INIT_SIZE);\r
+       }\r
+       \r
+       curBlock = _heap_start;\r
+       \r
+       bestSize = bytes + sizeof(heap_head) + sizeof(heap_foot) + BLOCK_SIZE - 1;\r
+       bestSize = (bestSize/BLOCK_SIZE)*BLOCK_SIZE;    //Round up to block size\r
+       \r
+       while((Uint)curBlock < (Uint)_heap_end)\r
+       {\r
+               //SysDebug(" malloc: curBlock = 0x%x, curBlock->magic = 0x%x\n", curBlock, curBlock->magic);\r
+               if(curBlock->magic == MAGIC_FREE)\r
+               {\r
+                       if(curBlock->size == bestSize)\r
+                               break;\r
+                       if(bestSize < curBlock->size && (curBlock->size < closestMatch || closestMatch == 0)) {\r
+                               closestMatch = curBlock->size;\r
+                               bestMatchAddr = (Uint)curBlock;\r
+                       }\r
+               }\r
+               else if(curBlock->magic != MAGIC)\r
+               {\r
+                       //Corrupt Heap\r
+                       //SysDebug("malloc: Corrupt Heap\n");\r
+                       return NULL;\r
+               }\r
+               curBlock = (heap_head*)((Uint)curBlock + curBlock->size);\r
+       }\r
+       \r
+       if((Uint)curBlock < (Uint)_heap_start) {\r
+               //SysDebug("malloc: Heap underrun for some reason\n");\r
+               return NULL;\r
+       }\r
+       \r
+       //Found a perfect match\r
+       if((Uint)curBlock < (Uint)_heap_end) {\r
+               curBlock->magic = MAGIC;\r
+               return (void*)((Uint)curBlock + sizeof(heap_head));\r
+       }\r
+       \r
+       //Out of Heap Space\r
+       if(!closestMatch) {\r
+               curBlock = extendHeap(bestSize);        //Allocate more\r
+               if(curBlock == NULL) {\r
+                       //SysDebug("malloc: Out of Heap Space\n");\r
+                       return NULL;\r
+               }\r
+               curBlock->magic = MAGIC;\r
+               return (void*)((Uint)curBlock + sizeof(heap_head));\r
+       }\r
+       \r
+       //Split Block?\r
+       if(closestMatch - bestSize > BLOCK_SIZE) {\r
+               heap_foot       *foot;\r
+               curBlock = (heap_head*)bestMatchAddr;\r
+               curBlock->magic = MAGIC;\r
+               curBlock->size = bestSize;\r
+               foot = (heap_foot*)(bestMatchAddr + bestSize - sizeof(heap_foot));\r
+               foot->header = curBlock;\r
+               foot->magic = MAGIC;\r
+\r
+               curBlock = (heap_head*)(bestMatchAddr + bestSize);\r
+               curBlock->magic = MAGIC_FREE;\r
+               curBlock->size = closestMatch - bestSize;\r
+               \r
+               foot = (heap_foot*)(bestMatchAddr + closestMatch - sizeof(heap_foot));\r
+               foot->header = curBlock;\r
+               \r
+               ((heap_head*)bestMatchAddr)->magic = MAGIC;     //mark as used\r
+               return (void*)(bestMatchAddr + sizeof(heap_head));\r
+       }\r
+       \r
+       //Don't Split the block\r
+       ((heap_head*)bestMatchAddr)->magic = MAGIC;\r
+       return (void*)(bestMatchAddr+sizeof(heap_head));\r
+}\r
+\r
+/**\r
+ \fn EXPORT void free(void *mem)\r
+ \brief Free previously allocated memory\r
+ \param mem    Pointer - Memory to free\r
+*/\r
+EXPORT void free(void *mem)\r
+{\r
+       heap_head       *head = mem;\r
+       \r
+       if(head->magic != MAGIC)        //Valid Heap Address\r
+               return;\r
+       \r
+       head->magic = MAGIC_FREE;\r
+       \r
+       //Unify Right\r
+       if((Uint)head + head->size < (Uint)_heap_end)\r
+       {\r
+               heap_head       *nextHead = (heap_head*)((Uint)head + head->size);\r
+               if(nextHead->magic == MAGIC_FREE) {     //Is the next block free\r
+                       head->size += nextHead->size;   //Amalgamate\r
+                       nextHead->magic = 0;    //For Security\r
+               }\r
+       }\r
+       //Unify Left\r
+       if((Uint)head - sizeof(heap_foot) > (Uint)_heap_start)\r
+       {\r
+               heap_head       *prevHead;\r
+               heap_foot       *prevFoot = (heap_foot *)((Uint)head - sizeof(heap_foot));\r
+               if(prevFoot->magic == MAGIC) {\r
+                       prevHead = prevFoot->header;\r
+                       if(prevHead->magic == MAGIC_FREE) {\r
+                               prevHead->size += head->size;   //Amalgamate\r
+                               head->magic = 0;        //For Security\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+/**\r
+ \fn EXPORT void *realloc(void *oldPos, size_t bytes)\r
+ \brief Reallocate a block of memory\r
+ \param bytes  Integer - Size of new buffer\r
+ \param oldPos Pointer - Old Buffer\r
+ \return Pointer to new buffer\r
+*/\r
+EXPORT void *realloc(void *oldPos, size_t bytes)\r
+{\r
+       void *ret;\r
+       heap_head       *head;\r
+       \r
+       if(oldPos == NULL) {\r
+               return malloc(bytes);\r
+       }\r
+       \r
+       //Check for free space after block\r
+       head = (heap_head*)((Uint)oldPos-sizeof(heap_head));\r
+       \r
+       //Hack to used free's amagamating algorithym and malloc's splitting\r
+       free(oldPos);\r
+       \r
+       //Allocate new memory\r
+       ret = malloc(bytes);\r
+       if(ret == NULL)\r
+               return NULL;\r
+       \r
+       //Copy Old Data\r
+       if((Uint)ret != (Uint)oldPos) {\r
+               memcpy(ret, oldPos, head->size-sizeof(heap_head)-sizeof(heap_foot));\r
+       }\r
+       \r
+       //Return\r
+       return ret;\r
+}\r
+\r
+/**\r
+ \fn LOCAL void *extendHeap(int bytes)\r
+ \brief Create a new block at the end of the heap area\r
+ \param bytes  Integer - Size reqired\r
+ \return Pointer to last free block\r
+ */\r
+\r
+LOCAL void *extendHeap(int bytes)\r
+{\r
+       heap_head       *head = _heap_end;\r
+       heap_foot       *foot;\r
+       \r
+       //Expand Memory Space  (Use foot as a temp pointer)\r
+       foot = sbrk(bytes);\r
+       if(foot == (void*)-1)\r
+               return NULL;\r
+       \r
+       \r
+       //Create New Block\r
+       // Header\r
+       head->magic = MAGIC_FREE;       //Unallocated\r
+       head->size = bytes;\r
+       // Footer\r
+       foot = _heap_end + bytes - sizeof(heap_foot);\r
+       foot->header = head;\r
+       foot->magic = MAGIC;\r
+       \r
+       //Combine with previous block if nessasary\r
+       if(_heap_end != _heap_start && ((heap_foot*)((Uint)_heap_end-sizeof(heap_foot)))->magic == MAGIC) {\r
+               heap_head       *tmpHead = ((heap_foot*)((Uint)_heap_end-sizeof(heap_foot)))->header;\r
+               if(tmpHead->magic == MAGIC_FREE) {\r
+                       tmpHead->size += bytes;\r
+                       foot->header = tmpHead;\r
+                       head = tmpHead;\r
+               }\r
+       }\r
+       \r
+       _heap_end = (void*) ((Uint)foot+sizeof(heap_foot));\r
+       return head;\r
+}\r
+\r
+/**\r
+ \fn EXPORT void *sbrk(int increment)\r
+ \brief Increases the program's memory space\r
+ \param count  Integer - Size of heap increase\r
+ \return Pointer to start of new region\r
+*/\r
+EXPORT void *sbrk(int increment)\r
+{\r
+       size_t newEnd;\r
+       static size_t oldEnd = 0;\r
+       static size_t curEnd = 0;\r
+\r
+       //SysDebug("sbrk: (increment=%i)\n", increment);\r
+\r
+       if (oldEnd == 0)        curEnd = oldEnd = brk(0);\r
+\r
+       //SysDebug(" sbrk: oldEnd = 0x%x\n", oldEnd);\r
+       if (increment == 0)     return (void *) curEnd;\r
+\r
+       newEnd = curEnd + increment;\r
+\r
+       if (brk(newEnd) == curEnd)      return (void *) -1;\r
+       oldEnd = curEnd;\r
+       curEnd = newEnd;\r
+       //SysDebug(" sbrk: newEnd = 0x%x\n", newEnd);\r
+\r
+       return (void *) oldEnd;\r
+}\r
+\r
+/**\r
+ * \fn EXPORT int IsHeap(void *ptr)\r
+ */\r
+EXPORT int IsHeap(void *ptr)\r
+{\r
+       #if 0\r
+       heap_head       *head;\r
+       heap_foot       *foot;\r
+       #endif\r
+       if( (Uint)ptr < (Uint)_heap_start )     return 0;\r
+       if( (Uint)ptr > (Uint)_heap_end )       return 0;\r
+       \r
+       #if 0\r
+       head = (void*)((Uint)ptr - 4);\r
+       if( head->magic != MAGIC )      return 0;\r
+       foot = (void*)( (Uint)ptr + head->size - sizeof(heap_foot) );\r
+       if( foot->magic != MAGIC )      return 0;\r
+       #endif\r
+       return 1;\r
+}\r
+\r
+// === STATIC FUNCTIONS ===\r
+/**\r
+ * Does the job of brk(0)\r
+ */\r
+static void *FindHeapBase()\r
+{\r
+       #define MAX             0xC0000000      // Address\r
+       #define THRESHOLD       512     // Pages\r
+       uint    addr;\r
+       uint    stretch = 0;\r
+       \r
+       // Scan address space\r
+       for(addr = 0;\r
+               addr < MAX;\r
+               addr += 0x1000\r
+               )\r
+       {\r
+               if( _SysGetPhys(addr) == 0 ) {\r
+                       stretch = 0;\r
+               } else {\r
+                       stretch ++;\r
+                       if(stretch > THRESHOLD)\r
+                       {\r
+                               return (void*)( addr + stretch*0x1000 );\r
+                       }\r
+               }\r
+       }\r
+       return NULL;\r
+}\r
+\r
+LOCAL uint brk(int delta)\r
+{\r
+       static uint     curpos;\r
+       uint    pages;\r
+       uint    ret = curpos;\r
+       \r
+       // Find initial position\r
+       if(curpos == 0) curpos = (uint)FindHeapBase();\r
+       \r
+       // Get Current Position\r
+       if(delta == 0)\r
+       {\r
+               return curpos;\r
+       }\r
+       \r
+       // Do we need to add pages\r
+       if(curpos & 0xFFF && (curpos & 0xFFF) + delta < 0x1000)\r
+               return curpos += delta;\r
+       \r
+       // Page align current position\r
+       if(curpos & 0xFFF)      delta -= 0x1000 - (curpos & 0xFFF);\r
+       curpos = (curpos + 0xFFF) & ~0xFFF;\r
+       \r
+       // Allocate Pages\r
+       pages = (delta + 0xFFF) >> 12;\r
+       while(pages--)\r
+       {\r
+               _SysAllocate(curpos);\r
+               curpos += 0x1000;\r
+               delta -= 0x1000;\r
+       }\r
+       \r
+       // Bring the current position to exactly what we want\r
+       curpos -= ((delta + 0xFFF) & ~0xFFF) - delta;\r
+       \r
+       return ret;     // Return old curpos\r
+}\r
diff --git a/Usermode/Libraries/libc.so_src/signals.c b/Usermode/Libraries/libc.so_src/signals.c
new file mode 100644 (file)
index 0000000..ddaf544
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * AcessOS Basic C Library
+ * signals.c
+*/
+#include <syscalls.h>
+#include <stdlib.h>
+#include <signal.h>
+#include "lib.h"
+
+// === CONSTANTS ===
+#define NUM_SIGNALS    32
+
+// === GLOBALS ===
+sighandler_t   sighandlers[NUM_SIGNALS];
+
+// === CODE ===
+sighandler_t signal(int num, sighandler_t handler)
+{
+       sighandler_t    prev;
+       if(num < 0 || num >= NUM_SIGNALS)       return NULL;
+       prev = sighandlers[num];
+       sighandlers[num] = handler;
+       return prev;
+}
diff --git a/Usermode/Libraries/libc.so_src/stdlib.c b/Usermode/Libraries/libc.so_src/stdlib.c
new file mode 100644 (file)
index 0000000..44dc55f
--- /dev/null
@@ -0,0 +1,409 @@
+/*\r
+AcessOS Basic C Library\r
+\r
+stdlib.c\r
+*/\r
+#include <acess/sys.h>\r
+#include <stdlib.h>\r
+#include "lib.h"\r
+\r
+int _stdout = 1;\r
+int _stdin = 2;\r
+\r
+EXPORT int     puts(const char *str);\r
+EXPORT void    itoa(char *buf, unsigned long num, int base, int minLength, char pad);\r
+EXPORT int     atoi(const char *str);\r
+EXPORT int     puts(const char *str);\r
+EXPORT int     ssprintfv(char *format, va_list args);\r
+EXPORT void    sprintfv(char *buf, char *format, va_list args);\r
+EXPORT int     printf(const char *format, ...);\r
+EXPORT int     strlen(const char *str);\r
+EXPORT int     strcmp(char *str1, char *str2);\r
+EXPORT int     strncmp(char *str1, char *str2, size_t len);\r
+EXPORT char    *strcpy(char *dst, const char *src);\r
+\r
+// === CODE ===\r
+EXPORT int putchar(int ch)\r
+{\r
+       return write(_stdout, 1, (char*)&ch);\r
+}\r
+\r
+EXPORT int     puts(const char *str)\r
+{\r
+        int    len;\r
+       \r
+       if(!str)        return 0;\r
+       len = strlen(str);\r
+       \r
+       len = write(_stdout, len, (char*)str);\r
+       write(_stdout, 1, "\n");\r
+       return len;\r
+}\r
+\r
+//sprintfv\r
+/**\r
+ \fn EXPORT void sprintfv(char *buf, char *format, va_list args)\r
+ \brief Prints a formatted string to a buffer\r
+ \param buf    Pointer - Destination Buffer\r
+ \param format String - Format String\r
+ \param args   VarArgs List - Arguments\r
+*/\r
+EXPORT void sprintfv(char *buf, char *format, va_list args)\r
+{\r
+       char    tmp[33];\r
+        int    c, arg, minSize;\r
+        int    pos = 0;\r
+       char    *p;\r
+       char    pad;\r
+\r
+       tmp[32] = '\0';\r
+       \r
+       while((c = *format++) != 0)\r
+       {\r
+               //SysDebug("c = '%c'\n", c);\r
+               if (c != '%') {\r
+                       buf[pos++] = c;\r
+                       continue;\r
+               }\r
+               \r
+               c = *format++;\r
+               if(c == '%') {\r
+                       buf[pos++] = '%';\r
+                       continue;\r
+               }\r
+               \r
+               // Padding\r
+               if(c == '0') {\r
+                       pad = '0';\r
+                       c = *format++;\r
+               } else\r
+                       pad = ' ';\r
+               minSize = 0;\r
+               if('1' <= c && c <= '9')\r
+               {\r
+                       while('0' <= c && c <= '9')\r
+                       {\r
+                               minSize *= 10;\r
+                               minSize += c - '0';\r
+                               c = *format++;\r
+                       }\r
+               }\r
+       \r
+               p = tmp;\r
+       \r
+               // Get Argument\r
+               arg = va_arg(args, int);\r
+               // Get Type\r
+               switch (c) {\r
+               case 'd':\r
+               case 'i':\r
+                       if(arg < 0) {\r
+                               buf[pos++] = '-';\r
+                               arg = -arg;\r
+                       }\r
+                       itoa(tmp, arg, 10, minSize, pad);\r
+                       goto sprintf_puts;\r
+               //      break;\r
+               case 'u':\r
+                       itoa(tmp, arg, 10, minSize, pad);\r
+                       goto sprintf_puts;\r
+               //      break;\r
+               case 'x':\r
+                       itoa(tmp, arg, 16, minSize, pad);\r
+                       goto sprintf_puts;\r
+               //      break;\r
+               case 'o':\r
+                       itoa(tmp, arg, 8, minSize, pad);\r
+                       goto sprintf_puts;\r
+               //      break;\r
+               case 'b':\r
+                       itoa(tmp, arg, 2, minSize, pad);\r
+                       goto sprintf_puts;\r
+               //      break;\r
+\r
+               case 's':\r
+                       p = (void*)arg;\r
+               sprintf_puts:\r
+                       if(!p)  p = "(null)";\r
+                       while(*p)       buf[pos++] = *p++;\r
+                       break;\r
+\r
+               default:\r
+                       buf[pos++] = arg;\r
+                       break;\r
+               }\r
+    }\r
+       buf[pos++] = '\0';\r
+}\r
+/*\r
+ssprintfv\r
+- Size, Stream, Print Formated, Variable Argument List\r
+*/\r
+/**\r
+ \fn EXPORT int ssprintfv(char *format, va_list args)\r
+ \brief Gets the total character count from a formatted string\r
+ \param format String - Format String\r
+ \param args   VarArgs - Argument List\r
+*/\r
+EXPORT int ssprintfv(char *format, va_list args)\r
+{\r
+       char    tmp[33];\r
+        int    c, arg, minSize;\r
+        int    len = 0;\r
+       char    *p;\r
+       char    pad;\r
+\r
+       tmp[32] = '\0';\r
+       \r
+       while((c = *format++) != 0)\r
+       {\r
+               if (c != '%') {\r
+                       len++;\r
+                       continue;\r
+               }\r
+               \r
+               c = *format++;\r
+               \r
+               // Literal '%'\r
+               if(c == '%') {\r
+                       len++;\r
+                       continue;\r
+               }\r
+               \r
+               // Padding\r
+               if(c == '0') {\r
+                       pad = '0';\r
+                       c = *format++;\r
+               } else\r
+                       pad = ' ';\r
+               minSize = 0;\r
+               if('1' <= c && c <= '9')\r
+               {\r
+                       while('0' <= c && c <= '9')\r
+                       {\r
+                               minSize *= 10;\r
+                               minSize += c - '0';\r
+                               c = *format++;\r
+                       }\r
+               }\r
+               \r
+               p = tmp;\r
+               arg = va_arg(args, int);\r
+               switch (c) {                    \r
+               case 'd':\r
+               case 'i':\r
+                       if(arg < 0) {\r
+                               len ++;\r
+                               arg = -arg;\r
+                       }\r
+                       itoa(tmp, arg, 10, minSize, pad);\r
+                       goto sprintf_puts;\r
+               case 'u':\r
+                       itoa(tmp, arg, 10, minSize, pad);\r
+                       goto sprintf_puts;\r
+               case 'x':\r
+                       itoa(tmp, arg, 16, minSize, pad);\r
+                       goto sprintf_puts;\r
+               case 'o':\r
+                       itoa(tmp, arg, 8, minSize, pad);\r
+                       p = tmp;\r
+                       goto sprintf_puts;\r
+               case 'b':\r
+                       itoa(tmp, arg, 2, minSize, pad);\r
+                       goto sprintf_puts;\r
+\r
+               case 's':\r
+                       p = (char*)arg;\r
+               sprintf_puts:\r
+                       if(!p)  p = "(null)";\r
+                       while(*p)       len++, p++;\r
+                       break;\r
+\r
+               default:\r
+                       len ++;\r
+                       break;\r
+               }\r
+    }\r
+       return len;\r
+}\r
+\r
+const char cUCDIGITS[] = "0123456789ABCDEF";\r
+/**\r
+ * \fn static void itoa(char *buf, unsigned long num, int base, int minLength, char pad)\r
+ * \brief Convert an integer into a character string\r
+ */\r
+EXPORT void itoa(char *buf, unsigned long num, int base, int minLength, char pad)\r
+{\r
+       char    tmpBuf[32];\r
+        int    pos=0, i;\r
+\r
+       if(!buf)        return;\r
+       if(base > 16) {\r
+               buf[0] = 0;\r
+               return;\r
+       }\r
+       \r
+       while(num > base-1) {\r
+               tmpBuf[pos] = cUCDIGITS[ num % base ];\r
+               num = (long) num / base;                //Shift {number} right 1 digit\r
+               pos++;\r
+       }\r
+\r
+       tmpBuf[pos++] = cUCDIGITS[ num % base ];                //Last digit of {number}\r
+       i = 0;\r
+       minLength -= pos;\r
+       while(minLength-- > 0)  buf[i++] = pad;\r
+       while(pos-- > 0)                buf[i++] = tmpBuf[pos]; //Reverse the order of characters\r
+       buf[i] = 0;\r
+}\r
+\r
+/**\r
+ */\r
+EXPORT int atoi(const char *str)\r
+{\r
+        int    neg = 0;\r
+        int    ret = 0;\r
+       \r
+       // NULL Check\r
+       if(!str)        return 0;\r
+       \r
+       while(*str == ' ' || *str == '\t')      str++;\r
+       \r
+       // Check for negative\r
+       if(*str == '-') {\r
+               neg = 1;\r
+               str++;\r
+       }\r
+       \r
+       if(*str == '0') {\r
+               str ++;\r
+               if(*str == 'x') {\r
+                       str++;\r
+                       // Hex\r
+                       while( ('0' <= *str && *str <= '9')\r
+                               || ('A' <= *str && *str <= 'F' )\r
+                               || ('a' <= *str && *str <= 'f' )\r
+                               )\r
+                       {\r
+                               ret *= 16;\r
+                               if(*str <= '9') {\r
+                                       ret += *str - '0';\r
+                               } else if (*str <= 'F') {\r
+                                       ret += *str - 'A' + 10;\r
+                               } else {\r
+                                       ret += *str - 'a' + 10;\r
+                               }\r
+                               str++;\r
+                       }\r
+               } else {\r
+                       // Octal\r
+                       while( '0' <= *str && *str <= '7' )\r
+                       {\r
+                               ret *= 8;\r
+                               ret += *str - '0';\r
+                               str++;\r
+                       }\r
+               }\r
+       } else {\r
+               // Decimal\r
+               while( '0' <= *str && *str <= '9' )\r
+               {\r
+                       ret *= 10;\r
+                       ret += *str - '0';\r
+                       str++;\r
+               }\r
+       }\r
+       \r
+       // Negate if needed\r
+       if(neg) ret = -ret;\r
+       return ret;\r
+}\r
+\r
+//printf\r
+EXPORT int printf(const char *format, ...)\r
+{\r
+        int    size;\r
+       char    *buf;\r
+       va_list args;\r
+       \r
+       va_start(args, format);\r
+       size = ssprintfv((char*)format, args);\r
+       va_end(args);\r
+       \r
+       buf = (char*)malloc(size+1);\r
+       buf[size] = '\0';\r
+       \r
+       va_start(args, format);\r
+       sprintfv(buf, (char*)format, args);\r
+       va_end(args);\r
+       \r
+       \r
+       write(_stdout, size+1, buf);\r
+       \r
+       free(buf);\r
+       return size;\r
+}\r
+\r
+EXPORT int sprintf(const char *buf, char *format, ...)\r
+{\r
+       va_list args;\r
+       va_start(args, format);\r
+       sprintfv((char*)buf, (char*)format, args);\r
+       va_end(args);\r
+       return 1;\r
+}\r
+\r
+\r
+//MEMORY\r
+EXPORT int strcmp(char *s1, char *s2)\r
+{\r
+       while(*s1 == *s2 && *s1 != '\0' && *s2 != '\0') {\r
+               s1++; s2++;\r
+       }\r
+       return (int)*s1 - (int)*s2;\r
+}\r
+EXPORT char *strcpy(char *dst, const char *src)\r
+{\r
+       char *_dst = dst;\r
+       while(*src) {\r
+               *dst = *src;\r
+               src++; dst++;\r
+       }\r
+       *dst = '\0';\r
+       return _dst;\r
+}\r
+EXPORT int strlen(const char *str)\r
+{\r
+       int retval;\r
+       for(retval = 0; *str != '\0'; str++)\r
+               retval++;\r
+       return retval;\r
+}\r
+\r
+EXPORT int strncmp(char *s1, char *s2, size_t len)\r
+{\r
+       while(--len && *s1 == *s2 && *s1 != '\0' && *s2 != '\0') {\r
+               s1++; s2++;\r
+       }\r
+       return (int)*s1 - (int)*s2;\r
+}\r
+\r
+EXPORT void *memcpy(void *dest, void *src, unsigned int count)\r
+{\r
+    char *sp = (char *)src;\r
+    char *dp = (char *)dest;\r
+    for(;count--;) *dp++ = *sp++;\r
+    return dest;\r
+}\r
+\r
+EXPORT void *memmove(void *dest, void *src, unsigned int count)\r
+{\r
+    char *sp = (char *)src;\r
+    char *dp = (char *)dest;\r
+       // Check if corruption will happen\r
+       if( (unsigned int)dest > (unsigned int)src && (unsigned int)dest < (unsigned int)src+count )\r
+               for(;count--;) dp[count] = sp[count];\r
+       else\r
+       for(;count--;) *dp++ = *sp++;\r
+    return dest;\r
+}\r
diff --git a/Usermode/Libraries/libc.so_src/stub.c b/Usermode/Libraries/libc.so_src/stub.c
new file mode 100644 (file)
index 0000000..05adb8e
--- /dev/null
@@ -0,0 +1,21 @@
+/*\r
+AcessOS Basic C Library\r
+*/\r
+\r
+extern char **_envp;\r
+\r
+/**\r
+ * \fn int SoMain()\r
+ * \brief Stub Entrypoint\r
+ * \param BaseAddress  Unused - Load Address of libc\r
+ * \param argc Unused - Argument Count (0 for current version of ld-acess)\r
+ * \param argv Unused - Arguments (NULL for current version of ld-acess)\r
+ * \param envp Environment Pointer\r
+ */\r
+int SoMain(unsigned int BaseAddress, int argc, char **argv, char **envp)\r
+{\r
+       // Init for env.c\r
+       _envp = envp;\r
+       \r
+       return 1;\r
+}\r
diff --git a/Usermode/include/acess/sys.h b/Usermode/include/acess/sys.h
new file mode 100644 (file)
index 0000000..d0b4530
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Acess2 System Interface Header
+ */
+#ifndef _SYS_SYS_H_
+#define _SYS_SYS_H_
+
+#include <stdint.h>
+
+// === CONSTANTS ===
+#define OPENFLAG_EXEC  0x01
+#define OPENFLAG_READ  0x02
+#define OPENFLAG_WRITE 0x04
+#define        OPENFLAG_NOLINK 0x40
+#define SEEK_SET       1
+#define SEEK_CUR       0
+#define SEEK_END       -1
+#define CLONE_VM       0x10
+#define FILEFLAG_DIRECTORY     0x10
+
+// === TYPES ===
+struct s_sysFInfo {
+       uint    uid, gid;
+       uint    flags;
+        int    numacls;
+       uint64_t        size;
+       uint64_t        atime;
+       uint64_t        mtime;
+       uint64_t        ctime;
+};
+typedef struct s_sysFInfo      t_sysFInfo;
+
+// === FUNCTIONS ===
+// --- Proc ---
+void   sleep();
+ int   clone(int flags, void *stack);
+ int   execve(char *path, char **argv, char **envp);
+// --- VFS ---
+ int   open(char *path, int flags);
+ int   reopen(int fd, char *path, int flags);
+void   close(int fd);
+uint64_t       read(int fd, uint64_t length, void *buffer);
+uint64_t       write(int fd, uint64_t length, void *buffer);
+ int   seek(int fd, uint64_t offset, int whence);
+ int   ioctl(int fd, int id, void *data);
+ int   finfo(int fd, t_sysFInfo *info);
+
+// --- MEMORY ---
+uint64_t       _SysGetPhys(uint vaddr);
+uint64_t       _SysAllocate(uint vaddr);
+
+#endif
diff --git a/Usermode/include/stdint.h b/Usermode/include/stdint.h
new file mode 100644 (file)
index 0000000..3ad94bd
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ */
+#ifndef _STDTYPES_H_
+#define _STDTYPES_H_
+
+typedef unsigned int   uint;
+typedef unsigned char  uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long  uint32_t;
+typedef unsigned long long     uint64_t;
+
+typedef signed char            int8_t;
+typedef signed short   int16_t;
+typedef signed long            int32_t;
+typedef signed long long       int64_t;
+
+#endif
diff --git a/Usermode/include/stdio.h b/Usermode/include/stdio.h
new file mode 100644 (file)
index 0000000..b8e70f9
--- /dev/null
@@ -0,0 +1,23 @@
+/*\r
+ * AcessOS LibC\r
+ * stdlib.h\r
+ */\r
+#ifndef __STDIO_H\r
+#define __STDIO_H
+
+typedef struct sFILE   FILE;
+\r
+extern int     printf(const char *format, ...);\r
+extern void sprintfv(char *buf, char *format, va_list args);\r
+extern int     ssprintfv(char *format, va_list args);\r
+extern int     sprintf(char *buf, char *format, ...);
+\r
+extern FILE    *fopen(char *file, char *mode);\r
+extern FILE    *freopen(FILE *fp, char *file, char *mode);
+extern void fclose(FILE *fp);\r
+extern void fflush(FILE *fp);\r
+\r
+extern int     fprintf(FILE *fp, const char *format, ...);
+
+#endif\r
+
diff --git a/Usermode/include/stdlib.h b/Usermode/include/stdlib.h
new file mode 100644 (file)
index 0000000..8774427
--- /dev/null
@@ -0,0 +1,51 @@
+/*\r
+AcessOS LibC\r
+\r
+stdlib.h\r
+*/\r
+#ifndef __STDLIB_H\r
+#define __STDLIB_H\r
+\r
+#include <stdarg.h>\r
+#include <sys/types.h>\r
+\r
+#ifndef NULL\r
+# define NULL  ((void*)0)\r
+#endif\r
+\r
+typedef unsigned int   size_t;\r
+\r
+// --- Spinlock Macros ---\r
+#define DEFLOCK(_name) static int _spinlock_##_name=0;\r
+//#define LOCK(_name)  __asm__ __volatile__("jmp ._tst;\n\t._lp:call yield;\n\t._tst:lock btsl $1,(%0);\n\tjc ._lp"::"D"(&_spinlock_##_name))\r
+#define LOCK(_name)    do{int v=1;while(v){__asm__ __volatile__("lock cmpxchgl %%eax, (%1)":"=a"(v):"D"((&_spinlock_##_name)),"a"(1));yield();}}while(0)\r
+#define UNLOCK(_name) __asm__ __volatile__("lock andl $0, (%0)"::"D"(&_spinlock_##_name))\r
+\r
+// --- StdLib ---\r
+extern int     atoi(const char *ptr);\r
+\r
+extern void *memcpy(void *dest, void *src, size_t count);\r
+extern void *memmove(void *dest, void *src, size_t count);\r
+\r
+// --- Environment ---\r
+extern char    *getenv(const char *name);\r
+\r
+// --- Heap ---\r
+extern void free(void *mem);\r
+extern void *malloc(unsigned int bytes);\r
+extern void *realloc(void *oldPos, unsigned int bytes);\r
+extern int     IsHeap(void *ptr);\r
+\r
+// --- Strings ---\r
+extern int     strlen(const char *string);\r
+extern int     strcmp(char *str1, char *str2);\r
+extern int     strncmp(char *str1, char *str2, size_t len);\r
+extern char    *strcpy(char *dst, const char *src);\r
+\r
+#ifndef SEEK_CUR\r
+# define SEEK_CUR      0\r
+# define SEEK_SET      1\r
+# define SEEK_END      (-1)\r
+#endif\r
+\r
+#endif\r
diff --git a/Usermode/include/sys/basic_drivers.h b/Usermode/include/sys/basic_drivers.h
new file mode 100644 (file)
index 0000000..ee5334e
--- /dev/null
@@ -0,0 +1,47 @@
+/**
+ * \file basic_drivers.h
+ */
+#ifndef _SYS_BASIC_DRIVERS_H
+#define _SYS_BASIC_DRIVERS_H
+
+// === COMMON ===
+enum eDrv_Common {
+       DRV_IOCTL_NULL,
+       DRV_IOCTL_TYPE,
+       DRV_IOCTL_IDENT,
+       DRV_IOCTL_VER
+};
+
+enum eDrv_Types {
+       DRV_TYPE_NULL,          //!< NULL Type - Custom Interface
+       DRV_TYPE_TERMINAL,      //!< Terminal
+       DRV_TYPE_VIDEO,         //!< Video - LFB
+       DRV_TYPE_SOUND,         //!< Audio
+       DRV_TYPE_MOUSE,         //!< Mouse
+       DRV_TYPE_JOYSTICK       //!< Joystick / Gamepad
+};
+
+// === VIDEO ===
+enum eDrv_Video {
+       VID_IOCTL_SETMODE = 4,
+       VID_IOCTL_GETMODE,
+       VID_IOCTL_FINDMODE,
+       VID_IOCTL_MODEINFO,
+       VID_IOCTL_REQLFB        // Request LFB
+};\r
+struct sVideo_IOCtl_Mode {\r
+       short   id;\r
+       Uint16  width;\r
+       Uint16  height;\r
+       Uint16  bpp;\r
+};\r
+typedef struct sVideo_IOCtl_Mode       tVideo_IOCtl_Mode;      //!< Mode Type
+
+// === MOUSE ===
+enum eDrv_Mouse {\r
+       MSE_IOCTL_SENS = 4,\r
+       MSE_IOCTL_MAX_X,\r
+       MSE_IOCTL_MAX_Y\r
+};
+
+#endif
diff --git a/Usermode/include/sys/sys.h b/Usermode/include/sys/sys.h
new file mode 100644 (file)
index 0000000..7ddf583
--- /dev/null
@@ -0,0 +1,38 @@
+/*\r
+ Syscall Definitions\r
+*/\r
+\r
+#include <sys/types.h>\r
+\r
+#define        OPEN_FLAG_READ  1\r
+#define        OPEN_FLAG_WRITE 2\r
+#define        OPEN_FLAG_EXEC  4\r
+\r
+enum {\r
+       K_WAITPID_DIE = 0\r
+};\r
+\r
+// === System Calls ===\r
+extern void    _exit(int ret);\r
+extern int     brk(int bssend);\r
+extern int     execve(char *file, char *args[], char *envp[]);\r
+extern int     fork();\r
+extern int     yield();\r
+extern int     sleep();\r
+\r
+extern int     open(char *file, int flags);\r
+extern int     close(int fp);\r
+extern int     read(int fp, int len, void *buf);\r
+extern int     write(int fp, int len, void *buf);\r
+extern int     tell(int fp);\r
+extern void seek(int fp, int dist, int flag);\r
+extern int     fstat(int fp, t_fstat *st);\r
+extern int     ioctl(int fp, int call, void *arg);\r
+extern int     readdir(int fp, char *file);\r
+extern int     kdebug(char *fmt, ...);\r
+extern int     waitpid(int pid, int action);\r
+extern int     gettid();       // Get Thread ID\r
+extern int     getpid();       // Get Process ID\r
+extern int     sendmsg(int dest, unsigned int *Data);\r
+extern int     pollmsg(int *src, unsigned int *Data);\r
+extern int     getmsg(int *src, unsigned int *Data);\r
diff --git a/Usermode/include/sys/types.h b/Usermode/include/sys/types.h
new file mode 100644 (file)
index 0000000..03ee846
--- /dev/null
@@ -0,0 +1,28 @@
+
+#ifndef _SYS_TYPES_H
+#define _SYS_TYPES_H
+
+typedef struct {
+       int             st_dev;         //dev_t
+       int             st_ino;         //ino_t
+       int             st_mode;        //mode_t
+       unsigned int    st_nlink;
+       unsigned int    st_uid;
+       unsigned int    st_gid;
+       int             st_rdev;        //dev_t
+       unsigned int    st_size;
+       long    st_atime;       //time_t
+       long    st_mtime;
+       long    st_ctime;
+} t_fstat;
+
+#define        S_IFMT          0170000 /* type of file */
+#define                S_IFDIR 0040000 /* directory */
+#define                S_IFCHR 0020000 /* character special */
+#define                S_IFBLK 0060000 /* block special */
+#define                S_IFREG 0100000 /* regular */
+#define                S_IFLNK 0120000 /* symbolic link */
+#define                S_IFSOCK        0140000 /* socket */
+#define                S_IFIFO 0010000 /* fifo */
+
+#endif

UCC git Repository :: git.ucc.asn.au