Annotate doxygen-style
[centaur.git] / include / libelfu / modelops.h
index 538e97a6207fd4705ace7ff773cc7b5f6d5fbb25..92f863fd6b7b59d112a67c38e3d0f086619c8ff9 100644 (file)
@@ -1,3 +1,15 @@
+/*!
+ * @file modelops.h
+ * @brief Operations offered on libelfu's Elfu* models.
+ *
+ * This includes:
+ *  - Allocation/initialization, teardown of objects
+ *  - Iteration (*Forall)
+ *  - Stats (counts, lowest/highest element, ...)
+ *  - Lookups (addresses, ...)
+ *  - Scripted high-level operations (reladd, detour, ...)
+ */
+
 #ifndef __LIBELFU_MODELOPS_H__
 #define __LIBELFU_MODELOPS_H__
 
 #include <libelfu/types.h>
 
 
+/*!
+ * @brief Lookup name of a string.
+ * @param symtabscn ElfuScn of symbol table.
+ * @param off       Offset in string table at which name starts.
+ * @result Pointer to name.
+ * @result INTERNAL USE ONLY.
+ *         See elfu_mSymtabSymToName() for an alternative.
+ *
+ */
 #define ELFU_SYMSTR(symtabscn, off) ((symtabscn)->linkptr->databuf + (off))
 
 
-      int elfu_mSymtabLookupSymToAddr(ElfuElf *me, ElfuScn *msst, ElfuSym *sym, GElf_Addr *result);
-    char* elfu_mSymtabSymToName(ElfuScn *msst, ElfuSym *sym);
- ElfuSym* elfu_mSymtabIndexToSym(ElfuScn *msst, GElf_Word entry);
+/*!
+ * @brief Lookup the address a symbol points to.
+ * @param me     Entire ELF model.
+ * @param msst   ElfuScn containing the symbol table this symbol is in.
+ * @param sym    The symbol itself.
+ * @param result Will be set to the calculated address.
+ * @result 0 if *result is valid. Otherwise, *result is undefined and the
+ *         address could not be resolved.
+ * @note This is currently for INTERNAL USE in the relocator ONLY.
+ */
+int elfu_mSymtabLookupSymToAddr(ElfuElf *me, ElfuScn *msst, ElfuSym *sym, GElf_Addr *result);
+
+/*!
+ * @brief Lookup name of a symbol.
+ * @param msst ElfuScn containing the symbol table this symbol is in.
+ * @param sym  The symbol itself.
+ * @result Pointer to name.
+ */
+char* elfu_mSymtabSymToName(ElfuScn *msst, ElfuSym *sym);
+
+/*!
+ * @brief Lookup a symbol by its index in a symbol table.
+ * @param msst  ElfuScn containing the symbol table this symbol is in.
+ * @param entry The symbol's index in the table.
+ * @result Pointer to the symbol.
+ */
+ElfuSym* elfu_mSymtabIndexToSym(ElfuScn *msst, GElf_Word entry);
+
+/*!
+ * @brief Lookup the address a symbol points to, by the symbol name.
+ * @param me   Entire ELF model.
+ * @param msst ElfuScn containing the symbol table this symbol is in.
+ * @param name The symbol's name.
+ * @result The address the symbol points to.
+ */
 GElf_Addr elfu_mSymtabLookupAddrByName(ElfuElf *me, ElfuScn *msst, char *name);
-     void elfu_mSymtabFlatten(ElfuElf *me);
-     void elfu_mSymtabAddGlobalDymtabIfNotPresent(ElfuElf *me);
+
+/*!
+ * @brief Serialize an ELF's global symbol table.
+ * @param me Entire ELF model.
+ */
+void elfu_mSymtabFlatten(ElfuElf *me);
+
+/*!
+ * @brief Check if a global symbol table exists, and add it otherwise.
+ * @param me Entire ELF model.
+ */
+void elfu_mSymtabAddGlobalDymtabIfNotPresent(ElfuElf *me);
+
 
 
+
+/*!
+ * @brief Callback for elfu_mPhdrForall().
+ * @param me   Entire ELF model.
+ * @param mp   Current PHDR to process.
+ * @param aux1 User defined.
+ * @param aux2 User defined.
+ * @result NULL if iteration is to continue.
+ *         Otherwise it is aborted and the handler's return value is
+ *         returned by elfu_mPhdrForall() itself.
+ */
 typedef void* (PhdrHandlerFunc)(ElfuElf *me, ElfuPhdr *mp, void *aux1, void *aux2);
