void proc_add_library(struct Process *proc, struct library *lib) { assert(lib->next == NULL); lib->next = proc->libraries; proc->libraries = lib; debug(DEBUG_PROCESS, "added library %s@%p (%s) to %d", lib->soname, lib->base, lib->pathname, proc->pid); /* Insert breakpoints for all active (non-latent) symbols. */ struct library_symbol *libsym = NULL; while ((libsym = library_each_symbol(lib, libsym, cb_breakpoint_for_symbol, proc)) != NULL) fprintf(stderr, "Couldn't insert breakpoint for %s to %d: %s.", libsym->name, proc->pid, strerror(errno)); /* Look through export list of the new library and compare it * with latent symbols of all libraries (including this * library itself). */ struct library *lib2 = NULL; while ((lib2 = proc_each_library(proc, lib2, activate_latent_in, lib->exported_names)) != NULL) fprintf(stderr, "Couldn't activate latent symbols for %s in %d: %s.", libsym->name, proc->pid, strerror(errno)); }
int proc_find_symbol(struct Process *proc, struct library_symbol *sym, struct library **retlib, struct library_symbol **retsym) { struct library *lib = sym->lib; assert(lib != NULL); struct library *flib = proc_each_library(proc, NULL, library_with_key_cb, &lib->key); if (flib == NULL) return -1; struct library_symbol *fsym = library_each_symbol(flib, NULL, library_symbol_named_cb, (char *)sym->name); if (fsym == NULL) return -1; if (retlib != NULL) *retlib = flib; if (retsym != NULL) *retsym = fsym; return 0; }
static struct prototype * lookup_symbol_prototype(struct process *proc, struct library_symbol *libsym) { if (libsym->proto != NULL) return libsym->proto; struct library *lib = libsym->lib; if (lib != NULL) { struct find_proto_data data = { libsym->name }; data.ret = library_get_prototype(lib, libsym->name); if (data.ret == NULL && libsym->plt_type == LS_TOPLT_EXEC) proc_each_library(proc, NULL, find_proto_cb, &data); if (data.ret != NULL) return data.ret; } return build_default_prototype(); }
void arch_dynlink_done(struct Process *proc) { proc_each_library(proc->leader, NULL, cb_enable_breakpoint_lib, NULL); }
static void crawl_linkmap(struct Process *proc, struct lt_r_debug_64 *dbg) { debug (DEBUG_FUNCTION, "crawl_linkmap()"); if (!dbg || !dbg->r_map) { debug(2, "Debug structure or it's linkmap are NULL!"); return; } /* XXX The double cast should be removed when * arch_addr_t becomes integral type. */ arch_addr_t addr = (arch_addr_t)(uintptr_t)dbg->r_map; while (addr != 0) { struct lt_link_map_64 rlm = {}; if (lm_fetcher(proc)(proc, addr, &rlm) < 0) { debug(2, "Unable to read link map"); return; } arch_addr_t key = addr; /* XXX The double cast should be removed when * arch_addr_t becomes integral type. */ addr = (arch_addr_t)(uintptr_t)rlm.l_next; if (rlm.l_name == 0) { debug(2, "Name of mapped library is NULL"); return; } char lib_name[BUFSIZ]; /* XXX The double cast should be removed when * arch_addr_t becomes integral type. */ umovebytes(proc, (arch_addr_t)(uintptr_t)rlm.l_name, lib_name, sizeof(lib_name)); /* Library name can be an empty string, in which case * the entry represents either the main binary, or a * VDSO. Unfortunately we can't rely on that, as in * recent glibc, that entry is initialized to VDSO * SONAME. * * It's not clear how to detect VDSO in this case. We * can't assume that l_name of real DSOs will be * either absolute or relative (for LD_LIBRARY_PATH=: * it will be neither). We can't compare l_addr with * AT_SYSINFO_EHDR either, as l_addr is bias (which * also means it's not unique, and therefore useless * for this). We could load VDSO from process image * and at least compare actual SONAMEs. For now, this * kludge is about the best that we can do. */ if (*lib_name == 0 || strcmp(lib_name, "linux-vdso.so.1") == 0 || strcmp(lib_name, "linux-gate.so.1") == 0 || strcmp(lib_name, "linux-vdso32.so.1") == 0 || strcmp(lib_name, "linux-vdso64.so.1") == 0) continue; /* Do we have that library already? */ if (proc_each_library(proc, NULL, library_with_key_cb, &key)) continue; struct library *lib = malloc(sizeof(*lib)); if (lib == NULL) { fail: if (lib != NULL) library_destroy(lib); fprintf(stderr, "Couldn't load ELF object %s: %s\n", lib_name, strerror(errno)); continue; } library_init(lib, LT_LIBTYPE_DSO); if (ltelf_read_library(lib, proc, lib_name, rlm.l_addr) < 0) goto fail; lib->key = key; proc_add_library(proc, lib); } return; }