92f863fd6b7b59d112a67c38e3d0f086619c8ff9
[centaur.git] / include / libelfu / modelops.h
1 /*!
2  * @file modelops.h
3  * @brief Operations offered on libelfu's Elfu* models.
4  *
5  * This includes:
6  *  - Allocation/initialization, teardown of objects
7  *  - Iteration (*Forall)
8  *  - Stats (counts, lowest/highest element, ...)
9  *  - Lookups (addresses, ...)
10  *  - Scripted high-level operations (reladd, detour, ...)
11  */
12
13 #ifndef __LIBELFU_MODELOPS_H__
14 #define __LIBELFU_MODELOPS_H__
15
16 #include <elf.h>
17 #include <gelf.h>
18
19 #include <libelfu/types.h>
20
21
22 /*!
23  * @brief Lookup name of a string.
24  * @param symtabscn ElfuScn of symbol table.
25  * @param off       Offset in string table at which name starts.
26  * @result Pointer to name.
27  * @result INTERNAL USE ONLY.
28  *         See elfu_mSymtabSymToName() for an alternative.
29  *
30  */
31 #define ELFU_SYMSTR(symtabscn, off) ((symtabscn)->linkptr->databuf + (off))
32
33
34 /*!
35  * @brief Lookup the address a symbol points to.
36  * @param me     Entire ELF model.
37  * @param msst   ElfuScn containing the symbol table this symbol is in.
38  * @param sym    The symbol itself.
39  * @param result Will be set to the calculated address.
40  * @result 0 if *result is valid. Otherwise, *result is undefined and the
41  *         address could not be resolved.
42  * @note This is currently for INTERNAL USE in the relocator ONLY.
43  */
44 int elfu_mSymtabLookupSymToAddr(ElfuElf *me, ElfuScn *msst, ElfuSym *sym, GElf_Addr *result);
45
46 /*!
47  * @brief Lookup name of a symbol.
48  * @param msst ElfuScn containing the symbol table this symbol is in.
49  * @param sym  The symbol itself.
50  * @result Pointer to name.
51  */
52 char* elfu_mSymtabSymToName(ElfuScn *msst, ElfuSym *sym);
53
54 /*!
55  * @brief Lookup a symbol by its index in a symbol table.
56  * @param msst  ElfuScn containing the symbol table this symbol is in.
57  * @param entry The symbol's index in the table.
58  * @result Pointer to the symbol.
59  */
60 ElfuSym* elfu_mSymtabIndexToSym(ElfuScn *msst, GElf_Word entry);
61
62 /*!
63  * @brief Lookup the address a symbol points to, by the symbol name.
64  * @param me   Entire ELF model.
65  * @param msst ElfuScn containing the symbol table this symbol is in.
66  * @param name The symbol's name.
67  * @result The address the symbol points to.
68  */
69 GElf_Addr elfu_mSymtabLookupAddrByName(ElfuElf *me, ElfuScn *msst, char *name);
70
71 /*!
72  * @brief Serialize an ELF's global symbol table.
73  * @param me Entire ELF model.
74  */
75 void elfu_mSymtabFlatten(ElfuElf *me);
76
77 /*!
78  * @brief Check if a global symbol table exists, and add it otherwise.
79  * @param me Entire ELF model.
80  */
81 void elfu_mSymtabAddGlobalDymtabIfNotPresent(ElfuElf *me);
82
83
84
85
86 /*!
87  * @brief Callback for elfu_mPhdrForall().
88  * @param me   Entire ELF model.
89  * @param mp   Current PHDR to process.
90  * @param aux1 User defined.
91  * @param aux2 User defined.
92  * @result NULL if iteration is to continue.
93  *         Otherwise it is aborted and the handler's return value is
94  *         returned by elfu_mPhdrForall() itself.
95  */
96 typedef void* (PhdrHandlerFunc)(ElfuElf *me, ElfuPhdr *mp, void *aux1, void *aux2);
97
98 /*!
99  * @brief Iterate over all PHDRs.
100  * @param me   Entire ELF model.
101  * @param f    Callback function.
102  * @param aux1 User defined.
103  * @param aux2 User defined.
104  * @result NULL if all items have been processed.
105  *         Otherwise the return value of the last handler function
106  *         call before aborting.
107  */
108 void* elfu_mPhdrForall(ElfuElf *me, PhdrHandlerFunc f, void *aux1, void *aux2);
109
110 /*!
111  * @brief Calculate number of PHDRs in an ElfuElf.
112  * @param me Entire ELF model.
113  * @result Total number of PHDRs.
114  */
115 size_t elfu_mPhdrCount(ElfuElf *me);
116
117 /*!
118  * @brief Find a PHDR that covers a memory address.
119  * @param me   Entire ELF model.
120  * @param addr A memory address.
121  * @result Pointer to a PHDR containing the given memory address.
122  *         NULL if none found.
123  */
124 ElfuPhdr* elfu_mPhdrByAddr(ElfuElf *me, GElf_Addr addr);
125
126 /*!
127  * @brief Find a PHDR that covers a file offset.
128  * @param me     Entire ELF model.
129  * @param offset A file offset.
130  * @result Pointer to a PHDR containing the given file offset.
131  *         NULL if none found.
132  */
133 ElfuPhdr* elfu_mPhdrByOffset(ElfuElf *me, GElf_Off offset);
134
135 /*!
136  * @brief Find the ElfuElf's memory address and file offset
137  *        extrema in terms of PHDRs.
138  * @param me Entire ELF model.
139  * @param lowestAddr     Will be set to PHDR containing the lowest address referenced.
140  * @param highestAddr    Will be set to PHDR containing the highest address referenced.
141  * @param lowestOffs     Will be set to PHDR containing the lowest offset referenced.
142  * @param highestOffsEnd Will be set to PHDR containing the highest offset referenced.
143  */
144 void elfu_mPhdrLoadLowestHighest(ElfuElf *me,
145                                  ElfuPhdr **lowestAddr,
146                                  ElfuPhdr **highestAddr,
147                                  ElfuPhdr **lowestOffs,
148                                  ElfuPhdr **highestOffsEnd);
149
150 /*!
151  * @brief Update child sections' offsets in the file according to parent
152  *        PHDR's offset and address.
153  * @param mp Parent PHDR whose children to update.
154  */
155 void elfu_mPhdrUpdateChildOffsets(ElfuPhdr *mp);
156
157 /*!
158  * @brief Allocate and initialize a PHDR model.
159  * @result Pointer to a fresh ElfuPhdr.
160  *         NULL if allocation failed.
161  */
162 ElfuPhdr* elfu_mPhdrAlloc();
163
164 /*!
165  * @brief Tear down a PHDR and its children.
166  * @param mp PHDR to delete.
167  */
168 void elfu_mPhdrDestroy(ElfuPhdr* mp);
169
170
171
172
173 /*!
174  * @brief Callback for elfu_mScnForall().
175  * @param me   Entire ELF model.
176  * @param ms   Current section to process.
177  * @param aux1 User defined.
178  * @param aux2 User defined.
179  * @result NULL if iteration is to continue.
180  *         Otherwise it is aborted and the handler's return value is
181  *         returned by elfu_mScnForall() itself.
182  */
183 typedef void* (SectionHandlerFunc)(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2);
184
185 /*!
186  * @brief Iterate over all sections.
187  * @param me   Entire ELF model.
188  * @param f    Callback function.
189  * @param aux1 User defined.
190  * @param aux2 User defined.
191  * @result NULL if all items have been processed.
192  *         Otherwise the return value of the last handler function
193  *         call before aborting.
194  */
195 void* elfu_mScnForall(ElfuElf *me, SectionHandlerFunc f, void *aux1, void *aux2);
196
197 /*!
198  * @brief Calculate number of sections in an ElfuElf.
199  * @param me Entire ELF model.
200  * @result Total number of sections.
201  */
202 size_t elfu_mScnCount(ElfuElf *me);
203
204 /*!
205  * @brief Calculate index a section would currently have in its ElfuElf.
206  * @param me Entire ELF model.
207  * @param ms A section in *me.
208  * @result Estimated index.
209  */
210 size_t elfu_mScnIndex(ElfuElf *me, ElfuScn *ms);
211
212 /*!
213  * @brief Find a cloned section by its oldscn value.
214  * @param me     Entire ELF model.
215  * @param oldscn Original section to find the clone of.
216  * @result A section that is a clone of *oldscn.
217  *         NULL if none found.
218  */
219 ElfuScn* elfu_mScnByOldscn(ElfuElf *me, ElfuScn *oldscn);
220
221 /*!
222  * @brief Get a section's name.
223  * @param me Entire ELF model.
224  * @param ms A section in *me.
225  * @result Pointer to the section's name in .shstrtab.
226  */
227 char* elfu_mScnName(ElfuElf *me, ElfuScn *ms);
228
229 /*!
230  * @brief Allocate an array of pointers to all sections,
231  *        and sort them by offset.
232  * @param me    Entire ELF model.
233  * @param count Where to write total count of sections to.
234  * @result Pointer to the section's name in .shstrtab.
235  *         NULL if an error occurred.
236  */
237 ElfuScn** elfu_mScnSortedByOffset(ElfuElf *me, size_t *count);
238
239 /*!
240  * @brief Enlarge a section's buffer and append data to it.
241  * @param ms Section to append to.
242  * @param buf Source buffer with data to append.
243  * @param len Length of source buffer.
244  * @result 0 if successful.
245  *         Anything else indicates an error.
246  */
247 int elfu_mScnAppendData(ElfuScn *ms, void *buf, size_t len);
248
249 /*!
250  * @brief Allocate and initialize a section model.
251  * @result Pointer to a fresh ElfuScn.
252  *         NULL if allocation failed.
253  */
254 ElfuScn* elfu_mScnAlloc();
255
256 /*!
257  * @brief Tear down a section and associated buffers.
258  * @param ms Section to delete.
259  */
260 void elfu_mScnDestroy(ElfuScn* ms);
261
262
263
264
265 /*!
266  * @brief Allocate and initialize an ELF file model.
267  * @result Pointer to a fresh ElfuElf.
268  *         NULL if allocation failed.
269  */
270 ElfuElf* elfu_mElfAlloc();
271
272 /*!
273  * @brief Tear down an ELF file model and associated structures.
274  * @param me ElfuElf to destroy.
275  */
276 void elfu_mElfDestroy(ElfuElf* me);
277
278
279
280
281 /*!
282  * @brief Find a LOAD segment to inject into, and expand/create it.
283  * @param me      Entire ELF model.
284  * @param size    Size of data to inject.
285  * @param align   Alignment requirement of new data.
286  * @param w       Whether the new data should be writable when loaded.
287  * @param x       Whether the new data should be executable when loaded.
288  * @param injPhdr Will be set to the identified target PHDR.
289  * @result The address where the data will be located.
290  */
291 GElf_Addr elfu_mLayoutGetSpaceInPhdr(ElfuElf *me, GElf_Word size,
292                                      GElf_Word align, int w, int x,
293                                      ElfuPhdr **injPhdr);
294 /*!
295  * @brief Re-layout an ELF file so nothing overlaps that should not.
296  *        Also, recalculate various offsets and sizes where necessary.
297  * @param me Entire ELF model.
298  */
299 int elfu_mLayoutAuto(ElfuElf *me);
300
301
302
303
304 /*!
305  * @brief Lookup the address of a function in the PLT by its name.
306  * @param me   Entire ELF model.
307  * @param name The function's name.
308  * @param result Will be set to the calculated address.
309  * @result 0 if *result is valid. Otherwise, *result is undefined and the
310  *         address could not be resolved.
311  */
312 int elfu_mDynLookupPltAddrByName(ElfuElf *me, char *name, GElf_Addr *result);
313
314 /*!
315  * @brief Lookup the address of a dynamically loaded variable by its name.
316  * @param me   Entire ELF model.
317  * @param name The variable's name.
318  * @param result Will be set to the calculated address.
319  * @result 0 if *result is valid. Otherwise, *result is undefined and the
320  *         address could not be resolved.
321  */
322 int elfu_mDynLookupReldynAddrByName(ElfuElf *me, char *name, GElf_Addr *result);
323
324
325
326
327 /*!
328  * @brief Relocate a section.
329  * @param metarget ELF model containing cloned section.
330  * @param mstarget Cloned section to be relocated.
331  * @param msrt     Section in original ELF model,
332  *                 containing relocation table.
333  * @result 0 if successful.
334  *         Anything else indicates an error.
335  * @note This is currently for INTERNAL USE in Reladd ONLY.
336  */
337 int elfu_mRelocate(ElfuElf *metarget, ElfuScn *mstarget, ElfuScn *msrt);
338
339
340
341
342 /*!
343  * @brief Perform a few sanity checks.
344  * @param me Entire ELF model.
345  * @result 0 if successful.
346  *         Anything else indicates an error.
347  */
348 int elfu_mCheck(ElfuElf *me);
349
350
351
352
353 /*!
354  * @brief Dump contents of a PHDR to stdout.
355  * @param me Entire ELF model.
356  * @param mp PHDR to dump.
357  */
358 void elfu_mDumpPhdr(ElfuElf *me, ElfuPhdr *mp);
359
360 /*!
361  * @brief Dump details of a section to stdout.
362  * @param me Entire ELF model.
363  * @param ms Section to dump.
364  */
365 void elfu_mDumpScn(ElfuElf *me, ElfuScn *ms);
366
367 /*!
368  * @brief Dump contents of an entire ELF file model to stdout.
369  * @param me Entire ELF model to dump.
370  */
371 void elfu_mDumpElf(ElfuElf *me);
372
373
374
375
376 /*!
377  * @brief Parse an ELF file to a libelfu model via libelf.
378  * @param e libelf handle to source file.
379  * @result NULL if an error occurred, a fresh ElfuElf otherwise.
380  */
381 ElfuElf* elfu_mFromElf(Elf *e);
382
383 /*!
384  * @brief Serialize a libelfu model to an ELF file via libelf.
385  * @param me Entire ELF model.
386  * @param e  libelf handle to destination file.
387  */
388 void elfu_mToElf(ElfuElf *me, Elf *e);
389
390
391
392
393 /*!
394  * @brief Inject contents of an object file into an executable.
395  * @param me   Destination ELF model.
396  * @param mrel Source ELF model.
397  * @result 0 if successful.
398  *         Anything else indicates an error.
399  */
400 int elfu_mReladd(ElfuElf *me, const ElfuElf *mrel);
401
402
403
404
405 /*!
406  * @brief Overwrite a location with an unconditional jump.
407  * @param me   Entire ELF model.
408  * @param from Memory address to overwrite at.
409  * @param to   Memory address to jump to.
410  */
411 void elfu_mDetour(ElfuElf *me, GElf_Addr from, GElf_Addr to);
412
413
414 #endif