Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 31 Jul 2010 14:26:10 +0000 (UTC)
From:      Rui Paulo <rpaulo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r210678 - head/lib/librtld_db
Message-ID:  <201007311426.o6VEQAMj004497@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rpaulo
Date: Sat Jul 31 14:26:10 2010
New Revision: 210678
URL: http://svn.freebsd.org/changeset/base/210678

Log:
  Import the librtld_db library. This is needed by userland DTrace.
  This is not yet enabled in the build because I also need to import a new
  version of libproc.
  
  Sponsored by:	The FreeBSD Foundation

Added:
  head/lib/librtld_db/
  head/lib/librtld_db/Makefile   (contents, props changed)
  head/lib/librtld_db/librtld_db.3   (contents, props changed)
  head/lib/librtld_db/rtld_db.c   (contents, props changed)
  head/lib/librtld_db/rtld_db.h   (contents, props changed)

Added: head/lib/librtld_db/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/librtld_db/Makefile	Sat Jul 31 14:26:10 2010	(r210678)
@@ -0,0 +1,14 @@
+# $FreeBSD$
+
+.include <bsd.own.mk>
+
+LIB=		rtld_db
+SHLIB_MAJOR= 	1
+MAN=		librtld_db.3
+
+SRCS=		rtld_db.c
+INCS=		rtld_db.h
+
+CFLAGS+= -I${.CURDIR}
+
+.include <bsd.lib.mk>

Added: head/lib/librtld_db/librtld_db.3
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/librtld_db/librtld_db.3	Sat Jul 31 14:26:10 2010	(r210678)
@@ -0,0 +1,191 @@
+.\"-
+.\" Copyright (c) 2010 The FreeBSD Foundation
+.\" All rights reserved.
+.\"
+.\" This software was developed by Rui Paulo under sponsorship from
+.\" the FreeBSD Foundation.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd June 10, 2010
+.Dt LIBRTLD_DB 3
+.Os
+.Sh NAME
+.Nm librtld_db
+.Nd library for run-time linker debugging
+.Sh LIBRARY
+.Lb librtld_db
+.Sh SYNOPSIS
+.In rtld_db.h
+.Ft void
+.Fo rd_delete
+.Fa "rd_agent_t *rdap"
+.Fc
+.Ft char *
+.Fo rd_errstr
+.Fa "rd_err_e rderr" 
+.Fc
+.Ft rd_err_e
+.Fo rd_event_addr
+.Fa "rd_agent_t *rdap, rd_notify_t *notify"
+.Fc
+.Ft rd_err_e
+.Fo rd_event_enable
+.Fa "rd_agent_t *rdap, int onoff"
+.Fc
+.Ft rd_err_e
+.Fo rd_event_getmsg
+.Fa "rd_agent_t *rdap, rd_event_msg_t *msg"
+.Fc
+.Ft rd_err_e
+.Fo rd_init
+.Fa "int version"
+.Fc
+.Ft typedef int
+.Fo rl_iter_f
+.Fa "const rd_loadobj_t *, void *"
+.Fc
+.Ft rd_err_e
+.Fo rd_loadobj_iter
+.Fa "rd_agent_t *rdap, rl_iter_f *cb, void *clnt_data"
+.Fc
+.Ft void
+.Fo rd_log
+.Fa "const int onoff"
+.Fc
+.Ft rd_agent_t *
+.Fo rd_new
+.Fa "struct proc_handle *php"
+.Fc
+.Ft rd_err_e
+.Fo rd_objpad_enable
+.Fa "rd_agent_t *rdap, size_t padsize"
+.Fc
+.Ft rd_err_e
+.Fo rd_plt_resolution
+.Fa "rd_agent_t *rdap, uintptr_t pc, struct proc *proc
+.Fa  "uintptr_t plt_base, rd_plt_info_t *rpi"
+.Fc
+.Ft rd_err_e
+.Fo rd_reset
+.Fa "rd_agent_t *rdap"
+.Fc
+.Sh DESCRIPTION
+The
+.Nm librtld_db
+library provides a debugging interface to the run-time linker (rtld).
+This library must be used along with
+.Xr libproc 3 .
+.Pp
+Most library functions take a
+.Ft rd_agent_t
+argument.
+This argument is an opaque structure containing information associated with 
+the current status of the agent.
+.Pp
+Before you start using
+.Nm
+you should call
+.Fn rd_init
+with the
+.Ft RD_VERSION
+argument.
+This initializes the library to the correct version your program was compiled
+with and provides proper ABI stability.
+.Pp
+What follows is a description of what each function.
+.Pp
+.Fn rd_new
+creates a new
+.Nm
+agent.
+The
+.Ft php
+argument should be the
+.Ft proc_handle
+you received from
+.Xr libproc 3 .
+.Pp
+.Fn rd_reset
+resets your previously created agent.
+.Pp
+.Fn rd_delete
+dealocates the resources associated with the agent.
+.Pp
+.Fn rd_errstr
+returns an error string describing the error present in
+.Ft rderr .
+.Pp
+.Fn rd_event_enable
+enables reporting of events.
+This function always returns RD_OK.
+.Pp
+.Fn rd_event_addr
+returns the event address in the
+.Ft event
+paramenter.
+At the moment we only report RD_NOTIFY_BPT events.
+.Pp
+.Fn rd_event_getmsg
+returns the message assoicated wit hthe latest event.
+At the moment only RD_POSTINIT events are supported.
+.Pp
+.Fn rd_loadobj_iter
+allows you to iterate over the program's loaded objects.
+.Ft cb
+is a callback of type
+.Fn rl_iter_f .
+.Sh RETURN VALUES
+Most functions return an
+.Ft rd_err_e
+type error.
+The error codes are described in the header file for this library.
+You can get the error string using
+.Fn rd_errstr .
+.Sh CAVEATS
+The functions
+.Fn rd_event_enable ,
+.Fn rd_log ,
+.Fn rd_objpad_enable
+and
+.Fn rd_plt_resolution
+are not yet implemented.
+.Sh SEE ALSO
+.Xr ld 1 ,
+.Xr ld-elf.so.1 1 ,
+.Xr ld.so 1 ,
+.Xr libproc 3 ,
+.Xr rtld 1
+.Sh HISTORY
+The
+.Nm librtld_db 
+library first appeared in
+.Fx 9.0 
+and was modeled after the same library present in the Solaris operating system.
+.Sh AUTHORS
+The
+.Nm librtld_db
+library and this manual page were written by
+.An Rui Paulo Aq rpaulo@FreeBSD.org 
+under sponsorship from the FreeBSD Foundation.

