1441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Copyright (C) 2002, 2004 Red Hat, Inc.
2cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   This file is part of Red Hat elfutils.
3441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
4441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
5cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Red Hat elfutils is free software; you can redistribute it and/or modify
6cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   it under the terms of the GNU General Public License as published by the
7cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Free Software Foundation; version 2 of the License.
8441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
9cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Red Hat elfutils is distributed in the hope that it will be useful, but
10cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   WITHOUT ANY WARRANTY; without even the implied warranty of
11cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   General Public License for more details.
13cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
14cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   You should have received a copy of the GNU General Public License along
15cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   with Red Hat elfutils; if not, write to the Free Software Foundation,
16cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
17cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
18cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Red Hat elfutils is an included package of the Open Invention Network.
19cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   An included package of the Open Invention Network is a package for which
20cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Open Invention Network licensees cross-license their patents.  No patent
21cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   license is granted, either expressly or impliedly, by designation as an
22cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   included package.  Should you wish to participate in the Open Invention
23cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Network licensing program, please visit www.openinventionnetwork.com
24cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   <http://www.openinventionnetwork.com>.  */
25cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
26cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#ifdef HAVE_CONFIG_H
27cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng# include <config.h>
28cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#endif
29441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
30441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <fcntl.h>
31441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <inttypes.h>
32441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <libelf.h>
33cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include ELFUTILS_HEADER(dw)
34441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <stdio.h>
35441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <unistd.h>
36441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
37441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
38441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectint
39441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectmain (int argc, char *argv[])
40441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
41441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  int result = 0;
42441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  int cnt;
43441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
44441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  for (cnt = 1; cnt < argc; ++cnt)
45441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
46441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      int fd = open (argv[cnt], O_RDONLY);
47441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
48441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
49441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if  (dbg == NULL)
50441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	{
51441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  printf ("%s not usable: %s\n", argv[cnt], dwarf_errmsg (-1));
52441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  close  (fd);
53441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  continue;
54441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	}
55441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
56441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      Dwarf_Off cuoff = 0;
57441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      Dwarf_Off old_cuoff = 0;
58441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      size_t hsize;
59441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      Dwarf_Off ao;
60441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      uint8_t asz;
61441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      uint8_t osz;
62441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      while (dwarf_nextcu (dbg, cuoff, &cuoff, &hsize, &ao, &asz, &osz) == 0)
63441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	{
64441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  printf ("cuhl = %zu, o = %llu, asz = %hhu, osz = %hhu, ncu = %llu\n",
65441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		  hsize, (unsigned long long int) ao,
66441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		  asz, osz, (unsigned long long int) cuoff);
67441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
68441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  /* Get the DIE for the CU.  */
69441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  Dwarf_Die die;
70441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 	  if (dwarf_offdie (dbg, old_cuoff + hsize, &die) == NULL)
71441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    {
72441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      /* Something went wrong.  */
73441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      printf ("%s: cannot get CU die\n", argv[cnt]);
74441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      result = 1;
75441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      break;
76441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    }
77441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  old_cuoff = cuoff;
78441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
79441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  Dwarf_Lines *lb;
80441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  size_t nlb;
81441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  if (dwarf_getsrclines (&die, &lb, &nlb) != 0)
82441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    {
83441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      printf ("%s: cannot get lines\n", argv[cnt]);
84441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      result = 1;
85441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      break;
86441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    }
87441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
88441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  printf (" %zu lines\n", nlb);
89441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
90441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  for (size_t i = 0; i < nlb; ++i)
91441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    {
92441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      Dwarf_Line *l = dwarf_onesrcline (lb, i);
93441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      if (l == NULL)
94441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		{
95441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		  printf ("%s: cannot get individual line\n", argv[cnt]);
96441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		  result = 1;
97441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		  break;
98441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		}
99441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
100441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      Dwarf_Addr addr;
101441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      if (dwarf_lineaddr (l, &addr) != 0)
102441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		addr = 0;
103441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      const char *file = dwarf_linesrc (l, NULL, NULL);
104441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      int line;
105441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      if (dwarf_lineno (l, &line) != 0)
106441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		line = 0;
107441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
108441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      printf ("%" PRIx64 ": %s:%d:", (uint64_t) addr,
109441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		      file ?: "???", line);
110441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
111441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      int column;
112441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      if (dwarf_linecol (l, &column) != 0)
113441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		column = 0;
114441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      if (column >= 0)
115441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		printf ("%d:", column);
116441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
117441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      bool is_stmt;
118441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      if (dwarf_linebeginstatement (l, &is_stmt) != 0)
119441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		is_stmt = false;
120441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      bool end_sequence;
121441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      if (dwarf_lineendsequence (l, &end_sequence) != 0)
122441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		end_sequence = false;
123441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      bool basic_block;
124441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      if (dwarf_lineblock (l, &basic_block) != 0)
125441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		basic_block = false;
126441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      bool prologue_end;
127441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      if (dwarf_lineprologueend (l, &prologue_end) != 0)
128441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		prologue_end = false;
129441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      bool epilogue_begin;
130441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      if (dwarf_lineepiloguebegin (l, &epilogue_begin) != 0)
131441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		epilogue_begin = false;
132441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
133441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      printf (" is_stmt:%s, end_seq:%s, bb:%s, prologue:%s, epilogue:%s\n",
134441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		      is_stmt ? "yes" : "no", end_sequence ? "yes" : "no",
135441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		      basic_block ? "yes" : "no", prologue_end  ? "yes" : "no",
136441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		      epilogue_begin ? "yes" : "no");
137441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    }
138441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	}
139441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
140441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      dwarf_end (dbg);
141441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      close (fd);
142441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
143441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
144441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  return result;
145441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
146