DEADSOFTWARE

Sources of C-loader fixed for Linux. Author: A.Shiryaev
authorIvan Denisov <d.ivan.krsk@gmail.com>
Sat, 3 Oct 2015 10:43:44 +0000 (17:43 +0700)
committerIvan Denisov <d.ivan.krsk@gmail.com>
Sat, 3 Oct 2015 10:43:44 +0000 (17:43 +0700)
BlackBox/_Linux_/Lin/Rsrc/Makefile
BlackBox/_Linux_/Lin/Rsrc/blackbox.c
BlackBox/_Linux_/Lin/Rsrc/exe.img [changed mode: 0644->0755]

index 67a56f6177850450ad18eed5dad495517786b3aa..938607b3719ec9b6faf1bec98ca48a1bc0c6fb41 100644 (file)
@@ -1,8 +1,12 @@
 # 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);
+}
old mode 100644 (file)
new mode 100755 (executable)
index 728ac42..4e06ec4
Binary files a/BlackBox/_Linux_/Lin/Rsrc/exe.img and b/BlackBox/_Linux_/Lin/Rsrc/exe.img differ