3 * @brief Operations offered on libelfu's Elfu* models.
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, ...)
13 #ifndef __LIBELFU_MODELOPS_H__
14 #define __LIBELFU_MODELOPS_H__
19 #include <libelfu/types.h>
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.
31 #define ELFU_SYMSTR(symtabscn, off) ((symtabscn)->linkptr->databuf + (off))
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.
44 int elfu_mSymtabLookupSymToAddr(ElfuElf *me, ElfuScn *msst, ElfuSym *sym, GElf_Addr *result);
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.
52 char* elfu_mSymtabSymToName(ElfuScn *msst, ElfuSym *sym);
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.
60 ElfuSym* elfu_mSymtabIndexToSym(ElfuScn *msst, GElf_Word entry);
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.
69 GElf_Addr elfu_mSymtabLookupAddrByName(ElfuElf *me, ElfuScn *msst, char *name);
72 * @brief Serialize an ELF's global symbol table.
73 * @param me Entire ELF model.
75 void elfu_mSymtabFlatten(ElfuElf *me);
78 * @brief Check if a global symbol table exists, and add it otherwise.
79 * @param me Entire ELF model.
81 void elfu_mSymtabAddGlobalDymtabIfNotPresent(ElfuElf *me);
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.
96 typedef void* (PhdrHandlerFunc)(ElfuElf *me, ElfuPhdr *mp, void *aux1, void *aux2);
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.
108 void* elfu_mPhdrForall(ElfuElf *me, PhdrHandlerFunc f, void *aux1, void *aux2);
111 * @brief Calculate number of PHDRs in an ElfuElf.
112 * @param me Entire ELF model.
113 * @result Total number of PHDRs.
115 size_t elfu_mPhdrCount(ElfuElf *me);
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.
124 ElfuPhdr* elfu_mPhdrByAddr(ElfuElf *me, GElf_Addr addr);
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.
133 ElfuPhdr* elfu_mPhdrByOffset(ElfuElf *me, GElf_Off offset);
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.
144 void elfu_mPhdrLoadLowestHighest(ElfuElf *me,
145 ElfuPhdr **lowestAddr,
146 ElfuPhdr **highestAddr,
147 ElfuPhdr **lowestOffs,
148 ElfuPhdr **highestOffsEnd);
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.
155 void elfu_mPhdrUpdateChildOffsets(ElfuPhdr *mp);
158 * @brief Allocate and initialize a PHDR model.
159 * @result Pointer to a fresh ElfuPhdr.
160 * NULL if allocation failed.
162 ElfuPhdr* elfu_mPhdrAlloc();
165 * @brief Tear down a PHDR and its children.
166 * @param mp PHDR to delete.
168 void elfu_mPhdrDestroy(ElfuPhdr* mp);
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.
183 typedef void* (SectionHandlerFunc)(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2);
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.
195 void* elfu_mScnForall(ElfuElf *me, SectionHandlerFunc f, void *aux1, void *aux2);
198 * @brief Calculate number of sections in an ElfuElf.
199 * @param me Entire ELF model.
200 * @result Total number of sections.
202 size_t elfu_mScnCount(ElfuElf *me);
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.
210 size_t elfu_mScnIndex(ElfuElf *me, ElfuScn *ms);
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.
219 ElfuScn* elfu_mScnByOldscn(ElfuElf *me, ElfuScn *oldscn);
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.
227 char* elfu_mScnName(ElfuElf *me, ElfuScn *ms);
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.
237 ElfuScn** elfu_mScnSortedByOffset(ElfuElf *me, size_t *count);
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.
247 int elfu_mScnAppendData(ElfuScn *ms, void *buf, size_t len);
250 * @brief Allocate and initialize a section model.
251 * @result Pointer to a fresh ElfuScn.
252 * NULL if allocation failed.
254 ElfuScn* elfu_mScnAlloc();
257 * @brief Tear down a section and associated buffers.
258 * @param ms Section to delete.
260 void elfu_mScnDestroy(ElfuScn* ms);
266 * @brief Allocate and initialize an ELF file model.
267 * @result Pointer to a fresh ElfuElf.
268 * NULL if allocation failed.
270 ElfuElf* elfu_mElfAlloc();
273 * @brief Tear down an ELF file model and associated structures.
274 * @param me ElfuElf to destroy.
276 void elfu_mElfDestroy(ElfuElf* me);
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.
291 GElf_Addr elfu_mLayoutGetSpaceInPhdr(ElfuElf *me, GElf_Word size,
292 GElf_Word align, int w, int x,
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.
299 int elfu_mLayoutAuto(ElfuElf *me);
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.
312 int elfu_mDynLookupPltAddrByName(ElfuElf *me, char *name, GElf_Addr *result);
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.
322 int elfu_mDynLookupReldynAddrByName(ElfuElf *me, char *name, GElf_Addr *result);
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.
337 int elfu_mRelocate(ElfuElf *metarget, ElfuScn *mstarget, ElfuScn *msrt);
343 * @brief Perform a few sanity checks.
344 * @param me Entire ELF model.
345 * @result 0 if successful.
346 * Anything else indicates an error.
348 int elfu_mCheck(ElfuElf *me);
354 * @brief Dump contents of a PHDR to stdout.
355 * @param me Entire ELF model.
356 * @param mp PHDR to dump.
358 void elfu_mDumpPhdr(ElfuElf *me, ElfuPhdr *mp);
361 * @brief Dump details of a section to stdout.
362 * @param me Entire ELF model.
363 * @param ms Section to dump.
365 void elfu_mDumpScn(ElfuElf *me, ElfuScn *ms);
368 * @brief Dump contents of an entire ELF file model to stdout.
369 * @param me Entire ELF model to dump.
371 void elfu_mDumpElf(ElfuElf *me);
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.
381 ElfuElf* elfu_mFromElf(Elf *e);
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.
388 void elfu_mToElf(ElfuElf *me, Elf *e);
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.
400 int elfu_mReladd(ElfuElf *me, const ElfuElf *mrel);
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.
411 void elfu_mDetour(ElfuElf *me, GElf_Addr from, GElf_Addr to);