4637982a894c559e4b9713b97b84f7a86f4b872e
3 * C-startup and loader for BlackBox
4 * Implemented as the StdLoader.
14 /* #include <malloc.h> */
18 /* the exact size (in bytes) of the executable part of the file. */
19 /* this constant needs to be updated everytime a change is made to this file */
45 /* set to printf to debug and donothing to avoid debugging */
46 #define dprintf donothing
48 typedef void (*BodyProc
)();
49 typedef char String
[256];
55 int base
[16]; /* should be ARRAY 16 OF TYPE */
56 int fields
; /* should be Directory* */
60 typedef struct Object
{
67 typedef struct Directory
{
72 typedef struct Module
{ /* has to be exact copy of Kernel.Module */
76 short compTime
[6], loadTime
[6];
78 int term
; /* actually a pointer to type Command */
80 int csize
, dsize
, rsize
;
82 int procBase
, varBase
; /* meta base addresses */
83 char* names
; /* names[0] = 0X */
85 struct Module
* imports
;
90 typedef struct ImpList
96 typedef struct ModSpec
100 int start
, hs
, ms
, ds
, cs
, vs
, mad
, dad
;
103 typedef struct BootInfo
110 const char bbfile
[] = "./bb.boot";
114 String kernel
, mainmod
;
118 int newRecAdr
, newArrAdr
;
119 int newRecFP
, newArrFP
;
123 int donothing(char* fmt
, ...)
129 dprintf("\n\n---- Mod info:\n");
130 dprintf(" hs, ms, ds, cs, vs = %d, %d, %d, %d, %d\n",
131 mod
.hs
, mod
.ms
, mod
.ds
, mod
.cs
, mod
.vs
);
132 dprintf(" mad, dad = %d, %d\n\n", mod
.mad
, mod
.dad
);
136 void RegisterModule()
139 m
= (Module
*)mod
.dad
;
143 if (modlist == NULL){
151 dprintf("Registred module %s\n", mod
.name
);
158 dprintf("Loaded Modules\n");
160 dprintf("mod name: %s\n", ml
->name
);
163 dprintf("end of list\n");
167 Module
* ThisModule(char* name
)
171 while ((ml
!= NULL
) && (strcmp(ml
->name
, name
) != 0)){
177 Object
* ThisObject(Module
* mod
, char* name
)
181 l
= 0; r
= mod
->export
->num
;
184 p
= (char*) &(mod
->names
[mod
->export
->obj
[m
].id
/ 256]);
185 if (strcmp(p
, name
) == 0)
186 return (Object
*)&(mod
->export
->obj
[m
]);
187 if (strcmp(p
, name
) < 0)
195 Object
* ThisDesc(Module
* mod
, int fprint
)
198 i
= 0; n
= mod
->export
->num
;
199 while ((i
< n
) && (mod
->export
->obj
[i
].id
/ 256 == 0))
201 if (mod
->export
->obj
[i
].offs
== fprint
)
202 return (Object
*)&(mod
->export
->obj
[i
]);
208 int LoadDll (char* name
)
212 dprintf("loading: %s\n", name
);
213 if ((handle
= dlopen(name
, RTLD_LAZY
+ RTLD_GLOBAL
)) == NULL
) {
214 printf("LoadDll: failed to load lib %s\n", name
);
215 printf(" - dlerror: %s\n", dlerror());
218 return handle
!= NULL
;
222 int ThisDllObj (int mode
, int fprint
, char* dll
, char* name
)
226 if ((mode
== mVar
) || (mode
== mProc
)){
227 if ((handle
= dlopen(dll
, RTLD_LAZY
+ RTLD_GLOBAL
)) == NULL
) {
228 printf("ThisDllObj: lib %s not found\n", dll
);
229 printf(" - dlerror: %s\n", dlerror());
232 ad
= (int)dlsym((void *) handle
, name
);
234 printf("ThisDllObj: symbol %s not found\n", name
); exit(-1);
245 b
= fgetc(f
); w
= b
% 256;
246 b
= fgetc(f
); w
= w
+ 0x100 * (b
% 256);
247 b
= fgetc(f
); w
= w
+ 0x10000 * (b
% 256);
248 b
= fgetc(f
); w
= w
+ 0x1000000 * b
;
260 y
= y
+ ((b
+ 128) << s
);
264 return (((b
+ 64) % 128 - 64) << s
) + y
;
267 void ReadName (char* str
)
274 str
[i
] = b
; i
++; b
= fgetc(f
);
281 int link
, offset
, linkadr
, n
, x
, t
;
283 dprintf("fixup: %X ", adr
);
288 dprintf("+%d: ", offset
);
294 linkadr
= mod
.mad
+ mod
.ms
+ link
;
301 linkadr
= mod
.mad
+ link
;
303 linkadr
= mod
.dad
+ link
- mod
.ms
;
305 dprintf("%X ", link
);
308 t = *(char*)(linkadr + 3);
310 n = n << 8; n = n >> 8;
314 n
= (x
+ 0x800000) % 0x1000000 - 0x800000;
317 case absolute
: x
= adr
+ offset
; break;
318 case relative
: x
= adr
+ offset
- linkadr
-4; break;
319 case copy
: x
= *(int*)(adr
+ offset
); break;
320 case table
: x
= adr
+ n
; n
= link
+ 4; break;
321 case tableend
: x
= adr
+ n
; n
= 0; break;
322 case deref
: x
= *(int*)(adr
+ 2); x
= x
+ offset
; break;
324 printf("fixup: halfword not implemented\n");
327 printf("fixup error(link=%d, offset=%d, linkadr=%d, t=%d, x=%d)\n",
328 link
, offset
, linkadr
, t
, x
);
343 fseek(f
, exeSize
, SEEK_SET
);
346 if ((tag
!= 0x3A4B5C6D) || (version
!= 0))
351 dprintf("Linked modules: %d\n", nofMods
);
353 dprintf("kernel: %s\n", kernel
);
355 dprintf("main: %s\n", mainmod
);
356 newRecFP
= Read4(); newRecAdr
= 0;
357 newArrFP
= Read4(); newArrAdr
= 0;
358 mod
.start
= ftell(f
);
362 void * MEMALLOC (size_t len
)
366 res
= mmap(0, len
, PROT_READ
|PROT_WRITE
|PROT_EXEC
, MAP_PRIVATE
|MAP_ANON
, zerofd
, 0);
367 if (res
== MAP_FAILED
) {
377 int ofTag
, i
, nofImps
, processor
;
383 if (ofTag
!= 0x6F4F4346)
385 printf("wrong object file version\n");
394 dprintf("File tag: %d ", ofTag
); dprintf("Processor: %d\n", processor
);
395 dprintf("Header size: %d ", mod
.hs
);
396 dprintf("Meta size: %d ", mod
.ms
);
397 dprintf("Desc size: %d ", mod
.ds
);
398 dprintf("Code size: %d ", mod
.cs
);
399 dprintf("Data size: %d\n", mod
.vs
);
400 nofImps
= RNum(); dprintf("Nof imports: %d\n", nofImps
);
401 ReadName(mod
.name
); dprintf("Module name: %s\n", mod
.name
);
403 for (i
= 0; i
< nofImps
; i
++)
405 imp
= (ImpList
*)MEMALLOC(sizeof(ImpList
));
413 dprintf("Import %d: %s\n", i
, imp
->name
);
414 if ((imp
->name
[0] == '$') && (imp
->name
[1] == '$'))
415 strcpy(imp
->name
, "Kernel");
416 if (imp
->name
[0] == '$'){
420 printf("Could not load lib: %s\n", (char *)(&(imp
->name
[1])));
425 dprintf("Pos: %d\n", ftell(f
));
434 int x
, fp
, opt
, link
, ofp
, imptab
, a
;
441 mod
.dad
= (int) MEMALLOC(mod
.ds
);
442 mod
.mad
= (int) MEMALLOC(mod
.ms
+ mod
.cs
+ mod
.vs
);
443 if ((mod
.dad
== 0) || (mod
.mad
== 0))
445 printf("BootLoader: Couldn't initalize heap\n");
446 free((void*)mod
.dad
);
447 free((void*)mod
.mad
);
450 dp
= (char*) mod
.dad
;
451 mp
= (char*) mod
.mad
;
452 fseek(f
, mod
.start
+ mod
.hs
, SEEK_SET
);
453 dprintf("ReadModule after fseek pos: %d\n", ftell(f
));
454 cnt
= fread(mp
, 1, mod
.ms
, f
);
455 dprintf("Read meta bulk (%d bytes. New pos: %d)\n", cnt
, ftell(f
));
456 cnt
= fread(dp
, 1, mod
.ds
, f
);
457 dprintf("Read desc bulk (%d bytes. New pos: %d)\n", cnt
, ftell(f
));
458 mp
= (char*)(mod
.mad
+ mod
.ms
);
459 cnt
= fread(mp
, 1, mod
.cs
, f
);
460 dprintf("Read code bulk (%d bytes. New pos: %d)\n", cnt
, ftell(f
));
464 dprintf("before fixup: pos = %d\n", ftell(f
));
466 if ((!newRecAdr
) || (!newArrAdr
)){
467 k
= ThisModule(kernel
);
469 /* obj = ThisDesc(k, newRecFP);*/
470 obj
= ThisObject(k
, "NewRec");
472 newRecAdr
= k
->procBase
+ obj
->offs
;
473 /* obj = ThisDesc(k, newArrFP);*/
474 obj
= ThisObject(k
, "NewArr");
476 newArrAdr
= k
->procBase
+ obj
->offs
;
477 dprintf("newRecFP: %X newArrFP: %X\n", newRecFP
, newArrFP
);
478 dprintf("newRecAdr: %X newArrAdr: %X\n", newRecAdr
, newArrAdr
);
480 dprintf("no kernel before %s.\n", mod
.name
);
487 Fixup(mod
.mad
+ mod
.ms
);
488 Fixup(mod
.mad
+ mod
.ms
+ mod
.cs
);
489 dprintf("after fixup: pos = %d\n", ftell(f
));
490 imp
= mod
.imp
; imptab
= (int)((Module
*)(mod
.dad
))->imports
;
493 if ((imp
->name
[0] == '$') && (imp
->name
[1] == '$'))
494 printf("should be Kerneln");
495 if (imp
->name
[0] == '$')
499 desc
= ThisModule(imp
->name
);
501 printf("invalid import list\n");
506 ReadName(name
); fp
= RNum(); opt
= 0;
509 obj
= ThisDesc(desc
, fp
);
511 obj
= ThisObject(desc
, name
);
512 if ((obj
!= NULL
) && (obj
->id
% 16 == x
)){
517 if (opt
% 2 == 1) ofp
= obj
->offs
;
518 if ((opt
> 1) && ((obj
->id
/ 16) % 16 != mExported
)){
519 printf("object not found (%s)\n", imp
->name
);
522 Fixup((int)obj
->ostruct
);
525 Fixup(desc
->varBase
+ obj
->offs
);
528 Fixup(desc
->procBase
+ obj
->offs
);
531 printf("illigal foot print (%s)\n", imp
->name
);
535 if (obj
== NULL
) printf("obj == NULL\n");
536 printf("descriptor not found (%s, x: %d, id: %d)\n", name
, x
, obj
->id
);
540 if ((x
== mVar
) || (x
== mProc
)){
543 a
= ThisDllObj(x
, fp
, im
, name
);
547 printf("ReadModule: Object not found: %s\n", name
);
555 printf("ReadModule: Object not found: %s\n", name
);
563 *(int*)imptab
= (int)desc
; imptab
+= 4;
567 mod
.start
= ftell(f
);
571 int MOD (int x
, int y
)
578 res
= x
- y
* ((x
+ 1) / y
- 1);
583 int main (int argc
, char *argv
[])
590 zerofd
= open("/dev/zero", O_RDWR
);
592 printf("open /dev/zero failed: %s\n", strerror(errno
));
597 dprintf("initializing BlackBox for Linux...\n");
599 /*f = fopen(bbfile, "rb");*/
600 f
= fopen(argv
[0], "r");
603 if (ReadBootHeader())
606 while ((i
< nofMods
) && (ok
)){
613 printf("Incorrect module: %s\n", mod
.name
);
615 printf("Incorrect header: %s\n", mod
.name
);
620 k
= ThisModule(kernel
);
621 m
= ThisModule(mainmod
);
623 printf("no kernel\n");
627 printf("no main module");
630 /* assign the boot info to first variable in Kernel */
631 bootInfo
= MEMALLOC(sizeof(BootInfo
));
632 bootInfo
->modList
= modlist
;
633 bootInfo
->argc
= argc
;
634 bootInfo
->argv
= argv
;
635 *((int*)(k
->varBase
)) = (int)bootInfo
;
636 dprintf("before body\n");
637 body
= (BodyProc
)(m
->code
);
638 k
->opts
= k
->opts
| init
; /* include init in opts */
641 (void *)(((m->code) / pageSize) * pageSize),
642 (((m->csize) + MOD(m->code, pageSize) - 1) / pageSize) * pageSize + pageSize,
643 PROT_READ|PROT_WRITE|PROT_EXEC);
645 printf("mprotect failed: %s\n", strerror(errno));
650 dprintf("after body\n");
656 printf("Invalid BlackBox executable, make sure that the constant exeSize is correctly set\n");
659 printf("Couldn't find file: %s\n", bbfile
);