OberonLoader.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. G.F. 31.01.2017
  3. Loader for statically linked oberon binaries.
  4. Compile command:
  5. gcc -m32 OberonLoader.c -ldl -o OberonLoader
  6. The filename of the statically linked oberon binary is 'oberon.bin'.
  7. The oberon binary may be joined with the loader to create a Unix program:
  8. This is done in A2 by the following command:
  9. UnixBinary.Build oberon.bin -> <program name> ~
  10. */
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <fcntl.h>
  14. #include <sys/types.h>
  15. #include <sys/uio.h>
  16. #include <unistd.h>
  17. #include <sys/stat.h>
  18. #include <string.h>
  19. #include <dlfcn.h>
  20. #define Offset 10*1024 /* startpos of oberon.bin if it is appended to the loader binary */
  21. #define Bufsize 2*1024*1024
  22. typedef void (*OberonProc)();
  23. typedef void *addr;
  24. typedef unsigned int uint;
  25. typedef struct { /* cf. Generic.Unix.I386.Glue.Mod */
  26. /* Oberon --> loader: */
  27. char id[24]; /* must match coreID */
  28. int codesize;
  29. int relocations; /* if base = 0 */
  30. addr base; /* must be 0 or match the address of buf */
  31. OberonProc entry; /* Glue.Init0 */
  32. /* loader --> Oberon: */
  33. addr *dlopenaddr;
  34. addr *dlcloseaddr;
  35. addr *dlsymaddr;
  36. int *argc;
  37. addr *argv;
  38. addr *env;
  39. } *Header;
  40. char *coreID = "Oberon32G.binary";
  41. addr buf;
  42. int fd;
  43. uint ReadInteger( ) {
  44. union {
  45. char buf[4];
  46. uint i;
  47. } u;
  48. read( fd, &u.buf, 4 );
  49. return (u.i);
  50. }
  51. void Relocate( uint relocations ) {
  52. addr *a;
  53. uint i;
  54. for (i=0; i<relocations; i++) {
  55. a = buf + ReadInteger();
  56. *a = buf+(uint)(*a);
  57. }
  58. }
  59. int main( int argc, char *argv[], char *env[] ) {
  60. int r, n, binsize, relocations;
  61. size_t fsize;
  62. struct stat sb;
  63. Header header;
  64. char path[64];
  65. addr a;
  66. uint binpos;
  67. r = posix_memalign( &buf, 64*1024, Bufsize );
  68. a = realpath( argv[0], path );
  69. fd = open( path, O_RDONLY );
  70. r = fstat( fd, &sb );
  71. fsize = sb.st_size;
  72. if (fsize > Offset) {
  73. binpos = Offset;
  74. r = lseek( fd, binpos, SEEK_SET );
  75. } else {
  76. binpos = 0;
  77. fd = open( "oberon.bin", O_RDONLY );
  78. }
  79. n = read( fd, buf, 256 );
  80. header = (Header)buf;
  81. if (strcmp(header->id, coreID) != 0) {
  82. printf( "bad headerId: %s, expected: %s\n", header->id, coreID );
  83. exit( 2 );
  84. }
  85. if ((header->base != 0) & (header->base != buf)) {
  86. printf( "bad displacement: %x, expected: %x\n", header->base, buf );
  87. exit( 3 );
  88. }
  89. binsize = header->codesize;
  90. relocations = header->relocations;
  91. r = lseek( fd, binpos, SEEK_SET );
  92. n = read( fd, buf, binsize );
  93. Relocate( relocations );
  94. *(header->dlopenaddr) = dlopen;
  95. *(header->dlcloseaddr) = dlclose;
  96. *(header->dlsymaddr) = dlsym;
  97. *(header->argc) = argc;
  98. *(header->argv) = argv;
  99. *(header->env) = env;
  100. header->entry();
  101. return (0);
  102. }