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