-    void* elfu_mPhdrForall(ElfuElf *me, PhdrHandlerFunc f, void *aux1, void *aux2);
-   size_t elfu_mPhdrCount(ElfuElf *me);
+
+/*!
+ * @brief Iterate over all PHDRs.
+ * @param me   Entire ELF model.
+ * @param f    Callback function.
+ * @param aux1 User defined.
+ * @param aux2 User defined.
+ * @result NULL if all items have been processed.
+ *         Otherwise the return value of the last handler function
+ *         call before aborting.
+ */
+void* elfu_mPhdrForall(ElfuElf *me, PhdrHandlerFunc f, void *aux1, void *aux2);
+
+/*!
+ * @brief Calculate number of PHDRs in an ElfuElf.
+ * @param me Entire ELF model.
+ * @result Total number of PHDRs.
+ */
+size_t elfu_mPhdrCount(ElfuElf *me);
+
+/*!
+ * @brief Find a PHDR that covers a memory address.
+ * @param me   Entire ELF model.
+ * @param addr A memory address.
+ * @result Pointer to a PHDR containing the given memory address.
+ *         NULL if none found.
+ */
 ElfuPhdr* elfu_mPhdrByAddr(ElfuElf *me, GElf_Addr addr);
+
+/*!
+ * @brief Find a PHDR that covers a file offset.
+ * @param me     Entire ELF model.
+ * @param offset A file offset.
+ * @result Pointer to a PHDR containing the given file offset.
+ *         NULL if none found.
+ */
 ElfuPhdr* elfu_mPhdrByOffset(ElfuElf *me, GElf_Off offset);
-     void elfu_mPhdrLoadLowestHighest(ElfuElf *me,
-                                      ElfuPhdr **lowestAddr,
-                                      ElfuPhdr **highestAddr,
-                                      ElfuPhdr **lowestOffs,
-                                      ElfuPhdr **highestOffsEnd);
-     void elfu_mPhdrUpdateChildOffsets(ElfuPhdr *mp);
+
+/*!
+ * @brief Find the ElfuElf's memory address and file offset
+ *        extrema in terms of PHDRs.
+ * @param me Entire ELF model.
+ * @param lowestAddr     Will be set to PHDR containing the lowest address referenced.
+ * @param highestAddr    Will be set to PHDR containing the highest address referenced.
+ * @param lowestOffs     Will be set to PHDR containing the lowest offset referenced.
+ * @param highestOffsEnd Will be set to PHDR containing the highest offset referenced.
+ */
+void elfu_mPhdrLoadLowestHighest(ElfuElf *me,
+                                 ElfuPhdr **lowestAddr,
+                                 ElfuPhdr **highestAddr,
+                                 ElfuPhdr **lowestOffs,
+                                 ElfuPhdr **highestOffsEnd);
+
+/*!
+ * @brief Update child sections' offsets in the file according to parent
+ *        PHDR's offset and address.
+ * @param mp Parent PHDR whose children to update.
+ */
+void elfu_mPhdrUpdateChildOffsets(ElfuPhdr *mp);
+
+/*!
+ * @brief Allocate and initialize a PHDR model.
+ * @result Pointer to a fresh ElfuPhdr.
+ *         NULL if allocation failed.
+ */
 ElfuPhdr* elfu_mPhdrAlloc();
-     void elfu_mPhdrDestroy(ElfuPhdr* mp);
+
+/*!
+ * @brief Tear down a PHDR and its children.
+ * @param mp PHDR to delete.
+ */
+void elfu_mPhdrDestroy(ElfuPhdr* mp);
+
+
 
 
+/*!
+ * @brief Callback for elfu_mScnForall().
+ * @param me   Entire ELF model.
+ * @param ms   Current section to process.
+ * @param aux1 User defined.
+ * @param aux2 User defined.
+ * @result NULL if iteration is to continue.
+ *         Otherwise it is aborted and the handler's return value is
+ *         returned by elfu_mScnForall() itself.
+ */
 typedef void* (SectionHandlerFunc)(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2);
