aboutsummaryrefslogtreecommitdiffhomepage
path: root/notes/slusys_execfmt.txt
blob: d028c42a07fb974b58b5734addf6d7255f3a1e7d (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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

Executable/library format for SLUSYS
====================================

Minimum needed data:
- section with rodata and code
- rodata/code break (used to mark pages with only rodata as non-executable)
  (or to split code/data for harvard architectures)
    - should code or data come first
- string table (with names, versions, etc.)
- imported ABIs:
    - length
    - array:
        - hash, name-id & version-id of ABI
- exported ABIs (this includes "main" for executables):
    - length
    - array:
        - hash, name-id & version-id of ABI
    - array:
        - index of first function symbol
        - index of first data symbol
        - number of function symbols
        - number of data symbols
- function symbol table
    - length
    - array:
        - relative pointer to function entry point
- data symbol table
    - lengh
    - array:
        - relative pointer to function entry point

Design issues to solve:
- How to call into external libraries?
    - Relocate call addrs?
    - Global Offset Table + extra register?
    - Global Offset Table loaded at addrs just below the start addr?
        - (no?) this prevents placing libraries "back to back" in the same page
        - 

Nice to haves
- compressed pages



Format
------

Format structure:
- Fixed-Size Header
- Variable-Size Header
- Array of imported APIs, hashes
- Array of exported APIs, hashes
- Compression offset table
- LZ4 (or zstd?) compressed data (in 4 KiB chunks, but first one is smaller, such that each chunk ends on a 4 KiB boundary):
    - Array of exported APIs, number of functions/data addresses
    - Array of exported function addresses  (XXX do we need to know the calling convention?)
    - Array of exported data addresses
    - (Optional alignment)
    - Code
    - (Optional alignment)
    - Read-Only Data
    - String table (byte array)
    - (Alignment to length_t)
    - Array of imported APIs, corresponding name & version (for informational purposes)
    - Array of exported APIs, corresponding name & version (for informational purposes)
(- File hash or signature(s)?)

Fixed-Size Header:
- "SLUEXEC\0"
- uint8: format flags:
    .... ...X   : 0=Little endian, 1=Big endian
    .... .XX.   : Length / Relative Virtual Address size in file:
                  00=16, 01=32, 10=64, 11=reserved  (note: this has nothing to do with the arch bitness)
    other bits are reserved and must be 0
- uint8: requested CPU/platform features:
    .... ...1   : floating point (if a task does not use fp, then context switching can be optimized)
    .... ..1.   : trapping (XXX but can't this always happen? e.g. stack overflow)
    .... .1..   : handling traps (XXX)
    .... 1...   : managing owned data (XXX)
    other bits are reserved and must be 0
- uint16: CPU type (use the same as for the ELF format? should work if there is a common CPU type number "namespace" for ELF32 and ELF64)
- uint16: reserved, must be 0
- uint16: length of variable-sized header

Variable-Sized Header (missing fields are taken to be 0. fields marked with * are always required):
- length_t: *size of compressed data
- length_t: *number of imported APIs
- length_t: *size of code
- length_t: required alignment of code
- length_t: size of ro-data
- length_t: required alignment of ro-data
- length_t: number of exported APIs
- length_t: number of exported function addresses (XXX do we need to know the calling convention?)
- length_t: number of exported data addresses
- length_t: size of string table

API entry, hash part:
- 256 bit / 32 byte hash

Compression offset entry:
- uint16: uncompressed size of chunk - b (b = worst case minimum uncompressed size)
          (<= 0x7FFF: length below 32+b KiB is stored directly)
          (>= 0x8000: this and the following uint16 make up a 31-bit length)

API entry, name/version part:
- length_t: name id
- length_t: version id

Export API entry, number of functions/data addresses:
- length_t: number of exported function addresses in this API
- length_t: number of exported data addresses in this API

Exported function address entry:
- length_t: Offset from start of code

Exported data address entry:
- length_t: Offset from start of ro-data