summaryrefslogtreecommitdiff
path: root/sys/kern/link_elf_obj.c
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>2001-06-13 10:58:39 +0000
committerPeter Wemm <peter@FreeBSD.org>2001-06-13 10:58:39 +0000
commitf41325db5f16640212574a03b9a34e5ed4a884ca (patch)
tree88aef8097c80f09c2f725d61b6da4d433a595a61 /sys/kern/link_elf_obj.c
parentf3a6406c668744d1692c960352110b9b4c7ea9a6 (diff)
Notes
Diffstat (limited to 'sys/kern/link_elf_obj.c')
-rw-r--r--sys/kern/link_elf_obj.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c
index 32f45ce3ef48..da7462a86895 100644
--- a/sys/kern/link_elf_obj.c
+++ b/sys/kern/link_elf_obj.c
@@ -108,6 +108,8 @@ static int link_elf_search_symbol(linker_file_t, caddr_t value,
static void link_elf_unload_file(linker_file_t);
static void link_elf_unload_preload(linker_file_t);
+static int link_elf_lookup_set(linker_file_t, const char *,
+ void ***, void ***, int *);
static kobj_method_t link_elf_methods[] = {
KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol),
@@ -117,6 +119,7 @@ static kobj_method_t link_elf_methods[] = {
KOBJMETHOD(linker_load_file, link_elf_load_file),
KOBJMETHOD(linker_link_preload, link_elf_link_preload),
KOBJMETHOD(linker_link_preload_finish, link_elf_link_preload_finish),
+ KOBJMETHOD(linker_lookup_set, link_elf_lookup_set),
{ 0, 0 }
};
@@ -1075,3 +1078,61 @@ link_elf_search_symbol(linker_file_t lf, caddr_t value,
return 0;
}
+
+/*
+ * Look up a linker set on an ELF system.
+ */
+static int
+link_elf_lookup_set(linker_file_t lf, const char *name,
+ void ***startp, void ***stopp, int *countp)
+{
+ c_linker_sym_t sym;
+ linker_symval_t symval;
+ char *setsym;
+ void **start, **stop;
+ int len, error = 0, count;
+
+ len = strlen(name) + sizeof("__start_set_"); /* sizeof includes \0 */
+ setsym = malloc(len, M_LINKER, M_WAITOK);
+ if (setsym == NULL)
+ return ENOMEM;
+
+ /* get address of first entry */
+ snprintf(setsym, len, "%s%s", "__start_set_", name);
+ error = link_elf_lookup_symbol(lf, setsym, &sym);
+ if (error)
+ goto out;
+ link_elf_symbol_values(lf, sym, &symval);
+ if (symval.value == 0) {
+ error = ESRCH;
+ goto out;
+ }
+ start = (void **)symval.value;
+
+ /* get address of last entry */
+ snprintf(setsym, len, "%s%s", "__stop_set_", name);
+ error = link_elf_lookup_symbol(lf, setsym, &sym);
+ if (error)
+ goto out;
+ link_elf_symbol_values(lf, sym, &symval);
+ if (symval.value == 0) {
+ error = ESRCH;
+ goto out;
+ }
+ stop = (void **)symval.value;
+
+ /* and the number of entries */
+ count = stop - start;
+
+ /* and copy out */
+ if (startp)
+ *startp = start;
+ if (stopp)
+ *stopp = stop;
+ if (countp)
+ *countp = count;
+
+out:
+ free(setsym, M_LINKER);
+ return error;
+}