-    void* elfu_mScnForall(ElfuElf *me, SectionHandlerFunc f, void *aux1, void *aux2);
-   size_t elfu_mScnCount(ElfuElf *me);
-   size_t elfu_mScnIndex(ElfuElf *me, ElfuScn *ms);
- ElfuScn* elfu_mScnByOldscn(ElfuElf *me, ElfuScn *oldscn);
-    char* elfu_mScnName(ElfuElf *me, ElfuScn *ms);
+
+/*!
+ * @brief Iterate over all sections.
+ * @param me   Entire ELF model.
+ * @param f    Callback function.
+ * @param aux1 User defined.
+ * @param aux2 User defined.
+ * @result NULL if all items have been processed.
+ *         Otherwise the return value of the last handler function
+ *         call before aborting.
+ */
+void* elfu_mScnForall(ElfuElf *me, SectionHandlerFunc f, void *aux1, void *aux2);
+
+/*!
+ * @brief Calculate number of sections in an ElfuElf.
+ * @param me Entire ELF model.
+ * @result Total number of sections.
+ */
+size_t elfu_mScnCount(ElfuElf *me);
+
+/*!
+ * @brief Calculate index a section would currently have in its ElfuElf.
+ * @param me Entire ELF model.
+ * @param ms A section in *me.
+ * @result Estimated index.
+ */
+size_t elfu_mScnIndex(ElfuElf *me, ElfuScn *ms);
+
+/*!
+ * @brief Find a cloned section by its oldscn value.
+ * @param me     Entire ELF model.
+ * @param oldscn Original section to find the clone of.
+ * @result A section that is a clone of *oldscn.
+ *         NULL if none found.
+ */
+ElfuScn* elfu_mScnByOldscn(ElfuElf *me, ElfuScn *oldscn);
+
+/*!
+ * @brief Get a section's name.
+ * @param me Entire ELF model.
+ * @param ms A section in *me.
+ * @result Pointer to the section's name in .shstrtab.
+ */
+char* elfu_mScnName(ElfuElf *me, ElfuScn *ms);
+
+/*!
+ * @brief Allocate an array of pointers to all sections,
+ *        and sort them by offset.
+ * @param me    Entire ELF model.
+ * @param count Where to write total count of sections to.
+ * @result Pointer to the section's name in .shstrtab.
+ *         NULL if an error occurred.
+ */
 ElfuScn** elfu_mScnSortedByOffset(ElfuElf *me, size_t *count);
-      int elfu_mScnAppendData(ElfuScn *ms, void *buf, size_t len);
- ElfuScn* elfu_mScnAlloc();
-     void elfu_mScnDestroy(ElfuScn* ms);
+
+/*!
+ * @brief Enlarge a section's buffer and append data to it.
+ * @param ms Section to append to.
+ * @param buf Source buffer with data to append.
+ * @param len Length of source buffer.
+ * @result 0 if successful.
+ *         Anything else indicates an error.
+ */
+int elfu_mScnAppendData(ElfuScn *ms, void *buf, size_t len);
+
+/*!
+ * @brief Allocate and initialize a section model.
+ * @result Pointer to a fresh ElfuScn.
+ *         NULL if allocation failed.
+ */
+ElfuScn* elfu_mScnAlloc();
+
+/*!
+ * @brief Tear down a section and associated buffers.
+ * @param ms Section to delete.
+ */
+void elfu_mScnDestroy(ElfuScn* ms);
 
 
+
+
+/*!
+ * @brief Allocate and initialize an ELF file model.
+ * @result Pointer to a fresh ElfuElf.
+ *         NULL if allocation failed.
+ */
 ElfuElf* elfu_mElfAlloc();
-    void elfu_mElfDestroy(ElfuElf* me);
+
+/*!
+ * @brief Tear down an ELF file model and associated structures.
+ * @param me ElfuElf to destroy.
+ */
+void elfu_mElfDestroy(ElfuElf* me);
+
 
 
+
+/*!
+ * @brief Find a LOAD segment to inject into, and expand/create it.
+ * @param me      Entire ELF model.
+ * @param size    Size of data to inject.
+ * @param align   Alignment requirement of new data.
+ * @param w       Whether the new data should be writable when loaded.
+ * @param x       Whether the new data should be executable when loaded.
+ * @param injPhdr Will be set to the identified target PHDR.
+ * @result The address where the data will be located.
+ */
 GElf_Addr elfu_mLayoutGetSpaceInPhdr(ElfuElf *me, GElf_Word size,
                                      GElf_Word align, int w, int x,
                                      ElfuPhdr **injPhdr);
