blob: ea6ab6bba8d17494e51031aaf738f516821d1714 (
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
|
How to implement `giveme`s?
===========================
TODO clean up this note...
static void process_givemes(struct Type *type)
{
/* TODO how to map these to the funcs/constructors?
- preferably without requiring a relocation.
- or, alternatively, it could go into a separate memory
segment that could be unmapped/remapped (but that might
not work well together with large page sizes).
- A "function reference" is just a string reference (symbol) on
the dynamic linker level. So there's no real difference from
a string! So this could contain strings
- plus API-hashes maybe
- and maybe some data structure similar to .gnu.hash
- how should be list itself be exported?
- as a separate section? but the loader doesn't
care about sections.
- as a symbol? this works with plain C. For example:
SLUL__givemes
- as a PT_SOMETHING (on ELF platforms) ?
*/
struct Var *var;
size_t size = 0;
/* TODO size += header of gnuhash */
/* XXX deviations (problem!) from standard gnuhash:
- always using 32 bit regardless of platform
- need to concat the name with an API-hash.
and there's no point in hashing API hash again.
Maybe there's some simpler data structure?
Maybe only a hash should be used:
- service_type_hash = version_api_hash XOR symbol_hash_input
- neither of these need to be fast, so they can use a secure
hash function such as BLAKE256.
Then the data structure could be simple:
uint32 numentries
uint32 datasize
uint32 reserved1 (also for padding)
uint32 reserved2 (also for padding)
[n][32]byte linear_probe_set
[n]uint32 offset (length is offset[n+1]-offset[n],
or the remaining bytes)
- Array without holes, with a linear-probe set.
Each element contains a service_type_hash.
Or even:
uint32 servicetypes_count (=s)
uint32 servicetypes_datalen
uint32 givemes_count (=g)
uint32 givemes_datalen
uint32 importedtypes_count (=t)
uint32 reserved_and_padding1
uint32 reserved_and_padding2
uint32 reserved_and_padding3
[s][32]byte servicetypes_linearprobeset
# FIXME there can be more than one per type
[g][32]byte givemes_linearprobeset
[t][32]byte types_linearprobeset
[s]uint32 servicetypes_offsets (length is offset[n+1]-offset[n], or the remaining bytes)
[g]uint32 givemes_offsets (length is offset[n+1]-offset[n], or the remaining bytes)
[s]SvcTypeInfo servicetype_infos
[g]GiveMeInfo givemes_infos
[...]byte extradata
SvcTypeInfo
uint32 entry_count (=e)
[e]EntryInfo entry_infos
EntryInfo
[32]byte entry_hash (symbol_hash of function declaration [names and types])
uint32 offset_in_code (or sint32 offset_from_main?)
GiveMeInfo
[32]byte type_hash
uint32 offset_in_bss
uint32 param_count (=p)
uint32 ctor_id (orderedversion-then-alphabetic index in API definition)
[p]ParamInfo param_infos
ParamInfo
uint32 param_id (orderedversion-then-alphabetic index in API definition)
uint32 param_type (imported type, or: string, integer, bool)
uint32 data_offset
uint32 data_size
But this is way to complex... Can it be simplified?
*/
for (var = type->vars_list; var; var = var->next) {
if (!var->is_giveme) {
continue;
}
size += 0; /* TODO */
}
}
|