/* G.F. 31.01.2017 Loader for statically linked oberon binaries. Compile command: gcc -m32 -s -O OberonLoader.c -ldl -o OberonLoader gcc -m64 -s -O OberonLoader.c -ldl -o OberonLoader The statically linked oberon binary 'oberon.bin' has to be appended to this loader by the following A2-command: UnixBinary.Build oberon.bin -> ~ */ #include #include #include #include #include #include #include #include #include #include #define Offset 16*1024 /* startpos of the appended oberon binary */ #define BlkSize 4*1024 typedef void (*OberonProc)(); typedef void *addr; typedef unsigned int uint; typedef struct { /* cf. Generic.Unix.*.Glue.Mod */ /* Oberon --> loader: */ char id[24]; /* must match coreID */ int codesize; int relocations; OberonProc entry; /* Glue.Init0 */ /* loader --> Oberon: */ addr *dlopenaddr; addr *dlcloseaddr; addr *dlsymaddr; int *argc; addr *argv; addr *env; addr *cout; } *Header; #if defined(__LP64__) || defined(_LP64) char *coreID = "Oberon64G.binary"; /* cf. Generic.Unix.AMD64.Glue.Mod */ #else char *coreID = "Oberon32G.binary"; /* cf. Generic.Unix.I386.Glue.Mod */ #endif addr buf; int fd; uint bufsize; void cout( char c ) { char buf[8]; buf[0] = c; write( 1, &buf, 1 ); } 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; iid, coreID) != 0) { fprintf( stderr, "wrong Oberon headerId: got '%s', expected '%s'\n", header->id, coreID ); exit( 2 ); } binsize = header->codesize; relocations = header->relocations; bufsize = BlkSize; while (bufsize < binsize) bufsize += BlkSize; r = lseek( fd, Offset, SEEK_SET ); free( buf ); r = posix_memalign( &buf, BlkSize, bufsize ); if (mprotect( buf, bufsize, PROT_READ|PROT_WRITE|PROT_EXEC) != 0) perror("mprotect"); n = read( fd, buf, binsize ); Relocate( relocations ); header = (Header)buf; *(header->dlopenaddr) = dlopen; *(header->dlcloseaddr) = dlclose; *(header->dlsymaddr) = dlsym; *(header->argc) = argc; *(header->argv) = argv; *(header->env) = env; *(header->cout) = cout; header->entry(); return (0); }