display_debug_rnglists (struct dwarf_section *section)
{
  unsigned char *       start = section->start;
  unsigned char *       finish = start + section->size;

  while (start < finish)
    {
      unsigned char * table_start;
      dwarf_vma       offset = start - section->start;
      unsigned char * end;
      dwarf_vma       initial_length;
      unsigned char   segment_selector_size;
      unsigned int    offset_entry_count;
      unsigned int    i;
      unsigned short  version;
      unsigned char   address_size = 0;
      unsigned char   offset_size;

      /* Get and check the length of the block.  */
      SAFE_BYTE_GET_AND_INC (initial_length, start, 4, finish);

      if (initial_length == 0xffffffff)
	{
	  /* This section is 64-bit DWARF 3.  */
	  SAFE_BYTE_GET_AND_INC (initial_length, start, 8, finish);
	  offset_size = 8;
	}
      else
	offset_size = 4;

      if (initial_length > (size_t) (finish - start))
	{
	  /* If the length field has a relocation against it, then we should
	     not complain if it is inaccurate (and probably negative).
	     It is copied from .debug_line handling code.  */
	  if (reloc_at (section, (start - section->start) - offset_size))
	    initial_length = finish - start;
	  else
	    {
	      warn (_("The length field (0x%lx) in the debug_rnglists header is wrong - the section is too small\n"),
		    (long) initial_length);
	      return 0;
	    }
	}

      end = start + initial_length;

      /* Get the other fields in the header.  */
      SAFE_BYTE_GET_AND_INC (version, start, 2, finish);
      SAFE_BYTE_GET_AND_INC (address_size, start, 1, finish);
      SAFE_BYTE_GET_AND_INC (segment_selector_size, start, 1, finish);
      SAFE_BYTE_GET_AND_INC (offset_entry_count, start, 4, finish);

      printf (_(" Table at Offset: 0x%s:\n"), dwarf_vmatoa ("x", offset));
      printf (_("  Length:          0x%s\n"), dwarf_vmatoa ("x", initial_length));
      printf (_("  DWARF version:   %u\n"), version);
      printf (_("  Address size:    %u\n"), address_size);
      printf (_("  Segment size:    %u\n"), segment_selector_size);
      printf (_("  Offset entries:  %u\n"), offset_entry_count);

      /* Check the fields.  */
      if (segment_selector_size != 0)
	{
	  warn (_("The %s section contains "
		  "unsupported segment selector size: %d.\n"),
		section->name, segment_selector_size);
	  return 0;
	}

      if (version < 5)
	{
	  warn (_("Only DWARF version 5+ debug_rnglists info "
		  "is currently supported.\n"));
	  return 0;
	}

      table_start = start;

      if (offset_entry_count != 0)
	{
	  printf (_("\n   Offsets starting at 0x%lx:\n"), (long)(start - section->start));
	  if (offset_size == 8)
	    {
	      for (i = 0; i < offset_entry_count; i++)
		{
		  dwarf_vma entry;

		  SAFE_BYTE_GET_AND_INC (entry, start, 8, finish);
		  printf (_("    [%6u] 0x%s\n"), i, dwarf_vmatoa ("x", entry));
		}
	    }
	  else
	    {
	      for (i = 0; i < offset_entry_count; i++)
		{
		  uint32_t entry;

		  SAFE_BYTE_GET_AND_INC (entry, start, 4, finish);
		  printf (_("    [%6u] 0x%x\n"), i, entry);
		}
	    }
	}
      else
	offset_entry_count = 1;

      for (i = 0; i < offset_entry_count; i++)
	{
	  dwarf_vma indx = start - table_start;

	  offset = start - section->start;
	  printf (_("\n  Offset: %lx, Index: 0x%s\n"),
		  (long) offset, dwarf_vmatoa ("x", indx));
	  printf (_("    Offset   Begin    End\n"));
	  start = display_debug_rnglists_list
	    (start, end, address_size, offset, 0, offset_size);
	  if (start >= end)
	    break;
	}

      start = end;

      if (start < finish)
	putchar ('\n');
    }

  putchar ('\n');
  return 1;
}
display_debug_rnglists (struct dwarf_section *section)
{
  unsigned char *       start = section->start;
  unsigned char *       finish = start + section->size;

  while (start < finish)
    {
      unsigned char * table_start;
      dwarf_vma       offset = start - section->start;
      unsigned char * end;
      dwarf_vma       initial_length;
      unsigned char   segment_selector_size;
      unsigned int    offset_entry_count;
      unsigned int    i;
      unsigned short  version;
      unsigned char   address_size = 0;
      unsigned char   offset_size;

       
      SAFE_BYTE_GET_AND_INC (initial_length, start, 4, finish);

      if (initial_length == 0xffffffff)
	{
	   
	  SAFE_BYTE_GET_AND_INC (initial_length, start, 8, finish);
	  offset_size = 8;
	}
      else
	offset_size = 4;

      if (initial_length > (size_t) (finish - start))
	{
	   
	  if (reloc_at (section, (start - section->start) - offset_size))
	    initial_length = finish - start;
	  else
	    {
	      warn (_("The length field (0x%lx) in the debug_rnglists header is wrong - the section is too small\n"),
		    (long) initial_length);
	      return 0;
	    }
	}

      end = start + initial_length;

       
      SAFE_BYTE_GET_AND_INC (version, start, 2, finish);
      SAFE_BYTE_GET_AND_INC (address_size, start, 1, finish);
      SAFE_BYTE_GET_AND_INC (segment_selector_size, start, 1, finish);
      SAFE_BYTE_GET_AND_INC (offset_entry_count, start, 4, finish);

      printf (_(" Table at Offset: 0x%s:\n"), dwarf_vmatoa ("x", offset));
      printf (_("  Length:          0x%s\n"), dwarf_vmatoa ("x", initial_length));
      printf (_("  DWARF version:   %u\n"), version);
      printf (_("  Address size:    %u\n"), address_size);
      printf (_("  Segment size:    %u\n"), segment_selector_size);
      printf (_("  Offset entries:  %u\n"), offset_entry_count);

       
      if (segment_selector_size != 0)
	{
	  warn (_("The %s section contains "
		  "unsupported segment selector size: %d.\n"),
		section->name, segment_selector_size);
	  return 0;
	}

      if (version < 5)
	{
	  warn (_("Only DWARF version 5+ debug_rnglists info "
		  "is currently supported.\n"));
	  return 0;
	}

      table_start = start;

      if (offset_entry_count != 0)
	{
	  printf (_("\n   Offsets starting at 0x%lx:\n"), (long)(start - section->start));
	  if (offset_size == 8)
	    {
	      for (i = 0; i < offset_entry_count; i++)
		{
		  dwarf_vma entry;

		  SAFE_BYTE_GET_AND_INC (entry, start, 8, finish);
		  printf (_("    [%6u] 0x%s\n"), i, dwarf_vmatoa ("x", entry));
		}
	    }
	  else
	    {
	      for (i = 0; i < offset_entry_count; i++)
		{
		  uint32_t entry;

		  SAFE_BYTE_GET_AND_INC (entry, start, 4, finish);
		  printf (_("    [%6u] 0x%x\n"), i, entry);
		}
	    }
	}
      else
	offset_entry_count = 1;

      for (i = 0; i < offset_entry_count; i++)
	{
	  dwarf_vma indx = start - table_start;

	  offset = start - section->start;
	  printf (_("\n  Offset: %lx, Index: 0x%s\n"),
		  (long) offset, dwarf_vmatoa ("x", indx));
	  printf (_("    Offset   Begin    End\n"));
	  start = display_debug_rnglists_list
	    (start, end, address_size, offset, 0, offset_size);
	  if (start >= end)
	    break;
	}

      start = end;

      if (start < finish)
	putchar ('\n');
    }

  putchar ('\n');
  return 1;
}