blob: 9eb5ca807adcfd13f71c48b18893a04e853d12ae [file] [log] [blame]
Brad Bishop316dfdd2018-06-25 12:45:53 -04001// dwarfsrcfiles.c - Get source files associated with the dwarf in a elf file.
2// gcc -Wall -g -O2 -lelf -ldw -o dwarfsrcfiles dwarfsrcfiles.c
3//
4// Copyright (C) 2011, Mark Wielaard <mjw@redhat.com>
5//
6// This file is free software. You can redistribute it and/or modify
7// it under the terms of the GNU General Public License (GPL); either
8// version 2, or (at your option) any later version.
9
10#include <argp.h>
11#include <stdio.h>
Andrew Geissler5f350902021-07-23 13:09:54 -040012#include <stdlib.h>
Brad Bishop316dfdd2018-06-25 12:45:53 -040013
14#include <dwarf.h>
15#include <elfutils/libdw.h>
16#include <elfutils/libdwfl.h>
17
18static int
19process_cu (Dwarf_Die *cu_die)
20{
21 Dwarf_Attribute attr;
22 const char *name;
23 const char *dir = NULL;
24
25 Dwarf_Files *files;
26 size_t n;
27 int i;
28
29 if (dwarf_tag (cu_die) != DW_TAG_compile_unit)
30 {
31 fprintf (stderr, "DIE isn't a compile unit");
32 return -1;
33 }
34
35 if (dwarf_attr (cu_die, DW_AT_name, &attr) == NULL)
36 {
37 fprintf(stderr, "CU doesn't have a DW_AT_name");
38 return -1;
39 }
40
41 name = dwarf_formstring (&attr);
42 if (name == NULL)
43 {
44 fprintf(stderr, "Couldn't get DW_AT_name as string, %s",
45 dwarf_errmsg (-1));
46 return -1;
47 }
48
49 if (dwarf_attr (cu_die, DW_AT_comp_dir, &attr) != NULL)
50 {
51 dir = dwarf_formstring (&attr);
52 if (dir == NULL)
53 {
54 fprintf(stderr, "Couldn't get DW_AT_comp_die as string, %s",
55 dwarf_errmsg (-1));
56 return -1;
57 }
58 }
59
60 if (dir == NULL)
61 printf ("%s\n", name);
62 else
63 printf ("%s/%s\n", dir, name);
64
65 if (dwarf_getsrcfiles (cu_die, &files, &n) != 0)
66 {
67 fprintf(stderr, "Couldn't get CU file table, %s",
68 dwarf_errmsg (-1));
69 return -1;
70 }
71
72 for (i = 1; i < n; i++)
73 {
74 const char *file = dwarf_filesrc (files, i, NULL, NULL);
75 if (dir != NULL && file[0] != '/')
76 printf ("\t%s/%s\n", dir, file);
77 else
78 printf ("\t%s\n", file);
79 }
80
81 return 0;
82}
83
84int
85main (int argc, char **argv)
86{
Andrew Geissler5f350902021-07-23 13:09:54 -040087 char* args[5];
Brad Bishop316dfdd2018-06-25 12:45:53 -040088 int res = 0;
89 Dwfl *dwfl;
90 Dwarf_Addr bias;
91
Andrew Geissler5f350902021-07-23 13:09:54 -040092 if (argc != 2) {
Brad Bishop316dfdd2018-06-25 12:45:53 -040093 fprintf(stderr, "Usage %s <file>", argv[0]);
Andrew Geissler5f350902021-07-23 13:09:54 -040094 exit(EXIT_FAILURE);
95 }
Brad Bishop316dfdd2018-06-25 12:45:53 -040096
97 // Pretend "dwarfsrcfiles -e <file>" was given, so we can use standard
98 // dwfl argp parser to open the file for us and get our Dwfl. Useful
99 // in case argument is an ET_REL file (like kernel modules). libdwfl
100 // will fix up relocations for us.
101 args[0] = argv[0];
102 args[1] = "-e";
103 args[2] = argv[1];
Andrew Geissler5f350902021-07-23 13:09:54 -0400104 // We don't want to follow debug linked files due to the way OE processes
105 // files, could race against changes in the linked binary (e.g. objcopy on it)
106 args[3] = "--debuginfo-path";
107 args[4] = "/not/exist";
Brad Bishop316dfdd2018-06-25 12:45:53 -0400108
Andrew Geissler5f350902021-07-23 13:09:54 -0400109 argp_parse (dwfl_standard_argp (), 5, args, 0, NULL, &dwfl);
Brad Bishop316dfdd2018-06-25 12:45:53 -0400110
111 Dwarf_Die *cu = NULL;
112 while ((cu = dwfl_nextcu (dwfl, cu, &bias)) != NULL)
113 res |= process_cu (cu);
114
115 dwfl_end (dwfl);
116
117 return res;
118}