|
@@ -1,610 +1,634 @@
|
|
|
-
|
|
|
-/*
|
|
|
- * C-startup and loader for BlackBox
|
|
|
- * Implemented as the StdLoader.
|
|
|
- */
|
|
|
-
|
|
|
-
|
|
|
-#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 21399
|
|
|
-
|
|
|
-
|
|
|
-/* 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", 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 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 */
|
|
|
- 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);
|
|
|
-}
|
|
|
+
|
|
|
+/*
|
|
|
+ * 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);
|
|
|
+}
|