123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- (* Minimal ELF header for self contained linux Oberon programs *)
- (* Copyright (c) Felix Friedrich, ETH Zürich *)
- MODULE Glue;
- IMPORT SYSTEM, Trace;
- CONST
- base* = 08048000H;
- debug* = {};
- VAR
- last-: RECORD END; (* empty variable linked to end of kernel *)
-
- baseAdr*: ADDRESS;
- endAdr*: ADDRESS;
-
- dlsym- : PROCEDURE {C} ( handle: ADDRESS; name: ADDRESS): ADDRESS;
- dlopen- : PROCEDURE {C} ( pathname: ADDRESS; mode: LONGINT ): ADDRESS;
- dlclose- : PROCEDURE {C} ( handle: ADDRESS );
- exit- : PROCEDURE {C} (status: LONGINT);
- stackBottom- : ADDRESS; (* of main thread *)
- argc-: WORD;
- argv-: ADDRESS;
- environ-: ADDRESS;
- PROCEDURE {INITIAL, NOPAF} EntryPoint;
- CODE
- ; ELF header
- DB 07FH, 'ELF', 2, 1, 1, 0
- DD 0, 0
- DW 02, 62
- DD 01
- DQ entry + base; program entry point
- DQ elfheadersize
- DQ 0
- DD 0
- DW elfheadersize
- DW 38H
- DW 3 ; #program header table entries
- DW 0
- DW 0
- DW 0
- elfheadersize:
- ; program header
- DD 1
- DD 07
- DQ 0
- DQ base;
- DQ base;
- DQ @last - base; segment size (file)
- DQ @last - base; segment size (memory)
- DQ 1000H; alignment
-
- ; interpreter header
- DD 3
- DD 4H
- DQ interpretername; interpreter name offset
- DQ interpretername + base; interpreter name
- DQ interpretername + base; interpreter name
- DQ interpretername_end - interpretername ; interpreter name length
- DQ interpretername_end - interpretername ; interpreter name length
- DQ 1H
- ; dynamic header
- DD 02H
- DD 06H
- DQ dynamicsection
- DQ dynamicsection + base
- DQ dynamicsection + base
- DQ dynamicsection_end - dynamicsection ; size of dynamic section
- DQ dynamicsection_end - dynamicsection ; size of dynamic section
- DQ 08H
- dynamicsection:
- DQ 05H, base + stringtable
- DQ 06H, symboltablebegin + base
- DQ 07H, dlsymrelocation + base
- DQ 08H, dlsymrelocation_end-dlsymrelocation ; size (relocationtable)
- DQ 09H, 18H
- DQ 0AH, stringtable_end - stringtable; size (stringtable)
- DQ 0BH, 18H
-
- DQ 01H, libname - stringtable; position of libname
- DQ 0H, 0H ; sentinel
- dynamicsection_end:
-
- dlsymrelocation:
- DQ @dlsym
- DD 01H
- DD 01H ; index of the symbol
- DQ 0H
- dlsymrelocation_end:
- stringtable:
- DB 0H ; sentinel
- libname:
- DB 'libdl.so.2', 0
-
- dlsymname:
- DB 'dlsym', 0
-
-
- stringtable_end:
-
- ALIGN 8
- symboltablebegin:
- DD 0;
- DB 0
- DB 0
- DW 0
- DQ 0
- DQ 0
-
- ; dlsym symbol
- DD dlsymname - stringtable; position of dlsymname
- DB 12H ; info: global + function
- DB 0
- DW 0
- DQ 0
- DQ 0
- interpretername:
- DB '/lib64/ld-linux-x86-64.so.2', 0
- interpretername_end:
- ALIGN 8
- entry:
- END EntryPoint;
- (*
- PROCEDURE {FINAL} ExitPoint;
- BEGIN
- Trace.String("exiting"); Trace.Ln;
- exit(0);
- END ExitPoint;
- *)
- PROCEDURE {NOPAF} putc*(file: ADDRESS; c: CHAR);
- CODE
- MOV EAX, 1
- MOV RDI, [RSP + 16]
- LEA RSI, [RSP + 8]
- MOV RDX, 1
- SYSCALL
- RET
- END putc;
- PROCEDURE Dlsym*(handle: ADDRESS; CONST name: ARRAY OF CHAR; adr: ADDRESS);
- VAR val: ADDRESS;
- BEGIN
- val := dlsym(handle, ADDRESS OF name[0]);
- SYSTEM.PUT(adr, val);
- END Dlsym;
- PROCEDURE Char(c: CHAR);
- BEGIN
- putc(1, c);
- END Char;
-
- PROCEDURE Init;
- VAR i: ADDRESS;
- BEGIN
- baseAdr := ADDRESS OF EntryPoint;
- endAdr := ADDRESS OF last;
-
- Trace.Init;
- Trace.Char := Char;
-
- stackBottom := ADDRESSOF( i ) + 2*SIZEOF(ADDRESS);
- ASSERT(dlsym # NIL);
- Dlsym(0,"dlopen", ADDRESS OF dlopen);
- ASSERT(dlopen # NIL);
- Dlsym( 0, "dlclose", ADDRESS OF dlclose);
- ASSERT(dlclose # NIL);
- Dlsym(0,"exit", ADDRESS OF exit);
- ASSERT(exit # NIL);
- END Init;
-
- PROCEDURE {INITIAL,NOPAF} Init0;
- BEGIN
- (*initial stack layout:
- argc at rsp
- argv at rsp+8
- 0 at rsp+8+argc*8
- env at rsp+8+argc*8+8 = (2+argc)<<3 + rsp*)
- CODE{SYSTEM.AMD64}
- MOV RAX, [RSP]
- MOV argc, RAX
- LEA RAX, [RSP+8]
- MOV argv, RAX
- MOV RAX, [RSP]
- ADD RAX, 2
- SHL RAX, 3
- ADD RAX, RSP
- MOV environ, RAX
- END;
- Init;
- END Init0;
- END Glue.
- SystemTools.FreeDownTo FoxIntermediateBackend ~
- SystemTools.DoCommands
- Compiler.Compile -p=Linux32
- I386.Builtins.Mod Trace.Mod Linux.I386.Glue.Mod Linux.I386.Unix.Mod Unix.I386.Machine.Mod Heaps.Mod Modules.Mod
- Unix.Objects.Mod
- Unix.Kernel.Mod KernelLog.Mod Plugins.Mod Streams.Mod
- Pipes.Mod Commands.Mod I386.Reals.Mod Reflection.Mod TrapWriters.Mod CRC.Mod SystemVersion.Mod
- Unix.StdIO.Mod Unix.Traps.Mod Locks.Mod Unix.Clock.Mod Disks.Mod Files.Mod Dates.Mod Strings.Mod
- UTF8Strings.Mod FileTrapWriter.Mod Caches.Mod DiskVolumes.Mod OldDiskVolumes.Mod RAMVolumes.Mod
- DiskFS.Mod OldDiskFS.Mod OberonFS.Mod FATVolumes.Mod FATFiles.Mod ISO9660Volumes.Mod
- ISO9660Files.Mod Unix.UnixFiles.Mod RelativeFileSystem.Mod BitSets.Mod StringPool.Mod DIagnostics.Mod
- ObjectFile.Mod GenericLinker.Mod Loader.Mod Unix.BootConsole.Mod
- ~
- Linker.Link --fileFormat=Raw --fileName=simple_elf --extension=.GofU --displacement=08048000H
- Builtins Trace Glue Unix Machine Heaps Modules Objects Kernel KernelLog
- Streams Commands StdIO TrapWriters Traps
- Files UnixFiles Clock Dates Reals Strings Diagnostics
- BitSets StringPool ObjectFile GenericLinker Reflection Loader
- BootConsole
- ~
- FSTools.CloseFiles simple_elf ~
- ~
- MODULE Test;
- IMPORT StdIO, Commands, Streams, Modules;
- PROCEDURE Execute(context: Commands.Context);
- VAR str, msg: ARRAY 256 OF CHAR; res: WORD;
- BEGIN
- IF ~context.arg.GetString(str) THEN RETURN END;
- IF ~context.arg.GetString(str) THEN
- context.out.String("no command"); context.out.Ln;
- RETURN
- END;
- Commands.Activate(str, context, {Commands.Wait}, res, msg);
- END Execute;
- BEGIN
- Execute(StdIO.env);
- Modules.Shutdown(1);
- END Test.
|