summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: be72477)
raw | patch | inline | side by side (parent: be72477)
author | Ivan Denisov <d.ivan.krsk@gmail.com> | |
Sat, 3 Oct 2015 10:43:44 +0000 (17:43 +0700) | ||
committer | Ivan Denisov <d.ivan.krsk@gmail.com> | |
Sat, 3 Oct 2015 10:43:44 +0000 (17:43 +0700) |
BlackBox/_Linux_/Lin/Rsrc/Makefile | patch | blob | history | |
BlackBox/_Linux_/Lin/Rsrc/blackbox.c | patch | blob | history | |
BlackBox/_Linux_/Lin/Rsrc/exe.img | [changed mode: 0644->0755] | patch | blob | history |
index 67a56f6177850450ad18eed5dad495517786b3aa..938607b3719ec9b6faf1bec98ca48a1bc0c6fb41 100644 (file)
# Make File for building the Linux BlackBox Loader\r
# Runs on Linux ELF \r
\r
+# for 32-bit\r
CFLAGS = -O2\r
\r
+# for 64-bit\r
+# CFLAGS = -m32 -O2\r
+\r
exe.img: blackbox.o\r
gcc $(CFLAGS) -o exe.img blackbox.o -ldl -lm\r
\r
index c029504f6e93f05d03729b6fb18dc17b1ca0ed0c..50dab7321053814bd9b0aada642cf4cec58c964c 100644 (file)
-\r
-/*\r
- * C-startup and loader for BlackBox \r
- * Implemented as the StdLoader. \r
- */\r
-\r
-\r
-#include <dlfcn.h>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <malloc.h>\r
-\r
-/* the exact size (in bytes) of the executable part of the file. */\r
-/* this constant needs to be updated everytime a change is made to this file */\r
-#define exeSize 21399\r
-\r
-\r
-/* fixup types */\r
-#define absolute 100\r
-#define relative 101\r
-#define copy 102\r
-#define table 103\r
-#define tableend 104\r
-#define deref 105\r
-#define halfword 106\r
-\r
-/* import types */\r
-#define mConst 0x1\r
-#define mTyp 0x2\r
-#define mVar 0x3\r
-#define mProc 0x4\r
-#define mExported 4\r
-\r
-#define any 1000000\r
-\r
-#define init 0x10000\r
-\r
-/* set to printf to debug and donothing to avoid debugging */ \r
-#define dprintf donothing\r
-\r
-typedef void (*BodyProc)();\r
-typedef char String[256];\r
-\r
-typedef struct Type {\r
- int size;\r
- struct Module* mod;\r
- int id;\r
- int base[16]; /* should be ARRAY 16 OF TYPE */\r
- int fields; /* should be Directory* */\r
- int ptroffs[any];\r
-} Type;\r
-\r
-typedef struct Object{\r
- int fprint;\r
- int offs;\r
- int id;\r
- Type* ostruct;\r
-} Object;\r
-\r
-typedef struct Directory{\r
- int num;\r
- Object obj[any];\r
-} Directory;\r
-\r
-typedef struct Module{ /* has to be exact copy of Kernel.Module */\r
- struct Module *next;\r
- int opts;\r
- int refcnt;\r
- short compTime[6], loadTime[6];\r
- int ext;\r
- int term; /* actually a pointer to type Command */\r
- int nofimps, nofptrs;\r
- int csize, dsize, rsize;\r
- int code, data, refs;\r
- int procBase, varBase; /* meta base addresses */\r
- char* names; /* names[0] = 0X */\r
- int* ptrs;\r
- struct Module* imports;\r
- Directory* export;\r
- char name[256];\r
-} Module;\r
-\r
-typedef struct ImpList\r
-{\r
- struct ImpList* next;\r
- String name;\r
-} ImpList;\r
-\r
-typedef struct ModSpec\r
-{\r
- ImpList* imp;\r
- String name;\r
- int start, hs, ms, ds, cs, vs, mad, dad;\r
-} ModSpec;\r
-\r
-typedef struct BootInfo\r
-{\r
- Module* modList;\r
- int argc;\r
- char** argv;\r
-} BootInfo;\r
-\r
-const char bbfile[] = "./bb.boot";\r
-\r
-FILE* f;\r
-int nofMods;\r
-String kernel, mainmod;\r
-ModSpec mod;\r
-Module *modlist;\r
-BootInfo* bootInfo;\r
-int newRecAdr, newArrAdr;\r
-int newRecFP, newArrFP;\r
-\r
-int donothing(char* fmt, ...)\r
-{\r
-}\r
-\r
-void DumpMod()\r
-{ \r
- dprintf("\n\n---- Mod info:\n");\r
- dprintf(" hs, ms, ds, cs, vs = %d, %d, %d, %d, %d\n",\r
- mod.hs, mod.ms, mod.ds, mod.cs, mod.vs);\r
- dprintf(" mad, dad = %d, %d\n\n", mod.mad, mod.dad);\r
-}\r
-\r
-\r
-void RegisterModule()\r
-{\r
- Module* m;\r
- m = (Module*)mod.dad;\r
- m->next = modlist;\r
- modlist = m;\r
- /*\r
- if (modlist == NULL){\r
- modlist = m; \r
- } else {\r
- last->next = m;\r
- last = m;\r
- }\r
- last->next = NULL;\r
- */\r
- dprintf("Registred module %s\n", mod.name);\r
-}\r
-\r
-void PrintMods()\r
-{\r
- Module* ml;\r
- ml = modlist;\r
- dprintf("Loaded Modules\n");\r
- while (ml != NULL){\r
- dprintf("mod name: %s\n", ml->name);\r
- ml = ml->next;\r
- }\r
- dprintf("end of list\n");\r
-}\r
-\r
-\r
-Module* ThisModule(char* name)\r
-{\r
- Module* ml;\r
- ml = modlist;\r
- while ((ml != NULL) && (strcmp(ml->name, name) != 0)){\r
- ml = ml->next;\r
- }\r
- return ml;\r
-}\r
- \r
-Object* ThisObject(Module* mod, char* name)\r
-{\r
- int l, r, m;\r
- char* p;\r
- l = 0; r = mod->export->num;\r
- while (l < r){\r
- m = (l + r) / 2;\r
- p = (char*) &(mod->names[mod->export->obj[m].id / 256]);\r
- if (strcmp(p, name) == 0)\r
- return (Object*)&(mod->export->obj[m]);\r
- if (strcmp(p, name) < 0)\r
- l = m + 1;\r
- else\r
- r = m;\r
- }\r
- return NULL;\r
-}\r
-\r
-Object* ThisDesc(Module* mod, int fprint)\r
-{\r
- int i, n;\r
- i = 0; n = mod->export->num;\r
- while ((i < n) && (mod->export->obj[i].id / 256 == 0))\r
- {\r
- if (mod->export->obj[i].offs == fprint)\r
- return (Object*)&(mod->export->obj[i]);\r
- i++;\r
- }\r
- return NULL;\r
-}\r
-\r
-int LoadDll (char* name)\r
-{\r
- \r
- void *handle;\r
- dprintf("loading: %s\n", name);\r
- if ((handle = dlopen(name, RTLD_LAZY + RTLD_GLOBAL)) == NULL) {\r
- printf("LoadDll: failed to load lib %s\n", name); \r
- printf(" - dlerror: %s\n", dlerror());\r
- exit(-1);\r
- }\r
- return handle != NULL;\r
-}\r
-\r
- \r
-int ThisDllObj (int mode, int fprint, char* dll, char* name)\r
-{\r
- void *handle; \r
- int ad = 0;\r
- if ((mode == mVar) || (mode == mProc)){\r
- if ((handle = dlopen(dll, RTLD_LAZY + RTLD_GLOBAL)) == NULL) {\r
- printf("ThisDllObj: lib %s not found\n", dll); \r
- printf(" - dlerror: %s\n", dlerror());\r
- exit(-1);\r
- } else {\r
- ad = (int)dlsym((void *) handle, name);\r
- if (ad == 0) {\r
- printf("ThisDllObj: symbol %s not found\n", name); exit(-1);\r
- }\r
- }\r
- }\r
- return ad;\r
- }\r
-\r
-int Read4 ()\r
-{\r
- unsigned char b;\r
- int w;\r
- b = fgetc(f); w = b % 256;\r
- b = fgetc(f); w = w + 0x100 * (b % 256);\r
- b = fgetc(f); w = w + 0x10000 * (b % 256);\r
- b = fgetc(f); w = w + 0x1000000 * b;\r
- return w;\r
-}\r
-\r
-int RNum()\r
-{\r
- char b;\r
- int s, y;\r
- s = 0; y = 0;\r
- b = fgetc(f);\r
- while (b < 0) \r
- {\r
- y = y + ((b + 128) << s);\r
- s = s + 7;\r
- b = fgetc(f); \r
- }\r
- return (((b + 64) % 128 - 64) << s) + y;\r
-}\r
-\r
-void ReadName (char* str)\r
-{\r
- unsigned char b;\r
- int i;\r
- i = 0; b = fgetc(f);\r
- while (b != 0)\r
- {\r
- str[i] = b; i++; b = fgetc(f);\r
- }\r
- str[i] = 0;\r
-}\r
-\r
-void Fixup (int adr)\r
-{\r
- int link, offset, linkadr, n, x, t;\r
-\r
- dprintf("fixup: %X ", adr);\r
- link = RNum();\r
- while (link != 0)\r
- {\r
- offset = RNum();\r
- dprintf("+%d: ", offset);\r
- while (link != 0)\r
- {\r
- if (link > 0) \r
- {\r
- dprintf("c");\r
- linkadr = mod.mad + mod.ms + link;\r
- }\r
- else\r
- {\r
- dprintf("d");\r
- link = -link;\r
- if (link < mod.ms) \r
- linkadr = mod.mad + link;\r
- else\r
- linkadr = mod.dad + link - mod.ms;\r
- }\r
- dprintf("%X ", link);\r
- \r
- /*\r
- t = *(char*)(linkadr + 3);\r
- n = *(int*)linkadr;\r
- n = n << 8; n = n >> 8;\r
- */\r
- x = *(int*)linkadr;\r
- t = x / 0x1000000;\r
- n = (x + 0x800000) % 0x1000000 - 0x800000;\r
- \r
- switch (t) {\r
- case absolute: x = adr + offset; break;\r
- case relative: x = adr + offset - linkadr -4; break;\r
- case copy: x = *(int*)(adr + offset); break;\r
- case table: x = adr + n; n = link + 4; break;\r
- case tableend: x = adr + n; n = 0; break;\r
- case deref: x = *(int*)(adr + 2); x = x + offset; break;\r
- case halfword:\r
- printf("fixup: halfword not implemented\n");\r
- break;\r
- default:\r
- printf("fixup error(link=%d, offset=%d, linkadr=%d, t=%d, x=%d)\n",\r
- link, offset, linkadr, t, x);\r
- return;\r
- } \r
- *(int*)linkadr = x;\r
- link = n;\r
- }\r
- link = RNum();\r
- }\r
- dprintf("\n");\r
-}\r
-\r
-int ReadBootHeader()\r
-{\r
- int tag, version;\r
-\r
- fseek(f, exeSize, SEEK_SET);\r
- tag = Read4();\r
- version = Read4();\r
- if ((tag != 0x3A4B5C6D) || (version != 0))\r
- {\r
- return 0;\r
- }\r
- nofMods = Read4();\r
- dprintf("Linked modules: %d\n", nofMods);\r
- ReadName(kernel);\r
- dprintf("kernel: %s\n", kernel);\r
- ReadName(mainmod);\r
- dprintf("main: %s\n", mainmod);\r
- newRecFP = Read4(); newRecAdr = 0;\r
- newArrFP = Read4(); newArrAdr = 0;\r
- mod.start = ftell(f);\r
- return 1;\r
-}\r
-\r
-int ReadHeader ()\r
-{\r
- int ofTag, i, nofImps, processor;\r
- char str[80];\r
- ImpList *imp, *last;\r
- char* n;\r
-\r
- ofTag = Read4();\r
- if (ofTag != 0x6F4F4346) \r
- {\r
- printf("wrong object file version\n");\r
- return 0;\r
- }\r
- processor = Read4(); \r
- mod.hs = Read4();\r
- mod.ms = Read4();\r
- mod.ds = Read4();\r
- mod.cs = Read4();\r
- mod.vs = Read4();\r
- dprintf("File tag: %d ", ofTag); dprintf("Processor: %d\n", processor);\r
- dprintf("Header size: %d ", mod.hs);\r
- dprintf("Meta size: %d ", mod.ms);\r
- dprintf("Desc size: %d ", mod.ds );\r
- dprintf("Code size: %d ", mod.cs);\r
- dprintf("Data size: %d\n", mod.vs);\r
- nofImps = RNum(); dprintf("Nof imports: %d\n", nofImps);\r
- ReadName(mod.name); dprintf("Module name: %s\n", mod.name);\r
- mod.imp = NULL;\r
- for (i = 0; i < nofImps; i++)\r
- {\r
- imp = (ImpList*)calloc(1, sizeof(ImpList));\r
- ReadName(imp->name);\r
- if (mod.imp == NULL)\r
- mod.imp = imp;\r
- else\r
- last->next = imp;\r
- last = imp;\r
- last->next = NULL;\r
- dprintf("Import %d: %s\n", i, imp->name);\r
- if ((imp->name[0] == '$') && (imp->name[1] == '$'))\r
- strcpy(imp->name, "Kernel");\r
- if (imp->name[0] == '$'){\r
- n = imp->name;\r
- n++;\r
- if (!LoadDll(n)){\r
- printf("Could not load lib: %s\n", imp->name[1]);\r
- return 0;\r
- }\r
- }\r
- }\r
- dprintf("Pos: %d\n", ftell(f));\r
- return 1;\r
-}\r
-\r
-int ReadModule ()\r
-{\r
- char *dp, *mp; \r
- unsigned int cnt;\r
- ImpList* imp;\r
- int x, fp, opt, link, ofp, imptab, a;\r
- Module *desc, *k;\r
- String name;\r
- Object* obj;\r
- int isLib;\r
- char* im;\r
-\r
- mod.dad = (int) calloc(1, mod.ds);\r
- mod.mad = (int) calloc(1, mod.ms + mod.cs + mod.vs);\r
- if ((mod.dad == 0) || (mod.mad == 0)) \r
- {\r
- printf("BootLoader: Couldn't initalize heap\n");\r
- free((void*)mod.dad);\r
- free((void*)mod.mad);\r
- return 0;\r
- }\r
- dp = (char*) mod.dad;\r
- mp = (char*) mod.mad;\r
- fseek(f, mod.start + mod.hs, SEEK_SET);\r
- dprintf("ReadModule after fseek pos: %d\n", ftell(f));\r
- cnt = fread(mp, 1, mod.ms, f);\r
- dprintf("Read meta bulk (%d bytes. New pos: %d)\n", cnt, ftell(f));\r
- cnt = fread(dp, 1, mod.ds, f);\r
- dprintf("Read desc bulk (%d bytes. New pos: %d)\n", cnt, ftell(f));\r
- mp = (char*)(mod.mad + mod.ms);\r
- cnt = fread(mp, 1, mod.cs, f); \r
- dprintf("Read code bulk (%d bytes. New pos: %d)\n", cnt, ftell(f));\r
-\r
- DumpMod();\r
-\r
- dprintf("before fixup: pos = %d\n", ftell(f));\r
- \r
- if ((!newRecAdr) || (!newArrAdr)){\r
- k = ThisModule(kernel);\r
- if (k != NULL){\r
- /* obj = ThisDesc(k, newRecFP);*/\r
- obj = ThisObject(k, "NewRec");\r
- if (obj != NULL)\r
- newRecAdr = k->procBase + obj->offs;\r
- /* obj = ThisDesc(k, newArrFP);*/\r
- obj = ThisObject(k, "NewArr");\r
- if (obj != NULL)\r
- newArrAdr = k->procBase + obj->offs;\r
- dprintf("newRecFP: %X newArrFP: %X\n", newRecFP, newArrFP);\r
- dprintf("newRecAdr: %X newArrAdr: %X\n", newRecAdr, newArrAdr);\r
- } else {\r
- dprintf("no kernel before %s.\n", mod.name);\r
- }\r
- }\r
- Fixup(newRecAdr);\r
- Fixup(newArrAdr);\r
- Fixup(mod.mad);\r
- Fixup(mod.dad);\r
- Fixup(mod.mad + mod.ms);\r
- Fixup(mod.mad + mod.ms + mod.cs);\r
- dprintf("after fixup: pos = %d\n", ftell(f));\r
- imp = mod.imp; imptab = (int)((Module*)(mod.dad))->imports;\r
- while (imp != NULL){\r
- x = RNum();\r
- if ((imp->name[0] == '$') && (imp->name[1] == '$'))\r
- printf("should be Kerneln");\r
- if (imp->name[0] == '$')\r
- isLib = 1;\r
- else{\r
- isLib = 0;\r
- desc = ThisModule(imp->name);\r
- if (desc == NULL){\r
- printf("invalid import list\n");\r
- return 0;\r
- }\r
- }\r
- while (x != 0) {\r
- ReadName(name); fp = RNum(); opt = 0;\r
- if (!isLib) {\r
- if (name[0] == 0)\r
- obj = ThisDesc(desc, fp);\r
- else\r
- obj = ThisObject(desc, name);\r
- if ((obj != NULL) && (obj->id % 16 == x)){\r
- ofp = obj->fprint;\r
- switch (x){\r
- case mTyp:\r
- opt = RNum();\r
- if (opt % 2 == 1) ofp = obj->offs;\r
- if ((opt > 1) && ((obj->id / 16) % 16 != mExported)){\r
- printf("object not found (%s)\n", imp->name);\r
- return 0;\r
- }\r
- Fixup((int)obj->ostruct);\r
- break;\r
- case mVar:\r
- Fixup(desc->varBase + obj->offs);\r
- break;\r
- case mProc:\r
- Fixup(desc->procBase + obj->offs);\r
- }\r
- if (ofp != fp){\r
- printf("illigal foot print (%s)\n", imp->name);\r
- return 0;\r
- }\r
- } else {\r
- if (obj == NULL) printf("obj == NULL\n");\r
- printf("descriptor not found (%s, x: %d, id: %d)\n", name, x, obj->id);\r
- return 0;\r
- }\r
- }else{\r
- if ((x == mVar) || (x == mProc)){ \r
- im = imp->name;\r
- im++;\r
- a = ThisDllObj(x, fp, im, name);\r
- if (a != 0)\r
- Fixup(a);\r
- else{\r
- printf("ReadModule: Object not found: %s\n", name);\r
- return 0;\r
- }\r
- } else {\r
- if (x == mTyp) {\r
- opt = RNum();\r
- x = RNum();\r
- if (x != 0) {\r
- printf("ReadModule: Object not found: %s\n", name);\r
- return 0;\r
- }\r
- }\r
- }\r
- }\r
- x = RNum();\r
- }\r
- *(int*)imptab = (int)desc; imptab += 4;\r
- imp = imp->next;\r
- }\r
-\r
- mod.start = ftell(f);\r
- return 1;\r
-}\r
-\r
-int main (int argc, char *argv[])\r
-{\r
- int i, ok;\r
- BodyProc body;\r
- int callBackAdr;\r
- Module *k, *m;\r
-\r
- modlist = NULL;\r
- dprintf("initializing BlackBox for Linux...\n");\r
- /*f = fopen(bbfile, "rb");*/\r
- f = fopen(argv[0], "r");\r
- if (f != NULL) \r
- {\r
- if (ReadBootHeader())\r
- {\r
- i = 0; ok = 1;\r
- while ((i < nofMods) && (ok)){\r
- ok = ReadHeader();\r
- if (ok) {\r
- ok = ReadModule();\r
- if (ok)\r
- RegisterModule();\r
- else\r
- printf("Incorrect module: %s\n", mod.name);\r
- } else\r
- printf("Incorrect header: %s\n", mod.name);\r
- i++;\r
- }\r
- fclose(f);\r
- if (ok) {\r
- k = ThisModule(kernel);\r
- m = ThisModule(mainmod);\r
- if (k == NULL)\r
- printf("no kernel\n");\r
- else\r
- {\r
- if (m == NULL) \r
- printf("no main module");\r
- else\r
- {\r
- /* assign the boot info to first variable in Kernel */\r
- bootInfo = calloc(1, sizeof(BootInfo));\r
- bootInfo->modList = modlist;\r
- bootInfo->argc = argc;\r
- bootInfo->argv = argv;\r
- *((int*)(k->varBase)) = (int)bootInfo;\r
- dprintf("before body\n");\r
- body = (BodyProc)(m->code);\r
- k->opts = k->opts | init; /* include init in opts */\r
- body();\r
- dprintf("after body\n");\r
- }\r
- }\r
- PrintMods();\r
- }\r
- } else\r
- printf("Invalid BlackBox executable, make sure that the constant exeSize is correctly set\n");\r
-\r
- } else \r
- printf("Couldn't find file: %s\n", bbfile);\r
-}\r
+
+/*
+ * C-startup and loader for BlackBox
+ * Implemented as the StdLoader.
+ */
+
+
+#include <sys/mman.h>
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+
+/* the exact size (in bytes) of the executable part of the file. */
+/* this constant needs to be updated everytime a change is made to this file */
+#define exeSize 16860
+
+
+#define pageSize 4096
+
+/* fixup types */
+#define absolute 100
+#define relative 101
+#define copy 102
+#define table 103
+#define tableend 104
+#define deref 105
+#define halfword 106
+
+/* import types */
+#define mConst 0x1
+#define mTyp 0x2
+#define mVar 0x3
+#define mProc 0x4
+#define mExported 4
+
+#define any 1000000
+
+#define init 0x10000
+
+/* set to printf to debug and donothing to avoid debugging */
+#define dprintf donothing
+
+typedef void (*BodyProc)();
+typedef char String[256];
+
+typedef struct Type {
+ int size;
+ struct Module* mod;
+ int id;
+ int base[16]; /* should be ARRAY 16 OF TYPE */
+ int fields; /* should be Directory* */
+ int ptroffs[any];
+} Type;
+
+typedef struct Object{
+ int fprint;
+ int offs;
+ int id;
+ Type* ostruct;
+} Object;
+
+typedef struct Directory{
+ int num;
+ Object obj[any];
+} Directory;
+
+typedef struct Module{ /* has to be exact copy of Kernel.Module */
+ struct Module *next;
+ int opts;
+ int refcnt;
+ short compTime[6], loadTime[6];
+ int ext;
+ int term; /* actually a pointer to type Command */
+ int nofimps, nofptrs;
+ int csize, dsize, rsize;
+ int code, data, refs;
+ int procBase, varBase; /* meta base addresses */
+ char* names; /* names[0] = 0X */
+ int* ptrs;
+ struct Module* imports;
+ Directory* export;
+ char name[256];
+} Module;
+
+typedef struct ImpList
+{
+ struct ImpList* next;
+ String name;
+} ImpList;
+
+typedef struct ModSpec
+{
+ ImpList* imp;
+ String name;
+ int start, hs, ms, ds, cs, vs, mad, dad;
+} ModSpec;
+
+typedef struct BootInfo
+{
+ Module* modList;
+ int argc;
+ char** argv;
+} BootInfo;
+
+const char bbfile[] = "./bb.boot";
+
+FILE* f;
+int nofMods;
+String kernel, mainmod;
+ModSpec mod;
+Module *modlist;
+BootInfo* bootInfo;
+int newRecAdr, newArrAdr;
+int newRecFP, newArrFP;
+
+int donothing(char* fmt, ...)
+{
+}
+
+void DumpMod()
+{
+ dprintf("\n\n---- Mod info:\n");
+ dprintf(" hs, ms, ds, cs, vs = %d, %d, %d, %d, %d\n",
+ mod.hs, mod.ms, mod.ds, mod.cs, mod.vs);
+ dprintf(" mad, dad = %d, %d\n\n", mod.mad, mod.dad);
+}
+
+
+void RegisterModule()
+{
+ Module* m;
+ m = (Module*)mod.dad;
+ m->next = modlist;
+ modlist = m;
+ /*
+ if (modlist == NULL){
+ modlist = m;
+ } else {
+ last->next = m;
+ last = m;
+ }
+ last->next = NULL;
+ */
+ dprintf("Registred module %s\n", mod.name);
+}
+
+void PrintMods()
+{
+ Module* ml;
+ ml = modlist;
+ dprintf("Loaded Modules\n");
+ while (ml != NULL){
+ dprintf("mod name: %s\n", ml->name);
+ ml = ml->next;
+ }
+ dprintf("end of list\n");
+}
+
+
+Module* ThisModule(char* name)
+{
+ Module* ml;
+ ml = modlist;
+ while ((ml != NULL) && (strcmp(ml->name, name) != 0)){
+ ml = ml->next;
+ }
+ return ml;
+}
+
+Object* ThisObject(Module* mod, char* name)
+{
+ int l, r, m;
+ char* p;
+ l = 0; r = mod->export->num;
+ while (l < r){
+ m = (l + r) / 2;
+ p = (char*) &(mod->names[mod->export->obj[m].id / 256]);
+ if (strcmp(p, name) == 0)
+ return (Object*)&(mod->export->obj[m]);
+ if (strcmp(p, name) < 0)
+ l = m + 1;
+ else
+ r = m;
+ }
+ return NULL;
+}
+
+Object* ThisDesc(Module* mod, int fprint)
+{
+ int i, n;
+ i = 0; n = mod->export->num;
+ while ((i < n) && (mod->export->obj[i].id / 256 == 0))
+ {
+ if (mod->export->obj[i].offs == fprint)
+ return (Object*)&(mod->export->obj[i]);
+ i++;
+ }
+ return NULL;
+}
+
+int LoadDll (char* name)
+{
+
+ void *handle;
+ dprintf("loading: %s\n", name);
+ if ((handle = dlopen(name, RTLD_LAZY + RTLD_GLOBAL)) == NULL) {
+ printf("LoadDll: failed to load lib %s\n", name);
+ printf(" - dlerror: %s\n", dlerror());
+ exit(-1);
+ }
+ return handle != NULL;
+}
+
+
+int ThisDllObj (int mode, int fprint, char* dll, char* name)
+{
+ void *handle;
+ int ad = 0;
+ if ((mode == mVar) || (mode == mProc)){
+ if ((handle = dlopen(dll, RTLD_LAZY + RTLD_GLOBAL)) == NULL) {
+ printf("ThisDllObj: lib %s not found\n", dll);
+ printf(" - dlerror: %s\n", dlerror());
+ exit(-1);
+ } else {
+ ad = (int)dlsym((void *) handle, name);
+ if (ad == 0) {
+ printf("ThisDllObj: symbol %s not found\n", name); exit(-1);
+ }
+ }
+ }
+ return ad;
+ }
+
+int Read4 ()
+{
+ unsigned char b;
+ int w;
+ b = fgetc(f); w = b % 256;
+ b = fgetc(f); w = w + 0x100 * (b % 256);
+ b = fgetc(f); w = w + 0x10000 * (b % 256);
+ b = fgetc(f); w = w + 0x1000000 * b;
+ return w;
+}
+
+int RNum()
+{
+ char b;
+ int s, y;
+ s = 0; y = 0;
+ b = fgetc(f);
+ while (b < 0)
+ {
+ y = y + ((b + 128) << s);
+ s = s + 7;
+ b = fgetc(f);
+ }
+ return (((b + 64) % 128 - 64) << s) + y;
+}
+
+void ReadName (char* str)
+{
+ unsigned char b;
+ int i;
+ i = 0; b = fgetc(f);
+ while (b != 0)
+ {
+ str[i] = b; i++; b = fgetc(f);
+ }
+ str[i] = 0;
+}
+
+void Fixup (int adr)
+{
+ int link, offset, linkadr, n, x, t;
+
+ dprintf("fixup: %X ", adr);
+ link = RNum();
+ while (link != 0)
+ {
+ offset = RNum();
+ dprintf("+%d: ", offset);
+ while (link != 0)
+ {
+ if (link > 0)
+ {
+ dprintf("c");
+ linkadr = mod.mad + mod.ms + link;
+ }
+ else
+ {
+ dprintf("d");
+ link = -link;
+ if (link < mod.ms)
+ linkadr = mod.mad + link;
+ else
+ linkadr = mod.dad + link - mod.ms;
+ }
+ dprintf("%X ", link);
+
+ /*
+ t = *(char*)(linkadr + 3);
+ n = *(int*)linkadr;
+ n = n << 8; n = n >> 8;
+ */
+ x = *(int*)linkadr;
+ t = x / 0x1000000;
+ n = (x + 0x800000) % 0x1000000 - 0x800000;
+
+ switch (t) {
+ case absolute: x = adr + offset; break;
+ case relative: x = adr + offset - linkadr -4; break;
+ case copy: x = *(int*)(adr + offset); break;
+ case table: x = adr + n; n = link + 4; break;
+ case tableend: x = adr + n; n = 0; break;
+ case deref: x = *(int*)(adr + 2); x = x + offset; break;
+ case halfword:
+ printf("fixup: halfword not implemented\n");
+ break;
+ default:
+ printf("fixup error(link=%d, offset=%d, linkadr=%d, t=%d, x=%d)\n",
+ link, offset, linkadr, t, x);
+ return;
+ }
+ *(int*)linkadr = x;
+ link = n;
+ }
+ link = RNum();
+ }
+ dprintf("\n");
+}
+
+int ReadBootHeader()
+{
+ int tag, version;
+
+ fseek(f, exeSize, SEEK_SET);
+ tag = Read4();
+ version = Read4();
+ if ((tag != 0x3A4B5C6D) || (version != 0))
+ {
+ return 0;
+ }
+ nofMods = Read4();
+ dprintf("Linked modules: %d\n", nofMods);
+ ReadName(kernel);
+ dprintf("kernel: %s\n", kernel);
+ ReadName(mainmod);
+ dprintf("main: %s\n", mainmod);
+ newRecFP = Read4(); newRecAdr = 0;
+ newArrFP = Read4(); newArrAdr = 0;
+ mod.start = ftell(f);
+ return 1;
+}
+
+int ReadHeader ()
+{
+ int ofTag, i, nofImps, processor;
+ char str[80];
+ ImpList *imp, *last;
+ char* n;
+
+ ofTag = Read4();
+ if (ofTag != 0x6F4F4346)
+ {
+ printf("wrong object file version\n");
+ return 0;
+ }
+ processor = Read4();
+ mod.hs = Read4();
+ mod.ms = Read4();
+ mod.ds = Read4();
+ mod.cs = Read4();
+ mod.vs = Read4();
+ dprintf("File tag: %d ", ofTag); dprintf("Processor: %d\n", processor);
+ dprintf("Header size: %d ", mod.hs);
+ dprintf("Meta size: %d ", mod.ms);
+ dprintf("Desc size: %d ", mod.ds );
+ dprintf("Code size: %d ", mod.cs);
+ dprintf("Data size: %d\n", mod.vs);
+ nofImps = RNum(); dprintf("Nof imports: %d\n", nofImps);
+ ReadName(mod.name); dprintf("Module name: %s\n", mod.name);
+ mod.imp = NULL;
+ for (i = 0; i < nofImps; i++)
+ {
+ imp = (ImpList*)calloc(1, sizeof(ImpList));
+ ReadName(imp->name);
+ if (mod.imp == NULL)
+ mod.imp = imp;
+ else
+ last->next = imp;
+ last = imp;
+ last->next = NULL;
+ dprintf("Import %d: %s\n", i, imp->name);
+ if ((imp->name[0] == '$') && (imp->name[1] == '$'))
+ strcpy(imp->name, "Kernel");
+ if (imp->name[0] == '$'){
+ n = imp->name;
+ n++;
+ if (!LoadDll(n)){
+ printf("Could not load lib: %s\n", (char *)(&(imp->name[1])));
+ return 0;
+ }
+ }
+ }
+ dprintf("Pos: %d\n", ftell(f));
+ return 1;
+}
+
+int ReadModule ()
+{
+ char *dp, *mp;
+ unsigned int cnt;
+ ImpList* imp;
+ int x, fp, opt, link, ofp, imptab, a;
+ Module *desc, *k;
+ String name;
+ Object* obj;
+ int isLib;
+ char* im;
+
+ mod.dad = (int) calloc(1, mod.ds);
+ mod.mad = (int) calloc(1, mod.ms + mod.cs + mod.vs);
+ if ((mod.dad == 0) || (mod.mad == 0))
+ {
+ printf("BootLoader: Couldn't initalize heap\n");
+ free((void*)mod.dad);
+ free((void*)mod.mad);
+ return 0;
+ }
+ dp = (char*) mod.dad;
+ mp = (char*) mod.mad;
+ fseek(f, mod.start + mod.hs, SEEK_SET);
+ dprintf("ReadModule after fseek pos: %d\n", ftell(f));
+ cnt = fread(mp, 1, mod.ms, f);
+ dprintf("Read meta bulk (%d bytes. New pos: %d)\n", cnt, ftell(f));
+ cnt = fread(dp, 1, mod.ds, f);
+ dprintf("Read desc bulk (%d bytes. New pos: %d)\n", cnt, ftell(f));
+ mp = (char*)(mod.mad + mod.ms);
+ cnt = fread(mp, 1, mod.cs, f);
+ dprintf("Read code bulk (%d bytes. New pos: %d)\n", cnt, ftell(f));
+
+ DumpMod();
+
+ dprintf("before fixup: pos = %d\n", ftell(f));
+
+ if ((!newRecAdr) || (!newArrAdr)){
+ k = ThisModule(kernel);
+ if (k != NULL){
+ /* obj = ThisDesc(k, newRecFP);*/
+ obj = ThisObject(k, "NewRec");
+ if (obj != NULL)
+ newRecAdr = k->procBase + obj->offs;
+ /* obj = ThisDesc(k, newArrFP);*/
+ obj = ThisObject(k, "NewArr");
+ if (obj != NULL)
+ newArrAdr = k->procBase + obj->offs;
+ dprintf("newRecFP: %X newArrFP: %X\n", newRecFP, newArrFP);
+ dprintf("newRecAdr: %X newArrAdr: %X\n", newRecAdr, newArrAdr);
+ } else {
+ dprintf("no kernel before %s.\n", mod.name);
+ }
+ }
+ Fixup(newRecAdr);
+ Fixup(newArrAdr);
+ Fixup(mod.mad);
+ Fixup(mod.dad);
+ Fixup(mod.mad + mod.ms);
+ Fixup(mod.mad + mod.ms + mod.cs);
+ dprintf("after fixup: pos = %d\n", ftell(f));
+ imp = mod.imp; imptab = (int)((Module*)(mod.dad))->imports;
+ while (imp != NULL){
+ x = RNum();
+ if ((imp->name[0] == '$') && (imp->name[1] == '$'))
+ printf("should be Kerneln");
+ if (imp->name[0] == '$')
+ isLib = 1;
+ else{
+ isLib = 0;
+ desc = ThisModule(imp->name);
+ if (desc == NULL){
+ printf("invalid import list\n");
+ return 0;
+ }
+ }
+ while (x != 0) {
+ ReadName(name); fp = RNum(); opt = 0;
+ if (!isLib) {
+ if (name[0] == 0)
+ obj = ThisDesc(desc, fp);
+ else
+ obj = ThisObject(desc, name);
+ if ((obj != NULL) && (obj->id % 16 == x)){
+ ofp = obj->fprint;
+ switch (x){
+ case mTyp:
+ opt = RNum();
+ if (opt % 2 == 1) ofp = obj->offs;
+ if ((opt > 1) && ((obj->id / 16) % 16 != mExported)){
+ printf("object not found (%s)\n", imp->name);
+ return 0;
+ }
+ Fixup((int)obj->ostruct);
+ break;
+ case mVar:
+ Fixup(desc->varBase + obj->offs);
+ break;
+ case mProc:
+ Fixup(desc->procBase + obj->offs);
+ }
+ if (ofp != fp){
+ printf("illigal foot print (%s)\n", imp->name);
+ return 0;
+ }
+ } else {
+ if (obj == NULL) printf("obj == NULL\n");
+ printf("descriptor not found (%s, x: %d, id: %d)\n", name, x, obj->id);
+ return 0;
+ }
+ }else{
+ if ((x == mVar) || (x == mProc)){
+ im = imp->name;
+ im++;
+ a = ThisDllObj(x, fp, im, name);
+ if (a != 0)
+ Fixup(a);
+ else{
+ printf("ReadModule: Object not found: %s\n", name);
+ return 0;
+ }
+ } else {
+ if (x == mTyp) {
+ opt = RNum();
+ x = RNum();
+ if (x != 0) {
+ printf("ReadModule: Object not found: %s\n", name);
+ return 0;
+ }
+ }
+ }
+ }
+ x = RNum();
+ }
+ *(int*)imptab = (int)desc; imptab += 4;
+ imp = imp->next;
+ }
+
+ mod.start = ftell(f);
+ return 1;
+}
+
+int MOD (int x, int y)
+{
+ int res;
+
+ if (x >= 0) {
+ res = x % y;
+ } else {
+ res = x - y * ((x + 1) / y - 1);
+ }
+ return res;
+}
+
+int main (int argc, char *argv[])
+{
+ int i, ok;
+ BodyProc body;
+ int callBackAdr;
+ Module *k, *m;
+
+ modlist = NULL;
+ dprintf("initializing BlackBox for Linux...\n");
+ /*f = fopen(bbfile, "rb");*/
+ f = fopen(argv[0], "r");
+ if (f != NULL)
+ {
+ if (ReadBootHeader())
+ {
+ i = 0; ok = 1;
+ while ((i < nofMods) && (ok)){
+ ok = ReadHeader();
+ if (ok) {
+ ok = ReadModule();
+ if (ok)
+ RegisterModule();
+ else
+ printf("Incorrect module: %s\n", mod.name);
+ } else
+ printf("Incorrect header: %s\n", mod.name);
+ i++;
+ }
+ fclose(f);
+ if (ok) {
+ k = ThisModule(kernel);
+ m = ThisModule(mainmod);
+ if (k == NULL)
+ printf("no kernel\n");
+ else
+ {
+ if (m == NULL)
+ printf("no main module");
+ else
+ {
+ /* assign the boot info to first variable in Kernel */
+ bootInfo = calloc(1, sizeof(BootInfo));
+ bootInfo->modList = modlist;
+ bootInfo->argc = argc;
+ bootInfo->argv = argv;
+ *((int*)(k->varBase)) = (int)bootInfo;
+ dprintf("before body\n");
+ body = (BodyProc)(m->code);
+ k->opts = k->opts | init; /* include init in opts */
+ ok = mprotect(
+ (void *)(((m->code) / pageSize) * pageSize),
+ (((m->csize) + MOD(m->code, pageSize) - 1) / pageSize) * pageSize + pageSize,
+ PROT_READ|PROT_WRITE|PROT_EXEC);
+ if (ok != 0){
+ printf("mprotect failed!\n");
+ return 100;
+ }
+ body();
+ dprintf("after body\n");
+ }
+ }
+ PrintMods();
+ }
+ } else
+ printf("Invalid BlackBox executable, make sure that the constant exeSize is correctly set\n");
+
+ } else
+ printf("Couldn't find file: %s\n", bbfile);
+}