123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390 |
- (* 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
- #IF I386 THEN
- ; ELF header
- DB 07FH, 'ELF', 1, 1, 1, 0
- DD 0, 0
- DW 02, 03
- DD 01
- DD entry + base; program entry point
- DD elfheadersize
- DD 0
- DD 0
- DW elfheadersize
- DW 20H
- DW 3 ; #program header table entries
- DW 0
- DW 0
- DW 0
- elfheadersize:
- ; program header
- DD 1
- DD 0
- DD base;
- DD base;
- DD @last - base; segment size (file)
- DD @last - base; segment size (memory)
- DD 07
- DD 1000H; alignment
- ; interpreter header
- DD 3
- DD interpretername; interpreter name offset
- DD interpretername + base; interpreter name
- DD interpretername + base; interpreter name
- DD interpretername_end - interpretername ; interpreter name length
- DD interpretername_end - interpretername ; interpreter name length
- DD 4H
- DD 1H
- ; dynamic header
- DD 02H
- DD dynamicsection
- DD dynamicsection + base
- DD dynamicsection + base
- DD dynamicsection_end - dynamicsection ; size of dynamic section
- DD dynamicsection_end - dynamicsection ; size of dynamic section
- DD 06H
- DD 04H
- dynamicsection:
- DD 05H, base + stringtable
- DD 06H, symboltablebegin + base
- DD 07H, dlsymrelocation + base
- DD 08H, dlsymrelocation_end-dlsymrelocation ; size (relocationtable)
- DD 09H, 0CH
- DD 0AH, stringtable_end - stringtable; size (stringtable)
- DD 0BH, 10H
- DD 01H, libname - stringtable; position of libname
- DD 0H, 0H ; sentinel
- dynamicsection_end:
- dlsymrelocation:
- DD @dlsym
- DB 01H
- DB 01H, 00H, 00H; index of the symbol
- DD 0H
- dlsymrelocation_end:
- stringtable:
- DB 0H ; sentinel
- libname:
- DB 'libdl.so.2', 0
- dlsymname:
- DB 'dlsym', 0
- stringtable_end:
- ALIGN 4
- symboltablebegin:
- DD 0;
- DD 0
- DD 0
- DB 0
- DB 0
- DW 0
- ; dlsym symbol
- DD dlsymname - stringtable; position of dlsymname
- DD 0
- DD 0
- DB 12H ; info: global + function
- DB 0
- DW 0
- interpretername:
- DB '/lib/ld-linux.so.2', 0
- interpretername_end:
- ALIGN 4
- entry:
- #ELSIF AMD64 THEN
- ; 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:
- #ELSE
- unimplemented
- #END
- END EntryPoint;
- (*
- PROCEDURE {FINAL} ExitPoint;
- BEGIN
- Trace.String("exiting"); Trace.Ln;
- exit(0);
- END ExitPoint;
- *)
- PROCEDURE putc*(file: ADDRESS; c: CHAR);
- CODE
- #IF I386 THEN
- MOV EAX, 4
- MOV EBX, [EBP + file]
- LEA ECX, [EBP + c]
- MOV EDX, 1
- INT 80H
- #ELSIF AMD64 THEN
- MOV EAX, 1
- MOV RDI, [RBP + file]
- LEA RSI, [RBP + c]
- MOV RDX, 1
- SYSCALL
- #ELSE
- unimplemented
- #END
- END putc;
- PROCEDURE Dlsym*(handle: ADDRESS; CONST name: ARRAY OF CHAR; adr: ADDRESS);
- VAR val: ADDRESS;
- BEGIN {UNCOOPERATIVE, UNCHECKED}
- val := dlsym(handle, ADDRESS OF name[0]);
- SYSTEM.PUT(adr, val);
- END Dlsym;
- PROCEDURE Char(c: CHAR);
- BEGIN {UNCOOPERATIVE, UNCHECKED}
- putc(1, c);
- END Char;
- PROCEDURE Init;
- VAR i: ADDRESS;
- BEGIN {UNCOOPERATIVE, UNCHECKED}
- 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 {UNCOOPERATIVE, UNCHECKED}
- CODE
- #IF I386 THEN
- ; argc at esp
- ; argv at esp+4
- ; 0 at esp+4+argc*4
- ; env at esp+4+argc*4+4 = (2+argc)<<2 + esp
- MOV EAX, [ESP]
- MOV argc, EAX
- LEA EAX, [ESP+4]
- MOV argv, EAX
- MOV EAX, [ESP]
- ADD EAX, 2
- SHL EAX, 2
- ADD EAX, ESP
- MOV environ, EAX
- #ELSIF AMD64 THEN
- ; argc at rsp
- ; argv at rsp+8
- ; 0 at rsp+8+argc*8
- ; env at rsp+8+argc*8+8 = (2+argc)<<3 + rsp
- MOV RAX, [RSP]
- MOV argc, EAX
- LEA RAX, [RSP+8]
- MOV argv, RAX
- MOV RAX, [RSP]
- ADD RAX, 2
- SHL RAX, 3
- ADD RAX, RSP
- MOV environ, RAX
- #ELSE
- unimplemented
- #END
- END;
- Init;
- END Init0;
- END Glue.
- System.FreeDownTo FoxIntermediateBackend ~
- System.DoCommands
- Compiler.Compile -p=Unix32
- I386.Builtins.Mod Trace.Mod Linux.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.
|