-
Notifications
You must be signed in to change notification settings - Fork 0
/
dl.c
79 lines (65 loc) · 2.15 KB
/
dl.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include "support.h"
#include "eld.h"
#include "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 *PREFIX(dlsym)(void *handle, char *symbol) {
CHECK_ARGS_RET(symbol, 0);
DBG_MSG("dlsym(%p, %s)", handle, symbol);
if (handle) RETURN_NULL_ON_ERROR(eld_elf_object_is_registered(handle));
Elf_Sym *match = NULL;
elf_object_t *match_elf = NULL;
RETURN_NULL_ON_ERROR(eld_elf_object_find_symbol_by_name(handle, symbol,
&match, &match_elf));
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 *PREFIX(dlopen)(char *filename, int flag) {
DBG_MSG("dlopen(%p, %x)", filename, flag);
CHECK_ARGS_RET(filename, NULL);
// TODO: flags
mem_t *library = (unsigned char *) filename;
elf_object_t *loaded_elf = NULL;
SLIST_FOREACH(loaded_elf, &elves, next) {
if (loaded_elf->file_address == library) {
DBG_MSG("File at %p already registered as \"%s\"", filename,
loaded_elf->soname);
return NULL;
}
}
elf_object_t *library_descriptor = NULL;
RETURN_NULL_ON_ERROR(eld_open(library, &library_descriptor));
// TODO: implement dlerror
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 PREFIX(dlclose)(void *handle) {
CHECK_ARGS(handle);
int result = SUCCESS;
RETURN_ON_ERROR(eld_elf_object_is_registered(handle));
return eld_elf_object_close(handle);
}