3 * C-startup and loader for BlackBox
4 * Implemented as the StdLoader.
17 /* the exact size (in bytes) of the executable part of the file. */
18 /* this constant needs to be updated everytime a change is made to this file */
42 /* set to printf to debug and donothing to avoid debugging */
43 #define dprintf donothing
45 typedef void (*BodyProc
)();
46 typedef char String
[256];
52 int base
[16]; /* should be ARRAY 16 OF TYPE */
53 int fields
; /* should be Directory* */
57 typedef struct Object
{
64 typedef struct Directory
{
69 typedef struct Module
{ /* has to be exact copy of Kernel.Module */
73 short compTime
[6], loadTime
[6];
75 int term
; /* actually a pointer to type Command */
77 int csize
, dsize
, rsize
;
79 int procBase
, varBase
; /* meta base addresses */
80 char* names
; /* names[0] = 0X */
82 struct Module
* imports
;
87 typedef struct ImpList
93 typedef struct ModSpec
97 int start
, hs
, ms
, ds
, cs
, vs
, mad
, dad
;
100 typedef struct BootInfo
107 const char bbfile
[] = "./bb.boot";
111 String kernel
, mainmod
;
115 int newRecAdr
, newArrAdr
;
116 int newRecFP
, newArrFP
;
120 int donothing(char* fmt
, ...)
126 dprintf("\n\n---- Mod info:\n");
127 dprintf(" hs, ms, ds, cs, vs = %d, %d, %d, %d, %d\n",
128 mod
.hs
, mod
.ms
, mod
.ds
, mod
.cs
, mod
.vs
);
129 dprintf(" mad, dad = %d, %d\n\n", mod
.mad
, mod
.dad
);
133 void RegisterModule()
136 m
= (Module
*)mod
.dad
;
140 if (modlist == NULL){
148 dprintf("Registred module %s\n", mod
.name
);
155 dprintf("Loaded Modules\n");
157 dprintf("mod name: %s\n", ml
->name
);
160 dprintf("end of list\n");
164 Module
* ThisModule(char* name
)
168 while ((ml
!= NULL
) && (strcmp(ml
->name
, name
) != 0)){
174 Object
* ThisObject(Module
* mod
, char* name
)
178 l
= 0; r
= mod
->export
->num
;
181 p
= (char*) &(mod
->names
[mod
->export
->obj
[m
].id
/ 256]);
182 if (strcmp(p
, name
) == 0)
183 return (Object
*)&(mod
->export
->obj
[m
]);
184 if (strcmp(p
, name
) < 0)
192 Object
* ThisDesc(Module
* mod
, int fprint
)
195 i
= 0; n
= mod
->export
->num
;
196 while ((i
< n
) && (mod
->export
->obj
[i
].id
/ 256 == 0))
198 if (mod
->export
->obj
[i
].offs
== fprint
)
199 return (Object
*)&(mod
->export
->obj
[i
]);
205 int LoadDll (char* name
)
209 dprintf("loading: %s\n", name
);
210 if ((handle
= dlopen(name
, RTLD_LAZY
+ RTLD_GLOBAL
)) == NULL
) {
211 printf("LoadDll: failed to load lib %s\n", name
);
212 printf(" - dlerror: %s\n", dlerror());
215 return handle
!= NULL
;
219 int ThisDllObj (int mode
, int fprint
, char* dll
, char* name
)
223 if ((mode
== mVar
) || (mode
== mProc
)){
224 if ((handle
= dlopen(dll
, RTLD_LAZY
+ RTLD_GLOBAL
)) == NULL
) {
225 printf("ThisDllObj: lib %s not found\n", dll
);
226 printf(" - dlerror: %s\n", dlerror());
229 ad
= (int)dlsym((void *) handle
, name
);
231 printf("ThisDllObj: symbol %s not found\n", name
); exit(-1);
242 b
= fgetc(f
); w
= b
% 256;
243 b
= fgetc(f
); w
= w
+ 0x100 * (b
% 256);
244 b
= fgetc(f
); w
= w
+ 0x10000 * (b
% 256);
245 b
= fgetc(f
); w
= w
+ 0x1000000 * b
;
257 y
= y
+ ((b
+ 128) << s
);
261 return (((b
+ 64) % 128 - 64) << s
) + y
;
264 void ReadName (char* str
)
271 str
[i
] = b
; i
++; b
= fgetc(f
);
278 int link
, offset
, linkadr
, n
, x
, t
;
280 dprintf("fixup: %X ", adr
);
285 dprintf("+%d: ", offset
);
291 linkadr
= mod
.mad
+ mod
.ms
+ link
;
298 linkadr
= mod
.mad
+ link
;
300 linkadr
= mod
.dad
+ link
- mod
.ms
;
302 dprintf("%X ", link
);
305 t = *(char*)(linkadr + 3);
307 n = n << 8; n = n >> 8;
311 n
= (x
+ 0x800000) % 0x1000000 - 0x800000;
314 case absolute
: x
= adr
+ offset
; break;
315 case relative
: x
= adr
+ offset
- linkadr
-4; break;
316 case copy
: x
= *(int*)(adr
+ offset
); break;
317 case table
: x
= adr
+ n
; n
= link
+ 4; break;
318 case tableend
: x
= adr
+ n
; n
= 0; break;
319 case deref
: x
= *(int*)(adr
+ 2); x
= x
+ offset
; break;
321 printf("fixup: halfword not implemented\n");
324 printf("fixup error(link=%d, offset=%d, linkadr=%d, t=%d, x=%d)\n",
325 link
, offset
, linkadr
, t
, x
);
340 fseek(f
, exeSize
, SEEK_SET
);
343 if ((tag
!= 0x3A4B5C6D) || (version
!= 0))
348 dprintf("Linked modules: %d\n", nofMods
);
350 dprintf("kernel: %s\n", kernel
);
352 dprintf("main: %s\n", mainmod
);
353 newRecFP
= Read4(); newRecAdr
= 0;
354 newArrFP
= Read4(); newArrAdr
= 0;
355 mod
.start
= ftell(f
);
359 void * MemAlloc (size_t len
)
363 res
= mmap(0, len
, PROT_READ
|PROT_WRITE
|PROT_EXEC
, MAP_PRIVATE
|MAP_ANON
, zerofd
, 0);
364 if (res
== MAP_FAILED
) {
374 int ofTag
, i
, nofImps
, processor
;
380 if (ofTag
!= 0x6F4F4346)
382 printf("wrong object file version\n");
391 dprintf("File tag: %d ", ofTag
); dprintf("Processor: %d\n", processor
);
392 dprintf("Header size: %d ", mod
.hs
);
393 dprintf("Meta size: %d ", mod
.ms
);
394 dprintf("Desc size: %d ", mod
.ds
);
395 dprintf("Code size: %d ", mod
.cs
);
396 dprintf("Data size: %d\n", mod
.vs
);
397 nofImps
= RNum(); dprintf("Nof imports: %d\n", nofImps
);
398 ReadName(mod
.name
); dprintf("Module name: %s\n", mod
.name
);
400 for (i
= 0; i
< nofImps
; i
++)
402 imp
= (ImpList
*)MemAlloc(sizeof(ImpList
));
410 dprintf("Import %d: %s\n", i
, imp
->name
);
411 if ((imp
->name
[0] == '$') && (imp
->name
[1] == '$'))
412 strcpy(imp
->name
, "Kernel");
413 if (imp
->name
[0] == '$'){
417 printf("Could not load lib: %s\n", (char *)(&(imp
->name
[1])));
422 dprintf("Pos: %d\n", ftell(f
));
431 int x
, fp
, opt
, link
, ofp
, imptab
, a
;
438 mod
.dad
= (int) MemAlloc(mod
.ds
);
439 mod
.mad
= (int) MemAlloc(mod
.ms
+ mod
.cs
+ mod
.vs
);
440 if ((mod
.dad
== 0) || (mod
.mad
== 0))
442 printf("BootLoader: Couldn't initalize heap\n");
443 free((void*)mod
.dad
);
444 free((void*)mod
.mad
);
447 dp
= (char*) mod
.dad
;
448 mp
= (char*) mod
.mad
;
449 fseek(f
, mod
.start
+ mod
.hs
, SEEK_SET
);
450 dprintf("ReadModule after fseek pos: %d\n", ftell(f
));
451 cnt
= fread(mp
, 1, mod
.ms
, f
);
452 dprintf("Read meta bulk (%d bytes. New pos: %d)\n", cnt
, ftell(f
));
453 cnt
= fread(dp
, 1, mod
.ds
, f
);
454 dprintf("Read desc bulk (%d bytes. New pos: %d)\n", cnt
, ftell(f
));
455 mp
= (char*)(mod
.mad
+ mod
.ms
);
456 cnt
= fread(mp
, 1, mod
.cs
, f
);
457 dprintf("Read code bulk (%d bytes. New pos: %d)\n", cnt
, ftell(f
));
461 dprintf("before fixup: pos = %d\n", ftell(f
));
463 if ((!newRecAdr
) || (!newArrAdr
)){
464 k
= ThisModule(kernel
);
466 /* obj = ThisDesc(k, newRecFP);*/
467 obj
= ThisObject(k
, "NewRec");
469 newRecAdr
= k
->procBase
+ obj
->offs
;
470 /* obj = ThisDesc(k, newArrFP);*/
471 obj
= ThisObject(k
, "NewArr");
473 newArrAdr
= k
->procBase
+ obj
->offs
;
474 dprintf("newRecFP: %X newArrFP: %X\n", newRecFP
, newArrFP
);
475 dprintf("newRecAdr: %X newArrAdr: %X\n", newRecAdr
, newArrAdr
);
477 dprintf("no kernel before %s.\n", mod
.name
);
484 Fixup(mod
.mad
+ mod
.ms
);
485 Fixup(mod
.mad
+ mod
.ms
+ mod
.cs
);
486 dprintf("after fixup: pos = %d\n", ftell(f
));
487 imp
= mod
.imp
; imptab
= (int)((Module
*)(mod
.dad
))->imports
;
490 if ((imp
->name
[0] == '$') && (imp
->name
[1] == '$'))
491 printf("should be Kerneln");
492 if (imp
->name
[0] == '$')
496 desc
= ThisModule(imp
->name
);
498 printf("invalid import list\n");
503 ReadName(name
); fp
= RNum(); opt
= 0;
506 obj
= ThisDesc(desc
, fp
);
508 obj
= ThisObject(desc
, name
);
509 if ((obj
!= NULL
) && (obj
->id
% 16 == x
)){
514 if (opt
% 2 == 1) ofp
= obj
->offs
;
515 if ((opt
> 1) && ((obj
->id
/ 16) % 16 != mExported
)){
516 printf("object not found (%s)\n", imp
->name
);
519 Fixup((int)obj
->ostruct
);
522 Fixup(desc
->varBase
+ obj
->offs
);
525 Fixup(desc
->procBase
+ obj
->offs
);
528 printf("illigal foot print (%s)\n", imp
->name
);
532 if (obj
== NULL
) printf("obj == NULL\n");
533 printf("descriptor not found (%s, x: %d, id: %d)\n", name
, x
, obj
->id
);
537 if ((x
== mVar
) || (x
== mProc
)){
540 a
= ThisDllObj(x
, fp
, im
, name
);
544 printf("ReadModule: Object not found: %s\n", name
);
552 printf("ReadModule: Object not found: %s\n", name
);
560 *(int*)imptab
= (int)desc
; imptab
+= 4;
564 mod
.start
= ftell(f
);
568 int main (int argc
, char *argv
[])
575 zerofd
= open("/dev/zero", O_RDWR
);
577 printf("open /dev/zero failed: %s\n", strerror(errno
));
582 dprintf("initializing BlackBox for Linux...\n");
583 /*f = fopen(bbfile, "rb");*/
584 f
= fopen(argv
[0], "r");
587 if (ReadBootHeader())
590 while ((i
< nofMods
) && (ok
)){
597 printf("Incorrect module: %s\n", mod
.name
);
599 printf("Incorrect header: %s\n", mod
.name
);
604 k
= ThisModule(kernel
);
605 m
= ThisModule(mainmod
);
607 printf("no kernel\n");
611 printf("no main module");
614 /* assign the boot info to first variable in Kernel */
615 bootInfo
= MemAlloc(sizeof(BootInfo
));
616 bootInfo
->modList
= modlist
;
617 bootInfo
->argc
= argc
;
618 bootInfo
->argv
= argv
;
619 *((int*)(k
->varBase
)) = (int)bootInfo
;
620 dprintf("before body\n");
621 body
= (BodyProc
)(m
->code
);
622 k
->opts
= k
->opts
| init
; /* include init in opts */
624 dprintf("after body\n");
630 printf("Invalid BlackBox executable, make sure that the constant exeSize is correctly set\n");
633 printf("Couldn't find file: %s\n", bbfile
);