about summary refs log tree commit diff stats
path: root/src/elfs/elfloader_private.h
blob: 61de1a43a68ccecb5c336640bbf83b38a0a2dae4 (plain) (blame)
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#ifndef __ELFLOADER_PRIVATE_H_
#define __ELFLOADER_PRIVATE_H_

typedef struct library_s library_t;
typedef struct needed_libs_s needed_libs_t;
typedef struct cleanup_s cleanup_t;

#include <elf.h>
#include "elfloader.h"
#include "box32.h"

typedef struct multiblock_s {
    void*       p;
    uintptr_t   offs;
    uintptr_t   paddr;
    uintptr_t   align;
    uint64_t    size;
    uint64_t    asize;
    uint8_t     flags;
} multiblock_t;

typedef struct elfheader_s {
    char*       name;
    char*       path;   // Resolved path to file
    char*       soname; // soname of the elf
    uint16_t    numPHEntries;
    union {
        Elf64_Phdr* _64;
        Elf32_Phdr* _32;
    }           PHEntries;
    uint16_t    numSHEntries;
    union {
        Elf64_Shdr* _64;
        Elf32_Shdr* _32;
    }           SHEntries;
    size_t      SHIdx;
    size_t      numSST;
    char*       SHStrTab;
    char*       StrTab;
    union {
        Elf64_Sym*  _64;
        Elf32_Sym*  _32;
    }           SymTab;
    size_t      numSymTab;
    char*       DynStr;
    union {
        Elf64_Sym*  _64;
        Elf32_Sym*  _32;
    }           DynSym;
    size_t      numDynSym;
    union {
        Elf64_Dyn*  _64;
        Elf32_Dyn*  _32;
    }           Dynamic;
    size_t      numDynamic;
    char*       DynStrTab;
    size_t      szDynStrTab;
    uint16_t*   VerSym;
    union {
        Elf64_Verneed*  _64;
        Elf32_Verneed*  _32;
    }           VerNeed;
    int         szVerNeed;
    union {
        Elf64_Verdef*   _64;
        Elf32_Verdef*   _32;
    }           VerDef;
    int         szVerDef;
    int         e_type;
    uint32_t    flags;
    uintptr_t   hash;
    uintptr_t   gnu_hash;

    intptr_t    delta;  // should be 0
    void*       image;  // base of the elf image
    void*       raw;    // raw pointer (might be unaligned vs image and max_align of elf)
    size_t      raw_size;

    uintptr_t   entrypoint;
    uintptr_t   initentry;
    uintptr_t   initarray;
    size_t      initarray_sz;
    uintptr_t   finientry;
    uintptr_t   finiarray;
    size_t      finiarray_sz;

    uintptr_t   rel;
    size_t      relsz;
    int         relent;
    uintptr_t   rela;
    size_t      relasz;
    int         relaent;
    uintptr_t   relr;
    size_t      relrsz;
    int         relrent;
    uintptr_t   jmprel;
    size_t      pltsz;
    int         pltent;
    uint64_t    pltrel;
    uintptr_t   gotplt;
    uintptr_t   gotplt_end;
    uintptr_t   pltgot;
    uintptr_t   got;
    uintptr_t   got_end;
    uintptr_t   plt;
    uintptr_t   plt_end;
    uintptr_t   text;
    size_t      textsz;
    uintptr_t   ehframe;
    uintptr_t   ehframe_end;
    uintptr_t   ehframehdr;

    uintptr_t   paddr;
    uintptr_t   vaddr;
    size_t      align;
    uint64_t    memsz;
    uint64_t    stacksz;
    size_t      stackalign;
    uintptr_t   tlsaddr;
    uint64_t    tlssize;
    uint64_t    tlsfilesize;
    size_t      tlsalign;

    int64_t     tlsbase;    // the base of the tlsdata in the global tlsdata (always negative)

    int         init_done;
    int         fini_done;
    int         refcnt;     // ref count for the elf
    int         malloc_hook_2;  // this elf hook malloc, hacking it
    int         gnuunique;  // set if contains some STB_GNU_UNIQUE binding, preventing dlclose to unload the lib

    char*       memory;     // char* and not void* to allow math on memory pointer
    multiblock_t*  multiblocks;
    int         multiblock_n;

    library_t   *lib;       // attached lib (exept on main elf)
    needed_libs_t* needed;

    FILE*       file;
    int         fileno;

    cleanup_t           *cleanups;          // atexit functions
    int                 clean_sz;
    int                 clean_cap;

} elfheader_t;

