summaryrefslogtreecommitdiffstats
path: root/lib/librtld_db
diff options
context:
space:
mode:
authormarkj <markj@FreeBSD.org>2014-08-08 14:53:01 +0000
committermarkj <markj@FreeBSD.org>2014-08-08 14:53:01 +0000
commit104ac38f1460820d67f63fd4e02d262275343491 (patch)
tree96e0030461156ee6b7872ae3a4af8a0e58bece20 /lib/librtld_db
parentcbab32ad75d301ca36f59879d25b708ea241d7d9 (diff)
downloadFreeBSD-src-104ac38f1460820d67f63fd4e02d262275343491.zip
FreeBSD-src-104ac38f1460820d67f63fd4e02d262275343491.tar.gz
MFC r265629, r265630
MFC r265629: 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 r265630: Fix the rd_event_addr prototype and slightly clarify the use of the "event" parameter.
Diffstat (limited to 'lib/librtld_db')
-rw-r--r--lib/librtld_db/librtld_db.36
-rw-r--r--lib/librtld_db/rtld_db.c46
-rw-r--r--lib/librtld_db/rtld_db.h4
3 files changed, 43 insertions, 13 deletions
diff --git a/lib/librtld_db/librtld_db.3 b/lib/librtld_db/librtld_db.3
index 0c9a762..4645142 100644
--- a/lib/librtld_db/librtld_db.3
+++ b/lib/librtld_db/librtld_db.3
@@ -48,7 +48,7 @@
.Fc
.Ft rd_err_e
.Fo rd_event_addr
-.Fa "rd_agent_t *rdap, rd_notify_t *notify"
+.Fa "rd_agent_t *rdap, rd_event_e event, rd_notify_t *notify"
.Fc
.Ft rd_err_e
.Fo rd_event_enable
@@ -142,10 +142,10 @@ enables reporting of events.
This function always returns RD_OK.
.Pp
.Fn rd_event_addr
-returns the event address in the
+returns the event address corresponding to the
.Ft event
parameter.
-At the moment we only report RD_NOTIFY_BPT events.
+At the moment we only report events of type RD_NOTIFY_BPT.
.Pp
.Fn rd_event_getmsg
returns the message associated with the latest event.
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 {
OpenPOWER on IntegriCloud