xref: /netbsd-src/external/bsd/libproc/dist/proc_rtld.c (revision 52ebe1c2c4d4a306e5aa34057375d60716bcd6e9)
1fbcd1dd1Schristos /*
2fbcd1dd1Schristos  * Copyright (c) 2010 The FreeBSD Foundation
3fbcd1dd1Schristos  * All rights reserved.
4fbcd1dd1Schristos  *
5fbcd1dd1Schristos  * This software was developed by Rui Paulo under sponsorship from the
6fbcd1dd1Schristos  * FreeBSD Foundation.
7fbcd1dd1Schristos  *
8fbcd1dd1Schristos  * Redistribution and use in source and binary forms, with or without
9fbcd1dd1Schristos  * modification, are permitted provided that the following conditions
10fbcd1dd1Schristos  * are met:
11fbcd1dd1Schristos  * 1. Redistributions of source code must retain the above copyright
12fbcd1dd1Schristos  *    notice, this list of conditions and the following disclaimer.
13fbcd1dd1Schristos  * 2. Redistributions in binary form must reproduce the above copyright
14fbcd1dd1Schristos  *    notice, this list of conditions and the following disclaimer in the
15fbcd1dd1Schristos  *    documentation and/or other materials provided with the distribution.
16fbcd1dd1Schristos  *
17fbcd1dd1Schristos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18fbcd1dd1Schristos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19fbcd1dd1Schristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20fbcd1dd1Schristos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21fbcd1dd1Schristos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22fbcd1dd1Schristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23fbcd1dd1Schristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24fbcd1dd1Schristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25fbcd1dd1Schristos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26fbcd1dd1Schristos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27fbcd1dd1Schristos  * SUCH DAMAGE.
28fbcd1dd1Schristos  */
29fbcd1dd1Schristos 
30fbcd1dd1Schristos #include <sys/cdefs.h>
31*52ebe1c2Schristos #ifdef __FBSDID
32fbcd1dd1Schristos __FBSDID("$FreeBSD: head/lib/libproc/proc_rtld.c 265255 2014-05-03 04:44:03Z markj $");
33*52ebe1c2Schristos #else
34*52ebe1c2Schristos __RCSID("$NetBSD: proc_rtld.c,v 1.2 2015/09/24 14:12:48 christos Exp $");
35*52ebe1c2Schristos #endif
36fbcd1dd1Schristos 
37fbcd1dd1Schristos #include <stdio.h>
38fbcd1dd1Schristos #include <string.h>
39fbcd1dd1Schristos #include <stdlib.h>
40fbcd1dd1Schristos #include <rtld_db.h>
41fbcd1dd1Schristos #include "libproc.h"
42fbcd1dd1Schristos #include "_libproc.h"
43fbcd1dd1Schristos 
44fbcd1dd1Schristos static int
map_iter(const rd_loadobj_t * lop,void * arg)45fbcd1dd1Schristos map_iter(const rd_loadobj_t *lop, void *arg)
46fbcd1dd1Schristos {
47fbcd1dd1Schristos 	struct proc_handle *phdl = arg;
48fbcd1dd1Schristos 
49fbcd1dd1Schristos 	if (phdl->nobjs >= phdl->rdobjsz) {
50fbcd1dd1Schristos 		phdl->rdobjsz *= 2;
51*52ebe1c2Schristos 		if (reallocarr(&phdl->rdobjs, sizeof(*phdl->rdobjs),
52*52ebe1c2Schristos 		    phdl->rdobjsz))
53fbcd1dd1Schristos 			return (-1);
54fbcd1dd1Schristos 	}
55fbcd1dd1Schristos 	if (strcmp(lop->rdl_path, phdl->execname) == 0 &&
56fbcd1dd1Schristos 	    (lop->rdl_prot & RD_RDL_X) != 0)
57fbcd1dd1Schristos 		phdl->rdexec = &phdl->rdobjs[phdl->nobjs];
58fbcd1dd1Schristos 	memcpy(&phdl->rdobjs[phdl->nobjs++], lop, sizeof(*lop));
59fbcd1dd1Schristos 
60fbcd1dd1Schristos 	return (0);
61fbcd1dd1Schristos }
62fbcd1dd1Schristos 
63fbcd1dd1Schristos rd_agent_t *
proc_rdagent(struct proc_handle * phdl)64fbcd1dd1Schristos proc_rdagent(struct proc_handle *phdl)
65fbcd1dd1Schristos {
66fbcd1dd1Schristos 	if (phdl->rdap == NULL && phdl->status != PS_UNDEAD &&
67fbcd1dd1Schristos 	    phdl->status != PS_IDLE) {
68fbcd1dd1Schristos 		if ((phdl->rdap = rd_new(phdl)) != NULL) {
69fbcd1dd1Schristos 			phdl->rdobjs = malloc(sizeof(*phdl->rdobjs) * 64);
70fbcd1dd1Schristos 			phdl->rdobjsz = 64;
71fbcd1dd1Schristos 			if (phdl->rdobjs == NULL)
72fbcd1dd1Schristos 				return (phdl->rdap);
73fbcd1dd1Schristos 			rd_loadobj_iter(phdl->rdap, map_iter, phdl);
74fbcd1dd1Schristos 		}
75fbcd1dd1Schristos 	}
76fbcd1dd1Schristos 
77fbcd1dd1Schristos 	return (phdl->rdap);
78fbcd1dd1Schristos }
79fbcd1dd1Schristos 
80fbcd1dd1Schristos void
proc_updatesyms(struct proc_handle * phdl)81fbcd1dd1Schristos proc_updatesyms(struct proc_handle *phdl)
82fbcd1dd1Schristos {
83fbcd1dd1Schristos 
84fbcd1dd1Schristos 	memset(phdl->rdobjs, 0, sizeof(*phdl->rdobjs) * phdl->rdobjsz);
85fbcd1dd1Schristos 	phdl->nobjs = 0;
86fbcd1dd1Schristos 	rd_loadobj_iter(phdl->rdap, map_iter, phdl);
87fbcd1dd1Schristos }
88