50dab7321053814bd9b0aada642cf4cec58c964c
3 * C-startup and loader for BlackBox
4 * Implemented as the StdLoader.
16 /* the exact size (in bytes) of the executable part of the file. */
17 /* this constant needs to be updated everytime a change is made to this file */
43 /* set to printf to debug and donothing to avoid debugging */
44 #define dprintf donothing
46 typedef void (*BodyProc
)();
47 typedef char String
[256];
53 int base
[16]; /* should be ARRAY 16 OF TYPE */
54 int fields
; /* should be Directory* */
58 typedef struct Object
{
65 typedef struct Directory
{
70 typedef struct Module
{ /* has to be exact copy of Kernel.Module */
74 short compTime
[6], loadTime
[6];
76 int term
; /* actually a pointer to type Command */
78 int csize
, dsize
, rsize
;
80 int procBase
, varBase
; /* meta base addresses */
81 char* names
; /* names[0] = 0X */
83 struct Module
* imports
;
88 typedef struct ImpList
94 typedef struct ModSpec
98 int start
, hs
, ms
, ds
, cs
, vs
, mad
, dad
;
101 typedef struct BootInfo
108 const char bbfile
[] = "./bb.boot";
112 String kernel
, mainmod
;
116 int newRecAdr
, newArrAdr
;
117 int newRecFP
, newArrFP
;
119 int donothing(char* fmt
, ...)
125 dprintf("\n\n---- Mod info:\n");
126 dprintf(" hs, ms, ds, cs, vs = %d, %d, %d, %d, %d\n",
127 mod
.hs
, mod
.ms
, mod
.ds
, mod
.cs
, mod
.vs
);
128 dprintf(" mad, dad = %d, %d\n\n", mod
.mad
, mod
.dad
);
132 void RegisterModule()
135 m
= (Module
*)mod
.dad
;
139 if (modlist == NULL){
147 dprintf("Registred module %s\n", mod
.name
);
154 dprintf("Loaded Modules\n");
156 dprintf("mod name: %s\n", ml
->name
);
159 dprintf("end of list\n");
163 Module
* ThisModule(char* name
)
167 while ((ml
!= NULL
) && (strcmp(ml
->name
, name
) != 0)){
173 Object
* ThisObject(Module
* mod
, char* name
)
177 l
= 0; r
= mod
->export
->num
;
180 p
= (char*) &(mod
->names
[mod
->export
->obj
[m
].id
/ 256]);
181 if (strcmp(p
, name
) == 0)
182 return (Object
*)&(mod
->export
->obj
[m
]);
183 if (strcmp(p
, name
) < 0)
191 Object
* ThisDesc(Module
* mod
, int fprint
)
194 i
= 0; n
= mod
->export
->num
;
195 while ((i
< n
) && (mod
->export
->obj
[i
].id
/ 256 == 0))
197 if (mod
->export
->obj
[i
].offs
== fprint
)
198 return (Object
*)&(mod
->export
->obj
[i
]);
204 int LoadDll (char* name
)
208 dprintf("loading: %s\n", name
);
209 if ((handle
= dlopen(name
, RTLD_LAZY
+ RTLD_GLOBAL
)) == NULL
) {
210 printf("LoadDll: failed to load lib %s\n", name
);
211 printf(" - dlerror: %s\n", dlerror());
214 return handle
!= NULL
;
218 int ThisDllObj (int mode
, int fprint
, char* dll
, char* name
)
222 if ((mode
== mVar
) || (mode
== mProc
)){
223 if ((handle
= dlopen(dll
, RTLD_LAZY
+ RTLD_GLOBAL
)) == NULL
) {
224 printf("ThisDllObj: lib %s not found\n", dll
);
225 printf(" - dlerror: %s\n", dlerror());
228 ad
= (int)dlsym((void *) handle
, name
);
230 printf("ThisDllObj: symbol %s not found\n", name
); exit(-1);
241 b
= fgetc(f
); w
= b
% 256;
242 b
= fgetc(f
); w
= w
+ 0x100 * (b
% 256);
243 b
= fgetc(f
); w
= w
+ 0x10000 * (b
% 256);
244 b
= fgetc(f
); w
= w
+ 0x1000000 * b
;
256 y
= y
+ ((b
+ 128) << s
);
260 return (((b
+ 64) % 128 - 64) << s
) + y
;
263 void ReadName (char* str
)
270 str
[i
] = b
; i
++; b
= fgetc(f
);
277 int link
, offset
, linkadr
, n
, x
, t
;
279 dprintf("fixup: %X ", adr
);
284 dprintf("+%d: ", offset
);
290 linkadr
= mod
.mad
+ mod
.ms
+ link
;
297 linkadr
= mod
.mad
+ link
;
299 linkadr
= mod
.dad
+ link
- mod
.ms
;
301 dprintf("%X ", link
);
304 t = *(char*)(linkadr + 3);
306 n = n << 8; n = n >> 8;
310 n
= (x
+ 0x800000) % 0x1000000 - 0x800000;
313 case absolute
: x
= adr
+ offset
; break;
314 case relative
: x
= adr
+ offset
- linkadr
-4; break;
315 case copy
: x
= *(int*)(adr
+ offset
); break;
316 case table
: x
= adr
+ n
; n
= link
+ 4; break;
317 case tableend
: x
= adr
+ n
; n
= 0; break;
318 case deref
: x
= *(int*)(adr
+ 2); x
= x
+ offset
; break;
320 printf("fixup: halfword not implemented\n");
323 printf("fixup error(link=%d, offset=%d, linkadr=%d, t=%d, x=%d)\n",
324 link
, offset
, linkadr
, t
, x
);
339 fseek(f
, exeSize
, SEEK_SET
);
342 if ((tag
!= 0x3A4B5C6D) || (version
!= 0))
347 dprintf("Linked modules: %d\n", nofMods
);
349 dprintf("kernel: %s\n", kernel
);
351 dprintf("main: %s\n", mainmod
);
352 newRecFP
= Read4(); newRecAdr
= 0;
353 newArrFP
= Read4(); newArrAdr
= 0;
354 mod
.start
= ftell(f
);
360 int ofTag
, i
, nofImps
, processor
;
366 if (ofTag
!= 0x6F4F4346)
368 printf("wrong object file version\n");
377 dprintf("File tag: %d ", ofTag
); dprintf("Processor: %d\n", processor
);
378 dprintf("Header size: %d ", mod
.hs
);
379 dprintf("Meta size: %d ", mod
.ms
);
380 dprintf("Desc size: %d ", mod
.ds
);
381 dprintf("Code size: %d ", mod
.cs
);
382 dprintf("Data size: %d\n", mod
.vs
);
383 nofImps
= RNum(); dprintf("Nof imports: %d\n", nofImps
);
384 ReadName(mod
.name
); dprintf("Module name: %s\n", mod
.name
);
386 for (i
= 0; i
< nofImps
; i
++)
388 imp
= (ImpList
*)calloc(1, sizeof(ImpList
));
396 dprintf("Import %d: %s\n", i
, imp
->name
);
397 if ((imp
->name
[0] == '$') && (imp
->name
[1] == '$'))
398 strcpy(imp
->name
, "Kernel");
399 if (imp
->name
[0] == '$'){
403 printf("Could not load lib: %s\n", (char *)(&(imp
->name
[1])));
408 dprintf("Pos: %d\n", ftell(f
));
417 int x
, fp
, opt
, link
, ofp
, imptab
, a
;
424 mod
.dad
= (int) calloc(1, mod
.ds
);
425 mod
.mad
= (int) calloc(1, mod
.ms
+ mod
.cs
+ mod
.vs
);
426 if ((mod
.dad
== 0) || (mod
.mad
== 0))
428 printf("BootLoader: Couldn't initalize heap\n");
429 free((void*)mod
.dad
);
430 free((void*)mod
.mad
);
433 dp
= (char*) mod
.dad
;
434 mp
= (char*) mod
.mad
;
435 fseek(f
, mod
.start
+ mod
.hs
, SEEK_SET
);
436 dprintf("ReadModule after fseek pos: %d\n", ftell(f
));
437 cnt
= fread(mp
, 1, mod
.ms
, f
);
438 dprintf("Read meta bulk (%d bytes. New pos: %d)\n", cnt
, ftell(f
));
439 cnt
= fread(dp
, 1, mod
.ds
, f
);
440 dprintf("Read desc bulk (%d bytes. New pos: %d)\n", cnt
, ftell(f
));
441 mp
= (char*)(mod
.mad
+ mod
.ms
);
442 cnt
= fread(mp
, 1, mod
.cs
, f
);
443 dprintf("Read code bulk (%d bytes. New pos: %d)\n", cnt
, ftell(f
));
447 dprintf("before fixup: pos = %d\n", ftell(f
));
449 if ((!newRecAdr
) || (!newArrAdr
)){
450 k
= ThisModule(kernel
);
452 /* obj = ThisDesc(k, newRecFP);*/
453 obj
= ThisObject(k
, "NewRec");
455 newRecAdr
= k
->procBase
+ obj
->offs
;
456 /* obj = ThisDesc(k, newArrFP);*/
457 obj
= ThisObject(k
, "NewArr");
459 newArrAdr
= k
->procBase
+ obj
->offs
;
460 dprintf("newRecFP: %X newArrFP: %X\n", newRecFP
, newArrFP
);
461 dprintf("newRecAdr: %X newArrAdr: %X\n", newRecAdr
, newArrAdr
);
463 dprintf("no kernel before %s.\n", mod
.name
);
470 Fixup(mod
.mad
+ mod
.ms
);
471 Fixup(mod
.mad
+ mod
.ms
+ mod
.cs
);
472 dprintf("after fixup: pos = %d\n", ftell(f
));
473 imp
= mod
.imp
; imptab
= (int)((Module
*)(mod
.dad
))->imports
;
476 if ((imp
->name
[0] == '$') && (imp
->name
[1] == '$'))
477 printf("should be Kerneln");
478 if (imp
->name
[0] == '$')
482 desc
= ThisModule(imp
->name
);
484 printf("invalid import list\n");
489 ReadName(name
); fp
= RNum(); opt
= 0;
492 obj
= ThisDesc(desc
, fp
);
494 obj
= ThisObject(desc
, name
);
495 if ((obj
!= NULL
) && (obj
->id
% 16 == x
)){
500 if (opt
% 2 == 1) ofp
= obj
->offs
;
501 if ((opt
> 1) && ((obj
->id
/ 16) % 16 != mExported
)){
502 printf("object not found (%s)\n", imp
->name
);
505 Fixup((int)obj
->ostruct
);
508 Fixup(desc
->varBase
+ obj
->offs
);
511 Fixup(desc
->procBase
+ obj
->offs
);
514 printf("illigal foot print (%s)\n", imp
->name
);
518 if (obj
== NULL
) printf("obj == NULL\n");
519 printf("descriptor not found (%s, x: %d, id: %d)\n", name
, x
, obj
->id
);
523 if ((x
== mVar
) || (x
== mProc
)){
526 a
= ThisDllObj(x
, fp
, im
, name
);
530 printf("ReadModule: Object not found: %s\n", name
);
538 printf("ReadModule: Object not found: %s\n", name
);
546 *(int*)imptab
= (int)desc
; imptab
+= 4;
550 mod
.start
= ftell(f
);
554 int MOD (int x
, int y
)
561 res
= x
- y
* ((x
+ 1) / y
- 1);
566 int main (int argc
, char *argv
[])
574 dprintf("initializing BlackBox for Linux...\n");
575 /*f = fopen(bbfile, "rb");*/
576 f
= fopen(argv
[0], "r");
579 if (ReadBootHeader())
582 while ((i
< nofMods
) && (ok
)){
589 printf("Incorrect module: %s\n", mod
.name
);
591 printf("Incorrect header: %s\n", mod
.name
);
596 k
= ThisModule(kernel
);
597 m
= ThisModule(mainmod
);
599 printf("no kernel\n");
603 printf("no main module");
606 /* assign the boot info to first variable in Kernel */
607 bootInfo
= calloc(1, sizeof(BootInfo
));
608 bootInfo
->modList
= modlist
;
609 bootInfo
->argc
= argc
;
610 bootInfo
->argv
= argv
;
611 *((int*)(k
->varBase
)) = (int)bootInfo
;
612 dprintf("before body\n");
613 body
= (BodyProc
)(m
->code
);
614 k
->opts
= k
->opts
| init
; /* include init in opts */
616 (void *)(((m
->code
) / pageSize
) * pageSize
),
617 (((m
->csize
) + MOD(m
->code
, pageSize
) - 1) / pageSize
) * pageSize
+ pageSize
,
618 PROT_READ
|PROT_WRITE
|PROT_EXEC
);
620 printf("mprotect failed!\n");
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
);