Unix.BootLinker.Mod 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. (* ETH Oberon, Copyright 2000 ETH Zuerich Institut fuer Computersysteme, ETH Zentrum, CH-8092 Zuerich.
  2. Refer to the "General ETH Oberon System Source License" contract available at: http://www.oberon.ethz.ch/ *)
  3. MODULE BootLinker; (** AUTHOR "G.F." ; PURPOSE "UnixAos bootlinker"; *)
  4. (* based on Oberon for Windows bootlinker (MH) and MIPS bootlinker (RC) *)
  5. IMPORT S := SYSTEM, Heaps := BootLinkerHeaps, Modules := BootLinkerModules, Loader := BootLinkerLoader,
  6. Commands, Streams, Files, Strings;
  7. VAR
  8. out: Streams.Writer;
  9. error: Streams.Writer;
  10. PROCEDURE OutBootfile( CONST fileName: ARRAY OF CHAR );
  11. CONST
  12. AddrSize = SIZEOF( ADDRESS );
  13. VAR
  14. f: Files.File; w: Files.Writer; startOffset, i: LONGINT; top, adr: ADDRESS;
  15. BEGIN
  16. startOffset := Heaps.BlockSize - AddrSize;
  17. top := Heaps.beginFree;
  18. f := Files.New( fileName ); Files.OpenWriter( w, f, 0 );
  19. (* output heap *)
  20. w.RawLInt( LONGINT(AddrSize*8) );
  21. w.RawHInt( HUGEINT(Heaps.heapAdr) );
  22. w.RawLInt( LONGINT( Heaps.BootHeapSize) );
  23. adr := Heaps.heapAdr + startOffset;
  24. w.RawLInt( LONGINT(startOffset) );
  25. w.RawLInt( LONGINT(top - adr) );
  26. WHILE adr < top DO S.GET( adr, i ); w.RawLInt( i ); INC( adr, 4 ) END;
  27. w.RawLInt( LONGINT(Loader.entrypoint - Heaps.heapAdr) );
  28. w.RawLInt( LONGINT(Loader.dlsymAdr - Heaps.heapAdr) );
  29. (* output relocate information *)
  30. w.RawNum( Heaps.numRelocations ); i := 0;
  31. WHILE i < Heaps.numRelocations DO
  32. w.RawNum( LONGINT( Heaps.relocAddr[i] - Heaps.heapAdr ) ); INC( i )
  33. END;
  34. w.Update; Files.Register( f );
  35. out.String( "heap size (used heap space): " );
  36. out.Int( LONGINT(Heaps.BootHeapSize DIV 1024), 0 ); out.String( " KB (" );
  37. out.Int( LONGINT((Heaps.beginFree - Heaps.heapAdr) DIV 1024), 0 );
  38. out.String( " KB), relocations: " ); out.Int( Heaps.numRelocations, 0 );
  39. out.Ln
  40. END OutBootfile;
  41. PROCEDURE Link*( context: Commands.Context );
  42. CONST
  43. Ok = 0;
  44. VAR
  45. fileName, moduleName, fullPath: Modules.Name;
  46. token: ARRAY 8 OF CHAR;
  47. m: Modules.Module;
  48. res: LONGINT; msg: ARRAY 128 OF CHAR;
  49. BEGIN
  50. out := context.out; error := context.error;
  51. IF ~context.arg.GetString( fileName ) OR
  52. ~context.arg.GetString( token ) OR (token # ":=") THEN
  53. error.String( "wrong parameter(s), terminating" ); error.Ln; error.Update;
  54. RETURN
  55. END;
  56. fullPath := Loader.BuildDirectory; Strings.Append( fullPath, "/" ); Strings.Append( fullPath, fileName );
  57. out.String( "UnixAos BootLinker creating " ); out.String( fullPath ); out.Ln;
  58. Heaps.Initialize( context.error );
  59. Modules.Initialize( context.error );
  60. Loader.Initialize( context.error );
  61. res := Ok;
  62. IF context.arg.GetString( moduleName ) THEN
  63. REPEAT
  64. out.String( " " ); out.String( moduleName ); out.Ln;
  65. m := Loader.Load( moduleName, res, msg );
  66. IF m = NIL THEN
  67. error.String( "loading module failed: " ); error.String( msg ); error.Ln
  68. END;
  69. UNTIL ~context.arg.GetString( moduleName ) OR (m = NIL);
  70. IF res = Ok THEN
  71. Modules.AssignAddress( "Modules", "root", S.VAL( ADDRESS, Modules.root ) );
  72. Modules.RelocateProcOffsets;
  73. Modules.AssignAddress( "Modules", "procOffsets", S.VAL( ADDRESS, Modules.procOffsets ) );
  74. Modules.AssignValue( "Modules", "numProcs", Modules.numProcs );
  75. Modules.RelocatePtrOffsets;
  76. Modules.AssignAddress( "Modules", "ptrOffsets", S.VAL( ADDRESS, Modules.ptrOffsets ) );
  77. Modules.AssignValue( "Modules", "numPtrs", Modules.numPtrs );
  78. OutBootfile( fullPath )
  79. END;
  80. out.Ln
  81. ELSE
  82. error.String( "parameter error, module names missing, terminating" ); error.Ln
  83. END;
  84. out.Update; error.Update
  85. END Link;
  86. END BootLinker.
  87. Compiler.Compile
  88. Unix.BootLinkerHeaps.Mod Unix.BootLinkerModules.Mod Unix.BootLinkerLoader.Mod Unix.BootLinker.Mod ~
  89. SystemTools.Free BootLinker BootLinkerLoader BootLinkerModules BootLinkerHeaps ~
  90. BootLinker.Link bootFileName := modName0 modName1 ... ~
  91. All module names must be listed and topologically sorted.
  92. Boot File Format:
  93. architecture (* LONGINT, 32 or 64 *)
  94. heapAddr (* HUGEINT *)
  95. heapSize (* LONGINT *)
  96. startOffset (* LONGINT *)
  97. usedHeap (* LONGINT *)
  98. {heapValue} (* usedHeap DIV 4 times LONGINT *)
  99. entryOffset (* LONGINT, Aos entry point *)
  100. dlsymOffset (* LONGINT, location which receives the address of (Unix)'dlsym' *)
  101. nofPtr (* NUMBER *)
  102. {offset} (* nofPtr times relocation offset (NUMBER) *)
  103. All numbers in the relocate information part are in compact format and relative to
  104. heapAdr.