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