+/*!
+ * @brief Re-layout an ELF file so nothing overlaps that should not.
+ *        Also, recalculate various offsets and sizes where necessary.
+ * @param me Entire ELF model.
+ */
 int elfu_mLayoutAuto(ElfuElf *me);
 
 
+
+
+/*!
+ * @brief Lookup the address of a function in the PLT by its name.
+ * @param me   Entire ELF model.
+ * @param name The function's name.
+ * @param result Will be set to the calculated address.
+ * @result 0 if *result is valid. Otherwise, *result is undefined and the
+ *         address could not be resolved.
+ */
 int elfu_mDynLookupPltAddrByName(ElfuElf *me, char *name, GElf_Addr *result);
+
+/*!
+ * @brief Lookup the address of a dynamically loaded variable by its name.
+ * @param me   Entire ELF model.
+ * @param name The variable's name.
+ * @param result Will be set to the calculated address.
+ * @result 0 if *result is valid. Otherwise, *result is undefined and the
+ *         address could not be resolved.
+ */
 int elfu_mDynLookupReldynAddrByName(ElfuElf *me, char *name, GElf_Addr *result);
 
 
+
+
+/*!
+ * @brief Relocate a section.
+ * @param metarget ELF model containing cloned section.
+ * @param mstarget Cloned section to be relocated.
+ * @param msrt     Section in original ELF model,
+ *                 containing relocation table.
+ * @result 0 if successful.
+ *         Anything else indicates an error.
+ * @note This is currently for INTERNAL USE in Reladd ONLY.
+ */
 int elfu_mRelocate(ElfuElf *metarget, ElfuScn *mstarget, ElfuScn *msrt);
 
 
+
+
+/*!
+ * @brief Perform a few sanity checks.
+ * @param me Entire ELF model.
+ * @result 0 if successful.
+ *         Anything else indicates an error.
+ */
 int elfu_mCheck(ElfuElf *me);
 
 
+
+
+/*!
+ * @brief Dump contents of a PHDR to stdout.
+ * @param me Entire ELF model.
+ * @param mp PHDR to dump.
+ */
 void elfu_mDumpPhdr(ElfuElf *me, ElfuPhdr *mp);
+
+/*!
+ * @brief Dump details of a section to stdout.
+ * @param me Entire ELF model.
+ * @param ms Section to dump.
+ */
 void elfu_mDumpScn(ElfuElf *me, ElfuScn *ms);
+
+/*!
+ * @brief Dump contents of an entire ELF file model to stdout.
+ * @param me Entire ELF model to dump.
+ */
 void elfu_mDumpElf(ElfuElf *me);
 
 
+
+
+/*!
+ * @brief Parse an ELF file to a libelfu model via libelf.
+ * @param e libelf handle to source file.
+ * @result NULL if an error occurred, a fresh ElfuElf otherwise.
+ */
 ElfuElf* elfu_mFromElf(Elf *e);
-    void elfu_mToElf(ElfuElf *me, Elf *e);
 
- int elfu_mReladd(ElfuElf *me, const ElfuElf *mrel);
+/*!
+ * @brief Serialize a libelfu model to an ELF file via libelf.
+ * @param me Entire ELF model.
+ * @param e  libelf handle to destination file.
+ */
+void elfu_mToElf(ElfuElf *me, Elf *e);
+
+
 
+
+/*!
+ * @brief Inject contents of an object file into an executable.
+ * @param me   Destination ELF model.
+ * @param mrel Source ELF model.
+ * @result 0 if successful.
+ *         Anything else indicates an error.
+ */
+int elfu_mReladd(ElfuElf *me, const ElfuElf *mrel);
+
+
+
+
+/*!
+ * @brief Overwrite a location with an unconditional jump.
+ * @param me   Entire ELF model.
+ * @param from Memory address to overwrite at.
+ * @param to   Memory address to jump to.
+ */
 void elfu_mDetour(ElfuElf *me, GElf_Addr from, GElf_Addr to);
 
+
 #endif