From cce27fb37654feaf4afd261687dbd897972d1340 Mon Sep 17 00:00:00 2001 From: Ivan Denisov Date: Sat, 3 Oct 2015 17:43:44 +0700 Subject: [PATCH] Sources of C-loader fixed for Linux. Author: A.Shiryaev --- BlackBox/_Linux_/Lin/Rsrc/Makefile | 4 + BlackBox/_Linux_/Lin/Rsrc/blackbox.c | 1244 +++++++++++++------------- BlackBox/_Linux_/Lin/Rsrc/exe.img | Bin 21399 -> 16860 bytes 3 files changed, 638 insertions(+), 610 deletions(-) mode change 100644 => 100755 BlackBox/_Linux_/Lin/Rsrc/exe.img 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 728ac428ae5308bf3201b02e2f8b70335baf714e..4e06ec45df3a67157a92ff3cda495e92a208cbef GIT binary patch literal 16860 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 HTi$;G<3k`@ literal 21399 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 Pf}1yH2hB$Vz198)A|Ce` -- 2.29.2