Skip to content
Snippets Groups Projects
Commit 88d10c1f authored by Alessandro Di Federico's avatar Alessandro Di Federico
Browse files

Add documentation

parent d2707186
No related branches found
No related tags found
No related merge requests found
......@@ -15,4 +15,3 @@ the previously loaded shared objects are searched in load order.
* Import sys/queue.h
* Add support for having different address spaces
* Add support for TLS relocations
* Documentation
#include "support.h"
#include "eld.h"
/**
* Return the address of a dynamic symbol
*
* @param handle reference to library to search in. If NULL, the search will be
* performed over all the loaded libraries.
* @param symbol NULL-terminated string of the dynamic symbol to search.
*
* @return the address of the requested symbol, or NULL if not found.
*/
void *dlsym(void *handle, char *symbol) {
CHECK_ARGS_RET(symbol, 0);
......@@ -16,6 +25,18 @@ void *dlsym(void *handle, char *symbol) {
return match_elf->elf_offset + match->st_value;
}
/**
* Load the specified shared library.
*
* @param filename pointer to the library to load. Note that this is not a file
* name (since we assume not to have a file system), but it's the library
* itself, a bit as the "data:" URLs work.
* @param flag flags to use while loading the library. Currently this parameter
* has no effect.
*
* @return an handle to the loaded library, which can be later used with dlsym
* and dlclose.
*/
void *dlopen(char *filename, int flag) {
DBG_MSG("dlopen(%p, %x)", filename, flag);
CHECK_ARGS_RET(filename, NULL);
......@@ -40,6 +61,13 @@ void *dlopen(char *filename, int flag) {
return library_descriptor;
}
/**
* Unloads the specified library.
*
* @param handle handle (as returned by dlopen) of the library to close.
*
* @return zero, if success, non-zero otherwise.
*/
int dlclose(void *handle) {
CHECK_ARGS(handle);
int result = SUCCESS;
......
#ifndef DL_H
#define DL_H
/**
* Return the address of a dynamic symbol
*
* @param handle reference to library to search in. If NULL, the search will be
* performed over all the loaded libraries.
* @param symbol NULL-terminated string of the dynamic symbol to search.
*
* @return the address of the requested symbol, or NULL if not found.
*/
void *dlsym(void *handle, char *symbol);
/**
* Load the specified shared library.
*
* @param filename pointer to the library to load. Note that this is not a file
* name (since we assume not to have a file system), but it's the library
* itself, a bit as the "data:" URLs work.
* @param flag flags to use while loading the library. Currently this parameter
* has no effect.
*
* @return an handle to the loaded library, which can be later used with dlsym
* and dlclose.
*/
void *dlopen(char *filename, int flag);
/**
* Unloads the specified library.
*
* @param handle handle (as returned by dlopen) of the library to close.
*
* @return zero, if success, non-zero otherwise.
*/
int dlclose(void *handle);
#endif /* DL_H */
......@@ -5,6 +5,8 @@ elf_object_list_head_t elves;
/**
* Initialize ELF object list
*
* @return zero, if success, non-zero otherwise.
*/
int eld_init() {
int result = SUCCESS;
......@@ -24,6 +26,8 @@ int eld_init() {
/**
* Cleanup ELF object list
*
* @return zero, if success, non-zero otherwise.
*/
int eld_finish() {
elf_object_t *elf = NULL;
......@@ -37,9 +41,13 @@ int eld_finish() {
}
/**
* Load a library already in memory
* @param library
* @return
* Load a library already in memory.
*
* @param library pointer to the current position of the ELF file.
* @param library_descriptor pointer where a pointer the newly allocated library
* descriptor will be stored.
*
* @return zero, if success, non-zero otherwise.
*/
int eld_open(mem_t *library, elf_object_t **library_descriptor) {
CHECK_ARGS(library && library_descriptor);
......
#ifndef ELD_H
#define ELD_H
#include <sys/queue.h>
#include "elf-wrapper.h"
......@@ -39,18 +42,106 @@ typedef struct elf_object {
typedef SLIST_HEAD(elf_object_list_head, elf_object) elf_object_list_head_t;
extern elf_object_list_head_t elves;
/**
* Check if the specified ELF object descriptor is registered.
*
* @param this the input ELF object descriptor.
*
* @return zero, if success, non-zero otherwise.
*/
int eld_elf_object_is_registered(elf_object_t *this);
/**
* Find a symbol just using its name.
*
* @param this the input ELF object descriptor.
* @param name symbol name to search.
* @param match [out] pointer where the matching symbol will be stored.
* @param match_elf [out] pointer to where the matching ELF symbol
*
* @return zero, if success, non-zero otherwise.
*/
int eld_elf_object_find_symbol_by_name(elf_object_t *this, char *name,
Elf_Sym **match,
elf_object_t **match_elf);
/**
* Remove it from the list of loaded objects and close it.
*
* @param this the input ELF object descriptor.
*
* @return zero, if success, non-zero otherwise.
*/
int eld_elf_object_close(elf_object_t *this);
/**
* Create a new instance of an ELF object descriptor.
*
* @param soname the soname of the library.
* @param length size of the library.
*
* @return a pointer to the ELF descriptor.
*/
elf_object_t * eld_elf_object_new(char *soname, int length);
/**
* Handle the dynamic section of the ELF input object.
*
* @param this the input ELF object descriptor.
*
* @return zero, if success, non-zero otherwise.
*/
int eld_elf_object_handle_dyn(elf_object_t *this);
/**
* Destructor for an ELF object descriptor. Calls the finalization
* function and deallocates the associated memory.
*
* @param this the input ELF object descriptor.
*/
void eld_elf_object_destroy(elf_object_t *this);
/**
* Check that the input ELF is appropriate for being loaded.
*
* @param this the input ELF object descriptor.
*
* @return zero, if success, non-zero otherwise.
*/
int eld_elf_object_check(elf_object_t *this);
/**
* Load the ELF object in memory and initialize it.
*
* @param this the input ELF object descriptor.
*
* @return zero, if success, non-zero otherwise.
*/
int eld_elf_object_load(elf_object_t *this);
/**
* Load a library already in memory.
*
* @param library pointer to the current position of the ELF file.
* @param library_descriptor pointer where a pointer the newly allocated library
* descriptor will be stored.
*
* @return zero, if success, non-zero otherwise.
*/
int eld_open(mem_t *library, elf_object_t **library_descriptor);
/**
* Initialize ELF object list
*
* @return zero, if success, non-zero otherwise.
*/
__attribute__((constructor)) int eld_init();
/**
* Cleanup ELF object list
*
* @return zero, if success, non-zero otherwise.
*/
__attribute__((destructor)) int eld_finish();
#endif /* ELD_H */
......@@ -8,6 +8,13 @@ typedef void (*t_init_function)(void);
typedef void (*t_fini_function)(void);
typedef Elf_Addr Elf_Addr_Unaligned __attribute__((aligned(1)));
/**
* ELF hash function for quick symbol lookup
*
* @param cursor the name of the symbol to hash.
*
* @return the hash of the input symbol name.
*/
static elf_hash_t eld_elf_hash(char *cursor) {
elf_hash_t result = 0;
while (*cursor) {
......@@ -20,12 +27,6 @@ static elf_hash_t eld_elf_hash(char *cursor) {
return result;
}
/**
* Add an ELF to the list
* @param so_name
* @param length
* @return
*/
elf_object_t * eld_elf_object_new(char *soname, int length) {
elf_object_t *new_elf;
new_elf = calloc(sizeof (char), sizeof (elf_object_t));
......@@ -54,6 +55,18 @@ void eld_elf_object_destroy(elf_object_t *this) {
free(this);
}
/**
* Get the symbol matching a specified name.
*
* @param this the input ELF object descriptor.
* @param target_name symbol name.
* @param target_hash hash of the symbol name.
* @param target_symbol [out] pointer where the matching symbol will be stored.
* @param weak_symbol [out] pointer where a weak matching symbol will be stored.
* @param weak_elf [out] pointer to where a weak matching ELF will be stored.
*
* @return zero, if success, non-zero otherwise.
*/
static int eld_elf_object_get_symbol(elf_object_t *this, char *target_name,
elf_hash_t target_hash,
Elf_Sym **target_symbol,
......@@ -110,7 +123,19 @@ static int eld_elf_object_get_symbol(elf_object_t *this, char *target_name,
return ERROR_SYMBOL_NOT_FOUND;
}
/**
* Look for a symbol in the specified ELF or in one of those it is
* depending on.
*
* @param this the input ELF object descriptor.
* @param name symbol name to search.
* @param hash hash of the symbol name.
* @param match [out] pointer where the matching symbol will be stored.
* @param match_elf [out] pointer to where the matching ELF symbol
* will be stored.
*
* @return zero, if success, non-zero otherwise.
*/
static int eld_elf_object_find_symbol(elf_object_t *this, char *name,
elf_hash_t hash,
Elf_Sym **match,
......@@ -183,12 +208,13 @@ int eld_elf_object_find_symbol_by_name(elf_object_t *this, char *name,
}
/**
* Relocate symbols listed in an ELF section.
*
* @param this the input ELF object descriptor.
* @param reloc_index index of the relocation section.
* @param reloc_size_index size of the relocation section.
*
* @param dynamic_info
* @param reloc_index
* @param reloc_size_index
* @param elf_offset
* @return
* @return zero, if success, non-zero otherwise.
*/
static int eld_elf_object_relocate(elf_object_t *this,
int reloc_index, int reloc_size_index) {
......@@ -278,11 +304,6 @@ static int eld_elf_object_relocate(elf_object_t *this,
return SUCCESS;
}
/**
*
* @param library
* @return
*/
int eld_elf_object_check(elf_object_t *this) {
CHECK_ARGS(this && this->file_address);
......@@ -303,14 +324,6 @@ int eld_elf_object_check(elf_object_t *this) {
return SUCCESS;
}
/**
*
* @param library OUT
* @param dynamic_info_offset OUT
* @param destination OUT
* @param elf_offset OUT
* @return
*/
int eld_elf_object_load(elf_object_t *this) {
CHECK_ARGS(this && this->file_address);
......@@ -390,15 +403,6 @@ int eld_elf_object_load(elf_object_t *this) {
return SUCCESS;
}
/**
*
* @param dynamic_info_begin
* @param elf_offset
* @param dynamic_info
* @param strtab OUT
* @param symtab OUT
* @return
*/
int eld_elf_object_handle_dyn(elf_object_t *this) {
CHECK_ARGS(this && this->dynamic_info_section);
......
......@@ -15,9 +15,23 @@
// TODO: enable some of these only in debug mode
// Proof that macros lead to bad stuffs
#define DBG_MSG(format, ...) printf("[%s:%d] " format "\n", __FILE__, __LINE__, \
##__VA_ARGS__ )
/**
* Print a debug message to the standard output.
*
* @param format format string for the debug message.
*
* @return amount of written characters.
*/
#define DBG_MSG(format, ...) printf("[%s:%d] " format "\n", __FILE__, \
__LINE__, ##__VA_ARGS__ )
/**
* Check a condition and fail with an error in case it's false.
*
* @param condition condition to check.
* @param ret value to return in case of failure.
*/
#define CHECK_ARGS_RET(condition, ret) \
do { \
if (!(condition)) { \
......@@ -26,9 +40,20 @@
} \
} while(0)
/**
* Check a condition and return ERROR_BAD_ARGS in case of failure.
*
* @param condition condition to check.
*/
#define CHECK_ARGS(condition) CHECK_ARGS_RET(condition, ERROR_BAD_ARGS)
// Using this macro leads to loss of information on the error
/**
* Check an expression, if it's different from SUCCESS return NULL.
*
* @param expression expression to check.
*
* @note Using this macro leads to loss of information on the error.
*/
#define RETURN_NULL_ON_ERROR(expression) \
do { \
if ((expression) != SUCCESS) { \
......@@ -36,6 +61,13 @@
} \
} while (0)
/**
* Check an expression, if it's different from SUCCESS perform the
* specified action.
*
* @param expression expression to check.
* @param action action to perform in case of failure.
*/
#define ON_ERROR(expression, action) \
do { \
if ((result = (expression)) != SUCCESS) { \
......@@ -47,10 +79,31 @@
if (!(expression)) return ERROR_GENERIC; \
} while(0)
// Assumes a "result" variable has been declared
/**
* Checks an expression, if it's different from SUCCESS return the
* `result` variable.
*
* @param expression expression to check.
*
* @note Assumes a "result" variable has been declared.
*/
#define RETURN_ON_ERROR(expression) ON_ERROR(expression, return result)
// Also assumes in the function there's a "fail" label
/**
* Checks an expression, if it's different from SUCCESS goto the
* `fail` label.
*
* @param expression expression to check.
*
* @note Also assumes in the function there's a "fail" label.
*/
#define FAIL_ON_ERROR(expression) ON_ERROR(expression, goto fail)
/**
* Produce a pair of its string parameter and its length.
*
* @param str a constant string.
*
* @return a string-size pair.
*/
#define STR_PAR(str) (str), (sizeof(str))
......@@ -13,12 +13,20 @@ struct {
} libs[MAX_LIBS] = {0};
unsigned int lib_count = 0;
// Simple test function to be used by test libraries
/**
* Simple test function to be used by test libraries
*
* @param value value to print in decimal to stdout.
*/
void print(int value) {
printf("%d\n", value);
}
// Reads from stdin a 4-byte little endian integer
/**
* Reads from stdin a 4-byte little endian integer
*
* @return the read integer.
*/
int read_length() {
unsigned int i = 0, result = 0;
char input = 0;
......@@ -31,6 +39,11 @@ int read_length() {
return result;
}
/**
* Loads libraries reading them from stdin.
*
* @return zero, if success, non-zero otherwise.
*/
int load_libs() {
int result = SUCCESS;
......@@ -68,6 +81,11 @@ int load_libs() {
return result;
}
/**
* Unload the previously loaded libraries.
*
* @return zero, if success, non-zero otherwise.
*/
int unload_libs() {
int result = SUCCESS;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment