Blame libdw/dwarf_ranges.c

Packit 032894
/* Enumerate the PC ranges covered by a DIE.
Packit 032894
   Copyright (C) 2005, 2007, 2009, 2018 Red Hat, Inc.
Packit 032894
   This file is part of elfutils.
Packit 032894
Packit 032894
   This file is free software; you can redistribute it and/or modify
Packit 032894
   it under the terms of either
Packit 032894
Packit 032894
     * the GNU Lesser General Public License as published by the Free
Packit 032894
       Software Foundation; either version 3 of the License, or (at
Packit 032894
       your option) any later version
Packit 032894
Packit 032894
   or
Packit 032894
Packit 032894
     * the GNU General Public License as published by the Free
Packit 032894
       Software Foundation; either version 2 of the License, or (at
Packit 032894
       your option) any later version
Packit 032894
Packit 032894
   or both in parallel, as here.
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 GNU
Packit 032894
   General Public License for more details.
Packit 032894
Packit 032894
   You should have received copies of the GNU General Public License and
Packit 032894
   the GNU Lesser General Public License along with this program.  If
Packit 032894
   not, see <http://www.gnu.org/licenses/>.  */
Packit 032894
Packit 032894
#ifdef HAVE_CONFIG_H
Packit 032894
# include <config.h>
Packit 032894
#endif
Packit 032894
Packit 032894
#include "libdwP.h"
Packit 032894
#include <dwarf.h>
Packit 032894
#include <assert.h>
Packit 032894
Packit 032894
/* Read up begin/end pair and increment read pointer.
Packit 032894
    - If it's normal range record, set up `*beginp' and `*endp' and return 0.
Packit 032894
    - If it's a default location, set `*beginp' (0), `*endp' (-1) and return 0.
Packit 032894
    - If it's base address selection record, set up `*basep' and return 1.
Packit 032894
    - If it's end of rangelist, don't set anything and return 2
Packit 032894
    - If an error occurs, don't set anything and return -1.  */
Packit 032894
internal_function int
Packit 032894
__libdw_read_begin_end_pair_inc (Dwarf_CU *cu, int sec_index,
Packit 032894
				 const unsigned char **addrp,
Packit 032894
				 const unsigned char *addrend,
Packit 032894
				 int width,
Packit 032894
				 Dwarf_Addr *beginp, Dwarf_Addr *endp,
Packit 032894
				 Dwarf_Addr *basep)
