xref: /freebsd/lib/libpmcstat/libpmcstat_image.c (revision 81ad6265)
1 /*-
2  * Copyright (c) 2003-2008 Joseph Koshy
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 #include <sys/types.h>
31 #include <sys/cpuset.h>
32 #include <sys/param.h>
33 #include <sys/endian.h>
34 #include <sys/pmc.h>
35 #include <sys/sysctl.h>
36 #include <sys/imgact_aout.h>
37 #include <sys/imgact_elf.h>
38 
39 #include <netinet/in.h>
40 
41 #include <assert.h>
42 #include <err.h>
43 #include <fcntl.h>
44 #include <pmc.h>
45 #include <pmclog.h>
46 #include <stdbool.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <sysexits.h>
51 #include <unistd.h>
52 
53 #include "libpmcstat.h"
54 
55 #define	min(A,B)		((A) < (B) ? (A) : (B))
56 #define	max(A,B)		((A) > (B) ? (A) : (B))
57 
58 /*
59  * Add the list of symbols in the given section to the list associated
60  * with the object.
61  */
62 void
63 pmcstat_image_add_symbols(struct pmcstat_image *image, Elf *e,
64     Elf_Scn *scn, GElf_Shdr *sh)
65 {
66 	int firsttime;
67 	size_t n, newsyms, nshsyms, nfuncsyms;
68 	struct pmcstat_symbol *symptr;
69 	char *fnname;
70 	GElf_Sym sym;
71 	Elf_Data *data;
72 
73 	if ((data = elf_getdata(scn, NULL)) == NULL)
74 		return;
75 
76 	/*
77 	 * Determine the number of functions named in this
78 	 * section.
79 	 */
80 
81 	nshsyms = sh->sh_size / sh->sh_entsize;
82 	for (n = nfuncsyms = 0; n < nshsyms; n++) {
83 		if (gelf_getsym(data, (int) n, &sym) != &sym)
84 			return;
85 		if (GELF_ST_TYPE(sym.st_info) == STT_FUNC)
86 			nfuncsyms++;
87 	}
88 
89 	if (nfuncsyms == 0)
90 		return;
91 
92 	/*
93 	 * Allocate space for the new entries.
94 	 */
95 	firsttime = image->pi_symbols == NULL;
96 	symptr = reallocarray(image->pi_symbols,
97 	    image->pi_symcount + nfuncsyms, sizeof(*symptr));
98 	if (symptr == image->pi_symbols) /* realloc() failed. */
99 		return;
100 	image->pi_symbols = symptr;
101 
102 	/*
103 	 * Append new symbols to the end of the current table.
104 	 */
105 	symptr += image->pi_symcount;
106 
107 	for (n = newsyms = 0; n < nshsyms; n++) {
108 		if (gelf_getsym(data, (int) n, &sym) != &sym)
109 			return;
110 		if (GELF_ST_TYPE(sym.st_info) != STT_FUNC)
111 			continue;
112 
113 		if (sym.st_shndx == STN_UNDEF)
114 			continue;
115 
116 		if (!firsttime && pmcstat_symbol_search(image, sym.st_value))
117 			continue; /* We've seen this symbol already. */
118 
119 		if ((fnname = elf_strptr(e, sh->sh_link, sym.st_name))
120 		    == NULL)
121 			continue;
122 
123 #if defined(__aarch64__) || defined(__arm__)
124 		/* Ignore ARM mapping symbols. */
125 		if (fnname[0] == '$' &&
126 		    (fnname[1] == 'a' || fnname[1] == 't' ||
127 		    fnname[1] == 'd' || fnname[1] == 'x'))
128 			continue;
129 
130 		/*
131 		 * Clear LSB from starting addresses for functions
132 		 * which execute in Thumb mode.  We should perhaps
133 		 * only do this for functions in a $t mapping symbol
134 		 * range, but parsing mapping symbols would be a lot
135 		 * of work and function addresses shouldn't have the
136 		 * LSB set otherwise.
137 		 */
138 		sym.st_value &= ~1;
139 #endif
140 
141 		symptr->ps_name  = pmcstat_string_intern(fnname);
142 		symptr->ps_start = sym.st_value - image->pi_vaddr;
143 		symptr->ps_end   = symptr->ps_start + sym.st_size;
144 
145 		symptr++;
146 		newsyms++;
147 	}
148 
149 	image->pi_symcount += newsyms;
150 	if (image->pi_symcount == 0)
151 		return;
152 
153 	assert(newsyms <= nfuncsyms);
154 
155 	/*
156 	 * Return space to the system if there were duplicates.
157 	 */
158 	if (newsyms < nfuncsyms)
159 		image->pi_symbols = reallocarray(image->pi_symbols,
160 		    image->pi_symcount, sizeof(*symptr));
161 
162 	/*
163 	 * Keep the list of symbols sorted.
164 	 */
165 	qsort(image->pi_symbols, image->pi_symcount, sizeof(*symptr),
166 	    pmcstat_symbol_compare);
167 
168 	/*
169 	 * Deal with function symbols that have a size of 'zero' by
170 	 * making them extend to the next higher address.  These
171 	 * symbols are usually defined in assembly code.
172 	 */
173 	for (symptr = image->pi_symbols;
174 	     symptr < image->pi_symbols + (image->pi_symcount - 1);
175 	     symptr++)
176 		if (symptr->ps_start == symptr->ps_end)
177 			symptr->ps_end = (symptr+1)->ps_start;
178 }
179 
180 /*
181  * Record the fact that PC values from 'start' to 'end' come from
182  * image 'image'.
183  */
184 
185 void
186 pmcstat_image_link(struct pmcstat_process *pp, struct pmcstat_image *image,
187     uintfptr_t start)
188 {
189 	struct pmcstat_pcmap *pcm, *pcmnew;
190 	uintfptr_t offset;
191 #ifdef __powerpc__
192 	unsigned long kernbase;
193 	size_t kernbase_len;
194 #endif
195 
196 	assert(image->pi_type != PMCSTAT_IMAGE_UNKNOWN &&
197 	    image->pi_type != PMCSTAT_IMAGE_INDETERMINABLE);
198 
199 	if ((pcmnew = malloc(sizeof(*pcmnew))) == NULL)
200 		err(EX_OSERR, "ERROR: Cannot create a map entry");
201 
202 	/*
203 	 * PowerPC kernel is of DYN type and it has a base address
204 	 * where it is initially loaded, before being relocated.
205 	 * As the address in 'start' is where the kernel was relocated to,
206 	 * but the symbols always use the original base address, we need to
207 	 * subtract it to get the correct offset.
208 	 */
209 #ifdef __powerpc__
210 	if (pp->pp_pid == -1) {
211 		kernbase = 0;
212 		kernbase_len = sizeof(kernbase);
213 		if (sysctlbyname("kern.base_address", &kernbase, &kernbase_len,
214 		    NULL, 0) == -1)
215 			warnx(
216 			    "WARNING: Could not retrieve kernel base address");
217 		else
218 			start -= kernbase;
219 	}
220 #endif
221 
222 	/*
223 	 * Adjust the map entry to only cover the text portion
224 	 * of the object.
225 	 */
226 
227 	offset = start - image->pi_vaddr;
228 	pcmnew->ppm_lowpc  = image->pi_start + offset;
229 	pcmnew->ppm_highpc = image->pi_end + offset;
230 	pcmnew->ppm_image  = image;
231 
232 	assert(pcmnew->ppm_lowpc < pcmnew->ppm_highpc);
233 
234 	/* Overlapped mmap()'s are assumed to never occur. */
235 	TAILQ_FOREACH(pcm, &pp->pp_map, ppm_next)
236 	    if (pcm->ppm_lowpc >= pcmnew->ppm_highpc)
237 		    break;
238 
239 	if (pcm == NULL)
240 		TAILQ_INSERT_TAIL(&pp->pp_map, pcmnew, ppm_next);
241 	else
242 		TAILQ_INSERT_BEFORE(pcm, pcmnew, ppm_next);
243 }
244 
245 /*
246  * Determine whether a given executable image is an A.OUT object, and
247  * if so, fill in its parameters from the text file.
248  * Sets image->pi_type.
249  */
250 
251 void
252 pmcstat_image_get_aout_params(struct pmcstat_image *image,
253     struct pmcstat_args *args)
254 {
255 	int fd;
256 	ssize_t nbytes;
257 	struct exec ex;
258 	const char *path;
259 	char buffer[PATH_MAX];
260 
261 	path = pmcstat_string_unintern(image->pi_execpath);
262 	assert(path != NULL);
263 
264 	if (image->pi_iskernelmodule)
265 		errx(EX_SOFTWARE,
266 		    "ERROR: a.out kernel modules are unsupported \"%s\"", path);
267 
268 	(void) snprintf(buffer, sizeof(buffer), "%s%s",
269 	    args->pa_fsroot, path);
270 
271 	if ((fd = open(buffer, O_RDONLY, 0)) < 0 ||
272 	    (nbytes = read(fd, &ex, sizeof(ex))) < 0) {
273 		if (args->pa_verbosity >= 2)
274 			warn("WARNING: Cannot determine type of \"%s\"",
275 			    path);
276 		image->pi_type = PMCSTAT_IMAGE_INDETERMINABLE;
277 		if (fd != -1)
278 			(void) close(fd);
279 		return;
280 	}
281 
282 	(void) close(fd);
283 
284 	if ((unsigned) nbytes != sizeof(ex) ||
285 	    N_BADMAG(ex))
286 		return;
287 
288 	image->pi_type = PMCSTAT_IMAGE_AOUT;
289 
290 	/* TODO: the rest of a.out processing */
291 
292 	return;
293 }
294 
295 /*
296  * Examine an ELF file to determine the size of its text segment.
297  * Sets image->pi_type if anything conclusive can be determined about
298  * this image.
299  */
300 
301 void
302 pmcstat_image_get_elf_params(struct pmcstat_image *image,
303     struct pmcstat_args *args)
304 {
305 	int fd;
306 	size_t i, nph, nsh;
307 	const char *path, *elfbase;
308 	char *p, *endp;
309 	bool first_exec_segment;
310 	uintfptr_t minva, maxva;
311 	Elf *e;
312 	Elf_Scn *scn;
313 	GElf_Ehdr eh;
314 	GElf_Phdr ph;
315 	GElf_Shdr sh;
316 	enum pmcstat_image_type image_type;
317 	char buffer[PATH_MAX];
318 	char buffer_modules[PATH_MAX];
319 
320 	assert(image->pi_type == PMCSTAT_IMAGE_UNKNOWN);
321 
322 	image->pi_start = minva = ~(uintfptr_t) 0;
323 	image->pi_end = maxva = (uintfptr_t) 0;
324 	image->pi_type = image_type = PMCSTAT_IMAGE_INDETERMINABLE;
325 	image->pi_isdynamic = 0;
326 	image->pi_dynlinkerpath = NULL;
327 	image->pi_vaddr = 0;
328 
329 	path = pmcstat_string_unintern(image->pi_execpath);
330 	assert(path != NULL);
331 
332 	/*
333 	 * Look for kernel modules under FSROOT/KERNELPATH/NAME and
334 	 * FSROOT/boot/modules/NAME, and user mode executable objects
335 	 * under FSROOT/PATHNAME.
336 	 */
337 	if (image->pi_iskernelmodule) {
338 		(void) snprintf(buffer, sizeof(buffer), "%s%s/%s",
339 		    args->pa_fsroot, args->pa_kernel, path);
340 		(void) snprintf(buffer_modules, sizeof(buffer_modules),
341 		    "%s/boot/modules/%s", args->pa_fsroot, path);
342 	} else {
343 		(void) snprintf(buffer, sizeof(buffer), "%s%s",
344 		    args->pa_fsroot, path);
345 	}
346 
347 	e = NULL;
348 	fd = open(buffer, O_RDONLY, 0);
349 	if (fd < 0 && !image->pi_iskernelmodule) {
350 		warnx("WARNING: Cannot open \"%s\".",
351 		    buffer);
352 		goto done;
353 	}
354 	if (fd < 0 && (fd = open(buffer_modules, O_RDONLY, 0)) < 0) {
355 		warnx("WARNING: Cannot open \"%s\" or \"%s\".",
356 		    buffer, buffer_modules);
357 		goto done;
358 	}
359 	if (elf_version(EV_CURRENT) == EV_NONE) {
360 		warnx("WARNING: failed to init elf\n");
361 		goto done;
362 	}
363 
364 	if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
365 		warnx("WARNING: Cannot read \"%s\".",
366 		    buffer);
367 		goto done;
368 	}
369 
370 	if (elf_kind(e) != ELF_K_ELF) {
371 		if (args->pa_verbosity >= 2)
372 			warnx("WARNING: Cannot determine the type of \"%s\".",
373 			    buffer);
374 		goto done;
375 	}
376 
377 	if (gelf_getehdr(e, &eh) != &eh) {
378 		warnx(
379 		    "WARNING: Cannot retrieve the ELF Header for \"%s\": %s.",
380 		    buffer, elf_errmsg(-1));
381 		goto done;
382 	}
383 
384 	if (eh.e_type != ET_EXEC && eh.e_type != ET_DYN &&
385 	    !(image->pi_iskernelmodule && eh.e_type == ET_REL)) {
386 		warnx("WARNING: \"%s\" is of an unsupported ELF type.",
387 		    buffer);
388 		goto done;
389 	}
390 
391 	image_type = eh.e_ident[EI_CLASS] == ELFCLASS32 ?
392 	    PMCSTAT_IMAGE_ELF32 : PMCSTAT_IMAGE_ELF64;
393 
394 	/*
395 	 * Determine the virtual address where an executable would be
396 	 * loaded.  Additionally, for dynamically linked executables,
397 	 * save the pathname to the runtime linker.
398 	 */
399 	if (eh.e_type != ET_REL) {
400 		if (elf_getphnum(e, &nph) == 0) {
401 			warnx(
402 "WARNING: Could not determine the number of program headers in \"%s\": %s.",
403 			    buffer,
404 			    elf_errmsg(-1));
405 			goto done;
406 		}
407 		first_exec_segment = true;
408 		for (i = 0; i < eh.e_phnum; i++) {
409 			if (gelf_getphdr(e, i, &ph) != &ph) {
410 				warnx(
411 "WARNING: Retrieval of PHDR entry #%ju in \"%s\" failed: %s.",
412 				    (uintmax_t) i, buffer, elf_errmsg(-1));
413 				goto done;
414 			}
415 			switch (ph.p_type) {
416 			case PT_DYNAMIC:
417 				image->pi_isdynamic = 1;
418 				break;
419 			case PT_INTERP:
420 				if ((elfbase = elf_rawfile(e, NULL)) == NULL) {
421 					warnx(
422 "WARNING: Cannot retrieve the interpreter for \"%s\": %s.",
423 					    buffer, elf_errmsg(-1));
424 					goto done;
425 				}
426 				image->pi_dynlinkerpath =
427 				    pmcstat_string_intern(elfbase +
428 				        ph.p_offset);
429 				break;
430 			case PT_LOAD:
431 				if ((ph.p_flags & PF_X) != 0 &&
432 				    first_exec_segment) {
433 					image->pi_vaddr = ph.p_vaddr & (-ph.p_align);
434 					first_exec_segment = false;
435 				}
436 				break;
437 			}
438 		}
439 	}
440 
441 	/*
442 	 * Get the min and max VA associated with this ELF object.
443 	 */
444 	if (elf_getshnum(e, &nsh) == 0) {
445 		warnx(
446 "WARNING: Could not determine the number of sections for \"%s\": %s.",
447 		    buffer, elf_errmsg(-1));
448 		goto done;
449 	}
450 
451 	for (i = 0; i < nsh; i++) {
452 		if ((scn = elf_getscn(e, i)) == NULL ||
453 		    gelf_getshdr(scn, &sh) != &sh) {
454 			warnx(
455 "WARNING: Could not retrieve section header #%ju in \"%s\": %s.",
456 			    (uintmax_t) i, buffer, elf_errmsg(-1));
457 			goto done;
458 		}
459 		if (sh.sh_flags & SHF_EXECINSTR) {
460 			minva = min(minva, sh.sh_addr);
461 			maxva = max(maxva, sh.sh_addr + sh.sh_size);
462 		}
463 		if (sh.sh_type == SHT_SYMTAB || sh.sh_type == SHT_DYNSYM)
464 			pmcstat_image_add_symbols(image, e, scn, &sh);
465 	}
466 
467 	image->pi_start = minva;
468 	image->pi_end   = maxva;
469 	image->pi_type  = image_type;
470 	image->pi_fullpath = pmcstat_string_intern(buffer);
471 
472 	/* Build display name
473 	 */
474 	endp = buffer;
475 	for (p = buffer; *p; p++)
476 		if (*p == '/')
477 			endp = p+1;
478 	image->pi_name = pmcstat_string_intern(endp);
479 
480  done:
481 	(void) elf_end(e);
482 	if (fd >= 0)
483 		(void) close(fd);
484 	return;
485 }
486 
487 /*
488  * Given an image descriptor, determine whether it is an ELF, or AOUT.
489  * If no handler claims the image, set its type to 'INDETERMINABLE'.
490  */
491 
492 void
493 pmcstat_image_determine_type(struct pmcstat_image *image,
494     struct pmcstat_args *args)
495 {
496 	assert(image->pi_type == PMCSTAT_IMAGE_UNKNOWN);
497 
498 	/* Try each kind of handler in turn */
499 	if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
500 		pmcstat_image_get_elf_params(image, args);
501 	if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
502 		pmcstat_image_get_aout_params(image, args);
503 
504 	/*
505 	 * Otherwise, remember that we tried to determine
506 	 * the object's type and had failed.
507 	 */
508 	if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
509 		image->pi_type = PMCSTAT_IMAGE_INDETERMINABLE;
510 }
511 
512 /*
513  * Locate an image descriptor given an interned path, adding a fresh
514  * descriptor to the cache if necessary.  This function also finds a
515  * suitable name for this image's sample file.
516  *
517  * We defer filling in the file format specific parts of the image
518  * structure till the time we actually see a sample that would fall
519  * into this image.
520  */
521 
522 struct pmcstat_image *
523 pmcstat_image_from_path(pmcstat_interned_string internedpath,
524     int iskernelmodule, struct pmcstat_args *args,
525     struct pmc_plugins *plugins)
526 {
527 	int hash;
528 	struct pmcstat_image *pi;
529 
530 	hash = pmcstat_string_lookup_hash(internedpath);
531 
532 	/* First, look for an existing entry. */
533 	LIST_FOREACH(pi, &pmcstat_image_hash[hash], pi_next)
534 	    if (pi->pi_execpath == internedpath &&
535 		  pi->pi_iskernelmodule == iskernelmodule)
536 		    return (pi);
537 
538 	/*
539 	 * Allocate a new entry and place it at the head of the hash
540 	 * and LRU lists.
541 	 */
542 	pi = malloc(sizeof(*pi));
543 	if (pi == NULL)
544 		return (NULL);
545 
546 	pi->pi_type = PMCSTAT_IMAGE_UNKNOWN;
547 	pi->pi_execpath = internedpath;
548 	pi->pi_start = ~0;
549 	pi->pi_end = 0;
550 	pi->pi_entry = 0;
551 	pi->pi_vaddr = 0;
552 	pi->pi_isdynamic = 0;
553 	pi->pi_iskernelmodule = iskernelmodule;
554 	pi->pi_dynlinkerpath = NULL;
555 	pi->pi_symbols = NULL;
556 	pi->pi_symcount = 0;
557 	pi->pi_addr2line = NULL;
558 
559 	if (plugins[args->pa_pplugin].pl_initimage != NULL)
560 		plugins[args->pa_pplugin].pl_initimage(pi);
561 	if (plugins[args->pa_plugin].pl_initimage != NULL)
562 		plugins[args->pa_plugin].pl_initimage(pi);
563 
564 	LIST_INSERT_HEAD(&pmcstat_image_hash[hash], pi, pi_next);
565 
566 	return (pi);
567 }
568