xref: /third_party/elfutils/tests/get-lines.c (revision da0c48c4)
1/* Copyright (C) 2002, 2004 Red Hat, Inc.
2   This file is part of elfutils.
3   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
4
5   This file is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 3 of the License, or
8   (at your option) any later version.
9
10   elfutils is distributed in the hope that it will be useful, but
11   WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18#ifdef HAVE_CONFIG_H
19# include <config.h>
20#endif
21
22#include <fcntl.h>
23#include <inttypes.h>
24#include <libelf.h>
25#include ELFUTILS_HEADER(dw)
26#include <stdio.h>
27#include <string.h>
28#include <unistd.h>
29
30
31int
32main (int argc, char *argv[])
33{
34  int result = 0;
35  int cnt;
36
37  for (cnt = 1; cnt < argc; ++cnt)
38    {
39      int fd = open (argv[cnt], O_RDONLY);
40
41      Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
42      if  (dbg == NULL)
43	{
44	  printf ("%s not usable: %s\n", argv[cnt], dwarf_errmsg (-1));
45	  close  (fd);
46	  continue;
47	}
48
49      Dwarf_Off cuoff = 0;
50      Dwarf_Off old_cuoff = 0;
51      size_t hsize;
52      Dwarf_Off ao;
53      uint8_t asz;
54      uint8_t osz;
55      while (dwarf_nextcu (dbg, cuoff, &cuoff, &hsize, &ao, &asz, &osz) == 0)
56	{
57	  printf ("cuhl = %zu, o = %llu, asz = %hhu, osz = %hhu, ncu = %llu\n",
58		  hsize, (unsigned long long int) ao,
59		  asz, osz, (unsigned long long int) cuoff);
60
61	  /* Get the DIE for the CU.  */
62	  Dwarf_Die die;
63 	  if (dwarf_offdie (dbg, old_cuoff + hsize, &die) == NULL)
64	    {
65	      /* Something went wrong.  */
66	      printf ("%s: cannot get CU die\n", argv[cnt]);
67	      result = 1;
68	      break;
69	    }
70	  old_cuoff = cuoff;
71
72	  Dwarf_Lines *lb;
73	  size_t nlb;
74	  if (dwarf_getsrclines (&die, &lb, &nlb) != 0)
75	    {
76	      printf ("%s: cannot get lines\n", argv[cnt]);
77	      result = 1;
78	      break;
79	    }
80
81	  printf (" %zu lines\n", nlb);
82
83	  for (size_t i = 0; i < nlb; ++i)
84	    {
85	      Dwarf_Line *l = dwarf_onesrcline (lb, i);
86	      if (l == NULL)
87		{
88		  printf ("%s: cannot get individual line\n", argv[cnt]);
89		  result = 1;
90		  break;
91		}
92
93	      Dwarf_Addr addr;
94	      if (dwarf_lineaddr (l, &addr) != 0)
95		addr = 0;
96	      const char *file = dwarf_linesrc (l, NULL, NULL);
97	      int line;
98	      if (dwarf_lineno (l, &line) != 0)
99		line = 0;
100
101	      printf ("%" PRIx64 ": %s:%d:", (uint64_t) addr,
102		      file ?: "???", line);
103
104	      /* Getting the file path through the Dwarf_Files should
105		 result in the same path.  */
106	      Dwarf_Files *files;
107	      size_t idx;
108	      if (dwarf_line_file (l, &files, &idx) != 0)
109		{
110		  printf ("%s: cannot get file from line (%zd): %s\n",
111			  argv[cnt], i, dwarf_errmsg (-1));
112		  result = 1;
113		  break;
114		}
115	      const char *path = dwarf_filesrc (files, idx, NULL, NULL);
116	      if ((path == NULL && file != NULL)
117		  || (path != NULL && file == NULL)
118		  || (strcmp (file, path) != 0))
119		{
120		  printf ("%s: line %zd srcline (%s) != file srcline (%s)\n",
121			  argv[cnt], i, file ?: "???", path ?: "???");
122		  result = 1;
123		  break;
124		}
125
126	      int column;
127	      if (dwarf_linecol (l, &column) != 0)
128		column = 0;
129	      if (column >= 0)
130		printf ("%d:", column);
131
132	      bool is_stmt;
133	      if (dwarf_linebeginstatement (l, &is_stmt) != 0)
134		is_stmt = false;
135	      bool end_sequence;
136	      if (dwarf_lineendsequence (l, &end_sequence) != 0)
137		end_sequence = false;
138	      bool basic_block;
139	      if (dwarf_lineblock (l, &basic_block) != 0)
140		basic_block = false;
141	      bool prologue_end;
142	      if (dwarf_lineprologueend (l, &prologue_end) != 0)
143		prologue_end = false;
144	      bool epilogue_begin;
145	      if (dwarf_lineepiloguebegin (l, &epilogue_begin) != 0)
146		epilogue_begin = false;
147
148	      printf (" is_stmt:%s, end_seq:%s, bb:%s, prologue:%s, epilogue:%s\n",
149		      is_stmt ? "yes" : "no", end_sequence ? "yes" : "no",
150		      basic_block ? "yes" : "no", prologue_end  ? "yes" : "no",
151		      epilogue_begin ? "yes" : "no");
152	    }
153	}
154
155      dwarf_end (dbg);
156      close (fd);
157    }
158
159  return result;
160}
161