1/*-
2 * Copyright (c) 2009 Kai Wang
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/param.h>
28#include <sys/tree.h>
29
30#include <dwarf.h>
31#include <err.h>
32#include <fcntl.h>
33#include <gelf.h>
34#include <getopt.h>
35#include <libdwarf.h>
36#include <libelftc.h>
37#include <libgen.h>
38#include <stdbool.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42
43#include "_elftc.h"
44
45ELFTC_VCSID("$Id: addr2line.c 3499 2016-11-25 16:06:29Z emaste $");
46
47struct Func {
48	char *name;
49	Dwarf_Unsigned lopc;
50	Dwarf_Unsigned hipc;
51	Dwarf_Unsigned call_file;
52	Dwarf_Unsigned call_line;
53	Dwarf_Ranges *ranges;
54	Dwarf_Signed ranges_cnt;
55	struct Func *inlined_caller;
56	STAILQ_ENTRY(Func) next;
57};
58
59struct range {
60	RB_ENTRY(range) entry;
61	Dwarf_Off off;
62	Dwarf_Unsigned lopc;
63	Dwarf_Unsigned hipc;
64	char **srcfiles;
65	Dwarf_Signed nsrcfiles;
66	STAILQ_HEAD(, Func) funclist;
67	Dwarf_Die die;
68	Dwarf_Debug dbg;
69};
70
71static struct option longopts[] = {
72	{"addresses", no_argument, NULL, 'a'},
73	{"target" , required_argument, NULL, 'b'},
74	{"demangle", no_argument, NULL, 'C'},
75	{"exe", required_argument, NULL, 'e'},
76	{"functions", no_argument, NULL, 'f'},
77	{"inlines", no_argument, NULL, 'i'},
78	{"section", required_argument, NULL, 'j'},
79	{"pretty-print", no_argument, NULL, 'p'},
80	{"basename", no_argument, NULL, 's'},
81	{"help", no_argument, NULL, 'H'},
82	{"version", no_argument, NULL, 'V'},
83	{NULL, 0, NULL, 0}
84};
85
86static int demangle, func, base, inlines, print_addr, pretty_print;
87static char unknown[] = { '?', '?', '\0' };
88static Dwarf_Addr section_base;
89/* Need a new curlopc that stores last lopc value. */
90static Dwarf_Unsigned curlopc = ~0ULL;
91static RB_HEAD(cutree, range) cuhead = RB_INITIALIZER(&cuhead);
92
93static int
94lopccmp(struct range *e1, struct range *e2)
95{
96	return (e1->lopc < e2->lopc ? -1 : e1->lopc > e2->lopc);
97}
98
99RB_PROTOTYPE(cutree, range, entry, lopccmp);
100RB_GENERATE(cutree, range, entry, lopccmp)
101
102#define	USAGE_MESSAGE	"\
103Usage: %s [options] hexaddress...\n\
104  Map program addresses to source file names and line numbers.\n\n\
105  Options:\n\
106  -a      | --addresses       Display address prior to line number info.\n\
107  -b TGT  | --target=TGT      (Accepted but ignored).\n\
108  -e EXE  | --exe=EXE         Use program \"EXE\" to translate addresses.\n\
109  -f      | --functions       Display function names.\n\
110  -i      | --inlines         Display caller info for inlined functions.\n\
111  -j NAME | --section=NAME    Values are offsets into section \"NAME\".\n\
112  -p      | --pretty-print    Display line number info and function name\n\
113                              in human readable manner.\n\
114  -s      | --basename        Only show the base name for each file name.\n\
115  -C      | --demangle        Demangle C++ names.\n\
116  -H      | --help            Print a help message.\n\
117  -V      | --version         Print a version identifier and exit.\n"
118
119static void
120usage(void)
121{
122	(void) fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME());
123	exit(1);
124}
125
126static void
127version(void)
128{
129
130	fprintf(stderr, "%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version());
131	exit(0);
132}
133
134/*
135 * Handle DWARF 4 'offset from' DW_AT_high_pc.  Although we don't
136 * fully support DWARF 4, some compilers (like FreeBSD Clang 3.5.1)
137 * generate DW_AT_high_pc as an offset from DW_AT_low_pc.
138 *
139 * "If the value of the DW_AT_high_pc is of class address, it is the
140 * relocated address of the first location past the last instruction
141 * associated with the entity; if it is of class constant, the value
142 * is an unsigned integer offset which when added to the low PC gives
143 * the address of the first location past the last instruction
144 * associated with the entity."
145 *
146 * DWARF4 spec, section 2.17.2.
147 */
148static int
149handle_high_pc(Dwarf_Die die, Dwarf_Unsigned lopc, Dwarf_Unsigned *hipc)
150{
151	Dwarf_Error de;
152	Dwarf_Half form;
153	Dwarf_Attribute at;
154	int ret;
155
156	ret = dwarf_attr(die, DW_AT_high_pc, &at, &de);
157	if (ret == DW_DLV_ERROR) {
158		warnx("dwarf_attr failed: %s", dwarf_errmsg(de));
159		return (ret);
160	}
161	ret = dwarf_whatform(at, &form, &de);
162	if (ret == DW_DLV_ERROR) {
163		warnx("dwarf_whatform failed: %s", dwarf_errmsg(de));
164		return (ret);
165	}
166	if (dwarf_get_form_class(2, 0, 0, form) == DW_FORM_CLASS_CONSTANT)
167		*hipc += lopc;
168
169	return (DW_DLV_OK);
170}
171
172static struct Func *
173search_func(struct range *range, Dwarf_Unsigned addr)
174{
175	struct Func *f, *f0;
176	Dwarf_Unsigned lopc, hipc, addr_base;
177	int i;
178
179	f0 = NULL;
180
181	STAILQ_FOREACH(f, &range->funclist, next) {
182		if (f->ranges != NULL) {
183			addr_base = 0;
184			for (i = 0; i < f->ranges_cnt; i++) {
185				if (f->ranges[i].dwr_type == DW_RANGES_END)
186					break;
187				if (f->ranges[i].dwr_type ==
188				    DW_RANGES_ADDRESS_SELECTION) {
189					addr_base = f->ranges[i].dwr_addr2;
190					continue;
191				}
192
193				/* DW_RANGES_ENTRY */
194				lopc = f->ranges[i].dwr_addr1 + addr_base;
195				hipc = f->ranges[i].dwr_addr2 + addr_base;
196				if (addr >= lopc && addr < hipc) {
197					if (f0 == NULL ||
198					    (lopc >= f0->lopc &&
199					    hipc <= f0->hipc)) {
200						f0 = f;
201						f0->lopc = lopc;
202						f0->hipc = hipc;
203						break;
204					}
205				}
206			}
207		} else if (addr >= f->lopc && addr < f->hipc) {
208			if (f0 == NULL ||
209			    (f->lopc >= f0->lopc && f->hipc <= f0->hipc))
210				f0 = f;
211		}
212	}
213
214	return (f0);
215}
216
217static void
218collect_func(Dwarf_Debug dbg, Dwarf_Die die, struct Func *parent,
219    struct range *range)
220{
221	Dwarf_Die ret_die, abst_die, spec_die;
222	Dwarf_Error de;
223	Dwarf_Half tag;
224	Dwarf_Unsigned lopc, hipc, ranges_off;
225	Dwarf_Signed ranges_cnt;
226	Dwarf_Off ref;
227	Dwarf_Attribute abst_at, spec_at;
228	Dwarf_Ranges *ranges;
229	const char *funcname;
230	struct Func *f;
231	int found_ranges, ret;
232
233	f = NULL;
234	abst_die = spec_die = NULL;
235
236	if (dwarf_tag(die, &tag, &de)) {
237		warnx("dwarf_tag: %s", dwarf_errmsg(de));
238		goto cont_search;
239	}
240	if (tag == DW_TAG_subprogram || tag == DW_TAG_entry_point ||
241	    tag == DW_TAG_inlined_subroutine || tag == DW_TAG_label) {
242		/*
243		 * Function address range can be specified by either
244		 * a DW_AT_ranges attribute which points to a range list or
245		 * by a pair of DW_AT_low_pc and DW_AT_high_pc attributes.
246		 */
247		ranges = NULL;
248		ranges_cnt = 0;
249		found_ranges = 0;
250		if (dwarf_attrval_unsigned(die, DW_AT_ranges, &ranges_off,
251		    &de) == DW_DLV_OK &&
252		    dwarf_get_ranges(dbg, (Dwarf_Off) ranges_off, &ranges,
253		    &ranges_cnt, NULL, &de) == DW_DLV_OK) {
254			if (ranges != NULL && ranges_cnt > 0) {
255				found_ranges = 1;
256				goto get_func_name;
257			}
258		}
259
260		/*
261		 * Ranges pointer not found.  Search for DW_AT_low_pc, and
262		 * DW_AT_high_pc iff die is not a label.  Labels doesn't have
263		 * hipc attr. */
264		if (tag == DW_TAG_label) {
265			if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lopc,
266			    &de) != DW_DLV_OK)
267				goto cont_search;
268		} else {
269			if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lopc,
270			    &de) || dwarf_attrval_unsigned(die, DW_AT_high_pc,
271			    &hipc, &de))
272				goto cont_search;
273			if (handle_high_pc(die, lopc, &hipc) != DW_DLV_OK)
274				goto cont_search;
275		}
276
277	get_func_name:
278		/*
279		 * Most common case the function name is stored in DW_AT_name
280		 * attribute.
281		 */
282		if (dwarf_attrval_string(die, DW_AT_name, &funcname, &de) ==
283		    DW_DLV_OK)
284			goto add_func;
285
286		/*
287		 * For inlined function, the actual name is probably in the DIE
288		 * referenced by DW_AT_abstract_origin. (if present)
289		 */
290		if (dwarf_attr(die, DW_AT_abstract_origin, &abst_at, &de) ==
291		    DW_DLV_OK &&
292		    dwarf_global_formref(abst_at, &ref, &de) == DW_DLV_OK &&
293		    dwarf_offdie(dbg, ref, &abst_die, &de) == DW_DLV_OK &&
294		    dwarf_attrval_string(abst_die, DW_AT_name, &funcname,
295		    &de) == DW_DLV_OK)
296			goto add_func;
297
298		/*
299		 * If DW_AT_name is not present, but DW_AT_specification is
300		 * present, then probably the actual name is in the DIE
301		 * referenced by DW_AT_specification.
302		 */
303		if (dwarf_attr(die, DW_AT_specification, &spec_at, &de) ==
304		    DW_DLV_OK &&
305		    dwarf_global_formref(spec_at, &ref, &de) == DW_DLV_OK &&
306		    dwarf_offdie(dbg, ref, &spec_die, &de) == DW_DLV_OK &&
307		    dwarf_attrval_string(spec_die, DW_AT_name, &funcname,
308		    &de) == DW_DLV_OK)
309			goto add_func;
310
311		/* Skip if no name associated with this DIE. */
312		goto cont_search;
313
314	add_func:
315		if ((f = calloc(1, sizeof(*f))) == NULL)
316			err(EXIT_FAILURE, "calloc");
317		if ((f->name = strdup(funcname)) == NULL)
318			err(EXIT_FAILURE, "strdup");
319		if (found_ranges) {
320			f->ranges = ranges;
321			f->ranges_cnt = ranges_cnt;
322		} else {
323			f->lopc = lopc;
324			f->hipc = hipc;
325		}
326		if (tag == DW_TAG_inlined_subroutine) {
327			f->inlined_caller = parent;
328			dwarf_attrval_unsigned(die, DW_AT_call_file,
329			    &f->call_file, &de);
330			dwarf_attrval_unsigned(die, DW_AT_call_line,
331			    &f->call_line, &de);
332		}
333		STAILQ_INSERT_TAIL(&range->funclist, f, next);
334	}
335
336cont_search:
337
338	/* Search children. */
339	ret = dwarf_child(die, &ret_die, &de);
340	if (ret == DW_DLV_ERROR)
341		warnx("dwarf_child: %s", dwarf_errmsg(de));
342	else if (ret == DW_DLV_OK) {
343		if (f != NULL)
344			collect_func(dbg, ret_die, f, range);
345		else
346			collect_func(dbg, ret_die, parent, range);
347	}
348
349	/* Search sibling. */
350	ret = dwarf_siblingof(dbg, die, &ret_die, &de);
351	if (ret == DW_DLV_ERROR)
352		warnx("dwarf_siblingof: %s", dwarf_errmsg(de));
353	else if (ret == DW_DLV_OK)
354		collect_func(dbg, ret_die, parent, range);
355
356	/* Cleanup */
357	if (die != range->die)
358		dwarf_dealloc(dbg, die, DW_DLA_DIE);
359
360	if (abst_die != NULL)
361		dwarf_dealloc(dbg, abst_die, DW_DLA_DIE);
362
363	if (spec_die != NULL)
364		dwarf_dealloc(dbg, spec_die, DW_DLA_DIE);
365}
366
367static void
368print_inlines(struct range *range, struct Func *f, Dwarf_Unsigned call_file,
369    Dwarf_Unsigned call_line)
370{
371	char demangled[1024];
372	char *file;
373
374	if (call_file > 0 && (Dwarf_Signed) call_file <= range->nsrcfiles)
375		file = range->srcfiles[call_file - 1];
376	else
377		file = unknown;
378
379	if (pretty_print)
380		printf(" (inlined by) ");
381
382	if (func) {
383		if (demangle && !elftc_demangle(f->name, demangled,
384		    sizeof(demangled), 0)) {
385			if (pretty_print)
386				printf("%s at ", demangled);
387			else
388				printf("%s\n", demangled);
389		} else {
390			if (pretty_print)
391				printf("%s at ", f->name);
392			else
393				printf("%s\n", f->name);
394		}
395	}
396	(void) printf("%s:%ju\n", base ? basename(file) : file,
397	    (uintmax_t) call_line);
398
399	if (f->inlined_caller != NULL)
400		print_inlines(range, f->inlined_caller, f->call_file,
401		    f->call_line);
402}
403
404static struct range *
405culookup(Dwarf_Unsigned addr)
406{
407	struct range find, *res;
408
409	find.lopc = addr;
410	res = RB_NFIND(cutree, &cuhead, &find);
411	if (res != NULL) {
412		if (res->lopc != addr)
413			res = RB_PREV(cutree, &cuhead, res);
414		if (res != NULL && addr >= res->lopc && addr < res->hipc)
415			return (res);
416	} else {
417		res = RB_MAX(cutree, &cuhead);
418		if (res != NULL && addr >= res->lopc && addr < res->hipc)
419			return (res);
420	}
421	return (NULL);
422}
423
424/*
425 * When DW_AT_ranges, DW_AT_low_pc/DW_AT_high_pc are all absent, we check the
426 * children of cu die for labels.  If the address falls into one of the labels
427 * ranges(aranges), return the label DIE.
428 */
429static int
430check_labels(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Unsigned addr,
431    struct range **range) {
432	Dwarf_Addr start;
433	Dwarf_Arange *aranges;
434	Dwarf_Die prev_die, ret_die;
435	Dwarf_Error de;
436	Dwarf_Half tag;
437	Dwarf_Off die_off;
438	Dwarf_Unsigned lopc, length;
439	Dwarf_Signed arcnt;
440	struct range *labelp, **labels;
441	int i, j, label_cnt, ret;
442
443	prev_die = ret_die = NULL;
444	labels = NULL;
445	i = label_cnt = 0;
446
447	/* Find aranges. */
448	ret = dwarf_get_aranges(dbg, &aranges, &arcnt, &de);
449	if (ret != DW_DLV_OK && ret != DW_DLV_NO_ENTRY)
450		warnx("dwarf_get_aranges failed: %s", dwarf_errmsg(de));
451
452	/* Child of current CU. */
453	ret = dwarf_child(die, &prev_die, &de);
454	if (ret == DW_DLV_ERROR)
455		warnx("dwarf_child: %s", dwarf_errmsg(de));
456
457	/* Count labels. */
458	while (1) {
459		if (dwarf_tag(prev_die, &tag, &de) != DW_DLV_OK) {
460			warnx("dwarf_tag failed: %s",
461				dwarf_errmsg(de));
462			return DW_DLV_ERROR;
463		}
464		if (tag == DW_TAG_label) {
465			if (dwarf_attrval_unsigned(prev_die, DW_AT_low_pc,
466			    &lopc, &de) == DW_DLV_OK)
467				label_cnt++;
468		}
469
470		if (dwarf_siblingof(dbg, prev_die, &ret_die, &de) != DW_DLV_OK)
471			break;
472
473		if (prev_die != NULL)
474			dwarf_dealloc(dbg, prev_die, DW_DLA_DIE);
475		prev_die = ret_die;
476	}
477
478	if (label_cnt == 0)
479		return (DW_DLV_NO_ENTRY);
480
481	/* Allocate space for labels. */
482	if ((labels = calloc(label_cnt, sizeof(struct range *))) == NULL)
483		err(EXIT_FAILURE, "calloc");
484
485	/* Add labels to list. */
486	ret = dwarf_child(die, &prev_die, &de);
487	if (ret == DW_DLV_ERROR)
488		warnx("dwarf_child: %s", dwarf_errmsg(de));
489	while (1) {
490		if (dwarf_tag(prev_die, &tag, &de) != DW_DLV_OK) {
491			warnx("dwarf_tag failed: %s",
492				dwarf_errmsg(de));
493			free(labels);
494			return DW_DLV_ERROR;
495		}
496		if (tag == DW_TAG_label) {
497			if (dwarf_attrval_unsigned(prev_die, DW_AT_low_pc,
498			    &lopc, &de) == DW_DLV_OK) {
499				if (curlopc == lopc) {
500					for (i = 0; i < label_cnt - 1; i++) {
501						if (labels[i] != *range)
502							free(labels[i]);
503					}
504					free(labels);
505					return DW_DLV_ERROR;
506				}
507				labelp = calloc(1, sizeof(struct range));
508				if (labelp == NULL)
509					err(EXIT_FAILURE, "calloc");
510				labelp->lopc = lopc;
511				labelp->die = prev_die;
512				labelp->dbg = dbg;
513				STAILQ_INIT(&labelp->funclist);
514				labels[i++] = labelp;
515			}
516		}
517		if (dwarf_siblingof(dbg, prev_die, &ret_die, &de) != DW_DLV_OK)
518			break;
519		if (prev_die != NULL && tag != DW_TAG_label)
520			dwarf_dealloc(dbg, prev_die, DW_DLA_DIE);
521		prev_die = ret_die;
522	}
523
524	/* Set hipc for each label using aranges */
525	for (i = 0; i < label_cnt; i++) {
526		for (j = 0; j < arcnt; j++) {
527			if (dwarf_get_arange_info(aranges[j], &start, &length,
528			    &die_off, &de) != DW_DLV_OK) {
529				warnx("dwarf_get_arange_info failed: %s",
530					dwarf_errmsg(de));
531				continue;
532			}
533			if (labels[i]->lopc == (Dwarf_Unsigned)start) {
534				labels[i]->hipc = start + length;
535				break;
536			}
537		}
538	}
539
540	/* If addr in label's range, we have found the range for this label. */
541	for (i = 0; i < label_cnt; i++) {
542		if (addr >= labels[i]->lopc && addr < labels[i]->hipc) {
543			*range = labels[i];
544			RB_INSERT(cutree, &cuhead, (*range));
545			curlopc = (*range)->lopc;
546			break;
547		}
548	}
549
550	for (i = 0; i < label_cnt - 1; i++) {
551		if (labels[i] != *range)
552			free(labels[i]);
553	}
554	free(labels);
555
556	if (*range != NULL)
557		return (DW_DLV_OK);
558	else
559		return (DW_DLV_NO_ENTRY);
560}
561
562/*
563 * Check whether addr falls into range(s) of current CU.
564 * If so, save current CU to lookup tree.
565 */
566static int
567check_range(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Unsigned addr,
568    struct range **range)
569{
570	Dwarf_Error de;
571	Dwarf_Unsigned addr_base, lopc, hipc;
572	Dwarf_Off ranges_off;
573	Dwarf_Signed ranges_cnt;
574	Dwarf_Ranges *ranges;
575	int i, ret;
576	bool in_cu;
577
578	addr_base = 0;
579	ranges = NULL;
580	ranges_cnt = 0;
581	in_cu = false;
582
583	if (dwarf_attrval_unsigned(die, DW_AT_ranges, &ranges_off, &de) ==
584	    DW_DLV_OK) {
585		ret = dwarf_get_ranges(dbg, ranges_off, &ranges,
586			&ranges_cnt, NULL, &de);
587		if (ret != DW_DLV_OK)
588			return (ret);
589
590		if (!ranges || ranges_cnt <= 0)
591			return (DW_DLV_ERROR);
592
593		for (i = 0; i < ranges_cnt; i++) {
594			if (ranges[i].dwr_type == DW_RANGES_END)
595				return (DW_DLV_NO_ENTRY);
596
597			if (ranges[i].dwr_type ==
598				DW_RANGES_ADDRESS_SELECTION) {
599				addr_base = ranges[i].dwr_addr2;
600				continue;
601			}
602
603			/* DW_RANGES_ENTRY */
604			lopc = ranges[i].dwr_addr1 + addr_base;
605			hipc = ranges[i].dwr_addr2 + addr_base;
606
607			if (lopc == curlopc)
608				return (DW_DLV_ERROR);
609
610			if (addr >= lopc && addr < hipc){
611				in_cu = true;
612				break;
613			}
614		}
615	} else if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lopc, &de) ==
616	    DW_DLV_OK) {
617		if (lopc == curlopc)
618			return (DW_DLV_ERROR);
619		if (dwarf_attrval_unsigned(die, DW_AT_high_pc, &hipc, &de) ==
620		    DW_DLV_OK) {
621			/*
622			 * Check if the address falls into the PC
623			 * range of this CU.
624			 */
625			if (handle_high_pc(die, lopc, &hipc) != DW_DLV_OK)
626				return (DW_DLV_ERROR);
627		} else {
628			/* Assume ~0ULL if DW_AT_high_pc not present. */
629			hipc = ~0ULL;
630		}
631
632		if (addr >= lopc && addr < hipc) {
633			in_cu = true;
634		}
635	} else {
636		/* Addr not found above, try labels. */
637		ret = check_labels(dbg, die, addr, range);
638		return ret;
639	}
640
641	if (in_cu) {
642		if ((*range = calloc(1, sizeof(struct range))) == NULL)
643			err(EXIT_FAILURE, "calloc");
644		(*range)->lopc = lopc;
645		(*range)->hipc = hipc;
646		(*range)->die = die;
647		(*range)->dbg = dbg;
648		STAILQ_INIT(&(*range)->funclist);
649		RB_INSERT(cutree, &cuhead, *range);
650		curlopc = lopc;
651		return (DW_DLV_OK);
652	} else {
653		return (DW_DLV_NO_ENTRY);
654	}
655}
656
657static void
658translate(Dwarf_Debug dbg, Elf *e, const char* addrstr)
659{
660	Dwarf_Die die, ret_die;
661	Dwarf_Line *lbuf;
662	Dwarf_Error de;
663	Dwarf_Half tag;
664	Dwarf_Unsigned addr, lineno, plineno;
665	Dwarf_Signed lcount;
666	Dwarf_Addr lineaddr, plineaddr;
667	struct range *range;
668	struct Func *f;
669	const char *funcname;
670	char *file, *file0, *pfile;
671	char demangled[1024];
672	int ec, i, ret;
673
674	addr = strtoull(addrstr, NULL, 16);
675	addr += section_base;
676	lineno = 0;
677	file = unknown;
678	die = NULL;
679	ret = DW_DLV_OK;
680
681	range = culookup(addr);
682	if (range != NULL) {
683		die = range->die;
684		dbg = range->dbg;
685		goto status_ok;
686	}
687
688	while (true) {
689		/*
690		 * We resume the CU scan from the last place we found a match.
691		 * Because when we have 2 sequential addresses, and the second
692		 * one is of the next CU, it is faster to just go to the next CU
693		 * instead of starting from the beginning.
694		 */
695		ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL,
696		    &de);
697		if (ret == DW_DLV_NO_ENTRY) {
698			if (curlopc == ~0ULL)
699				goto out;
700			ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL,
701			    NULL, &de);
702		}
703		die = NULL;
704		while (dwarf_siblingof(dbg, die, &ret_die, &de) == DW_DLV_OK) {
705			if (die != NULL)
706				dwarf_dealloc(dbg, die, DW_DLA_DIE);
707			die = ret_die;
708			if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) {
709				warnx("dwarf_tag failed: %s",
710				    dwarf_errmsg(de));
711				goto next_cu;
712			}
713
714			/* XXX: What about DW_TAG_partial_unit? */
715			if (tag == DW_TAG_compile_unit)
716				break;
717		}
718
719		if (ret_die == NULL) {
720			warnx("could not find DW_TAG_compile_unit die");
721			goto next_cu;
722		}
723		ret = check_range(dbg, die, addr, &range);
724		if (ret == DW_DLV_OK)
725			break;
726		if (ret == DW_DLV_ERROR)
727			goto out;
728next_cu:
729		if (die != NULL) {
730			dwarf_dealloc(dbg, die, DW_DLA_DIE);
731			die = NULL;
732		}
733	}
734
735	if (ret != DW_DLV_OK || die == NULL)
736		goto out;
737
738status_ok:
739	switch (dwarf_srclines(die, &lbuf, &lcount, &de)) {
740	case DW_DLV_OK:
741		break;
742	case DW_DLV_NO_ENTRY:
743		/* If a CU lacks debug info, just skip it. */
744		goto out;
745	default:
746		warnx("dwarf_srclines: %s", dwarf_errmsg(de));
747		goto out;
748	}
749
750	plineaddr = ~0ULL;
751	plineno = 0;
752	pfile = unknown;
753	for (i = 0; i < lcount; i++) {
754		if (dwarf_lineaddr(lbuf[i], &lineaddr, &de)) {
755			warnx("dwarf_lineaddr: %s", dwarf_errmsg(de));
756			goto out;
757		}
758		if (dwarf_lineno(lbuf[i], &lineno, &de)) {
759			warnx("dwarf_lineno: %s", dwarf_errmsg(de));
760			goto out;
761		}
762		if (dwarf_linesrc(lbuf[i], &file0, &de)) {
763			warnx("dwarf_linesrc: %s", dwarf_errmsg(de));
764		} else
765			file = file0;
766		if (addr == lineaddr)
767			goto out;
768		else if (addr < lineaddr && addr > plineaddr) {
769			lineno = plineno;
770			file = pfile;
771			goto out;
772		}
773		plineaddr = lineaddr;
774		plineno = lineno;
775		pfile = file;
776	}
777
778out:
779	f = NULL;
780	funcname = NULL;
781	if (ret == DW_DLV_OK && (func || inlines) && range != NULL) {
782		if (range->srcfiles == NULL)
783			if (dwarf_srcfiles(die, &range->srcfiles,
784			    &range->nsrcfiles, &de))
785				warnx("dwarf_srcfiles: %s", dwarf_errmsg(de));
786		if (STAILQ_EMPTY(&range->funclist)) {
787			collect_func(dbg, range->die, NULL, range);
788			die = NULL;
789		}
790		f = search_func(range, addr);
791		if (f != NULL)
792			funcname = f->name;
793	}
794
795	if (print_addr) {
796		if ((ec = gelf_getclass(e)) == ELFCLASSNONE) {
797			warnx("gelf_getclass failed: %s", elf_errmsg(-1));
798			ec = ELFCLASS64;
799		}
800		if (ec == ELFCLASS32) {
801			if (pretty_print)
802				printf("0x%08jx: ", (uintmax_t) addr);
803			else
804				printf("0x%08jx\n", (uintmax_t) addr);
805		} else {
806			if (pretty_print)
807				printf("0x%016jx: ", (uintmax_t) addr);
808			else
809				printf("0x%016jx\n", (uintmax_t) addr);
810		}
811	}
812
813	if (func) {
814		if (funcname == NULL)
815			funcname = unknown;
816		if (demangle && !elftc_demangle(funcname, demangled,
817		    sizeof(demangled), 0)) {
818			if (pretty_print)
819				printf("%s at ", demangled);
820			else
821				printf("%s\n", demangled);
822		} else {
823			if (pretty_print)
824				printf("%s at ", funcname);
825			else
826				printf("%s\n", funcname);
827		}
828	}
829
830	(void) printf("%s:%ju\n", base ? basename(file) : file,
831	    (uintmax_t) lineno);
832
833	if (ret == DW_DLV_OK && inlines && range != NULL &&
834	    range->srcfiles != NULL && f != NULL && f->inlined_caller != NULL)
835		print_inlines(range, f->inlined_caller, f->call_file,
836		    f->call_line);
837}
838
839static void
840find_section_base(const char *exe, Elf *e, const char *section)
841{
842	Dwarf_Addr off;
843	Elf_Scn *scn;
844	GElf_Ehdr eh;
845	GElf_Shdr sh;
846	size_t shstrndx;
847	int elferr;
848	const char *name;
849
850	if (gelf_getehdr(e, &eh) != &eh) {
851		warnx("gelf_getehdr failed: %s", elf_errmsg(-1));
852		return;
853	}
854
855	if (!elf_getshstrndx(e, &shstrndx)) {
856		warnx("elf_getshstrndx failed: %s", elf_errmsg(-1));
857		return;
858	}
859
860	(void) elf_errno();
861	off = 0;
862	scn = NULL;
863	while ((scn = elf_nextscn(e, scn)) != NULL) {
864		if (gelf_getshdr(scn, &sh) == NULL) {
865			warnx("gelf_getshdr failed: %s", elf_errmsg(-1));
866			continue;
867		}
868		if ((name = elf_strptr(e, shstrndx, sh.sh_name)) == NULL)
869			goto next;
870		if (!strcmp(section, name)) {
871			if (eh.e_type == ET_EXEC || eh.e_type == ET_DYN) {
872				/*
873				 * For executables, section base is the virtual
874				 * address of the specified section.
875				 */
876				section_base = sh.sh_addr;
877			} else if (eh.e_type == ET_REL) {
878				/*
879				 * For relocatables, section base is the
880				 * relative offset of the specified section
881				 * to the start of the first section.
882				 */
883				section_base = off;
884			} else
885				warnx("unknown e_type %u", eh.e_type);
886			return;
887		}
888	next:
889		off += sh.sh_size;
890	}
891	elferr = elf_errno();
892	if (elferr != 0)
893		warnx("elf_nextscn failed: %s", elf_errmsg(elferr));
894
895	errx(EXIT_FAILURE, "%s: cannot find section %s", exe, section);
896}
897
898int
899main(int argc, char **argv)
900{
901	Elf *e;
902	Dwarf_Debug dbg;
903	Dwarf_Error de;
904	const char *exe, *section;
905	char line[1024];
906	int fd, i, opt;
907
908	exe = NULL;
909	section = NULL;
910	while ((opt = getopt_long(argc, argv, "ab:Ce:fij:psHV", longopts,
911	    NULL)) != -1) {
912		switch (opt) {
913		case 'a':
914			print_addr = 1;
915			break;
916		case 'b':
917			/* ignored */
918			break;
919		case 'C':
920			demangle = 1;
921			break;
922		case 'e':
923			exe = optarg;
924			break;
925		case 'f':
926			func = 1;
927			break;
928		case 'i':
929			inlines = 1;
930			break;
931		case 'j':
932			section = optarg;
933			break;
934		case 'p':
935			pretty_print = 1;
936			break;
937		case 's':
938			base = 1;
939			break;
940		case 'H':
941			usage();
942		case 'V':
943			version();
944		default:
945			usage();
946		}
947	}
948
949	argv += optind;
950	argc -= optind;
951
952	if (exe == NULL)
953		exe = "a.out";
954
955	if ((fd = open(exe, O_RDONLY)) < 0)
956		err(EXIT_FAILURE, "%s", exe);
957
958	if (dwarf_init(fd, DW_DLC_READ, NULL, NULL, &dbg, &de))
959		errx(EXIT_FAILURE, "dwarf_init: %s", dwarf_errmsg(de));
960
961	if (dwarf_get_elf(dbg, &e, &de) != DW_DLV_OK)
962		errx(EXIT_FAILURE, "dwarf_get_elf: %s", dwarf_errmsg(de));
963
964	if (section)
965		find_section_base(exe, e, section);
966	else
967		section_base = 0;
968
969	if (argc > 0)
970		for (i = 0; i < argc; i++)
971			translate(dbg, e, argv[i]);
972	else {
973		setvbuf(stdout, NULL, _IOLBF, 0);
974		while (fgets(line, sizeof(line), stdin) != NULL)
975			translate(dbg, e, line);
976	}
977
978	dwarf_finish(dbg, &de);
979
980	(void) elf_end(e);
981
982	exit(0);
983}
984