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
|