Linux.Glue.Mod 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. (* Minimal ELF header for self contained linux Oberon programs *)
  2. (* Copyright (c) Felix Friedrich, ETH Zürich *)
  3. MODULE Glue;
  4. IMPORT SYSTEM, Trace;
  5. CONST
  6. base* = 08048000H;
  7. debug* = {};
  8. VAR
  9. last-: RECORD END; (* empty variable linked to end of kernel *)
  10. baseAdr*: ADDRESS;
  11. endAdr*: ADDRESS;
  12. dlsym- : PROCEDURE {C} ( handle: ADDRESS; name: ADDRESS): ADDRESS;
  13. dlopen- : PROCEDURE {C} ( pathname: ADDRESS; mode: LONGINT ): ADDRESS;
  14. dlclose- : PROCEDURE {C} ( handle: ADDRESS );
  15. exit- : PROCEDURE {C} (status: LONGINT);
  16. stackBottom- : ADDRESS; (* of main thread *)
  17. argc-: WORD;
  18. argv-: ADDRESS;
  19. environ-: ADDRESS;
  20. PROCEDURE {INITIAL, NOPAF} EntryPoint;
  21. CODE
  22. #IF I386 THEN
  23. ; ELF header
  24. DB 07FH, 'ELF', 1, 1, 1, 0
  25. DD 0, 0
  26. DW 02, 03
  27. DD 01
  28. DD entry + base; program entry point
  29. DD elfheadersize
  30. DD 0
  31. DD 0
  32. DW elfheadersize
  33. DW 20H
  34. DW 3 ; #program header table entries
  35. DW 0
  36. DW 0
  37. DW 0
  38. elfheadersize:
  39. ; program header
  40. DD 1
  41. DD 0
  42. DD base;
  43. DD base;
  44. DD @last - base; segment size (file)
  45. DD @last - base; segment size (memory)
  46. DD 07
  47. DD 1000H; alignment
  48. ; interpreter header
  49. DD 3
  50. DD interpretername; interpreter name offset
  51. DD interpretername + base; interpreter name
  52. DD interpretername + base; interpreter name
  53. DD interpretername_end - interpretername ; interpreter name length
  54. DD interpretername_end - interpretername ; interpreter name length
  55. DD 4H
  56. DD 1H
  57. ; dynamic header
  58. DD 02H
  59. DD dynamicsection
  60. DD dynamicsection + base
  61. DD dynamicsection + base
  62. DD dynamicsection_end - dynamicsection ; size of dynamic section
  63. DD dynamicsection_end - dynamicsection ; size of dynamic section
  64. DD 06H
  65. DD 04H
  66. dynamicsection:
  67. DD 05H, base + stringtable
  68. DD 06H, symboltablebegin + base
  69. DD 07H, dlsymrelocation + base
  70. DD 08H, dlsymrelocation_end-dlsymrelocation ; size (relocationtable)
  71. DD 09H, 0CH
  72. DD 0AH, stringtable_end - stringtable; size (stringtable)
  73. DD 0BH, 10H
  74. DD 01H, libname - stringtable; position of libname
  75. DD 0H, 0H ; sentinel
  76. dynamicsection_end:
  77. dlsymrelocation:
  78. DD @dlsym
  79. DB 01H
  80. DB 01H, 00H, 00H; index of the symbol
  81. DD 0H
  82. dlsymrelocation_end:
  83. stringtable:
  84. DB 0H ; sentinel
  85. libname:
  86. DB 'libdl.so.2', 0
  87. dlsymname:
  88. DB 'dlsym', 0
  89. stringtable_end:
  90. ALIGN 4
  91. symboltablebegin:
  92. DD 0;
  93. DD 0
  94. DD 0
  95. DB 0
  96. DB 0
  97. DW 0
  98. ; dlsym symbol
  99. DD dlsymname - stringtable; position of dlsymname
  100. DD 0
  101. DD 0
  102. DB 12H ; info: global + function
  103. DB 0
  104. DW 0
  105. interpretername:
  106. DB '/lib/ld-linux.so.2', 0
  107. interpretername_end:
  108. ALIGN 4
  109. entry:
  110. #ELSIF AMD64 THEN
  111. ; ELF header
  112. DB 07FH, 'ELF', 2, 1, 1, 0
  113. DD 0, 0
  114. DW 02, 62
  115. DD 01
  116. DQ entry + base; program entry point
  117. DQ elfheadersize
  118. DQ 0
  119. DD 0
  120. DW elfheadersize
  121. DW 38H
  122. DW 3 ; #program header table entries
  123. DW 0
  124. DW 0
  125. DW 0
  126. elfheadersize:
  127. ; program header
  128. DD 1
  129. DD 07
  130. DQ 0
  131. DQ base;
  132. DQ base;
  133. DQ @last - base; segment size (file)
  134. DQ @last - base; segment size (memory)
  135. DQ 1000H; alignment
  136. ; interpreter header
  137. DD 3
  138. DD 4H
  139. DQ interpretername; interpreter name offset
  140. DQ interpretername + base; interpreter name
  141. DQ interpretername + base; interpreter name
  142. DQ interpretername_end - interpretername ; interpreter name length
  143. DQ interpretername_end - interpretername ; interpreter name length
  144. DQ 1H
  145. ; dynamic header
  146. DD 02H
  147. DD 06H
  148. DQ dynamicsection
  149. DQ dynamicsection + base
  150. DQ dynamicsection + base
  151. DQ dynamicsection_end - dynamicsection ; size of dynamic section
  152. DQ dynamicsection_end - dynamicsection ; size of dynamic section
  153. DQ 08H
  154. dynamicsection:
  155. DQ 05H, base + stringtable
  156. DQ 06H, symboltablebegin + base
  157. DQ 07H, dlsymrelocation + base
  158. DQ 08H, dlsymrelocation_end-dlsymrelocation ; size (relocationtable)
  159. DQ 09H, 18H
  160. DQ 0AH, stringtable_end - stringtable; size (stringtable)
  161. DQ 0BH, 18H
  162. DQ 01H, libname - stringtable; position of libname
  163. DQ 0H, 0H ; sentinel
  164. dynamicsection_end:
  165. dlsymrelocation:
  166. DQ @dlsym
  167. DD 01H
  168. DD 01H ; index of the symbol
  169. DQ 0H
  170. dlsymrelocation_end:
  171. stringtable:
  172. DB 0H ; sentinel
  173. libname:
  174. DB 'libdl.so.2', 0
  175. dlsymname:
  176. DB 'dlsym', 0
  177. stringtable_end:
  178. ALIGN 8
  179. symboltablebegin:
  180. DD 0;
  181. DB 0
  182. DB 0
  183. DW 0
  184. DQ 0
  185. DQ 0
  186. ; dlsym symbol
  187. DD dlsymname - stringtable; position of dlsymname
  188. DB 12H ; info: global + function
  189. DB 0
  190. DW 0
  191. DQ 0
  192. DQ 0
  193. interpretername:
  194. DB '/lib64/ld-linux-x86-64.so.2', 0
  195. interpretername_end:
  196. ALIGN 8
  197. entry:
  198. #ELSE
  199. unimplemented
  200. #END
  201. END EntryPoint;
  202. (*
  203. PROCEDURE {FINAL} ExitPoint;
  204. BEGIN
  205. Trace.String("exiting"); Trace.Ln;
  206. exit(0);
  207. END ExitPoint;
  208. *)
  209. PROCEDURE putc*(file: ADDRESS; c: CHAR);
  210. CODE
  211. #IF I386 THEN
  212. MOV EAX, 4
  213. MOV EBX, [EBP + file]
  214. LEA ECX, [EBP + c]
  215. MOV EDX, 1
  216. INT 80H
  217. #ELSIF AMD64 THEN
  218. MOV EAX, 1
  219. MOV RDI, [RBP + file]
  220. LEA RSI, [RBP + c]
  221. MOV RDX, 1
  222. SYSCALL
  223. #ELSE
  224. unimplemented
  225. #END
  226. END putc;
  227. PROCEDURE Dlsym*(handle: ADDRESS; CONST name: ARRAY OF CHAR; adr: ADDRESS);
  228. VAR val: ADDRESS;
  229. BEGIN {UNCOOPERATIVE, UNCHECKED}
  230. val := dlsym(handle, ADDRESS OF name[0]);
  231. SYSTEM.PUT(adr, val);
  232. END Dlsym;
  233. PROCEDURE Char(c: CHAR);
  234. BEGIN {UNCOOPERATIVE, UNCHECKED}
  235. putc(1, c);
  236. END Char;
  237. PROCEDURE Init;
  238. VAR i: ADDRESS;
  239. BEGIN {UNCOOPERATIVE, UNCHECKED}
  240. baseAdr := ADDRESS OF EntryPoint;
  241. endAdr := ADDRESS OF last;
  242. Trace.Init;
  243. Trace.Char := Char;
  244. stackBottom := ADDRESSOF( i ) + 2*SIZEOF(ADDRESS);
  245. ASSERT(dlsym # NIL);
  246. Dlsym(0,"dlopen", ADDRESS OF dlopen);
  247. ASSERT(dlopen # NIL);
  248. Dlsym( 0, "dlclose", ADDRESS OF dlclose);
  249. ASSERT(dlclose # NIL);
  250. Dlsym(0,"exit", ADDRESS OF exit);
  251. ASSERT(exit # NIL);
  252. END Init;
  253. PROCEDURE {INITIAL,NOPAF} Init0;
  254. BEGIN {UNCOOPERATIVE, UNCHECKED}
  255. CODE
  256. #IF I386 THEN
  257. ; argc at esp
  258. ; argv at esp+4
  259. ; 0 at esp+4+argc*4
  260. ; env at esp+4+argc*4+4 = (2+argc)<<2 + esp
  261. MOV EAX, [ESP]
  262. MOV argc, EAX
  263. LEA EAX, [ESP+4]
  264. MOV argv, EAX
  265. MOV EAX, [ESP]
  266. ADD EAX, 2
  267. SHL EAX, 2
  268. ADD EAX, ESP
  269. MOV environ, EAX
  270. #ELSIF AMD64 THEN
  271. ; argc at rsp
  272. ; argv at rsp+8
  273. ; 0 at rsp+8+argc*8
  274. ; env at rsp+8+argc*8+8 = (2+argc)<<3 + rsp
  275. MOV RAX, [RSP]
  276. MOV argc, EAX
  277. LEA RAX, [RSP+8]
  278. MOV argv, RAX
  279. MOV RAX, [RSP]
  280. ADD RAX, 2
  281. SHL RAX, 3
  282. ADD RAX, RSP
  283. MOV environ, RAX
  284. #ELSE
  285. unimplemented
  286. #END
  287. END;
  288. Init;
  289. END Init0;
  290. END Glue.
  291. System.FreeDownTo FoxIntermediateBackend ~
  292. System.DoCommands
  293. Compiler.Compile -p=Unix32
  294. I386.Builtins.Mod Trace.Mod Linux.Glue.Mod Linux.I386.Unix.Mod Unix.I386.Machine.Mod Heaps.Mod Modules.Mod
  295. Unix.Objects.Mod
  296. Unix.Kernel.Mod KernelLog.Mod Plugins.Mod Streams.Mod
  297. Pipes.Mod Commands.Mod I386.Reals.Mod Reflection.Mod TrapWriters.Mod CRC.Mod SystemVersion.Mod
  298. Unix.StdIO.Mod Unix.Traps.Mod Locks.Mod Unix.Clock.Mod Disks.Mod Files.Mod Dates.Mod Strings.Mod
  299. UTF8Strings.Mod FileTrapWriter.Mod Caches.Mod DiskVolumes.Mod OldDiskVolumes.Mod RAMVolumes.Mod
  300. DiskFS.Mod OldDiskFS.Mod OberonFS.Mod FATVolumes.Mod FATFiles.Mod ISO9660Volumes.Mod
  301. ISO9660Files.Mod Unix.UnixFiles.Mod RelativeFileSystem.Mod BitSets.Mod StringPool.Mod DIagnostics.Mod
  302. ObjectFile.Mod GenericLinker.Mod Loader.Mod Unix.BootConsole.Mod
  303. ~
  304. Linker.Link --fileFormat=Raw --fileName=simple_elf --extension=.GofU --displacement=08048000H
  305. Builtins Trace Glue Unix Machine Heaps Modules Objects Kernel KernelLog
  306. Streams Commands StdIO TrapWriters Traps
  307. Files UnixFiles Clock Dates Reals Strings Diagnostics
  308. BitSets StringPool ObjectFile GenericLinker Reflection Loader
  309. BootConsole
  310. ~
  311. FSTools.CloseFiles simple_elf ~
  312. ~
  313. MODULE Test;
  314. IMPORT StdIO, Commands, Streams, Modules;
  315. PROCEDURE Execute(context: Commands.Context);
  316. VAR str, msg: ARRAY 256 OF CHAR; res: WORD;
  317. BEGIN
  318. IF ~context.arg.GetString(str) THEN RETURN END;
  319. IF ~context.arg.GetString(str) THEN
  320. context.out.String("no command"); context.out.Ln;
  321. RETURN
  322. END;
  323. Commands.Activate(str, context, {Commands.Wait}, res, msg);
  324. END Execute;
  325. BEGIN
  326. Execute(StdIO.env);
  327. Modules.Shutdown(1);
  328. END Test.