Added: head/lib/librtld_db/rtld_db.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/librtld_db/rtld_db.c	Sat Jul 31 14:26:10 2010	(r210678)
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2010 The FreeBSD Foundation 
+ * All rights reserved. 
+ * 
+ * This software was developed by Rui Paulo under sponsorship from the
+ * FreeBSD Foundation. 
+ *  
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */ 
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <machine/_inttypes.h>
+#include <sys/types.h>
+#include <sys/user.h>
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <libproc.h>
+#include <libutil.h>
+
+#include "rtld_db.h"
+
+static int _librtld_db_debug = 0;
+#define DPRINTF(...) do {				\
+	if (_librtld_db_debug) {			\
+		fprintf(stderr, "librtld_db: DEBUG: ");	\
+		fprintf(stderr, __VA_ARGS__);		\
+	}						\
+} while (0)
+
+void
+rd_delete(rd_agent_t *rdap)
+{
+
+	free(rdap);
+}
+
+const char *
+rd_errstr(rd_err_e rderr)
+{
+
+	switch (rderr) {
+	case RD_ERR:
+		return "generic error";
+	case RD_OK:
+		return "no error";
+	case RD_NOCAPAB:
+		return "capability not supported";
+	case RD_DBERR:
+		return "database error";
+	case RD_NOBASE:
+		return "NOBASE";
+	case RD_NOMAPS:
+		return "NOMAPS";
+	default:
+		return "unknown error";
+	}
+}
+
+rd_err_e
+rd_event_addr(rd_agent_t *rdap, rd_event_e event __unused, 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
+rd_event_enable(rd_agent_t *rdap __unused, int onoff)
+{
+	DPRINTF("%s onoff %d\n", __func__, onoff);	
+
+	return (RD_OK);
+}
+
+rd_err_e
+rd_event_getmsg(rd_agent_t *rdap __unused, rd_event_msg_t *msg)
+{
+	DPRINTF("%s\n", __func__);
+
+	msg->type = RD_POSTINIT;
+	msg->u.state = RD_CONSISTENT;
+
+	return (RD_OK);
+}
+
+rd_err_e
+rd_init(int version)
+{
+	char *debug = NULL;
+
+	if (version == RD_VERSION) {
+		debug = getenv("LIBRTLD_DB_DEBUG");
+		_librtld_db_debug = debug ? atoi(debug) : 0;
+		return (RD_OK);
+	} else
+		return (RD_NOCAPAB);
+}
+
+rd_err_e
+rd_loadobj_iter(rd_agent_t *rdap, rl_iter_f *cb, void *clnt_data)
+{
+	int cnt, i, lastvn = 0;
+	rd_loadobj_t rdl;
+	struct kinfo_vmentry *kves, *kve;
+
+	DPRINTF("%s\n", __func__);
+
+        if ((kves = kinfo_getvmmap(proc_getpid(rdap->rda_php), &cnt)) == NULL) {
+		warn("ERROR: kinfo_getvmmap() failed");
+		return (RD_ERR);
+	}
+	for (i = 0; i < cnt; i++) {
+		kve = kves + i;
+		if (kve->kve_type == KVME_TYPE_VNODE)
+			lastvn = i;
+		memset(&rdl, 0, sizeof(rdl));
+		/*
+		 * Map the kinfo_vmentry struct to the rd_loadobj structure.
+		 */
+		rdl.rdl_saddr = kve->kve_start;
+		rdl.rdl_eaddr = kve->kve_end;
+		rdl.rdl_offset = kve->kve_offset;
+		if (kve->kve_protection & KVME_PROT_READ)
+			rdl.rdl_prot |= RD_RDL_R;
+		if (kve->kve_protection & KVME_PROT_WRITE)
+			rdl.rdl_prot |= RD_RDL_W;
+		if (kve->kve_protection & KVME_PROT_EXEC)
+			rdl.rdl_prot |= RD_RDL_X;
+		strlcpy(rdl.rdl_path, kves[lastvn].kve_path,
+			sizeof(rdl.rdl_path));
+		(*cb)(&rdl, clnt_data);
+	}
+	free(kves);
+
+	return (RD_OK);
+}
+
+void
+rd_log(const int onoff)
+{
+	DPRINTF("%s\n", __func__);
+
+	(void)onoff;
+}
+
+rd_agent_t *
+rd_new(struct proc_handle *php)
+{
+	rd_agent_t *rdap;
+
+	rdap = malloc(sizeof(rd_agent_t));
+	if (rdap) {
+		memset(rdap, 0, sizeof(rd_agent_t));
+		rdap->rda_php = php;
+		rd_reset(rdap);
+	}
+
+	return (rdap);
+}
+
+rd_err_e
+rd_objpad_enable(rd_agent_t *rdap, size_t padsize)
+{
+	DPRINTF("%s\n", __func__);
+
+	(void)rdap;
+	(void)padsize;
+
+	return (RD_ERR);
+}
+
+rd_err_e
+rd_plt_resolution(rd_agent_t *rdap, uintptr_t pc, struct proc *proc,
+    uintptr_t plt_base, rd_plt_info_t *rpi)
+{
+	DPRINTF("%s\n", __func__);
+
+	(void)rdap;
+	(void)pc;
+	(void)proc;
+	(void)plt_base;
+	(void)rpi;
+
+	return (RD_ERR);
+}
+
+rd_err_e
+rd_reset(rd_agent_t *rdap)
+{
+	GElf_Sym sym;
+
+	if (proc_name2sym(rdap->rda_php, "ld-elf.so.1", "r_debug_state",
+	    &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;
+
+	return (RD_OK);
+}

Added: head/lib/librtld_db/rtld_db.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/librtld_db/rtld_db.h	Sat Jul 31 14:26:10 2010	(r210678)
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2010 The FreeBSD Foundation 
+ * All rights reserved. 
+ * 
+ * This software was developed by Rui Paulo under sponsorship from the
+ * FreeBSD Foundation. 
+ *  
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ *
+ * $FreeBSD$
+ */ 
+
+#ifndef _RTLD_DB_H_
+#define _RTLD_DB_H_
+
+#include <sys/param.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+
+#define	RD_VERSION	1
+
+typedef enum {
+	RD_OK,
+	RD_ERR,
+	RD_DBERR,
+	RD_NOCAPAB,
+	RD_NODYNAM,
+	RD_NOBASE,
+	RD_NOMAPS
+} rd_err_e;
+
+typedef struct rd_agent {
+	struct proc_handle *rda_php;
+	uintptr_t rda_addr;		/* address of r_debug_state */
+} rd_agent_t;
+
+typedef struct rd_loadobj {
+	uintptr_t	rdl_saddr;		/* start address */
+	uintptr_t	rdl_eaddr;		/* end address */
+	uint32_t	rdl_offset;
+	uint8_t		rdl_prot;
+#define RD_RDL_R	0x01
+#define RD_RDL_W	0x02
+#define RD_RDL_X	0x04
+	enum {
+		RDL_TYPE_NONE	= 0,
+		RDL_TYPE_DEF,
+		RDL_TYPE_VNODE,
+		RDL_TYPE_SWAP,
+		RDL_TYPE_DEV,
+		/* XXX some types missing */
+		RDL_TYPE_UNKNOWN = 255
+	} rdl_type;
+	unsigned char	rdl_path[PATH_MAX];
+} rd_loadobj_t;
+
+typedef enum {
+	RD_NONE = 0,
+	RD_PREINIT,
+	RD_POSTINIT,
+	RD_DLACTIVITY
+} rd_event_e;
+
+typedef enum {
+	RD_NOTIFY_BPT,
+	RD_NOTIFY_AUTOBPT,
+	RD_NOTIFY_SYSCALL
+} rd_notify_e;
+
+typedef struct rd_notify {
+	rd_notify_e type;
+	union {
+		uintptr_t bptaddr;
+		long      syscallno;
+	} u;
+} rd_notify_t;
+
+typedef enum {
+	RD_NOSTATE = 0,
+	RD_CONSISTENT,
+	RD_ADD,
+	RD_DELETE
+} rd_state_e;
+
+typedef struct rd_event_msg {
+	rd_event_e type;
+	union {
+		rd_state_e state;
+	} u;
+} rd_event_msg_t;
+
+typedef enum {
+	RD_RESOLVE_NONE,
+	RD_RESOLVE_STEP,
+	RD_RESOLVE_TARGET,
+	RD_RESOLVE_TARGET_STEP
+} rd_skip_e;
+
+typedef struct rd_plt_info {
+	rd_skip_e pi_skip_method;
+	long	  pi_nstep;
+	uintptr_t pi_target;
+	uintptr_t pi_baddr;
+	unsigned int pi_flags;
+} rd_plt_info_t;
+
+#define RD_FLG_PI_PLTBOUND	0x0001
+
+__BEGIN_DECLS
+
+struct proc_handle;
+void		rd_delete(rd_agent_t *);
+const char 	*rd_errstr(rd_err_e);
+rd_err_e	rd_event_addr(rd_agent_t *, rd_event_e, rd_notify_t *);
+rd_err_e	rd_event_enable(rd_agent_t *, int);
+rd_err_e	rd_event_getmsg(rd_agent_t *, rd_event_msg_t *);
+rd_err_e	rd_init(int);
+typedef int rl_iter_f(const rd_loadobj_t *, void *);
+rd_err_e	rd_loadobj_iter(rd_agent_t *, rl_iter_f *, void *);
+void		rd_log(const int);
+rd_agent_t 	*rd_new(struct proc_handle *);
+rd_err_e	rd_objpad_enable(rd_agent_t *, size_t);
+struct proc;
+rd_err_e	rd_plt_resolution(rd_agent_t *, uintptr_t, struct proc *,
+		    uintptr_t, rd_plt_info_t *);
+rd_err_e	rd_reset(rd_agent_t *);
+
+__END_DECLS
+
+#endif /* _RTLD_DB_H_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201007311426.o6VEQAMj004497>