1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2010 The FreeBSD Foundation 5 * 6 * This software was developed by Rui Paulo under sponsorship from the 7 * FreeBSD Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <string.h> 35 36 #include <rtld_db.h> 37 38 #include "_libproc.h" 39 40 static void rdl2prmap(const rd_loadobj_t *, prmap_t *); 41 42 static int 43 map_iter(const rd_loadobj_t *lop, void *arg) 44 { 45 struct file_info *file; 46 struct map_info *mapping, *tmp; 47 struct proc_handle *phdl; 48 size_t i; 49 50 phdl = arg; 51 if (phdl->nmappings >= phdl->maparrsz) { 52 phdl->maparrsz *= 2; 53 tmp = reallocarray(phdl->mappings, phdl->maparrsz, 54 sizeof(*phdl->mappings)); 55 if (tmp == NULL) 56 return (-1); 57 phdl->mappings = tmp; 58 } 59 60 mapping = &phdl->mappings[phdl->nmappings]; 61 rdl2prmap(lop, &mapping->map); 62 if (strcmp(lop->rdl_path, phdl->execpath) == 0 && 63 (lop->rdl_prot & RD_RDL_X) != 0) 64 phdl->exec_map = phdl->nmappings; 65 66 file = NULL; 67 if (lop->rdl_path[0] != '\0') { 68 /* Look for an existing mapping of the same file. */ 69 for (i = 0; i < phdl->nmappings; i++) 70 if (strcmp(mapping->map.pr_mapname, 71 phdl->mappings[i].map.pr_mapname) == 0) { 72 file = phdl->mappings[i].file; 73 break; 74 } 75 76 if (file == NULL) { 77 file = malloc(sizeof(*file)); 78 if (file == NULL) 79 return (-1); 80 file->elf = NULL; 81 file->fd = -1; 82 file->refs = 1; 83 } else 84 file->refs++; 85 } 86 mapping->file = file; 87 phdl->nmappings++; 88 return (0); 89 } 90 91 static void 92 rdl2prmap(const rd_loadobj_t *rdl, prmap_t *map) 93 { 94 95 map->pr_vaddr = rdl->rdl_saddr; 96 map->pr_size = rdl->rdl_eaddr - rdl->rdl_saddr; 97 map->pr_offset = rdl->rdl_offset; 98 map->pr_mflags = 0; 99 if (rdl->rdl_prot & RD_RDL_R) 100 map->pr_mflags |= MA_READ; 101 if (rdl->rdl_prot & RD_RDL_W) 102 map->pr_mflags |= MA_WRITE; 103 if (rdl->rdl_prot & RD_RDL_X) 104 map->pr_mflags |= MA_EXEC; 105 (void)strlcpy(map->pr_mapname, rdl->rdl_path, 106 sizeof(map->pr_mapname)); 107 } 108 109 rd_agent_t * 110 proc_rdagent(struct proc_handle *phdl) 111 { 112 113 if (phdl->rdap == NULL && phdl->status != PS_UNDEAD && 114 phdl->status != PS_IDLE) { 115 if ((phdl->rdap = rd_new(phdl)) == NULL) 116 return (NULL); 117 118 phdl->maparrsz = 64; 119 phdl->mappings = calloc(phdl->maparrsz, 120 sizeof(*phdl->mappings)); 121 if (phdl->mappings == NULL) 122 return (phdl->rdap); 123 if (rd_loadobj_iter(phdl->rdap, map_iter, phdl) != RD_OK) 124 return (NULL); 125 } 126 return (phdl->rdap); 127 } 128 129 void 130 proc_updatesyms(struct proc_handle *phdl) 131 { 132 133 memset(phdl->mappings, 0, sizeof(*phdl->mappings) * phdl->maparrsz); 134 rd_loadobj_iter(phdl->rdap, map_iter, phdl); 135 } 136