Example #1
0
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));
}
Example #2
0
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;
}
Example #3
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();
}
Example #4
0
void arch_dynlink_done(struct Process *proc)
{
	proc_each_library(proc->leader, NULL, cb_enable_breakpoint_lib, NULL);
}
Example #5
0
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;
}