diff options
author | markj <markj@FreeBSD.org> | 2014-05-08 03:26:25 +0000 |
---|---|---|
committer | markj <markj@FreeBSD.org> | 2014-05-08 03:26:25 +0000 |
commit | 528a3801b3ba64d829836d203a64c19c368d9a30 (patch) | |
tree | 373ef2a2b78348de3a9ec1ee950cc9601687a852 /lib | |
parent | 24d0e4063dc442ef04be1d02ddd6ab48d888b24d (diff) | |
download | FreeBSD-src-528a3801b3ba64d829836d203a64c19c368d9a30.zip FreeBSD-src-528a3801b3ba64d829836d203a64c19c368d9a30.tar.gz |
Handle the different event types properly in rd_event_addr(). In particular,
with r265456 _r_debug_postinit can be used for RD_POSTINIT events. rtld(1)
uses r_debug_state for dl state transitions, so we use its address for
RD_DLACTIVITY events.
MFC after: 2 weeks
Diffstat (limited to 'lib')
-rw-r--r-- | lib/librtld_db/rtld_db.c | 46 | ||||
-rw-r--r-- | lib/librtld_db/rtld_db.h | 4 |
2 files changed, 40 insertions, 10 deletions
diff --git a/lib/librtld_db/rtld_db.c b/lib/librtld_db/rtld_db.c index fef8d46..2d1f6e6 100644 --- a/lib/librtld_db/rtld_db.c +++ b/lib/librtld_db/rtld_db.c @@ -81,20 +81,40 @@ rd_errstr(rd_err_e rderr) } rd_err_e -rd_event_addr(rd_agent_t *rdap, rd_event_e event __unused, rd_notify_t *notify) +rd_event_addr(rd_agent_t *rdap, rd_event_e event, rd_notify_t *notify) { - DPRINTF("%s rdap %p notify %p\n", __func__, rdap, notify); - - notify->type = RD_NOTIFY_BPT; - notify->u.bptaddr = rdap->rda_addr; - - return (RD_OK); + rd_err_e ret; + + DPRINTF("%s rdap %p event %d notify %p\n", __func__, rdap, event, + notify); + + ret = RD_OK; + switch (event) { + case RD_NONE: + break; + case RD_PREINIT: + notify->type = RD_NOTIFY_BPT; + notify->u.bptaddr = rdap->rda_preinit_addr; + break; + case RD_POSTINIT: + notify->type = RD_NOTIFY_BPT; + notify->u.bptaddr = rdap->rda_postinit_addr; + break; + case RD_DLACTIVITY: + notify->type = RD_NOTIFY_BPT; + notify->u.bptaddr = rdap->rda_dlactivity_addr; + break; + default: + ret = RD_ERR; + break; + } + return (ret); } rd_err_e rd_event_enable(rd_agent_t *rdap __unused, int onoff) { - DPRINTF("%s onoff %d\n", __func__, onoff); + DPRINTF("%s onoff %d\n", __func__, onoff); return (RD_OK); } @@ -220,7 +240,15 @@ rd_reset(rd_agent_t *rdap) &sym) < 0) return (RD_ERR); DPRINTF("found r_debug_state at 0x%lx\n", (unsigned long)sym.st_value); - rdap->rda_addr = sym.st_value; + rdap->rda_preinit_addr = sym.st_value; + rdap->rda_dlactivity_addr = sym.st_value; + + if (proc_name2sym(rdap->rda_php, "ld-elf.so.1", "_r_debug_postinit", + &sym) < 0) + return (RD_ERR); + DPRINTF("found _r_debug_postinit at 0x%lx\n", + (unsigned long)sym.st_value); + rdap->rda_postinit_addr = sym.st_value; return (RD_OK); } diff --git a/lib/librtld_db/rtld_db.h b/lib/librtld_db/rtld_db.h index 33da4d3..9dd53f0 100644 --- a/lib/librtld_db/rtld_db.h +++ b/lib/librtld_db/rtld_db.h @@ -51,7 +51,9 @@ typedef enum { typedef struct rd_agent { struct proc_handle *rda_php; - uintptr_t rda_addr; /* address of r_debug_state */ + uintptr_t rda_dlactivity_addr; + uintptr_t rda_preinit_addr; + uintptr_t rda_postinit_addr; } rd_agent_t; typedef struct rd_loadobj { |