3 * C-startup and loader for BlackBox
4 * Implemented as the StdLoader.
14 /* the exact size (in bytes) of the executable part of the file. */
15 /* this constant needs to be updated everytime a change is made to this file */
39 /* set to printf to debug and donothing to avoid debugging */
40 #define dprintf donothing
42 typedef void (*BodyProc
)();
43 typedef char String
[256];
49 int base
[16]; /* should be ARRAY 16 OF TYPE */
50 int fields
; /* should be Directory* */
54 typedef struct Object
{
61 typedef struct Directory
{
66 typedef struct Module
{ /* has to be exact copy of Kernel.Module */
70 short compTime
[6], loadTime
[6];
72 int term
; /* actually a pointer to type Command */
74 int csize
, dsize
, rsize
;
76 int procBase
, varBase
; /* meta base addresses */
77 char* names
; /* names[0] = 0X */
79 struct Module
* imports
;
84 typedef struct ImpList
90 typedef struct ModSpec
94 int start
, hs
, ms
, ds
, cs
, vs
, mad
, dad
;
97 typedef struct BootInfo
104 const char bbfile
[] = "./bb.boot";
108 String kernel
, mainmod
;
112 int newRecAdr
, newArrAdr
;
113 int newRecFP
, newArrFP
;
115 int donothing(char* fmt
, ...)
121 dprintf("\n\n---- Mod info:\n");
122 dprintf(" hs, ms, ds, cs, vs = %d, %d, %d, %d, %d\n",
123 mod
.hs
, mod
.ms
, mod
.ds
, mod
.cs
, mod
.vs
);
124 dprintf(" mad, dad = %d, %d\n\n", mod
.mad
, mod
.dad
);
128 void RegisterModule()
131 m
= (Module
*)mod
.dad
;
135 if (modlist == NULL){
143 dprintf("Registred module %s\n", mod
.name
);
150 dprintf("Loaded Modules\n");
152 dprintf("mod name: %s\n", ml
->name
);
155 dprintf("end of list\n");
159 Module
* ThisModule(char* name
)
163 while ((ml
!= NULL
) && (strcmp(ml
->name
, name
) != 0)){
169 Object
* ThisObject(Module
* mod
, char* name
)
173 l
= 0; r
= mod
->export
->num
;
176 p
= (char*) &(mod
->names
[mod
->export
->obj
[m
].id
/ 256]);
177 if (strcmp(p
, name
) == 0)
178 return (Object
*)&(mod
->export
->obj
[m
]);
179 if (strcmp(p
, name
) < 0)
187 Object
* ThisDesc(Module
* mod
, int fprint
)
190 i
= 0; n
= mod
->export
->num
;
191 while ((i
< n
) && (mod
->export
->obj
[i
].id
/ 256 == 0))
193 if (mod
->export
->obj
[i
].offs
== fprint
)
194 return (Object
*)&(mod
->export
->obj
[i
]);
200 int LoadDll (char* name
)
204 dprintf("loading: %s\n", name
);
205 if ((handle
= dlopen(name
, RTLD_LAZY
+ RTLD_GLOBAL
)) == NULL
) {
206 printf("LoadDll: failed to load lib %s\n", name
);
207 printf(" - dlerror: %s\n", dlerror());
210 return handle
!= NULL
;
214 int ThisDllObj (int mode
, int fprint
, char* dll
, char* name
)
218 if ((mode
== mVar
) || (mode
== mProc
)){
219 if ((handle
= dlopen(dll
, RTLD_LAZY
+ RTLD_GLOBAL
)) == NULL
) {
220 printf("ThisDllObj: lib %s not found\n", dll
);
221 printf(" - dlerror: %s\n", dlerror());
224 ad
= (int)dlsym((void *) handle
, name
);
226 printf("ThisDllObj: symbol %s not found\n", name
); exit(-1);
237 b
= fgetc(f
); w
= b
% 256;
238 b
= fgetc(f
); w
= w
+ 0x100 * (b
% 256);
239 b
= fgetc(f
); w
= w
+ 0x10000 * (b
% 256);
240 b
= fgetc(f
); w
= w
+ 0x1000000 * b
;
252 y
= y
+ ((b
+ 128) << s
);
256 return (((b
+ 64) % 128 - 64) << s
) + y
;
259 void ReadName (char* str
)
266 str
[i
] = b
; i
++; b
= fgetc(f
);
273 int link
, offset
, linkadr
, n
, x
, t
;
275 dprintf("fixup: %X ", adr
);
280 dprintf("+%d: ", offset
);
286 linkadr
= mod
.mad
+ mod
.ms
+ link
;
293 linkadr
= mod
.mad
+ link
;
295 linkadr
= mod
.dad
+ link
- mod
.ms
;
297 dprintf("%X ", link
);
300 t = *(char*)(linkadr + 3);
302 n = n << 8; n = n >> 8;
306 n
= (x
+ 0x800000) % 0x1000000 - 0x800000;
309 case absolute
: x
= adr
+ offset
; break;
310 case relative
: x
= adr
+ offset
- linkadr
-4; break;
311 case copy
: x
= *(int*)(adr
+ offset
); break;
312 case table
: x
= adr
+ n
; n
= link
+ 4; break;
313 case tableend
: x
= adr
+ n
; n
= 0; break;
314 case deref
: x
= *(int*)(adr
+ 2); x
= x
+ offset
; break;
316 printf("fixup: halfword not implemented\n");
319 printf("fixup error(link=%d, offset=%d, linkadr=%d, t=%d, x=%d)\n",
320 link
, offset
, linkadr
, t
, x
);
335 fseek(f
, exeSize
, SEEK_SET
);
338 if ((tag
!= 0x3A4B5C6D) || (version
!= 0))
343 dprintf("Linked modules: %d\n", nofMods
);
345 dprintf("kernel: %s\n", kernel
);
347 dprintf("main: %s\n", mainmod
);
348 newRecFP
= Read4(); newRecAdr
= 0;
349 newArrFP
= Read4(); newArrAdr
= 0;
350 mod
.start
= ftell(f
);
356 int ofTag
, i
, nofImps
, processor
;
362 if (ofTag
!= 0x6F4F4346)
364 printf("wrong object file version\n");
373 dprintf("File tag: %d ", ofTag
); dprintf("Processor: %d\n", processor
);
374 dprintf("Header size: %d ", mod
.hs
);
375 dprintf("Meta size: %d ", mod
.ms
);
376 dprintf("Desc size: %d ", mod
.ds
);
377 dprintf("Code size: %d ", mod
.cs
);
378 dprintf("Data size: %d\n", mod
.vs
);
379 nofImps
= RNum(); dprintf("Nof imports: %d\n", nofImps
);
380 ReadName(mod
.name
); dprintf("Module name: %s\n", mod
.name
);
382 for (i
= 0; i
< nofImps
; i
++)
384 imp
= (ImpList
*)calloc(1, sizeof(ImpList
));
392 dprintf("Import %d: %s\n", i
, imp
->name
);
393 if ((imp
->name
[0] == '$') && (imp
->name
[1] == '$'))
394 strcpy(imp
->name
, "Kernel");
395 if (imp
->name
[0] == '$'){
399 printf("Could not load lib: %s\n", imp
->name
[1]);
404 dprintf("Pos: %d\n", ftell(f
));
413 int x
, fp
, opt
, link
, ofp
, imptab
, a
;
420 mod
.dad
= (int) calloc(1, mod
.ds
);
421 mod
.mad
= (int) calloc(1, mod
.ms
+ mod
.cs
+ mod
.vs
);
422 if ((mod
.dad
== 0) || (mod
.mad
== 0))
424 printf("BootLoader: Couldn't initalize heap\n");
425 free((void*)mod
.dad
);
426 free((void*)mod
.mad
);
429 dp
= (char*) mod
.dad
;
430 mp
= (char*) mod
.mad
;
431 fseek(f
, mod
.start
+ mod
.hs
, SEEK_SET
);
432 dprintf("ReadModule after fseek pos: %d\n", ftell(f
));
433 cnt
= fread(mp
, 1, mod
.ms
, f
);
434 dprintf("Read meta bulk (%d bytes. New pos: %d)\n", cnt
, ftell(f
));
435 cnt
= fread(dp
, 1, mod
.ds
, f
);
436 dprintf("Read desc bulk (%d bytes. New pos: %d)\n", cnt
, ftell(f
));
437 mp
= (char*)(mod
.mad
+ mod
.ms
);
438 cnt
= fread(mp
, 1, mod
.cs
, f
);
439 dprintf("Read code bulk (%d bytes. New pos: %d)\n", cnt
, ftell(f
));
443 dprintf("before fixup: pos = %d\n", ftell(f
));
445 if ((!newRecAdr
) || (!newArrAdr
)){
446 k
= ThisModule(kernel
);
448 /* obj = ThisDesc(k, newRecFP);*/
449 obj
= ThisObject(k
, "NewRec");
451 newRecAdr
= k
->procBase
+ obj
->offs
;
452 /* obj = ThisDesc(k, newArrFP);*/
453 obj
= ThisObject(k
, "NewArr");
455 newArrAdr
= k
->procBase
+ obj
->offs
;
456 dprintf("newRecFP: %X newArrFP: %X\n", newRecFP
, newArrFP
);
457 dprintf("newRecAdr: %X newArrAdr: %X\n", newRecAdr
, newArrAdr
);
459 dprintf("no kernel before %s.\n", mod
.name
);
466 Fixup(mod
.mad
+ mod
.ms
);
467 Fixup(mod
.mad
+ mod
.ms
+ mod
.cs
);
468 dprintf("after fixup: pos = %d\n", ftell(f
));
469 imp
= mod
.imp
; imptab
= (int)((Module
*)(mod
.dad
))->imports
;
472 if ((imp
->name
[0] == '$') && (imp
->name
[1] == '$'))
473 printf("should be Kerneln");
474 if (imp
->name
[0] == '$')
478 desc
= ThisModule(imp
->name
);
480 printf("invalid import list\n");
485 ReadName(name
); fp
= RNum(); opt
= 0;
488 obj
= ThisDesc(desc
, fp
);
490 obj
= ThisObject(desc
, name
);
491 if ((obj
!= NULL
) && (obj
->id
% 16 == x
)){
496 if (opt
% 2 == 1) ofp
= obj
->offs
;
497 if ((opt
> 1) && ((obj
->id
/ 16) % 16 != mExported
)){
498 printf("object not found (%s)\n", imp
->name
);
501 Fixup((int)obj
->ostruct
);
504 Fixup(desc
->varBase
+ obj
->offs
);
507 Fixup(desc
->procBase
+ obj
->offs
);
510 printf("illigal foot print (%s)\n", imp
->name
);
514 if (obj
== NULL
) printf("obj == NULL\n");
515 printf("descriptor not found (%s, x: %d, id: %d)\n", name
, x
, obj
->id
);
519 if ((x
== mVar
) || (x
== mProc
)){
522 a
= ThisDllObj(x
, fp
, im
, name
);
526 printf("ReadModule: Object not found: %s\n", name
);
534 printf("ReadModule: Object not found: %s\n", name
);
542 *(int*)imptab
= (int)desc
; imptab
+= 4;
546 mod
.start
= ftell(f
);
550 int main (int argc
, char *argv
[])
558 dprintf("initializing BlackBox for Linux...\n");
559 /*f = fopen(bbfile, "rb");*/
560 f
= fopen(argv
[0], "r");
563 if (ReadBootHeader())
566 while ((i
< nofMods
) && (ok
)){
573 printf("Incorrect module: %s\n", mod
.name
);
575 printf("Incorrect header: %s\n", mod
.name
);
580 k
= ThisModule(kernel
);
581 m
= ThisModule(mainmod
);
583 printf("no kernel\n");
587 printf("no main module");
590 /* assign the boot info to first variable in Kernel */
591 bootInfo
= calloc(1, sizeof(BootInfo
));
592 bootInfo
->modList
= modlist
;
593 bootInfo
->argc
= argc
;
594 bootInfo
->argv
= argv
;
595 *((int*)(k
->varBase
)) = (int)bootInfo
;
596 dprintf("before body\n");
597 body
= (BodyProc
)(m
->code
);
598 k
->opts
= k
->opts
| init
; /* include init in opts */
600 dprintf("after body\n");
606 printf("Invalid BlackBox executable, make sure that the constant exeSize is correctly set\n");
609 printf("Couldn't find file: %s\n", bbfile
);