1*12927SRod.Evans@Sun.COM /*
2*12927SRod.Evans@Sun.COM * CDDL HEADER START
3*12927SRod.Evans@Sun.COM *
4*12927SRod.Evans@Sun.COM * The contents of this file are subject to the terms of the
5*12927SRod.Evans@Sun.COM * Common Development and Distribution License (the "License").
6*12927SRod.Evans@Sun.COM * You may not use this file except in compliance with the License.
7*12927SRod.Evans@Sun.COM *
8*12927SRod.Evans@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12927SRod.Evans@Sun.COM * or http://www.opensolaris.org/os/licensing.
10*12927SRod.Evans@Sun.COM * See the License for the specific language governing permissions
11*12927SRod.Evans@Sun.COM * and limitations under the License.
12*12927SRod.Evans@Sun.COM *
13*12927SRod.Evans@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
14*12927SRod.Evans@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12927SRod.Evans@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
16*12927SRod.Evans@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*12927SRod.Evans@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*12927SRod.Evans@Sun.COM *
19*12927SRod.Evans@Sun.COM * CDDL HEADER END
20*12927SRod.Evans@Sun.COM */
21*12927SRod.Evans@Sun.COM
22*12927SRod.Evans@Sun.COM /*
23*12927SRod.Evans@Sun.COM * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24*12927SRod.Evans@Sun.COM */
25*12927SRod.Evans@Sun.COM
26*12927SRod.Evans@Sun.COM #include <stdio.h>
27*12927SRod.Evans@Sun.COM #include <stdlib.h>
28*12927SRod.Evans@Sun.COM #include <unistd.h>
29*12927SRod.Evans@Sun.COM #include <fcntl.h>
30*12927SRod.Evans@Sun.COM #include <string.h>
31*12927SRod.Evans@Sun.COM #include <errno.h>
32*12927SRod.Evans@Sun.COM #include <sys/types.h>
33*12927SRod.Evans@Sun.COM #include <sys/signal.h>
34*12927SRod.Evans@Sun.COM #include <sys/fault.h>
35*12927SRod.Evans@Sun.COM #include <sys/syscall.h>
36*12927SRod.Evans@Sun.COM #include <procfs.h>
37*12927SRod.Evans@Sun.COM #include <sys/auxv.h>
38*12927SRod.Evans@Sun.COM #include <libelf.h>
39*12927SRod.Evans@Sun.COM #include <sys/stat.h>
40*12927SRod.Evans@Sun.COM #include <sys/mman.h>
41*12927SRod.Evans@Sun.COM #include <link.h>
42*12927SRod.Evans@Sun.COM #include <sys/param.h>
43*12927SRod.Evans@Sun.COM #include <sys/machelf.h>
44*12927SRod.Evans@Sun.COM #include <stdarg.h>
45*12927SRod.Evans@Sun.COM
46*12927SRod.Evans@Sun.COM #include "rdb.h"
47*12927SRod.Evans@Sun.COM
48*12927SRod.Evans@Sun.COM static char *
conv_lmid(Lmid_t ident,char * buf,size_t len)49*12927SRod.Evans@Sun.COM conv_lmid(Lmid_t ident, char *buf, size_t len)
50*12927SRod.Evans@Sun.COM {
51*12927SRod.Evans@Sun.COM if (len < 17)
52*12927SRod.Evans@Sun.COM return (NULL);
53*12927SRod.Evans@Sun.COM if (ident == LM_ID_BASE)
54*12927SRod.Evans@Sun.COM return (strncpy(buf, " BASE ", len));
55*12927SRod.Evans@Sun.COM
56*12927SRod.Evans@Sun.COM if (ident == LM_ID_LDSO)
57*12927SRod.Evans@Sun.COM return (strncpy(buf, " LDSO ", len));
58*12927SRod.Evans@Sun.COM
59*12927SRod.Evans@Sun.COM (void) sprintf(buf, "0x%llx", (unsigned long long)ident);
60*12927SRod.Evans@Sun.COM return (buf);
61*12927SRod.Evans@Sun.COM }
62*12927SRod.Evans@Sun.COM
63*12927SRod.Evans@Sun.COM map_info_t *
str_to_map(struct ps_prochandle * ph,const char * soname)64*12927SRod.Evans@Sun.COM str_to_map(struct ps_prochandle *ph, const char *soname)
65*12927SRod.Evans@Sun.COM {
66*12927SRod.Evans@Sun.COM map_info_t *mip;
67*12927SRod.Evans@Sun.COM
68*12927SRod.Evans@Sun.COM if (soname == PS_OBJ_LDSO)
69*12927SRod.Evans@Sun.COM mip = (map_info_t *)&(ph->pp_ldsomap);
70*12927SRod.Evans@Sun.COM else if (soname == PS_OBJ_EXEC)
71*12927SRod.Evans@Sun.COM mip = (map_info_t *)&(ph->pp_execmap);
72*12927SRod.Evans@Sun.COM else {
73*12927SRod.Evans@Sun.COM for (mip = ph->pp_lmaplist.ml_head; mip; mip = mip->mi_next)
74*12927SRod.Evans@Sun.COM if (strcmp(soname, mip->mi_name) == 0)
75*12927SRod.Evans@Sun.COM break;
76*12927SRod.Evans@Sun.COM }
77*12927SRod.Evans@Sun.COM return (mip);
78*12927SRod.Evans@Sun.COM }
79*12927SRod.Evans@Sun.COM
80*12927SRod.Evans@Sun.COM map_info_t *
addr_to_map(struct ps_prochandle * ph,ulong_t addr)81*12927SRod.Evans@Sun.COM addr_to_map(struct ps_prochandle *ph, ulong_t addr)
82*12927SRod.Evans@Sun.COM {
83*12927SRod.Evans@Sun.COM map_info_t *mip;
84*12927SRod.Evans@Sun.COM if (ph->pp_lmaplist.ml_head == NULL) {
85*12927SRod.Evans@Sun.COM /*
86*12927SRod.Evans@Sun.COM * To early to have the full Link Map info available
87*12927SRod.Evans@Sun.COM * so we use the initial info obtained from procfs
88*12927SRod.Evans@Sun.COM */
89*12927SRod.Evans@Sun.COM if ((addr >= ph->pp_ldsomap.mi_addr) &&
90*12927SRod.Evans@Sun.COM (addr <= ph->pp_ldsomap.mi_end))
91*12927SRod.Evans@Sun.COM return ((map_info_t *)&(ph->pp_ldsomap));
92*12927SRod.Evans@Sun.COM
93*12927SRod.Evans@Sun.COM if ((addr >= ph->pp_execmap.mi_addr) &&
94*12927SRod.Evans@Sun.COM (addr <= ph->pp_execmap.mi_end))
95*12927SRod.Evans@Sun.COM return ((map_info_t *)&(ph->pp_execmap));
96*12927SRod.Evans@Sun.COM
97*12927SRod.Evans@Sun.COM return (NULL);
98*12927SRod.Evans@Sun.COM }
99*12927SRod.Evans@Sun.COM
100*12927SRod.Evans@Sun.COM for (mip = ph->pp_lmaplist.ml_head; mip; mip = mip->mi_next)
101*12927SRod.Evans@Sun.COM if ((addr >= mip->mi_addr) &&
102*12927SRod.Evans@Sun.COM (addr <= mip->mi_end))
103*12927SRod.Evans@Sun.COM return (mip);
104*12927SRod.Evans@Sun.COM
105*12927SRod.Evans@Sun.COM return (NULL);
106*12927SRod.Evans@Sun.COM }
107*12927SRod.Evans@Sun.COM
108*12927SRod.Evans@Sun.COM retc_t
display_linkmaps(struct ps_prochandle * ph)109*12927SRod.Evans@Sun.COM display_linkmaps(struct ps_prochandle *ph)
110*12927SRod.Evans@Sun.COM {
111*12927SRod.Evans@Sun.COM char flagstr[1024];
112*12927SRod.Evans@Sun.COM map_info_t *mip;
113*12927SRod.Evans@Sun.COM
114*12927SRod.Evans@Sun.COM if (ph->pp_lmaplist.ml_head == NULL) {
115*12927SRod.Evans@Sun.COM (void) printf("link-maps not yet available\n");
116*12927SRod.Evans@Sun.COM return (RET_FAILED);
117*12927SRod.Evans@Sun.COM }
118*12927SRod.Evans@Sun.COM (void) printf("Link Maps\n");
119*12927SRod.Evans@Sun.COM (void) printf("---------\n");
120*12927SRod.Evans@Sun.COM for (mip = ph->pp_lmaplist.ml_head; mip; mip = mip->mi_next) {
121*12927SRod.Evans@Sun.COM char sbuf[32];
122*12927SRod.Evans@Sun.COM rd_loadobj_t *lp = &mip->mi_loadobj;
123*12927SRod.Evans@Sun.COM (void) printf("link-map: id: %s name: ",
124*12927SRod.Evans@Sun.COM conv_lmid(lp->rl_lmident, sbuf, 32));
125*12927SRod.Evans@Sun.COM if (mip->mi_refname)
126*12927SRod.Evans@Sun.COM (void) printf("%s(%s)\n", mip->mi_name,
127*12927SRod.Evans@Sun.COM mip->mi_refname);
128*12927SRod.Evans@Sun.COM else
129*12927SRod.Evans@Sun.COM (void) printf("%s\n", mip->mi_name);
130*12927SRod.Evans@Sun.COM
131*12927SRod.Evans@Sun.COM (void) printf(" base: 0x%08lx padd_base: 0x%08lx\n",
132*12927SRod.Evans@Sun.COM lp->rl_base, lp->rl_padstart);
133*12927SRod.Evans@Sun.COM (void) printf(" data_base: 0x%08llx\n",
134*12927SRod.Evans@Sun.COM (unsigned long long)lp->rl_data_base);
135*12927SRod.Evans@Sun.COM (void) printf(" end: 0x%08lx padd_end: 0x%08lx\n",
136*12927SRod.Evans@Sun.COM lp->rl_bend, lp->rl_padend);
137*12927SRod.Evans@Sun.COM flagstr[0] = '\0';
138*12927SRod.Evans@Sun.COM
139*12927SRod.Evans@Sun.COM if (lp->rl_flags & RD_FLG_MEM_OBJECT) {
140*12927SRod.Evans@Sun.COM (void) strcat(flagstr, " MEMOBJECT");
141*12927SRod.Evans@Sun.COM }
142*12927SRod.Evans@Sun.COM (void) printf(" dynamic: 0x%08lx flags: "
143*12927SRod.Evans@Sun.COM "0x%08x:[%s ]\n", lp->rl_dynamic, lp->rl_flags, flagstr);
144*12927SRod.Evans@Sun.COM }
145*12927SRod.Evans@Sun.COM
146*12927SRod.Evans@Sun.COM return (RET_OK);
147*12927SRod.Evans@Sun.COM }
148*12927SRod.Evans@Sun.COM
149*12927SRod.Evans@Sun.COM retc_t
display_maps(struct ps_prochandle * ph)150*12927SRod.Evans@Sun.COM display_maps(struct ps_prochandle *ph)
151*12927SRod.Evans@Sun.COM {
152*12927SRod.Evans@Sun.COM struct stat stbuf;
153*12927SRod.Evans@Sun.COM void *ptr;
154*12927SRod.Evans@Sun.COM prmap_t *mapptr;
155*12927SRod.Evans@Sun.COM
156*12927SRod.Evans@Sun.COM if (fstat(ph->pp_mapfd, &stbuf) == -1)
157*12927SRod.Evans@Sun.COM perr("stat map");
158*12927SRod.Evans@Sun.COM
159*12927SRod.Evans@Sun.COM ptr = malloc(stbuf.st_size);
160*12927SRod.Evans@Sun.COM if (pread(ph->pp_mapfd, ptr, stbuf.st_size, 0) == -1)
161*12927SRod.Evans@Sun.COM perr("dm: reading map");
162*12927SRod.Evans@Sun.COM
163*12927SRod.Evans@Sun.COM (void) puts("\nMappings");
164*12927SRod.Evans@Sun.COM (void) puts("--------");
165*12927SRod.Evans@Sun.COM if (ph->pp_dmodel == PR_MODEL_LP64)
166*12927SRod.Evans@Sun.COM (void) puts("addr size prot ident name");
167*12927SRod.Evans@Sun.COM else
168*12927SRod.Evans@Sun.COM (void) puts("addr size prot ident name");
169*12927SRod.Evans@Sun.COM
170*12927SRod.Evans@Sun.COM for (mapptr = (prmap_t *)ptr;
171*12927SRod.Evans@Sun.COM (uintptr_t)mapptr < ((uintptr_t)ptr + stbuf.st_size);
172*12927SRod.Evans@Sun.COM mapptr++) {
173*12927SRod.Evans@Sun.COM map_info_t *mip;
174*12927SRod.Evans@Sun.COM
175*12927SRod.Evans@Sun.COM if (ph->pp_dmodel == PR_MODEL_LP64)
176*12927SRod.Evans@Sun.COM (void) printf("%#18llx %#08llx %#04x",
177*12927SRod.Evans@Sun.COM EC_ADDR(mapptr->pr_vaddr), EC_OFF(mapptr->pr_size),
178*12927SRod.Evans@Sun.COM mapptr->pr_mflags);
179*12927SRod.Evans@Sun.COM else
180*12927SRod.Evans@Sun.COM (void) printf("0x%08llx 0x%06llx 0x%02x",
181*12927SRod.Evans@Sun.COM EC_ADDR(mapptr->pr_vaddr), EC_OFF(mapptr->pr_size),
182*12927SRod.Evans@Sun.COM mapptr->pr_mflags);
183*12927SRod.Evans@Sun.COM
184*12927SRod.Evans@Sun.COM if ((mip = addr_to_map(ph,
185*12927SRod.Evans@Sun.COM (ulong_t)(mapptr->pr_vaddr))) != NULL) {
186*12927SRod.Evans@Sun.COM if (mip->mi_refname) {
187*12927SRod.Evans@Sun.COM (void) printf(" 0x%02lx %s(%s)",
188*12927SRod.Evans@Sun.COM mip->mi_lmident, mip->mi_name,
189*12927SRod.Evans@Sun.COM mip->mi_refname);
190*12927SRod.Evans@Sun.COM } else
191*12927SRod.Evans@Sun.COM (void) printf(" 0x%02lx %s", mip->mi_lmident,
192*12927SRod.Evans@Sun.COM mip->mi_name);
193*12927SRod.Evans@Sun.COM }
194*12927SRod.Evans@Sun.COM (void) putchar('\n');
195*12927SRod.Evans@Sun.COM }
196*12927SRod.Evans@Sun.COM (void) putchar('\n');
197*12927SRod.Evans@Sun.COM
198*12927SRod.Evans@Sun.COM free(ptr);
199*12927SRod.Evans@Sun.COM return (RET_OK);
200*12927SRod.Evans@Sun.COM }
201*12927SRod.Evans@Sun.COM
202*12927SRod.Evans@Sun.COM retc_t
load_map(struct ps_prochandle * procp,caddr_t baddr,map_info_t * mp)203*12927SRod.Evans@Sun.COM load_map(struct ps_prochandle *procp, caddr_t baddr, map_info_t *mp)
204*12927SRod.Evans@Sun.COM {
205*12927SRod.Evans@Sun.COM Elf *elf;
206*12927SRod.Evans@Sun.COM GElf_Ehdr ehdr;
207*12927SRod.Evans@Sun.COM GElf_Phdr phdr;
208*12927SRod.Evans@Sun.COM Elf_Scn *scn = NULL;
209*12927SRod.Evans@Sun.COM int cnt;
210*12927SRod.Evans@Sun.COM prmap_t *mapptr;
211*12927SRod.Evans@Sun.COM void *ptr;
212*12927SRod.Evans@Sun.COM struct stat stbuf;
213*12927SRod.Evans@Sun.COM int filefd = -1;
214*12927SRod.Evans@Sun.COM
215*12927SRod.Evans@Sun.COM if (fstat(procp->pp_mapfd, &stbuf) == -1)
216*12927SRod.Evans@Sun.COM perr("stat map");
217*12927SRod.Evans@Sun.COM
218*12927SRod.Evans@Sun.COM ptr = malloc(stbuf.st_size);
219*12927SRod.Evans@Sun.COM if (pread(procp->pp_mapfd, ptr, stbuf.st_size, 0) == -1)
220*12927SRod.Evans@Sun.COM perr("dm: reading map");
221*12927SRod.Evans@Sun.COM
222*12927SRod.Evans@Sun.COM for (mapptr = (prmap_t *)ptr;
223*12927SRod.Evans@Sun.COM (uintptr_t)mapptr < ((uintptr_t)ptr + stbuf.st_size);
224*12927SRod.Evans@Sun.COM mapptr++) {
225*12927SRod.Evans@Sun.COM
226*12927SRod.Evans@Sun.COM if ((mapptr->pr_vaddr <= (uintptr_t)baddr) &&
227*12927SRod.Evans@Sun.COM ((mapptr->pr_vaddr + mapptr->pr_size) >
228*12927SRod.Evans@Sun.COM (uintptr_t)baddr)) {
229*12927SRod.Evans@Sun.COM if (mapptr->pr_mapname[0]) {
230*12927SRod.Evans@Sun.COM char procname[MAXPATHLEN];
231*12927SRod.Evans@Sun.COM
232*12927SRod.Evans@Sun.COM (void) snprintf(procname, MAXPATHLEN - 1,
233*12927SRod.Evans@Sun.COM "/proc/%d/object/%s", procp->pp_pid,
234*12927SRod.Evans@Sun.COM mapptr->pr_mapname);
235*12927SRod.Evans@Sun.COM filefd = open(procname, O_RDONLY);
236*12927SRod.Evans@Sun.COM }
237*12927SRod.Evans@Sun.COM break;
238*12927SRod.Evans@Sun.COM }
239*12927SRod.Evans@Sun.COM }
240*12927SRod.Evans@Sun.COM free(ptr);
241*12927SRod.Evans@Sun.COM
242*12927SRod.Evans@Sun.COM if (filefd == -1) {
243*12927SRod.Evans@Sun.COM (void) fprintf(stderr, "unable to find file association to "
244*12927SRod.Evans@Sun.COM "mapping address 0x%08llx\n", EC_NATPTR(baddr));
245*12927SRod.Evans@Sun.COM return (RET_FAILED);
246*12927SRod.Evans@Sun.COM }
247*12927SRod.Evans@Sun.COM
248*12927SRod.Evans@Sun.COM if ((elf = elf_begin(filefd, ELF_C_READ, 0)) == NULL) {
249*12927SRod.Evans@Sun.COM (void) fprintf(stderr, "elf_begin(): %s\n", elf_errmsg(-1));
250*12927SRod.Evans@Sun.COM return (RET_FAILED);
251*12927SRod.Evans@Sun.COM }
252*12927SRod.Evans@Sun.COM
253*12927SRod.Evans@Sun.COM if (elf_kind(elf) != ELF_K_ELF) {
254*12927SRod.Evans@Sun.COM (void) printf("non-elf file\n");
255*12927SRod.Evans@Sun.COM (void) elf_end(elf);
256*12927SRod.Evans@Sun.COM return (RET_FAILED);
257*12927SRod.Evans@Sun.COM }
258*12927SRod.Evans@Sun.COM
259*12927SRod.Evans@Sun.COM mp->mi_elf = elf;
260*12927SRod.Evans@Sun.COM mp->mi_flags = 0;
261*12927SRod.Evans@Sun.COM mp->mi_mapfd = filefd;
262*12927SRod.Evans@Sun.COM
263*12927SRod.Evans@Sun.COM if (gelf_getehdr(mp->mi_elf, &ehdr) == NULL) {
264*12927SRod.Evans@Sun.COM (void) printf("gelf_getehdr(): %s\n", elf_errmsg(-1));
265*12927SRod.Evans@Sun.COM (void) elf_end(mp->mi_elf);
266*12927SRod.Evans@Sun.COM return (RET_FAILED);
267*12927SRod.Evans@Sun.COM }
268*12927SRod.Evans@Sun.COM mp->mi_ehdr = ehdr;
269*12927SRod.Evans@Sun.COM if (ehdr.e_type == ET_EXEC)
270*12927SRod.Evans@Sun.COM mp->mi_flags |= FLG_MI_EXEC;
271*12927SRod.Evans@Sun.COM
272*12927SRod.Evans@Sun.COM mp->mi_end = 0;
273*12927SRod.Evans@Sun.COM #if defined(_ELF64)
274*12927SRod.Evans@Sun.COM mp->mi_addr = (ulong_t)0xffffffffffffffff;
275*12927SRod.Evans@Sun.COM #else
276*12927SRod.Evans@Sun.COM mp->mi_addr = (ulong_t)0xffffffff;
277*12927SRod.Evans@Sun.COM #endif
278*12927SRod.Evans@Sun.COM for (cnt = 0; cnt < (int)(ehdr.e_phnum); cnt++) {
279*12927SRod.Evans@Sun.COM if (gelf_getphdr(mp->mi_elf, cnt, &phdr) == NULL) {
280*12927SRod.Evans@Sun.COM (void) printf("gelf_getphdr(): %s\n", elf_errmsg(-1));
281*12927SRod.Evans@Sun.COM (void) elf_end(mp->mi_elf);
282*12927SRod.Evans@Sun.COM return (RET_FAILED);
283*12927SRod.Evans@Sun.COM }
284*12927SRod.Evans@Sun.COM
285*12927SRod.Evans@Sun.COM if (phdr.p_type == PT_LOAD) {
286*12927SRod.Evans@Sun.COM if (mp->mi_end < (ulong_t)(phdr.p_vaddr +
287*12927SRod.Evans@Sun.COM phdr.p_memsz))
288*12927SRod.Evans@Sun.COM mp->mi_end = (ulong_t)(phdr.p_vaddr +
289*12927SRod.Evans@Sun.COM phdr.p_memsz);
290*12927SRod.Evans@Sun.COM if (mp->mi_addr > phdr.p_vaddr)
291*12927SRod.Evans@Sun.COM mp->mi_addr = phdr.p_vaddr;
292*12927SRod.Evans@Sun.COM }
293*12927SRod.Evans@Sun.COM }
294*12927SRod.Evans@Sun.COM
295*12927SRod.Evans@Sun.COM mp->mi_pltbase = 0;
296*12927SRod.Evans@Sun.COM mp->mi_pltsize = 0;
297*12927SRod.Evans@Sun.COM mp->mi_pltentsz = 0;
298*12927SRod.Evans@Sun.COM mp->mi_dynsym.st_symn = 0;
299*12927SRod.Evans@Sun.COM while ((scn = elf_nextscn(mp->mi_elf, scn)) != NULL) {
300*12927SRod.Evans@Sun.COM GElf_Shdr shdr;
301*12927SRod.Evans@Sun.COM Elf_Data *dp;
302*12927SRod.Evans@Sun.COM Elf_Scn *tscn = NULL;
303*12927SRod.Evans@Sun.COM
304*12927SRod.Evans@Sun.COM if (gelf_getshdr(scn, &shdr) == NULL) {
305*12927SRod.Evans@Sun.COM (void) printf("gelf_getshdr(): %s\n", elf_errmsg(-1));
306*12927SRod.Evans@Sun.COM (void) elf_end(mp->mi_elf);
307*12927SRod.Evans@Sun.COM return (RET_FAILED);
308*12927SRod.Evans@Sun.COM }
309*12927SRod.Evans@Sun.COM
310*12927SRod.Evans@Sun.COM switch (shdr.sh_type) {
311*12927SRod.Evans@Sun.COM case SHT_DYNSYM:
312*12927SRod.Evans@Sun.COM dp = elf_getdata(scn, 0);
313*12927SRod.Evans@Sun.COM mp->mi_dynsym.st_syms_pri = dp;
314*12927SRod.Evans@Sun.COM tscn = elf_getscn(mp->mi_elf, shdr.sh_link);
315*12927SRod.Evans@Sun.COM mp->mi_dynsym.st_symn +=
316*12927SRod.Evans@Sun.COM shdr.sh_size / shdr.sh_entsize;
317*12927SRod.Evans@Sun.COM dp = elf_getdata(tscn, 0);
318*12927SRod.Evans@Sun.COM mp->mi_dynsym.st_strs = (char *)dp->d_buf;
319*12927SRod.Evans@Sun.COM break;
320*12927SRod.Evans@Sun.COM case SHT_SUNW_LDYNSYM:
321*12927SRod.Evans@Sun.COM dp = elf_getdata(scn, 0);
322*12927SRod.Evans@Sun.COM mp->mi_dynsym.st_syms_aux = dp;
323*12927SRod.Evans@Sun.COM mp->mi_dynsym.st_symn_aux =
324*12927SRod.Evans@Sun.COM shdr.sh_size / shdr.sh_entsize;
325*12927SRod.Evans@Sun.COM mp->mi_dynsym.st_symn += mp->mi_dynsym.st_symn_aux;
326*12927SRod.Evans@Sun.COM break;
327*12927SRod.Evans@Sun.COM case SHT_SYMTAB:
328*12927SRod.Evans@Sun.COM dp = elf_getdata(scn, 0);
329*12927SRod.Evans@Sun.COM mp->mi_symtab.st_syms_pri = dp;
330*12927SRod.Evans@Sun.COM tscn = elf_getscn(mp->mi_elf, shdr.sh_link);
331*12927SRod.Evans@Sun.COM mp->mi_symtab.st_symn =
332*12927SRod.Evans@Sun.COM shdr.sh_size / shdr.sh_entsize;
333*12927SRod.Evans@Sun.COM dp = elf_getdata(tscn, 0);
334*12927SRod.Evans@Sun.COM mp->mi_symtab.st_strs = (char *)dp->d_buf;
335*12927SRod.Evans@Sun.COM break;
336*12927SRod.Evans@Sun.COM case PLTSECTT:
337*12927SRod.Evans@Sun.COM if (strcmp(PLTSECT, elf_strptr(mp->mi_elf,
338*12927SRod.Evans@Sun.COM ehdr.e_shstrndx, shdr.sh_name)) == 0) {
339*12927SRod.Evans@Sun.COM mp->mi_pltbase = shdr.sh_addr;
340*12927SRod.Evans@Sun.COM mp->mi_pltsize = shdr.sh_size;
341*12927SRod.Evans@Sun.COM mp->mi_pltentsz = shdr.sh_entsize;
342*12927SRod.Evans@Sun.COM }
343*12927SRod.Evans@Sun.COM break;
344*12927SRod.Evans@Sun.COM default:
345*12927SRod.Evans@Sun.COM /* nothing */
346*12927SRod.Evans@Sun.COM break;
347*12927SRod.Evans@Sun.COM }
348*12927SRod.Evans@Sun.COM }
349*12927SRod.Evans@Sun.COM return (RET_OK);
350*12927SRod.Evans@Sun.COM }
351*12927SRod.Evans@Sun.COM
352*12927SRod.Evans@Sun.COM static int
map_iter(const rd_loadobj_t * lop,void * cd)353*12927SRod.Evans@Sun.COM map_iter(const rd_loadobj_t *lop, void *cd)
354*12927SRod.Evans@Sun.COM {
355*12927SRod.Evans@Sun.COM struct ps_prochandle *ph = (struct ps_prochandle *)cd;
356*12927SRod.Evans@Sun.COM map_info_t *mip;
357*12927SRod.Evans@Sun.COM char buf[MAXPATHLEN];
358*12927SRod.Evans@Sun.COM
359*12927SRod.Evans@Sun.COM if ((mip = (map_info_t *)calloc(1, sizeof (map_info_t))) == NULL) {
360*12927SRod.Evans@Sun.COM (void) fprintf(stderr, "map_iter: memory error: allocation "
361*12927SRod.Evans@Sun.COM "failed\n");
362*12927SRod.Evans@Sun.COM return (0);
363*12927SRod.Evans@Sun.COM }
364*12927SRod.Evans@Sun.COM
365*12927SRod.Evans@Sun.COM mip->mi_loadobj = *lop;
366*12927SRod.Evans@Sun.COM
367*12927SRod.Evans@Sun.COM if (proc_string_read(ph, lop->rl_nameaddr,
368*12927SRod.Evans@Sun.COM buf, MAXPATHLEN) == RET_FAILED) {
369*12927SRod.Evans@Sun.COM (void) fprintf(stderr, "mi: bad object name address "
370*12927SRod.Evans@Sun.COM "passed: 0x%lx\n", lop->rl_nameaddr);
371*12927SRod.Evans@Sun.COM free(mip);
372*12927SRod.Evans@Sun.COM return (0);
373*12927SRod.Evans@Sun.COM }
374*12927SRod.Evans@Sun.COM mip->mi_name = strdup(buf);
375*12927SRod.Evans@Sun.COM
376*12927SRod.Evans@Sun.COM
377*12927SRod.Evans@Sun.COM if (lop->rl_refnameaddr) {
378*12927SRod.Evans@Sun.COM if (proc_string_read(ph, lop->rl_refnameaddr, buf,
379*12927SRod.Evans@Sun.COM MAXPATHLEN) == RET_FAILED) {
380*12927SRod.Evans@Sun.COM (void) fprintf(stderr, "mi1: bad object name address "
381*12927SRod.Evans@Sun.COM "passed: 0x%lx\n", lop->rl_refnameaddr);
382*12927SRod.Evans@Sun.COM free(mip);
383*12927SRod.Evans@Sun.COM return (0);
384*12927SRod.Evans@Sun.COM }
385*12927SRod.Evans@Sun.COM mip->mi_refname = strdup(buf);
386*12927SRod.Evans@Sun.COM } else
387*12927SRod.Evans@Sun.COM mip->mi_refname = NULL;
388*12927SRod.Evans@Sun.COM
389*12927SRod.Evans@Sun.COM /*
390*12927SRod.Evans@Sun.COM * Relocatable objects are processed to create in-memory shared objects,
391*12927SRod.Evans@Sun.COM * and as such have no file associated with the allocated memory shared
392*12927SRod.Evans@Sun.COM * object.
393*12927SRod.Evans@Sun.COM */
394*12927SRod.Evans@Sun.COM if ((lop->rl_flags & RD_FLG_MEM_OBJECT) == 0)
395*12927SRod.Evans@Sun.COM (void) load_map(ph, (caddr_t)lop->rl_base, mip);
396*12927SRod.Evans@Sun.COM if ((mip->mi_flags & FLG_MI_EXEC) == 0) {
397*12927SRod.Evans@Sun.COM mip->mi_end += lop->rl_base;
398*12927SRod.Evans@Sun.COM mip->mi_addr += lop->rl_base;
399*12927SRod.Evans@Sun.COM }
400*12927SRod.Evans@Sun.COM mip->mi_lmident = lop->rl_lmident;
401*12927SRod.Evans@Sun.COM mip->mi_next = NULL;
402*12927SRod.Evans@Sun.COM
403*12927SRod.Evans@Sun.COM if (ph->pp_lmaplist.ml_head == NULL) {
404*12927SRod.Evans@Sun.COM ph->pp_lmaplist.ml_head = ph->pp_lmaplist.ml_tail = mip;
405*12927SRod.Evans@Sun.COM return (1);
406*12927SRod.Evans@Sun.COM }
407*12927SRod.Evans@Sun.COM
408*12927SRod.Evans@Sun.COM ph->pp_lmaplist.ml_tail->mi_next = mip;
409*12927SRod.Evans@Sun.COM ph->pp_lmaplist.ml_tail = mip;
410*12927SRod.Evans@Sun.COM
411*12927SRod.Evans@Sun.COM return (1);
412*12927SRod.Evans@Sun.COM }
413*12927SRod.Evans@Sun.COM
414*12927SRod.Evans@Sun.COM void
free_linkmaps(struct ps_prochandle * ph)415*12927SRod.Evans@Sun.COM free_linkmaps(struct ps_prochandle *ph)
416*12927SRod.Evans@Sun.COM {
417*12927SRod.Evans@Sun.COM map_info_t *cur, *prev;
418*12927SRod.Evans@Sun.COM
419*12927SRod.Evans@Sun.COM for (cur = ph->pp_lmaplist.ml_head, prev = NULL; cur;
420*12927SRod.Evans@Sun.COM prev = cur, cur = cur->mi_next) {
421*12927SRod.Evans@Sun.COM if (prev) {
422*12927SRod.Evans@Sun.COM (void) elf_end(prev->mi_elf);
423*12927SRod.Evans@Sun.COM (void) close(prev->mi_mapfd);
424*12927SRod.Evans@Sun.COM free(prev->mi_name);
425*12927SRod.Evans@Sun.COM if (prev->mi_refname)
426*12927SRod.Evans@Sun.COM free(prev->mi_refname);
427*12927SRod.Evans@Sun.COM free(prev);
428*12927SRod.Evans@Sun.COM }
429*12927SRod.Evans@Sun.COM }
430*12927SRod.Evans@Sun.COM if (prev) {
431*12927SRod.Evans@Sun.COM (void) elf_end(prev->mi_elf);
432*12927SRod.Evans@Sun.COM (void) close(prev->mi_mapfd);
433*12927SRod.Evans@Sun.COM free(prev->mi_name);
434*12927SRod.Evans@Sun.COM if (prev->mi_refname)
435*12927SRod.Evans@Sun.COM free(prev->mi_refname);
436*12927SRod.Evans@Sun.COM free(prev);
437*12927SRod.Evans@Sun.COM }
438*12927SRod.Evans@Sun.COM ph->pp_lmaplist.ml_head = ph->pp_lmaplist.ml_tail = NULL;
439*12927SRod.Evans@Sun.COM }
440*12927SRod.Evans@Sun.COM
441*12927SRod.Evans@Sun.COM retc_t
get_linkmaps(struct ps_prochandle * ph)442*12927SRod.Evans@Sun.COM get_linkmaps(struct ps_prochandle *ph)
443*12927SRod.Evans@Sun.COM {
444*12927SRod.Evans@Sun.COM free_linkmaps(ph);
445*12927SRod.Evans@Sun.COM (void) rd_loadobj_iter(ph->pp_rap, map_iter, ph);
446*12927SRod.Evans@Sun.COM return (RET_OK);
447*12927SRod.Evans@Sun.COM }
448*12927SRod.Evans@Sun.COM
449*12927SRod.Evans@Sun.COM retc_t
set_objpad(struct ps_prochandle * ph,size_t padsize)450*12927SRod.Evans@Sun.COM set_objpad(struct ps_prochandle *ph, size_t padsize)
451*12927SRod.Evans@Sun.COM {
452*12927SRod.Evans@Sun.COM if (rd_objpad_enable(ph->pp_rap, padsize) != RD_OK) {
453*12927SRod.Evans@Sun.COM (void) printf("rdb: error setting object padding\n");
454*12927SRod.Evans@Sun.COM return (RET_FAILED);
455*12927SRod.Evans@Sun.COM }
456*12927SRod.Evans@Sun.COM return (RET_OK);
457*12927SRod.Evans@Sun.COM }
458