int linkmap_init(Process *proc, struct ltelf *lte) { void *dbg_addr = NULL, *dyn_addr = GELF_ADDR_CAST(lte->dyn_addr); struct r_debug *rdbg = NULL; struct cb_data data; debug(DEBUG_FUNCTION, "linkmap_init()"); if (find_dynamic_entry_addr(proc, dyn_addr, DT_DEBUG, &dbg_addr) == -1) { debug(2, "Couldn't find debug structure!"); return -1; } proc->debug = dbg_addr; if (!(rdbg = load_debug_struct(proc))) { debug(2, "No debug structure or no memory to allocate one!"); return -1; } data.lte = lte; add_library_symbol(rdbg->r_brk, "", &library_symbols, LS_TOPLT_NONE, 0); insert_breakpoint(proc, sym2addr(proc, library_symbols), library_symbols, 1); crawl_linkmap(proc, rdbg, hook_libdl_cb, &data); free(rdbg); return 0; }
int linkmap_init(struct Process *proc, arch_addr_t dyn_addr) { debug(DEBUG_FUNCTION, "linkmap_init(%d, dyn_addr=%p)", proc->pid, dyn_addr); if (arch_find_dl_debug(proc, dyn_addr, &proc->os.debug_addr) == -1) { debug(2, "Couldn't find debug structure!"); return -1; } int status; struct lt_r_debug_64 rdbg; if ((status = load_debug_struct(proc, &rdbg)) < 0) { debug(2, "No debug structure or no memory to allocate one!"); return status; } /* XXX The double cast should be removed when * arch_addr_t becomes integral type. */ arch_addr_t addr = (arch_addr_t)(uintptr_t)rdbg.r_brk; if (arch_translate_address_dyn(proc, addr, &addr) < 0) return -1; struct breakpoint *rdebug_bp = insert_breakpoint(proc, addr, NULL); static struct bp_callbacks rdebug_callbacks = { .on_hit = rdebug_bp_on_hit, }; rdebug_bp->cbs = &rdebug_callbacks; crawl_linkmap(proc, &rdbg); return 0; }
void arch_check_dbg(Process *proc) { struct r_debug *dbg = NULL; struct cb_data data; debug(DEBUG_FUNCTION, "arch_check_dbg"); if (!(dbg = load_debug_struct(proc))) { debug(2, "Unable to load debug structure!"); return; } if (dbg->r_state == RT_CONSISTENT) { debug(2, "Linkmap is now consistent"); if (proc->debug_state == RT_ADD) { debug(2, "Adding DSO to linkmap"); data.proc = proc; crawl_linkmap(proc, dbg, linkmap_add_cb, &data); } else if (proc->debug_state == RT_DELETE) { debug(2, "Removing DSO from linkmap"); } else { debug(2, "Unexpected debug state!"); } } proc->debug_state = dbg->r_state; return; }
static void rdebug_bp_on_hit(struct breakpoint *bp, struct Process *proc) { debug(DEBUG_FUNCTION, "arch_check_dbg"); struct lt_r_debug_64 rdbg; if (load_debug_struct(proc, &rdbg) < 0) { debug(2, "Unable to load debug structure!"); return; } if (rdbg.r_state == RT_CONSISTENT) { debug(2, "Linkmap is now consistent"); switch (proc->os.debug_state) { case RT_ADD: debug(2, "Adding DSO to linkmap"); crawl_linkmap(proc, &rdbg); break; case RT_DELETE: debug(2, "Removing DSO from linkmap"); // XXX unload that library break; default: debug(2, "Unexpected debug state!"); } } proc->os.debug_state = rdbg.r_state; }