aboutsummaryrefslogtreecommitdiff
path: root/notes/givemes_impl.txt
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 */
    }
}