LCOV - code coverage report
Current view: top level - libdw - dwarf_nextcu.c (source / functions) Hit Total Coverage
Test: lcov.out Lines: 41 47 87.2 %
Date: 2017-01-05 09:15:16 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Advance to next CU header.
       2             :    Copyright (C) 2002-2010 Red Hat, Inc.
       3             :    This file is part of elfutils.
       4             :    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
       5             : 
       6             :    This file is free software; you can redistribute it and/or modify
       7             :    it under the terms of either
       8             : 
       9             :      * the GNU Lesser General Public License as published by the Free
      10             :        Software Foundation; either version 3 of the License, or (at
      11             :        your option) any later version
      12             : 
      13             :    or
      14             : 
      15             :      * the GNU General Public License as published by the Free
      16             :        Software Foundation; either version 2 of the License, or (at
      17             :        your option) any later version
      18             : 
      19             :    or both in parallel, as here.
      20             : 
      21             :    elfutils is distributed in the hope that it will be useful, but
      22             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      23             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      24             :    General Public License for more details.
      25             : 
      26             :    You should have received copies of the GNU General Public License and
      27             :    the GNU Lesser General Public License along with this program.  If
      28             :    not, see <http://www.gnu.org/licenses/>.  */
      29             : 
      30             : #ifdef HAVE_CONFIG_H
      31             : # include <config.h>
      32             : #endif
      33             : 
      34             : #include <libdwP.h>
      35             : #include <dwarf.h>
      36             : 
      37             : 
      38             : int
      39      114065 : dwarf_next_unit (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off,
      40             :                  size_t *header_sizep, Dwarf_Half *versionp,
      41             :                  Dwarf_Off *abbrev_offsetp, uint8_t *address_sizep,
      42             :                  uint8_t *offset_sizep, uint64_t *type_signaturep,
      43             :                  Dwarf_Off *type_offsetp)
      44             : {
      45      114065 :   const bool debug_types = type_signaturep != NULL;
      46      114065 :   const size_t sec_idx = debug_types ? IDX_debug_types : IDX_debug_info;
      47             : 
      48             :   /* Maybe there has been an error before.  */
      49      114065 :   if (dwarf == NULL)
      50             :     return -1;
      51             : 
      52             :   /* If we reached the end before don't do anything.  */
      53      114065 :   if (off == (Dwarf_Off) -1l
      54      114065 :       || unlikely (dwarf->sectiondata[sec_idx] == NULL)
      55             :       /* Make sure there is enough space in the .debug_info section
      56             :          for at least the initial word.  We cannot test the rest since
      57             :          we don't know yet whether this is a 64-bit object or not.  */
      58      114065 :       || unlikely (off + 4 >= dwarf->sectiondata[sec_idx]->d_size))
      59             :     {
      60         172 :       *next_off = (Dwarf_Off) -1l;
      61         172 :       return 1;
      62             :     }
      63             : 
      64             :   /* This points into the .debug_info section to the beginning of the
      65             :      CU entry.  */
      66      113893 :   const unsigned char *data = dwarf->sectiondata[sec_idx]->d_buf;
      67      113893 :   const unsigned char *bytes = data + off;
      68             : 
      69             :   /* The format of the CU header is described in dwarf2p1 7.5.1:
      70             : 
      71             :      1.  A 4-byte or 12-byte unsigned integer representing the length
      72             :          of the .debug_info contribution for that compilation unit, not
      73             :          including the length field itself. In the 32-bit DWARF format,
      74             :          this is a 4-byte unsigned integer (which must be less than
      75             :          0xfffffff0); in the 64-bit DWARF format, this consists of the
      76             :          4-byte value 0xffffffff followed by an 8-byte unsigned integer
      77             :          that gives the actual length (see Section 7.2.2).
      78             : 
      79             :       2. A 2-byte unsigned integer representing the version of the
      80             :          DWARF information for that compilation unit. For DWARF Version
      81             :          2.1, the value in this field is 2.
      82             : 
      83             :       3. A 4-byte or 8-byte unsigned offset into the .debug_abbrev
      84             :          section. This offset associates the compilation unit with a
      85             :          particular set of debugging information entry abbreviations. In
      86             :          the 32-bit DWARF format, this is a 4-byte unsigned length; in
      87             :          the 64-bit DWARF format, this is an 8-byte unsigned length (see
      88             :          Section 7.4).
      89             : 
      90             :       4. A 1-byte unsigned integer representing the size in bytes of
      91             :          an address on the target architecture. If the system uses
      92             :          segmented addressing, this value represents the size of the
      93             :          offset portion of an address.  */
      94      114015 :   uint64_t length = read_4ubyte_unaligned_inc (dwarf, bytes);
      95      113893 :   size_t offset_size = 4;
      96             :   /* Lengths of 0xfffffff0 - 0xffffffff are escape codes.  Oxffffffff is
      97             :      used to indicate that 64-bit dwarf information is being used, the
      98             :      other values are currently reserved.  */
      99      113893 :   if (length == DWARF3_LENGTH_64_BIT)
     100             :     offset_size = 8;
     101      113893 :   else if (unlikely (length >= DWARF3_LENGTH_MIN_ESCAPE_CODE
     102             :                      && length <= DWARF3_LENGTH_MAX_ESCAPE_CODE))
     103             :     {
     104             :     invalid:
     105           0 :       __libdw_seterrno (DWARF_E_INVALID_DWARF);
     106           0 :       return -1;
     107             :     }
     108             : 
     109             :   /* Now we know how large the header is.  */
     110      113893 :   if (unlikely (DIE_OFFSET_FROM_CU_OFFSET (off, offset_size, debug_types)
     111             :                 >= dwarf->sectiondata[sec_idx]->d_size))
     112             :     {
     113           0 :       *next_off = -1;
     114           0 :       return 1;
     115             :     }
     116             : 
     117      113893 :   if (length == DWARF3_LENGTH_64_BIT)
     118             :     /* This is a 64-bit DWARF format.  */
     119           0 :     length = read_8ubyte_unaligned_inc (dwarf, bytes);
     120             : 
     121             :   /* Read the version stamp.  Always a 16-bit value.  */
     122      113893 :   uint_fast16_t version = read_2ubyte_unaligned_inc (dwarf, bytes);
     123             : 
     124             :   /* Get offset in .debug_abbrev.  Note that the size of the entry
     125             :      depends on whether this is a 32-bit or 64-bit DWARF definition.  */
     126             :   uint64_t abbrev_offset;
     127      113893 :   if (__libdw_read_offset_inc (dwarf, sec_idx, &bytes, offset_size,
     128             :                                &abbrev_offset, IDX_debug_abbrev, 0))
     129             :     return -1;
     130             : 
     131             :   /* The address size.  Always an 8-bit value.  */
     132      113893 :   uint8_t address_size = *bytes++;
     133             : 
     134      113893 :   if (debug_types)
     135             :     {
     136           8 :       uint64_t type_sig8 = read_8ubyte_unaligned_inc (dwarf, bytes);
     137             : 
     138             :       Dwarf_Off type_offset;
     139           8 :       if (__libdw_read_offset_inc (dwarf, sec_idx, &bytes, offset_size,
     140             :                                    &type_offset, sec_idx, 0))
     141           0 :         return -1;
     142             : 
     143             :       /* Validate that the TYPE_OFFSET points past the header.  */
     144           8 :       if (unlikely (type_offset < (size_t) (bytes - (data + off))))
     145             :         goto invalid;
     146             : 
     147           8 :       *type_signaturep = type_sig8;
     148           8 :       if (type_offsetp != NULL)
     149           4 :         *type_offsetp = type_offset;
     150             :     }
     151             : 
     152             :   /* Store the header length.  */
     153      113893 :   if (header_sizep != NULL)
     154      103562 :     *header_sizep = bytes - (data + off);
     155             : 
     156      113893 :   if (versionp != NULL)
     157       11616 :     *versionp = version;
     158             : 
     159      113893 :   if (abbrev_offsetp != NULL)
     160       11636 :     *abbrev_offsetp = abbrev_offset;
     161             : 
     162      113893 :   if (address_sizep != NULL)
     163       11636 :     *address_sizep = address_size;
     164             : 
     165             :   /* Store the offset size.  */
     166      113893 :   if (offset_sizep != NULL)
     167       11636 :     *offset_sizep = offset_size;
     168             : 
     169             :   /* See definition of DIE_OFFSET_FROM_CU_OFFSET macro
     170             :      for an explanation of the trick in this expression.  */
     171      113893 :   *next_off = off + 2 * offset_size - 4 + length;
     172             : 
     173      113893 :   return 0;
     174             : }
     175             : INTDEF(dwarf_next_unit)
     176             : 
     177             : int
     178      102388 : dwarf_nextcu (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off,
     179             :               size_t *header_sizep, Dwarf_Off *abbrev_offsetp,
     180             :               uint8_t *address_sizep, uint8_t *offset_sizep)
     181             : {
     182      102388 :   return INTUSE(dwarf_next_unit) (dwarf, off, next_off, header_sizep, NULL,
     183             :                                   abbrev_offsetp, address_sizep, offset_sizep,
     184             :                                   NULL, NULL);
     185             : }
     186             : INTDEF(dwarf_nextcu)

Generated by: LCOV version 1.12