Home | History | Annotate | Download | only in libdw
      1 /* Return tag of given DIE.
      2    Copyright (C) 2003, 2004 Red Hat, Inc.
      3    Written by Ulrich Drepper <drepper (at) redhat.com>, 2003.
      4 
      5    This program is Open Source software; you can redistribute it and/or
      6    modify it under the terms of the Open Software License version 1.0 as
      7    published by the Open Source Initiative.
      8 
      9    You should have received a copy of the Open Software License along
     10    with this program; if not, you may obtain a copy of the Open Software
     11    License version 1.0 from http://www.opensource.org/licenses/osl.php or
     12    by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
     13    3001 King Ranch Road, Ukiah, CA 95482.   */
     14 
     15 #ifdef HAVE_CONFIG_H
     16 # include <config.h>
     17 #endif
     18 
     19 #include "libdwP.h"
     20 
     21 
     22 Dwarf_Abbrev *
     23 internal_function_def
     24 __libdw_findabbrev (struct Dwarf_CU *cu, unsigned int code)
     25 {
     26   Dwarf_Abbrev *abb;
     27 
     28   /* See whether the entry is already in the hash table.  */
     29   abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code, NULL);
     30   if (abb == NULL)
     31     while (cu->last_abbrev_offset != (size_t) -1l)
     32       {
     33 	size_t length;
     34 
     35 	/* Find the next entry.  It gets automatically added to the
     36 	   hash table.  */
     37 	abb = __libdw_getabbrev (cu->dbg, cu, cu->last_abbrev_offset, &length,
     38 				 NULL);
     39 	if (abb == NULL)
     40 	  {
     41 	    /* Make sure we do not try to search for it again.  */
     42 	    cu->last_abbrev_offset = (size_t) -1l;
     43 	    abb = (void *) -1l;
     44 	    break;
     45 	  }
     46 
     47 	cu->last_abbrev_offset += length;
     48 
     49 	/* Is this the code we are looking for?  */
     50 	if (abb->code == code)
     51 	  break;
     52       }
     53 
     54   return abb;
     55 }
     56 
     57 
     58 int
     59 dwarf_tag (die)
     60      Dwarf_Die *die;
     61 {
     62   /* Do we already know the abbreviation?  */
     63   if (die->abbrev == NULL)
     64     {
     65       /* Get the abbreviation code.  */
     66       unsigned int u128;
     67       unsigned char *addr = die->addr;
     68       get_uleb128 (u128, addr);
     69 
     70       /* Find the abbreviation.  */
     71       die->abbrev = __libdw_findabbrev (die->cu, u128);
     72     }
     73 
     74   if (die->abbrev == (Dwarf_Abbrev *) -1l)
     75     {
     76       __libdw_seterrno (DWARF_E_INVALID_DWARF);
     77       return DW_TAG_invalid;
     78     }
     79 
     80   return die->abbrev->tag;
     81 }
     82