/* G.F. 31.01.2017 Loader for statically linked oberon binaries. Compile command: gcc -m32 OberonLoader.c -ldl -o OberonLoader The filename of the statically linked oberon binary is 'oberon.bin'. The oberon binary may be joined with the loader to create a Unix program: This is done in A2 by the following command: UnixBinary.Build oberon.bin -> ~ */ #include #include #include #include #include #include #include #include #include #define Offset 10*1024 /* startpos of oberon.bin if it is appended to the loader binary */ #define Bufsize 2*1024*1024 typedef void (*OberonProc)(); typedef void *addr; typedef unsigned int uint; typedef struct { /* cf. Generic.Unix.I386.Glue.Mod */ /* Oberon --> loader: */ char id[24]; /* must match coreID */ int codesize; int relocations; /* if base = 0 */ addr base; /* must be 0 or match the address of buf */ OberonProc entry; /* Glue.Init0 */ /* loader --> Oberon: */ addr *dlopenaddr; addr *dlcloseaddr; addr *dlsymaddr; int *argc; addr *argv; addr *env; } *Header; char *coreID = "Oberon32G.binary"; addr buf; int fd; uint ReadInteger( ) { union { char buf[4]; uint i; } u; read( fd, &u.buf, 4 ); return (u.i); } void Relocate( uint relocations ) { addr *a; uint i; for (i=0; i Offset) { binpos = Offset; r = lseek( fd, binpos, SEEK_SET ); } else { binpos = 0; fd = open( "oberon.bin", O_RDONLY ); } n = read( fd, buf, 256 ); header = (Header)buf; if (strcmp(header->id, coreID) != 0) { printf( "bad headerId: %s, expected: %s\n", header->id, coreID ); exit( 2 ); } if ((header->base != 0) & (header->base != buf)) { printf( "bad displacement: %x, expected: %x\n", header->base, buf ); exit( 3 ); } binsize = header->codesize; relocations = header->relocations; r = lseek( fd, binpos, SEEK_SET ); n = read( fd, buf, binsize ); Relocate( relocations ); *(header->dlopenaddr) = dlopen; *(header->dlcloseaddr) = dlclose; *(header->dlsymaddr) = dlsym; *(header->argc) = argc; *(header->argv) = argv; *(header->env) = env; header->entry(); return (0); }