/* * 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 = kmalloc(len, M_LINKER, M_WAITOK); /* get address of first entry */ ksnprintf(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 == NULL) { error = ESRCH; goto out; } start = (void **)symval.value; /* get address of last entry */ ksnprintf(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 == NULL) { 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: kfree(setsym, M_LINKER); return error; }
static int link_elf_each_function_nameval(linker_file_t file, linker_function_nameval_callback_t callback, void *opaque) { linker_symval_t symval; elf_file_t ef = (elf_file_t)file; const Elf_Sym* symp; int i, error; /* Exhaustive search */ for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { if (symp->st_value != 0 && ELF_ST_TYPE(symp->st_info) == STT_FUNC) { error = link_elf_symbol_values(file, (c_linker_sym_t) symp, &symval); if (error) return (error); error = callback(file, i, &symval, opaque); if (error) return (error); } } return (0); }