Packit 032894
{
Packit 032894
  Dwarf *dbg = cu->dbg;
Packit 032894
  if (sec_index == IDX_debug_loc
Packit 032894
      && cu->version < 5
Packit 032894
      && cu->unit_type == DW_UT_split_compile)
Packit 032894
    {
Packit 032894
      /* GNU DebugFission.  */
Packit 032894
      const unsigned char *addr = *addrp;
Packit 032894
      if (addrend - addr < 1)
Packit 032894
	goto invalid;
Packit 032894
Packit 032894
      const char code = *addr++;
Packit 032894
      uint64_t begin = 0, end = 0, base = *basep, addr_idx;
Packit 032894
      switch (code)
Packit 032894
	{
Packit 032894
	case DW_LLE_GNU_end_of_list_entry:
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 2;
Packit 032894
Packit 032894
	case DW_LLE_GNU_base_address_selection_entry:
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (addr_idx, addr, addrend);
Packit 032894
	  if (__libdw_addrx (cu, addr_idx, &base) != 0)
Packit 032894
	    return -1;
Packit 032894
	  *basep = base;
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 1;
Packit 032894
Packit 032894
	case DW_LLE_GNU_start_end_entry:
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (addr_idx, addr, addrend);
Packit 032894
	  if (__libdw_addrx (cu, addr_idx, &begin) != 0)
Packit 032894
	    return -1;
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (addr_idx, addr, addrend);
Packit 032894
	  if (__libdw_addrx (cu, addr_idx, &end) != 0)
Packit 032894
	    return -1;
Packit 032894
Packit 032894
	  *beginp = begin;
Packit 032894
	  *endp = end;
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 0;
Packit 032894
Packit 032894
	case DW_LLE_GNU_start_length_entry:
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (addr_idx, addr, addrend);
Packit 032894
	  if (__libdw_addrx (cu, addr_idx, &begin) != 0)
Packit 032894
	    return -1;
Packit 032894
	  if (addrend - addr < 4)
Packit 032894
	    goto invalid;
Packit 032894
	  end = read_4ubyte_unaligned_inc (dbg, addr);
Packit 032894
Packit 032894
	  *beginp = begin;
Packit 032894
	  *endp = begin + end;
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 0;
Packit 032894
Packit 032894
	default:
Packit 032894
	  goto invalid;
Packit 032894
	}
Packit 032894
    }
Packit 032894
  else if (sec_index == IDX_debug_ranges || sec_index == IDX_debug_loc)
Packit 032894
    {
Packit 032894
      Dwarf_Addr escape = (width == 8 ? (Elf64_Addr) -1
Packit 032894
			   : (Elf64_Addr) (Elf32_Addr) -1);
Packit 032894
      Dwarf_Addr begin;
Packit 032894
      Dwarf_Addr end;
Packit 032894
Packit 032894
      const unsigned char *addr = *addrp;
Packit 032894
      if (addrend - addr < width * 2)
Packit 032894
	{
Packit 032894
	invalid:
Packit 032894
	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
Packit 032894
	  return -1;
Packit 032894
	}
Packit 032894
Packit 032894
      bool begin_relocated = READ_AND_RELOCATE (__libdw_relocate_address,
Packit 032894
						begin);
Packit 032894
      bool end_relocated = READ_AND_RELOCATE (__libdw_relocate_address,
Packit 032894
					      end);
Packit 032894
      *addrp = addr;
Packit 032894
Packit 032894
      /* Unrelocated escape for begin means base address selection.  */
Packit 032894
      if (begin == escape && !begin_relocated)
Packit 032894
	{
Packit 032894
	  if (unlikely (end == escape))
Packit 032894
	    goto invalid;
Packit 032894
Packit 032894
	  *basep = end;
Packit 032894
	  return 1;
Packit 032894
	}
Packit 032894
Packit 032894
      /* Unrelocated pair of zeroes means end of range list.  */
Packit 032894
      if (begin == 0 && end == 0 && !begin_relocated && !end_relocated)
Packit 032894
	return 2;
Packit 032894
Packit 032894
      /* Don't check for begin_relocated == end_relocated.  Serve the data
Packit 032894
	 to the client even though it may be buggy.  */
Packit 032894
      *beginp = begin + *basep;
Packit 032894
      *endp = end + *basep;
Packit 032894
Packit 032894
      return 0;
Packit 032894
    }
Packit 032894
  else if (sec_index == IDX_debug_rnglists)
Packit 032894
    {
Packit 032894
      const unsigned char *addr = *addrp;
Packit 032894
      if (addrend - addr < 1)
Packit 032894
	goto invalid;
Packit 032894
Packit 032894
      const char code = *addr++;
Packit 032894
      uint64_t begin = 0, end = 0, base = *basep, addr_idx;
Packit 032894
      switch (code)
Packit 032894
	{
Packit 032894
	case DW_RLE_end_of_list:
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 2;
Packit 032894
Packit 032894
	case DW_RLE_base_addressx:
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (addr_idx, addr, addrend);
Packit 032894
	  if (__libdw_addrx (cu, addr_idx, &base) != 0)
Packit 032894
	    return -1;
Packit 032894
Packit 032894
	  *basep = base;
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 1;
Packit 032894
Packit 032894
	case DW_RLE_startx_endx:
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (addr_idx, addr, addrend);
Packit 032894
	  if (__libdw_addrx (cu, addr_idx, &begin) != 0)
Packit 032894
	    return -1;
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (addr_idx, addr, addrend);
Packit 032894
	  if (__libdw_addrx (cu, addr_idx, &end) != 0)
Packit 032894
	    return -1;
Packit 032894
Packit 032894
	  *beginp = begin;
Packit 032894
	  *endp = end;
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 0;
Packit 032894
Packit 032894
	case DW_RLE_startx_length:
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (addr_idx, addr, addrend);
Packit 032894
	  if (__libdw_addrx (cu, addr_idx, &begin) != 0)
Packit 032894
	    return -1;
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (end, addr, addrend);
Packit 032894
Packit 032894
	  *beginp = begin;
Packit 032894
	  *endp = begin + end;
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 0;
Packit 032894
Packit 032894
	case DW_RLE_offset_pair:
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (begin, addr, addrend);
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (end, addr, addrend);
Packit 032894
Packit 032894
	  *beginp = begin + base;
Packit 032894
	  *endp = end + base;
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 0;
Packit 032894
Packit 032894
	case DW_RLE_base_address:
Packit 032894
	  if (addrend - addr < width)
Packit 032894
	    goto invalid;
Packit 032894
	  __libdw_read_address_inc (dbg, sec_index, &addr, width, &base);
Packit 032894
Packit 032894
	  *basep = base;
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 1;
Packit 032894
Packit 032894
	case DW_RLE_start_end:
Packit 032894
	  if (addrend - addr < 2 * width)
Packit 032894
	    goto invalid;
Packit 032894
	  __libdw_read_address_inc (dbg, sec_index, &addr, width, &begin);
Packit 032894
	  __libdw_read_address_inc (dbg, sec_index, &addr, width, &end;;
Packit 032894
Packit 032894
	  *beginp = begin;
Packit 032894
	  *endp = end;
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 0;
Packit 032894
Packit 032894
	case DW_RLE_start_length:
Packit 032894
	  if (addrend - addr < width)
Packit 032894
	    goto invalid;
Packit 032894
	  __libdw_read_address_inc (dbg, sec_index, &addr, width, &begin);
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (end, addr, addrend);
Packit 032894
Packit 032894
	  *beginp = begin;
Packit 032894
	  *endp = begin + end;
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 0;
Packit 032894
Packit 032894
	default:
Packit 032894
	  goto invalid;
Packit 032894
	}
Packit 032894
    }
Packit 032894
  else if (sec_index == IDX_debug_loclists)
Packit 032894
    {
Packit 032894
      const unsigned char *addr = *addrp;
Packit 032894
      if (addrend - addr < 1)
Packit 032894
	goto invalid;
Packit 032894
Packit 032894
      const char code = *addr++;
Packit 032894
      uint64_t begin = 0, end = 0, base = *basep, addr_idx;
Packit 032894
      switch (code)
Packit 032894
	{
Packit 032894
	case DW_LLE_end_of_list:
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 2;
Packit 032894
Packit 032894
	case DW_LLE_base_addressx:
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (addr_idx, addr, addrend);
Packit 032894
	  if (__libdw_addrx (cu, addr_idx, &base) != 0)
Packit 032894
	    return -1;
Packit 032894
Packit 032894
	  *basep = base;
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 1;
Packit 032894
Packit 032894
	case DW_LLE_startx_endx:
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (addr_idx, addr, addrend);
Packit 032894
	  if (__libdw_addrx (cu, addr_idx, &begin) != 0)
Packit 032894
	    return -1;
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (addr_idx, addr, addrend);
Packit 032894
	  if (__libdw_addrx (cu, addr_idx, &end) != 0)
Packit 032894
	    return -1;
Packit 032894
Packit 032894
	  *beginp = begin;
Packit 032894
	  *endp = end;
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 0;
Packit 032894
Packit 032894
	case DW_LLE_startx_length:
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (addr_idx, addr, addrend);
Packit 032894
	  if (__libdw_addrx (cu, addr_idx, &begin) != 0)
Packit 032894
	    return -1;
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (end, addr, addrend);
Packit 032894
Packit 032894
	  *beginp = begin;
Packit 032894
	  *endp = begin + end;
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 0;
Packit 032894
Packit 032894
	case DW_LLE_offset_pair:
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (begin, addr, addrend);
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (end, addr, addrend);
Packit 032894
Packit 032894
	  *beginp = begin + base;
Packit 032894
	  *endp = end + base;
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 0;
Packit 032894
Packit 032894
	case DW_LLE_default_location:
Packit 032894
	  *beginp = 0;
Packit 032894
	  *endp = (Dwarf_Addr) -1;
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 0;
Packit 032894
Packit 032894
	case DW_LLE_base_address:
Packit 032894
	  if (addrend - addr < width)
Packit 032894
	    goto invalid;
Packit 032894
	  __libdw_read_address_inc (dbg, sec_index, &addr, width, &base);
Packit 032894
Packit 032894
	  *basep = base;
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 1;
Packit 032894
Packit 032894
	case DW_LLE_start_end:
Packit 032894
	  if (addrend - addr < 2 * width)
Packit 032894
	    goto invalid;
Packit 032894
	  __libdw_read_address_inc (dbg, sec_index, &addr, width, &begin);
Packit 032894
	  __libdw_read_address_inc (dbg, sec_index, &addr, width, &end;;
Packit 032894
Packit 032894
	  *beginp = begin;
Packit 032894
	  *endp = end;
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 0;
Packit 032894
Packit 032894
	case DW_LLE_start_length:
Packit 032894
	  if (addrend - addr < width)
Packit 032894
	    goto invalid;
Packit 032894
	  __libdw_read_address_inc (dbg, sec_index, &addr, width, &begin);
Packit 032894
	  if (addrend - addr < 1)
Packit 032894
	    goto invalid;
Packit 032894
	  get_uleb128 (end, addr, addrend);
Packit 032894
Packit 032894
	  *beginp = begin;
Packit 032894
	  *endp = begin + end;
Packit 032894
	  *addrp = addr;
Packit 032894
	  return 0;
Packit 032894
Packit 032894
	default:
Packit 032894
	  goto invalid;
Packit 032894
	}
Packit 032894
    }
Packit 032894
  else
Packit 032894
    {
Packit 032894
      __libdw_seterrno (DWARF_E_INVALID_DWARF);
Packit 032894
      return -1;
Packit 032894
    }
Packit 032894
}
Packit 032894
Packit 032894
static int
Packit 032894
initial_offset (Dwarf_Attribute *attr, ptrdiff_t *offset)
Packit 032894
{
Packit 032894
  size_t secidx = (attr->cu->version < 5
Packit 032894
		   ? IDX_debug_ranges : IDX_debug_rnglists);
Packit 032894
Packit 032894
  Dwarf_Word start_offset;
Packit 032894
  if (attr->form == DW_FORM_rnglistx)
Packit 032894
    {
Packit 032894
      Dwarf_Word idx;
Packit 032894
      Dwarf_CU *cu = attr->cu;
Packit 032894
      const unsigned char *datap = attr->valp;
Packit 032894
      const unsigned char *endp = cu->endp;
Packit 032894
      if (datap >= endp)
Packit 032894
	{
Packit 032894
	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
Packit 032894
	  return -1;
Packit 032894
	}
Packit 032894
      get_uleb128 (idx, datap, endp);
Packit 032894
Packit 032894
      Elf_Data *data = cu->dbg->sectiondata[secidx];
Packit 032894
      if (data == NULL && cu->unit_type == DW_UT_split_compile)
Packit 032894
	{
Packit 032894
	  cu = __libdw_find_split_unit (cu);
Packit 032894
	  if (cu != NULL)
Packit 032894
	    data = cu->dbg->sectiondata[secidx];
Packit 032894
	}
Packit 032894
Packit 032894
      if (data == NULL)
Packit 032894
	{
Packit 032894
	  __libdw_seterrno (secidx == IDX_debug_ranges
Packit 032894
                            ? DWARF_E_NO_DEBUG_RANGES
Packit 032894
                            : DWARF_E_NO_DEBUG_RNGLISTS);
Packit 032894
	  return -1;
Packit 032894
	}
Packit 032894
Packit 032894
      Dwarf_Off range_base_off = __libdw_cu_ranges_base (cu);
Packit 032894
Packit 032894
      /* The section should at least contain room for one offset.  */
Packit 032894
      size_t sec_size = cu->dbg->sectiondata[secidx]->d_size;
Packit 032894
      size_t offset_size = cu->offset_size;
Packit 032894
      if (offset_size > sec_size)
Packit 032894
	{
Packit 032894
	invalid_offset:
Packit 032894
	  __libdw_seterrno (DWARF_E_INVALID_OFFSET);
Packit 032894
	  return -1;
Packit 032894
	}
Packit 032894
Packit 032894
      /* And the base offset should be at least inside the section.  */
Packit 032894
      if (range_base_off > (sec_size - offset_size))
Packit 032894
	goto invalid_offset;
Packit 032894
Packit 032894
      size_t max_idx = (sec_size - offset_size - range_base_off) / offset_size;
Packit 032894
      if (idx > max_idx)
Packit 032894
	goto invalid_offset;
Packit 032894
Packit 032894
      datap = (cu->dbg->sectiondata[secidx]->d_buf
Packit 032894
	       + range_base_off + (idx * offset_size));
Packit 032894
      if (offset_size == 4)
Packit 032894
	start_offset = read_4ubyte_unaligned (cu->dbg, datap);
Packit 032894
      else
Packit 032894
	start_offset = read_8ubyte_unaligned (cu->dbg, datap);
Packit 032894
Packit 032894
      start_offset += range_base_off;
Packit 032894
    }
Packit 032894
  else
Packit 032894
    {
Packit 032894
      if (__libdw_formptr (attr, secidx,
Packit 032894
			   (secidx == IDX_debug_ranges
Packit 032894
			    ? DWARF_E_NO_DEBUG_RANGES
Packit 032894
			    : DWARF_E_NO_DEBUG_RNGLISTS),
Packit 032894
			   NULL, &start_offset) == NULL)
Packit 032894
	return -1;
Packit 032894
    }
Packit 032894
Packit 032894
  *offset = start_offset;
Packit 032894
  return 0;
Packit 032894
}
Packit 032894
Packit 032894
ptrdiff_t
Packit 032894
dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
Packit 032894
	      Dwarf_Addr *startp, Dwarf_Addr *endp)
Packit 032894
{
Packit 032894
  if (die == NULL)
Packit 032894
    return -1;
Packit 032894
Packit 032894
  if (offset == 0
Packit 032894
      /* Usually there is a single contiguous range.  */
Packit 032894
      && INTUSE(dwarf_highpc) (die, endp) == 0
Packit 032894
      && INTUSE(dwarf_lowpc) (die, startp) == 0)
Packit 032894
    /* A offset into .debug_ranges will never be 1, it must be at least a
Packit 032894
       multiple of 4.  So we can return 1 as a special case value to mark
Packit 032894
       there are no ranges to look for on the next call.  */
Packit 032894
    return 1;
Packit 032894
Packit 032894
  if (offset == 1)
Packit 032894
    return 0;
Packit 032894
Packit 032894
  /* We have to look for a noncontiguous range.  */
Packit 032894
  Dwarf_CU *cu = die->cu;
Packit 032894
  if (cu == NULL)
Packit 032894
    {
Packit 032894
      __libdw_seterrno (DWARF_E_INVALID_DWARF);
Packit 032894
      return -1;
Packit 032894
    }
Packit 032894
Packit 032894
  size_t secidx = (cu->version < 5 ? IDX_debug_ranges : IDX_debug_rnglists);
Packit 032894
  const Elf_Data *d = cu->dbg->sectiondata[secidx];
Packit 032894
  if (d == NULL && cu->unit_type == DW_UT_split_compile)
Packit 032894
    {
Packit 032894
      Dwarf_CU *skel = __libdw_find_split_unit (cu);
Packit 032894
      if (skel != NULL)
Packit 032894
	{
Packit 032894
	  cu = skel;
Packit 032894
	  d = cu->dbg->sectiondata[secidx];
Packit 032894
	}
Packit 032894
    }
Packit 032894
Packit 032894
  const unsigned char *readp;
Packit 032894
  const unsigned char *readendp;
Packit 032894
  if (offset == 0)
Packit 032894
    {
Packit 032894
      Dwarf_Attribute attr_mem;
Packit 032894
      Dwarf_Attribute *attr = INTUSE(dwarf_attr) (die, DW_AT_ranges,
Packit 032894
						  &attr_mem);
Packit 032894
      if (attr == NULL
Packit 032894
	  && is_cudie (die)
Packit 032894
	  && die->cu->unit_type == DW_UT_split_compile)
Packit 032894
	attr = INTUSE(dwarf_attr_integrate) (die, DW_AT_ranges, &attr_mem);
Packit 032894
      if (attr == NULL)
Packit 032894
	/* No PC attributes in this DIE at all, so an empty range list.  */
Packit 032894
	return 0;
Packit 032894
Packit 032894
      *basep = __libdw_cu_base_address (attr->cu);
Packit 032894
      if (*basep == (Dwarf_Addr) -1)
Packit 032894
	return -1;
Packit 032894
Packit 032894
      if (initial_offset (attr, &offset) != 0)
Packit 032894
	return -1;
Packit 032894
    }
Packit 032894
  else
Packit 032894
    {
Packit 032894
      if (__libdw_offset_in_section (cu->dbg,
Packit 032894
				     secidx, offset, 1))
Packit 032894
	return -1;
Packit 032894
    }
Packit 032894
Packit 032894
  readp = d->d_buf + offset;
Packit 032894
  readendp = d->d_buf + d->d_size;
Packit 032894
Packit 032894
  Dwarf_Addr begin;
Packit 032894
  Dwarf_Addr end;
Packit 032894
Packit 032894
 next:
Packit 032894
  switch (__libdw_read_begin_end_pair_inc (cu, secidx,
Packit 032894
					   &readp, readendp,
Packit 032894
					   cu->address_size,
Packit 032894
					   &begin, &end, basep))
Packit 032894
    {
Packit 032894
    case 0:
Packit 032894
      break;
Packit 032894
    case 1:
Packit 032894
      goto next;
Packit 032894
    case 2:
Packit 032894
      return 0;
Packit 032894
    default:
Packit 032894
      return -1;
Packit 032894
    }
Packit 032894
Packit 032894
  *startp = begin;
Packit 032894
  *endp = end;
Packit 032894
  return readp - (unsigned char *) d->d_buf;
Packit 032894
}
Packit 032894
INTDEF (dwarf_ranges)