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