aboutsummaryrefslogtreecommitdiffhomepage
path: root/notes/loader.txt
blob: ca6de75a01c58d2a3b5baf2149c97913355ac50d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

Dynamic loader
==============

Goals:
* Not be tied to a specific OS/libc (or even a libc at all)
* Call all system functions via libc (if this is a good thing to do on the
  platform)
* Be able to cross-compile to/from any platform, and preferably even
  generate bit-identical files (for the same executable format, e.g.
  ELF or PE).

Idea 1
------
* interp points to /lib/ld-slul-ARCHNAME.so.1
* ld-slul execs /usr/lib(exec)/ARCHTRIPLE/slul-loader PATHTOFILE
    - but this will unmap the target binary!
* slul-loader is written in C and loads the binary

Idea 2
------
* interp points to /lib/ld-slul-ARCHNAME.so.1
* ld-slul maps /usr/lib/ARCHTRIPLE/slul-loader-ARCHTRIPLE.pso
* ld-slul maps /lib/ld-linux.so (or whatever the C library's loader is called)
  (and maybe all other libraries?)
* ld-slul calls the entry point ("_start") in slul-loader-ARCHTRIPLE.pso
* slul-loader then does the following:
    - this is the C library's initialization routine
    - this then calls "main"
    - the "main" function calls _SLUL_rtinit, which sets up the initial arena.
    - the "main" function _SLUL_main

Tricky parts:
* Libraries need to be loaded also!
    - This could be solved by programmatically "building"/modifying the
      "slul-loader", and letting the C loader do the job.
    - It could also be done by simply mmap'ing the libraries and setting
      up the minimal mappings/relocations/whatever else is needed by SLUL
      libraries.

Idea 2b
-------
* interp points to /lib/ld-slul-ARCHNAME.so.1
* ld-slul maps /usr/lib/ARCHTRIPLE/slul-init-ARCHTRIPLE.pso
  in the way that the kernel loader would have loaded an executable.
* ld-slul inserts a library dependency on the real executable in
  the mapped slul-init-ARCHTRIPLE.pso.
  This creates a dirty mapping :(
* ld-slul loads ld.so of the system,
  in the way that the kernel loader would have loaded a program interpreter.
* ld-slul modifies the aux vector etc. to make the system interpreter
  think slul-init-ARCHTRIPLE.pso is the executable.

Idea 3
------
* interp points to the standard location
* the executable contains the following library dependencies:
    - libslul-runtime.so
    - libslul-init.so
* libslul-init.so contains the following:
    - a dependency on the libc, so it gets mapped.
    - the crt*.o startup code for the system (BUT... does it work in a library? maybe there is a PIE version?)
    - main(), which calls _SLUL_main()
* _start in the executable calls _SLUL_init_libc() libslul-init.so
* _SLUL_init_libc() does the following:
    - runs the initialization code from crt*.o and calls it's own main()
* main() in libslul-init.so does the following:
    - calls _SLUL_make_initial_arena() libslul-runtime.so.
      The return value will be passed to _SLUL_main.
    - clears the stack and jumps to _SLUL_main(ar) in the executable.
* _SLUL_main does the following:
    - calls the real "main" function (which need not be exported),
      with the arena as the parameter.
    - calls _SLUL_exit(ar)