From: Ivan Denisov Date: Sat, 3 Oct 2015 10:43:44 +0000 (+0700) Subject: Sources of C-loader fixed for Linux. Author: A.Shiryaev X-Git-Url: https://deadsoftware.ru/gitweb?a=commitdiff_plain;h=cce27fb37654feaf4afd261687dbd897972d1340;p=bbcp.git Sources of C-loader fixed for Linux. Author: A.Shiryaev --- diff --git a/BlackBox/_Linux_/Lin/Rsrc/Makefile b/BlackBox/_Linux_/Lin/Rsrc/Makefile index 67a56f6..938607b 100644 --- a/BlackBox/_Linux_/Lin/Rsrc/Makefile +++ b/BlackBox/_Linux_/Lin/Rsrc/Makefile @@ -1,8 +1,12 @@ # Make File for building the Linux BlackBox Loader # Runs on Linux ELF +# for 32-bit CFLAGS = -O2 +# for 64-bit +# CFLAGS = -m32 -O2 + exe.img: blackbox.o gcc $(CFLAGS) -o exe.img blackbox.o -ldl -lm diff --git a/BlackBox/_Linux_/Lin/Rsrc/blackbox.c b/BlackBox/_Linux_/Lin/Rsrc/blackbox.c index c029504..50dab73 100644 --- a/BlackBox/_Linux_/Lin/Rsrc/blackbox.c +++ b/BlackBox/_Linux_/Lin/Rsrc/blackbox.c @@ -1,610 +1,634 @@ - -/* - * C-startup and loader for BlackBox - * Implemented as the StdLoader. - */ - - -#include -#include -#include -#include -#include - -/* 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 + +#include +#include +#include +#include +#include + +/* 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); +} diff --git a/BlackBox/_Linux_/Lin/Rsrc/exe.img b/BlackBox/_Linux_/Lin/Rsrc/exe.img old mode 100644 new mode 100755 index 728ac42..4e06ec4 Binary files a/BlackBox/_Linux_/Lin/Rsrc/exe.img and b/BlackBox/_Linux_/Lin/Rsrc/exe.img differ