#define R_X86_64_NONE           0       /* No reloc */
#define R_X86_64_64             1       /* Direct 64 bit  */
#define R_X86_64_PC32           2       /* PC relative 32 bit signed */
#define R_X86_64_GOT32          3       /* 32 bit GOT entry */
#define R_X86_64_PLT32          4       /* 32 bit PLT address */
#define R_X86_64_COPY           5       /* Copy symbol at runtime */
#define R_X86_64_GLOB_DAT       6       /* Create GOT entry */
#define R_X86_64_JUMP_SLOT      7       /* Create PLT entry */
#define R_X86_64_RELATIVE       8       /* Adjust by program base */
#define R_X86_64_GOTPCREL       9       /* 32 bit signed PC relative offset to GOT */
#define R_X86_64_32             10      /* Direct 32 bit zero extended */
#define R_X86_64_32S            11      /* Direct 32 bit sign extended */
#define R_X86_64_16             12      /* Direct 16 bit zero extended */
#define R_X86_64_PC16           13      /* 16 bit sign extended pc relative */
#define R_X86_64_8              14      /* Direct 8 bit sign extended  */
#define R_X86_64_PC8            15      /* 8 bit sign extended pc relative */
#define R_X86_64_DTPMOD64       16      /* ID of module containing symbol */
#define R_X86_64_DTPOFF64       17      /* Offset in module's TLS block */
#define R_X86_64_TPOFF64        18      /* Offset in initial TLS block */
#define R_X86_64_TLSGD          19      /* 32 bit signed PC relative offset to two GOT entries for GD symbol */
#define R_X86_64_TLSLD          20      /* 32 bit signed PC relative offset to two GOT entries for LD symbol */
#define R_X86_64_DTPOFF32       21      /* Offset in TLS block */
#define R_X86_64_GOTTPOFF       22      /* 32 bit signed PC relative offset to GOT entry for IE symbol */
#define R_X86_64_TPOFF32        23      /* Offset in initial TLS block */
#define R_X86_64_PC64           24      /* PC relative 64 bit */
#define R_X86_64_GOTOFF64       25      /* 64 bit offset to GOT */
#define R_X86_64_GOTPC32        26      /* 32 bit signed pc relative offset to GOT */
#define R_X86_64_GOT64          27      /* 64-bit GOT entry offset */
#define R_X86_64_GOTPCREL64     28      /* 64-bit PC relative offset to GOT entry */
#define R_X86_64_GOTPC64        29      /* 64-bit PC relative offset to GOT */
#define R_X86_64_GOTPLT64       30      /* like GOT64, says PLT entry needed */
#define R_X86_64_PLTOFF64       31      /* 64-bit GOT relative offset to PLT entry */
#define R_X86_64_SIZE32         32      /* Size of symbol plus 32-bit addend */
#define R_X86_64_SIZE64         33      /* Size of symbol plus 64-bit addend */
#define R_X86_64_GOTPC32_TLSDESC 34     /* GOT offset for TLS descriptor.  */
#define R_X86_64_TLSDESC_CALL   35      /* Marker for call through TLS descriptor.  */
#define R_X86_64_TLSDESC        36      /* TLS descriptor.  */
#define R_X86_64_IRELATIVE      37      /* Adjust indirectly by program base */
#define R_X86_64_RELATIVE64     38      /* 64-bit adjust by program base */
                                        /* 39 Reserved was R_X86_64_PC32_BND */
                                        /* 40 Reserved was R_X86_64_PLT32_BND */
#define R_X86_64_GOTPCRELX      41      /* Load from 32 bit signed pc relative offset to GOT entry without REX prefix, relaxable.  */
#define R_X86_64_REX_GOTPCRELX  42      /* Load from 32 bit signed pc relative offset to GOT entry with REX prefix, relaxable.  */
#define R_X86_64_NUM            43

#ifndef STB_GNU_UNIQUE
#define STB_GNU_UNIQUE  10
#endif

#ifndef ELF32_ST_VISIBILITY
#define ELF32_ST_VISIBILITY(o)  ((o) & 0x03)
#endif

#ifndef ELF64_ST_VISIBILITY
#define ELF64_ST_VISIBILITY(o)  ELF32_ST_VISIBILITY (o)
#endif

elfheader_t* ParseElfHeader32(FILE* f, const char* name, int exec);
elfheader_t* ParseElfHeader64(FILE* f, const char* name, int exec);

const char* BindSym(int bind);
const char* BindSymFriendly(int bind);

uint16_t GetSymbolVersionFlag(elfheader_t* h, int index);

uint32_t old_elf_hash(const char* name);
uint32_t new_elf_hash(const char *name);

Elf32_Sym* ElfLookup32(elfheader_t* h, const char* symname, int ver, const char* vername, int local, int veropt);
Elf32_Sym* ElfSymTabLookup32(elfheader_t* h, const char* symname);
Elf32_Sym* ElfDynSymLookup32(elfheader_t* h, const char* symname);

Elf64_Sym* ElfLookup64(elfheader_t* h, const char* symname, int ver, const char* vername, int local, int veropt);
Elf64_Sym* ElfSymTabLookup64(elfheader_t* h, const char* symname);
Elf64_Sym* ElfDynSymLookup64(elfheader_t* h, const char* symname);

#endif //__ELFLOADER_PRIVATE_H_