Blame tests/show-die-info.c

Packit 032894
/* Copyright (C) 1998-2002, 2004, 2006, 2012, 2015 Red Hat, Inc.
Packit 032894
   This file is part of elfutils.
Packit 032894
   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
Packit 032894
Packit 032894
   This file is free software; you can redistribute it and/or modify
Packit 032894
   it under the terms of the GNU General Public License as published by
Packit 032894
   the Free Software Foundation; either version 3 of the License, or
Packit 032894
   (at your option) any later version.
Packit 032894
Packit 032894
   elfutils is distributed in the hope that it will be useful, but
Packit 032894
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 032894
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 032894
   GNU General Public License for more details.
Packit 032894
Packit 032894
   You should have received a copy of the GNU General Public License
Packit 032894
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit 032894
Packit 032894
#include <config.h>
Packit 032894
Packit 032894
#include <dwarf.h>
Packit 032894
#include <inttypes.h>
Packit 032894
#include <libelf.h>
Packit 032894
#include ELFUTILS_HEADER(dw)
Packit 032894
#include <fcntl.h>
Packit 032894
#include <stdio.h>
Packit 032894
#include <string.h>
Packit 032894
#include <unistd.h>
Packit 032894
Packit 032894
#include "../libdw/known-dwarf.h"
Packit 032894
Packit 032894
static const char *
Packit 032894
dwarf_tag_string (unsigned int tag)
Packit 032894
{
Packit 032894
  switch (tag)
Packit 032894
    {
Packit 032894
#define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
Packit 032894
      DWARF_ALL_KNOWN_DW_TAG
Packit 032894
#undef DWARF_ONE_KNOWN_DW_TAG
Packit 032894
    default:
Packit 032894
      return NULL;
Packit 032894
    }
Packit 032894
}
Packit 032894
Packit 032894
static const char *
Packit 032894
dwarf_attr_string (unsigned int attrnum)
Packit 032894
{
Packit 032894
  switch (attrnum)
Packit 032894
    {
Packit 032894
#define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
Packit 032894
      DWARF_ALL_KNOWN_DW_AT
Packit 032894
#undef DWARF_ONE_KNOWN_DW_AT
Packit 032894
    default:
Packit 032894
      return NULL;
Packit 032894
    }
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
void
Packit 032894
handle (Dwarf *dbg, Dwarf_Die *die, int n)
Packit 032894
{
Packit 032894
  Dwarf_Die child;
Packit 032894
  unsigned int tag;
Packit 032894
  const char *str;
Packit 032894
  char buf[30];
Packit 032894
  const char *name;
Packit 032894
  Dwarf_Off off;
Packit 032894
  Dwarf_Off cuoff;
Packit 032894
  size_t cnt;
Packit 032894
  Dwarf_Addr addr;
Packit 032894
  int i;
Packit 032894
Packit 032894
  tag = dwarf_tag (die);
Packit 032894
  if (tag != DW_TAG_invalid)
Packit 032894
    {
Packit 032894
      str = dwarf_tag_string (tag);
Packit 032894
      if (str == NULL)
Packit 032894
	{
Packit 032894
	  snprintf (buf, sizeof buf, "%#x", tag);
Packit 032894
	  str = buf;
Packit 032894
	}
Packit 032894
    }
Packit 032894
  else
Packit 032894
    str = "* NO TAG *";
Packit 032894
Packit 032894
  name = dwarf_diename (die);
Packit 032894
  if (name == 0)
Packit 032894
    name = "* NO NAME *";
Packit 032894
Packit 032894
  off = dwarf_dieoffset (die);
Packit 032894
  cuoff = dwarf_cuoffset (die);
Packit 032894
Packit 032894
  printf ("%*sDW_TAG_%s\n", n * 5, "", str);
Packit 032894
  printf ("%*s Name      : %s\n", n * 5, "", name);
Packit 032894
  printf ("%*s Offset    : %lld\n", n * 5, "", (long long int) off);
Packit 032894
  printf ("%*s CU offset : %lld\n", n * 5, "", (long long int) cuoff);
Packit 032894
Packit 032894
  printf ("%*s Attrs     :", n * 5, "");
Packit 032894
  for (cnt = 0; cnt < 0xffff; ++cnt)
Packit 032894
    if (dwarf_hasattr (die, cnt))
Packit 032894
      printf (" %s", dwarf_attr_string (cnt));
Packit 032894
  puts ("");
Packit 032894
Packit 032894
  if (dwarf_hasattr (die, DW_AT_low_pc) && dwarf_lowpc (die, &addr) == 0)
Packit 032894
    {
Packit 032894
      Dwarf_Attribute attr;
Packit 032894
      Dwarf_Addr addr2;
Packit 032894
      printf ("%*s low PC    : %#llx\n",
Packit 032894
	      n * 5, "", (unsigned long long int) addr);
Packit 032894
Packit 032894
      if (dwarf_attr (die, DW_AT_low_pc, &attr) == NULL
Packit 032894
	  || dwarf_formaddr (&attr, &addr2) != 0
Packit 032894
	  || addr != addr2)
Packit 032894
	puts ("************* DW_AT_low_pc verify failed ************");
Packit 032894
      else if (! dwarf_hasform (&attr, DW_FORM_addr))
Packit 032894
	puts ("************* DW_AT_low_pc form failed ************");
Packit 032894
      else if (dwarf_whatform (&attr) != DW_FORM_addr)
Packit 032894
	puts ("************* DW_AT_low_pc form (2) failed ************");
Packit 032894
      else if (dwarf_whatattr (&attr) != DW_AT_low_pc)
Packit 032894
	puts ("************* DW_AT_low_pc attr failed ************");
Packit 032894
    }
Packit 032894
  if (dwarf_hasattr (die, DW_AT_high_pc) && dwarf_highpc (die, &addr) == 0)
Packit 032894
    {
Packit 032894
      Dwarf_Attribute attr;
Packit 032894
      Dwarf_Addr addr2;
Packit 032894
      printf ("%*s high PC   : %#llx\n",
Packit 032894
	      n * 5, "", (unsigned long long int) addr);
Packit 032894
      if (dwarf_attr (die, DW_AT_high_pc, &attr) == NULL
Packit 032894
	  || dwarf_formaddr (&attr, &addr2) != 0
Packit 032894
	  || addr != addr2)
Packit 032894
	puts ("************* DW_AT_high_pc verify failed ************");
Packit 032894
      else if (! dwarf_hasform (&attr, DW_FORM_addr))
Packit 032894
	puts ("************* DW_AT_high_pc form failed ************");
Packit 032894
      else if (dwarf_whatform (&attr) != DW_FORM_addr)
Packit 032894
	puts ("************* DW_AT_high_pc form (2) failed ************");
Packit 032894
      else if (dwarf_whatattr (&attr) != DW_AT_high_pc)
Packit 032894
	puts ("************* DW_AT_high_pc attr failed ************");
Packit 032894
    }
Packit 032894
Packit 032894
  if (dwarf_hasattr (die, DW_AT_byte_size) && (i = dwarf_bytesize (die)) != -1)
Packit 032894
    {
Packit 032894
      Dwarf_Attribute attr;
Packit 032894
      Dwarf_Word u2;
Packit 032894
      unsigned int u;
Packit 032894
      printf ("%*s byte size : %d\n", n * 5, "", i);
Packit 032894
      if (dwarf_attr (die, DW_AT_byte_size, &attr) == NULL
Packit 032894
	  || dwarf_formudata (&attr, &u2) != 0
Packit 032894
	  || i != (int) u2)
Packit 032894
	puts ("************* DW_AT_byte_size verify failed ************");
Packit 032894
      else if (! dwarf_hasform (&attr, DW_FORM_data1)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_data2)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_data4)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_data8)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_udata))
Packit 032894
	puts ("************* DW_AT_byte_size form failed ************");
Packit 032894
      else if ((u = dwarf_whatform (&attr)) == 0
Packit 032894
	       || (u != DW_FORM_data1
Packit 032894
		   && u != DW_FORM_data2
Packit 032894
		   && u != DW_FORM_data4
Packit 032894
		   && u != DW_FORM_data8
Packit 032894
		   && u != DW_FORM_sdata
Packit 032894
		   && u != DW_FORM_udata))
Packit 032894
	puts ("************* DW_AT_byte_size form (2) failed ************");
Packit 032894
      else if (dwarf_whatattr (&attr) != DW_AT_byte_size)
Packit 032894
	puts ("************* DW_AT_byte_size attr failed ************");
Packit 032894
    }
Packit 032894
  if (dwarf_hasattr (die, DW_AT_bit_size) && (i = dwarf_bitsize (die)) != -1)
Packit 032894
    {
Packit 032894
      Dwarf_Attribute attr;
Packit 032894
      Dwarf_Word u2;
Packit 032894
      unsigned int u;
Packit 032894
      printf ("%*s bit size  : %d\n", n * 5, "", i);
Packit 032894
      if (dwarf_attr (die, DW_AT_bit_size, &attr) == NULL
Packit 032894
	  || dwarf_formudata (&attr, &u2) != 0
Packit 032894
	  || i != (int) u2)
Packit 032894
	puts ("************* DW_AT_bit_size test failed ************");
Packit 032894
      else if (! dwarf_hasform (&attr, DW_FORM_data1)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_data2)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_data4)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_data8)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_udata))
Packit 032894
	puts ("************* DW_AT_bit_size form failed ************");
Packit 032894
      else if ((u = dwarf_whatform (&attr)) == 0
Packit 032894
	       || (u != DW_FORM_data1
Packit 032894
		   && u != DW_FORM_data2
Packit 032894
		   && u != DW_FORM_data4
Packit 032894
		   && u != DW_FORM_data8
Packit 032894
		   && u != DW_FORM_sdata
Packit 032894
		   && u != DW_FORM_udata))
Packit 032894
	puts ("************* DW_AT_bit_size form (2) failed ************");
Packit 032894
      else if (dwarf_whatattr (&attr) != DW_AT_bit_size)
Packit 032894
	puts ("************* DW_AT_bit_size attr failed ************");
Packit 032894
    }
Packit 032894
  if (dwarf_hasattr (die, DW_AT_bit_offset)
Packit 032894
      && (i = dwarf_bitoffset (die)) != -1)
Packit 032894
    {
Packit 032894
      Dwarf_Attribute attr;
Packit 032894
      Dwarf_Word u2;
Packit 032894
      unsigned int u;
Packit 032894
      printf ("%*s bit offset: %d\n", n * 5, "", i);
Packit 032894
      if (dwarf_attr (die, DW_AT_bit_offset, &attr) == NULL
Packit 032894
	  || dwarf_formudata (&attr, &u2) != 0
Packit 032894
	  || i != (int) u2)
Packit 032894
	puts ("************* DW_AT_bit_offset test failed ************");
Packit 032894
      else if (! dwarf_hasform (&attr, DW_FORM_data1)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_data2)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_data4)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_data8)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_udata))
Packit 032894
	puts ("************* DW_AT_bit_offset form failed ************");
Packit 032894
      else if ((u = dwarf_whatform (&attr)) == 0
Packit 032894
	       || (u != DW_FORM_data1
Packit 032894
		   && u != DW_FORM_data2
Packit 032894
		   && u != DW_FORM_data4
Packit 032894
		   && u != DW_FORM_data8
Packit 032894
		   && u != DW_FORM_sdata
Packit 032894
		   && u != DW_FORM_udata))
Packit 032894
	puts ("************* DW_AT_bit_offset form (2) failed ************");
Packit 032894
      else if (dwarf_whatattr (&attr) != DW_AT_bit_offset)
Packit 032894
	puts ("************* DW_AT_bit_offset attr failed ************");
Packit 032894
    }
Packit 032894
Packit 032894
  if (dwarf_hasattr (die, DW_AT_language) && (i = dwarf_srclang (die)) != -1)
Packit 032894
    {
Packit 032894
      Dwarf_Attribute attr;
Packit 032894
      Dwarf_Word u2;
Packit 032894
      unsigned int u;
Packit 032894
      printf ("%*s language  : %d\n", n * 5, "", i);
Packit 032894
      if (dwarf_attr (die, DW_AT_language, &attr) == NULL
Packit 032894
	  || dwarf_formudata (&attr, &u2) != 0
Packit 032894
	  || i != (int) u2)
Packit 032894
	puts ("************* DW_AT_language test failed ************");
Packit 032894
      else if (! dwarf_hasform (&attr, DW_FORM_data1)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_data2)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_data4)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_data8)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_udata))
Packit 032894
	puts ("************* DW_AT_language form failed ************");
Packit 032894
      else if ((u = dwarf_whatform (&attr)) == 0
Packit 032894
	       || (u != DW_FORM_data1
Packit 032894
		   && u != DW_FORM_data2
Packit 032894
		   && u != DW_FORM_data4
Packit 032894
		   && u != DW_FORM_data8
Packit 032894
		   && u != DW_FORM_sdata
Packit 032894
		   && u != DW_FORM_udata))
Packit 032894
	puts ("************* DW_AT_language form (2) failed ************");
Packit 032894
      else if (dwarf_whatattr (&attr) != DW_AT_language)
Packit 032894
	puts ("************* DW_AT_language attr failed ************");
Packit 032894
    }
Packit 032894
Packit 032894
  if (dwarf_hasattr (die, DW_AT_ordering)
Packit 032894
      && (i = dwarf_arrayorder (die)) != -1)
Packit 032894
    {
Packit 032894
      Dwarf_Attribute attr;
Packit 032894
      Dwarf_Word u2;
Packit 032894
      unsigned int u;
Packit 032894
      printf ("%*s ordering  : %d\n", n * 5, "", i);
Packit 032894
      if (dwarf_attr (die, DW_AT_ordering, &attr) == NULL
Packit 032894
	  || dwarf_formudata (&attr, &u2) != 0
Packit 032894
	  || i != (int) u2)
Packit 032894
	puts ("************* DW_AT_ordering test failed ************");
Packit 032894
      else if (! dwarf_hasform (&attr, DW_FORM_data1)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_data2)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_data4)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_data8)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
Packit 032894
	       && ! dwarf_hasform (&attr, DW_FORM_udata))
Packit 032894
	puts ("************* DW_AT_ordering failed ************");
Packit 032894
      else if ((u = dwarf_whatform (&attr)) == 0
Packit 032894
	       || (u != DW_FORM_data1
Packit 032894
		   && u != DW_FORM_data2
Packit 032894
		   && u != DW_FORM_data4
Packit 032894
		   && u != DW_FORM_data8
Packit 032894
		   && u != DW_FORM_sdata
Packit 032894
		   && u != DW_FORM_udata))
Packit 032894
	puts ("************* DW_AT_ordering form (2) failed ************");
Packit 032894
      else if (dwarf_whatattr (&attr) != DW_AT_ordering)
Packit 032894
	puts ("************* DW_AT_ordering attr failed ************");
Packit 032894
    }
Packit 032894
Packit 032894
  if (dwarf_hasattr (die, DW_AT_comp_dir))
Packit 032894
    {
Packit 032894
      Dwarf_Attribute attr;
Packit 032894
      if (dwarf_attr (die, DW_AT_comp_dir, &attr) == NULL
Packit 032894
	  || (name = dwarf_formstring (&attr)) == NULL)
Packit 032894
	puts ("************* DW_AT_comp_dir attr failed ************");
Packit 032894
      else
Packit 032894
	printf ("%*s directory : %s\n", n * 5, "", name);
Packit 032894
    }
Packit 032894
Packit 032894
  if (dwarf_hasattr (die, DW_AT_producer))
Packit 032894
    {
Packit 032894
      Dwarf_Attribute attr;
Packit 032894
      if (dwarf_attr (die, DW_AT_producer, &attr) == NULL
Packit 032894
	  || (name = dwarf_formstring (&attr)) == NULL)
Packit 032894
	puts ("************* DW_AT_comp_dir attr failed ************");
Packit 032894
      else
Packit 032894
	printf ("%*s producer  : %s\n", n * 5, "", name);
Packit 032894
    }
Packit 032894
Packit 032894
  if (dwarf_haschildren (die) != 0 && dwarf_child (die, &child) == 0)
Packit 032894
    handle (dbg, &child, n + 1);
Packit 032894
  if (dwarf_siblingof (die, die) == 0)
Packit 032894
    handle (dbg, die, n);
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
int
Packit 032894
main (int argc, char *argv[])
Packit 032894
{
Packit 032894
 int cnt;
Packit 032894
Packit 032894
  for (cnt = 1; cnt < argc; ++cnt)
Packit 032894
    {
Packit 032894
      int fd = open (argv[cnt], O_RDONLY);
Packit 032894
      Dwarf *dbg;
Packit 032894
Packit 032894
      printf ("file: %s\n", basename (argv[cnt]));
Packit 032894
Packit 032894
      dbg = dwarf_begin (fd, DWARF_C_READ);
Packit 032894
      if (dbg == NULL)
Packit 032894
	{
Packit 032894
	  printf ("%s not usable\n", argv[cnt]);
Packit 032894
	  close (fd);
Packit 032894
	  continue;
Packit 032894
	}
Packit 032894
Packit 032894
      Dwarf_Off off = 0;
Packit 032894
      Dwarf_Off old_off = 0;
Packit 032894
      size_t hsize;
Packit 032894
      Dwarf_Off abbrev;
Packit 032894
      uint8_t addresssize;
Packit 032894
      uint8_t offsetsize;
Packit 032894
      while (dwarf_nextcu (dbg, off, &off, &hsize, &abbrev, &addresssize,
Packit 032894
			   &offsetsize) == 0)
Packit 032894
	{
Packit 032894
	  printf ("New CU: off = %llu, hsize = %zu, ab = %llu, as = %" PRIu8
Packit 032894
		  ", os = %" PRIu8 "\n",
Packit 032894
		  (unsigned long long int) old_off, hsize,
Packit 032894
		  (unsigned long long int) abbrev, addresssize,
Packit 032894
		  offsetsize);
Packit 032894
Packit 032894
	  Dwarf_Die die;
Packit 032894
	  if (dwarf_offdie (dbg, old_off + hsize, &die) != NULL)
Packit 032894
	    handle (dbg, &die, 1);
Packit 032894
Packit 032894
	  old_off = off;
Packit 032894
	}
Packit 032894
Packit 032894
      dwarf_end (dbg);
Packit 032894
      close (fd);
Packit 032894
    }
Packit 032894
Packit 032894
  return 0;
Packit 032894
}