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