Commit message: Replace a run-time assertion failure with a warning message when parsing corrupt DWARF data.

	PR 29289
	* dwarf.c (display_debug_names): Replace assert with a warning
	message.
CVE: None
Vulnerability description: None

Project: binutils-gdb
File: dwarf.c

display_debug_frames (struct dwarf_section *section,
		      void *file ATTRIBUTE_UNUSED)
{
  unsigned char *start = section->start;
  unsigned char *end = start + section->size;
  unsigned char *section_start = start;
  Frame_Chunk *chunks = NULL, *forward_refs = NULL;
  Frame_Chunk *remembered_state = NULL;
  Frame_Chunk *rs;
  bool is_eh = strcmp (section->name, ".eh_frame") == 0;
  unsigned int max_regs = 0;
  const char *bad_reg = _("bad register: ");
  unsigned int saved_eh_addr_size = eh_addr_size;

  introduce (section, false);

  while (start < end)
    {
      unsigned char *saved_start;
      unsigned char *block_end;
      dwarf_vma length;
      dwarf_vma cie_id;
      Frame_Chunk *fc;
      Frame_Chunk *cie;
      int need_col_headers = 1;
      unsigned char *augmentation_data = NULL;
      bfd_size_type augmentation_data_len = 0;
      unsigned int encoded_ptr_size = saved_eh_addr_size;
      unsigned int offset_size;
      bool all_nops;
      static Frame_Chunk fde_fc;

      saved_start = start;

      SAFE_BYTE_GET_AND_INC (length, start, 4, end);

      if (length == 0)
	{
	  printf ("\n%08lx ZERO terminator\n\n",
		    (unsigned long)(saved_start - section_start));
	  /* Skip any zero terminators that directly follow.
	     A corrupt section size could have loaded a whole
	     slew of zero filled memory bytes.  eg
	     PR 17512: file: 070-19381-0.004.  */
	  while (start < end && * start == 0)
	    ++ start;
	  continue;
	}

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

      if (length > (size_t) (end - start))
	{
	  warn ("Invalid length 0x%s in FDE at %#08lx\n",
		dwarf_vmatoa_1 (NULL, length, offset_size),
		(unsigned long) (saved_start - section_start));
	  block_end = end;
	}
      else
	block_end = start + length;

      SAFE_BYTE_GET_AND_INC (cie_id, start, offset_size, block_end);

      if (is_eh ? (cie_id == 0) : ((offset_size == 4 && cie_id == DW_CIE_ID)
				   || (offset_size == 8 && cie_id == DW64_CIE_ID)))
	{
	  int version;
	  unsigned int mreg;

	  start = read_cie (start, block_end, &cie, &version,
			    &augmentation_data_len, &augmentation_data);
	  /* PR 17512: file: 027-135133-0.005.  */
	  if (cie == NULL)
	    break;

	  fc = cie;
	  fc->next = chunks;
	  chunks = fc;
	  fc->chunk_start = saved_start;
	  mreg = max_regs > 0 ? max_regs - 1 : 0;
	  if (mreg < fc->ra)
	    mreg = fc->ra;
	  if (frame_need_space (fc, mreg) < 0)
	    break;
	  if (fc->fde_encoding)
	    encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);

	  printf ("\n%08lx ", (unsigned long) (saved_start - section_start));
	  print_dwarf_vma (length, fc->ptr_size);
	  print_dwarf_vma (cie_id, offset_size);

	  if (do_debug_frames_interp)
	    {
	      printf ("CIE \"%s\" cf=%d df=%d ra=%d\n", fc->augmentation,
		      fc->code_factor, fc->data_factor, fc->ra);
	    }
	  else
	    {
	      printf ("CIE\n");
	      printf ("  Version:               %d\n", version);
	      printf ("  Augmentation:          \"%s\"\n", fc->augmentation);
	      if (version >= 4)
		{
		  printf ("  Pointer Size:          %u\n", fc->ptr_size);
		  printf ("  Segment Size:          %u\n", fc->segment_size);
		}
	      printf ("  Code alignment factor: %u\n", fc->code_factor);
	      printf ("  Data alignment factor: %d\n", fc->data_factor);
	      printf ("  Return address column: %d\n", fc->ra);

	      if (augmentation_data_len)
		display_augmentation_data (augmentation_data, augmentation_data_len);

	      putchar ('\n');
	    }
	}
      else
	{
	  unsigned char *look_for;
	  unsigned long segment_selector;
	  dwarf_vma cie_off;

	  cie_off = cie_id;
	  if (is_eh)
	    {
	      dwarf_vma sign = (dwarf_vma) 1 << (offset_size * 8 - 1);
	      cie_off = (cie_off ^ sign) - sign;
	      cie_off = start - 4 - section_start - cie_off;
	    }

	  look_for = section_start + cie_off;
	  if (cie_off <= (dwarf_vma) (saved_start - section_start))
	    {
	      for (cie = chunks; cie ; cie = cie->next)
		if (cie->chunk_start == look_for)
		  break;
	    }
	  else if (cie_off >= section->size)
	    cie = NULL;
	  else
	    {
	      for (cie = forward_refs; cie ; cie = cie->next)
		if (cie->chunk_start == look_for)
		  break;
	      if (!cie)
		{
		  unsigned int off_size;
		  unsigned char *cie_scan;

		  cie_scan = look_for;
		  off_size = 4;
		  SAFE_BYTE_GET_AND_INC (length, cie_scan, 4, end);
		  if (length == 0xffffffff)
		    {
		      SAFE_BYTE_GET_AND_INC (length, cie_scan, 8, end);
		      off_size = 8;
		    }
		  if (length != 0 && length <= (size_t) (end - cie_scan))
		    {
		      dwarf_vma c_id;
		      unsigned char *cie_end = cie_scan + length;

		      SAFE_BYTE_GET_AND_INC (c_id, cie_scan, off_size,
					     cie_end);
		      if (is_eh
			  ? c_id == 0
			  : ((off_size == 4 && c_id == DW_CIE_ID)
			     || (off_size == 8 && c_id == DW64_CIE_ID)))
			{
			  int version;
			  unsigned int mreg;

			  read_cie (cie_scan, cie_end, &cie, &version,
				    &augmentation_data_len, &augmentation_data);
			  /* PR 17512: file: 3450-2098-0.004.  */
			  if (cie == NULL)
			    {
			      warn (_("Failed to read CIE information\n"));
			      break;
			    }
			  cie->next = forward_refs;
			  forward_refs = cie;
			  cie->chunk_start = look_for;
			  mreg = max_regs > 0 ? max_regs - 1 : 0;
			  if (mreg < cie->ra)
			    mreg = cie->ra;
			  if (frame_need_space (cie, mreg) < 0)
			    {
			      warn (_("Invalid max register\n"));
			      break;
			    }
			  if (cie->fde_encoding)
			    encoded_ptr_size
			      = size_of_encoded_value (cie->fde_encoding);
			}
		    }
		}
	    }

	  fc = &fde_fc;
	  memset (fc, 0, sizeof (Frame_Chunk));

	  if (!cie)
	    {
	      fc->ncols = 0;
	      fc->col_type = (short int *) xmalloc (sizeof (short int));
	      fc->col_offset = (int *) xmalloc (sizeof (int));
	      if (frame_need_space (fc, max_regs > 0 ? max_regs - 1 : 0) < 0)
		{
		  warn (_("Invalid max register\n"));
		  break;
		}
	      cie = fc;
	      fc->augmentation = "";
	      fc->fde_encoding = 0;
	      fc->ptr_size = eh_addr_size;
	      fc->segment_size = 0;
	    }
	  else
	    {
	      fc->ncols = cie->ncols;
	      fc->col_type = (short int *) xcmalloc (fc->ncols, sizeof (short int));
	      fc->col_offset =  (int *) xcmalloc (fc->ncols, sizeof (int));
	      memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
	      memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
	      fc->augmentation = cie->augmentation;
	      fc->ptr_size = cie->ptr_size;
	      eh_addr_size = cie->ptr_size;
	      fc->segment_size = cie->segment_size;
	      fc->code_factor = cie->code_factor;
	      fc->data_factor = cie->data_factor;
	      fc->cfa_reg = cie->cfa_reg;
	      fc->cfa_offset = cie->cfa_offset;
	      fc->ra = cie->ra;
	      if (frame_need_space (fc, max_regs > 0 ? max_regs - 1: 0) < 0)
		{
		  warn (_("Invalid max register\n"));
		  break;
		}
	      fc->fde_encoding = cie->fde_encoding;
	    }

	  if (fc->fde_encoding)
	    encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);

	  segment_selector = 0;
	  if (fc->segment_size)
	    {
	      if (fc->segment_size > sizeof (segment_selector))
		{
		  /* PR 17512: file: 9e196b3e.  */
		  warn (_("Probably corrupt segment size: %d - using 4 instead\n"), fc->segment_size);
		  fc->segment_size = 4;
		}
	      SAFE_BYTE_GET_AND_INC (segment_selector, start,
				     fc->segment_size, block_end);
	    }

	  fc->pc_begin = get_encoded_value (&start, fc->fde_encoding, section,
					    block_end);

	  /* FIXME: It appears that sometimes the final pc_range value is
	     encoded in less than encoded_ptr_size bytes.  See the x86_64
	     run of the "objcopy on compressed debug sections" test for an
	     example of this.  */
	  SAFE_BYTE_GET_AND_INC (fc->pc_range, start, encoded_ptr_size,
				 block_end);

	  if (cie->augmentation[0] == 'z')
	    {
	      READ_ULEB (augmentation_data_len, start, block_end);
	      augmentation_data = start;
	      /* PR 17512 file: 722-8446-0.004 and PR 22386.  */
	      if (augmentation_data_len > (bfd_size_type) (block_end - start))
		{
		  warn (_("Augmentation data too long: 0x%s, "
			  "expected at most %#lx\n"),
			dwarf_vmatoa ("x", augmentation_data_len),
			(unsigned long) (block_end - start));
		  start = block_end;
		  augmentation_data = NULL;
		  augmentation_data_len = 0;
		}
	      start += augmentation_data_len;
	    }

	  printf ("\n%08lx %s %s FDE ",
		  (unsigned long)(saved_start - section_start),
		  dwarf_vmatoa_1 (NULL, length, fc->ptr_size),
		  dwarf_vmatoa_1 (NULL, cie_id, offset_size));

	  if (cie->chunk_start)
	    printf ("cie=%08lx",
		    (unsigned long) (cie->chunk_start - section_start));
	  else
	    /* Ideally translate "invalid " to 8 chars, trailing space
	       is optional.  */
	    printf (_("cie=invalid "));

	  printf (" pc=");
	  if (fc->segment_size)
	    printf ("%04lx:", segment_selector);

	  printf ("%s..%s\n",
		  dwarf_vmatoa_1 (NULL, fc->pc_begin, fc->ptr_size),
		  dwarf_vmatoa_1 (NULL, fc->pc_begin + fc->pc_range, fc->ptr_size));

	  if (! do_debug_frames_interp && augmentation_data_len)
	    {
	      display_augmentation_data (augmentation_data, augmentation_data_len);
	      putchar ('\n');
	    }
	}

      /* At this point, fc is the current chunk, cie (if any) is set, and
	 we're about to interpret instructions for the chunk.  */
      /* ??? At present we need to do this always, since this sizes the
	 fc->col_type and fc->col_offset arrays, which we write into always.
	 We should probably split the interpreted and non-interpreted bits
	 into two different routines, since there's so much that doesn't
	 really overlap between them.  */
      if (1 || do_debug_frames_interp)
	{
	  /* Start by making a pass over the chunk, allocating storage
	     and taking note of what registers are used.  */
	  unsigned char *tmp = start;

	  while (start < block_end)
	    {
	      unsigned int reg, op, opa;
	      unsigned long temp;

	      op = *start++;
	      opa = op & 0x3f;
	      if (op & 0xc0)
		op &= 0xc0;

	      /* Warning: if you add any more cases to this switch, be
		 sure to add them to the corresponding switch below.  */
	      reg = -1u;
	      switch (op)
		{
		case DW_CFA_advance_loc:
		  break;
		case DW_CFA_offset:
		  SKIP_ULEB (start, block_end);
		  reg = opa;
		  break;
		case DW_CFA_restore:
		  reg = opa;
		  break;
		case DW_CFA_set_loc:
		  if ((size_t) (block_end - start) < encoded_ptr_size)
		    start = block_end;
		  else
		    start += encoded_ptr_size;
		  break;
		case DW_CFA_advance_loc1:
		  if ((size_t) (block_end - start) < 1)
		    start = block_end;
		  else
		    start += 1;
		  break;
		case DW_CFA_advance_loc2:
		  if ((size_t) (block_end - start) < 2)
		    start = block_end;
		  else
		    start += 2;
		  break;
		case DW_CFA_advance_loc4:
		  if ((size_t) (block_end - start) < 4)
		    start = block_end;
		  else
		    start += 4;
		  break;
		case DW_CFA_offset_extended:
		case DW_CFA_val_offset:
		  READ_ULEB (reg, start, block_end);
		  SKIP_ULEB (start, block_end);
		  break;
		case DW_CFA_restore_extended:
		  READ_ULEB (reg, start, block_end);
		  break;
		case DW_CFA_undefined:
		  READ_ULEB (reg, start, block_end);
		  break;
		case DW_CFA_same_value:
		  READ_ULEB (reg, start, block_end);
		  break;
		case DW_CFA_register:
		  READ_ULEB (reg, start, block_end);
		  SKIP_ULEB (start, block_end);
		  break;
		case DW_CFA_def_cfa:
		  SKIP_ULEB (start, block_end);
		  SKIP_ULEB (start, block_end);
		  break;
		case DW_CFA_def_cfa_register:
		  SKIP_ULEB (start, block_end);
		  break;
		case DW_CFA_def_cfa_offset:
		  SKIP_ULEB (start, block_end);
		  break;
		case DW_CFA_def_cfa_expression:
		  READ_ULEB (temp, start, block_end);
		  if ((size_t) (block_end - start) < temp)
		    start = block_end;
		  else
		    start += temp;
		  break;
		case DW_CFA_expression:
		case DW_CFA_val_expression:
		  READ_ULEB (reg, start, block_end);
		  READ_ULEB (temp, start, block_end);
		  if ((size_t) (block_end - start) < temp)
		    start = block_end;
		  else
		    start += temp;
		  break;
		case DW_CFA_offset_extended_sf:
		case DW_CFA_val_offset_sf:
		  READ_ULEB (reg, start, block_end);
		  SKIP_SLEB (start, block_end);
		  break;
		case DW_CFA_def_cfa_sf:
		  SKIP_ULEB (start, block_end);
		  SKIP_SLEB (start, block_end);
		  break;
		case DW_CFA_def_cfa_offset_sf:
		  SKIP_SLEB (start, block_end);
		  break;
		case DW_CFA_MIPS_advance_loc8:
		  if ((size_t) (block_end - start) < 8)
		    start = block_end;
		  else
		    start += 8;
		  break;
		case DW_CFA_GNU_args_size:
		  SKIP_ULEB (start, block_end);
		  break;
		case DW_CFA_GNU_negative_offset_extended:
		  READ_ULEB (reg, start, block_end);
		  SKIP_ULEB (start, block_end);
		  break;
		default:
		  break;
		}
	      if (reg != -1u && frame_need_space (fc, reg) >= 0)
		{
		  /* Don't leave any reg as DW_CFA_unreferenced so
		     that frame_display_row prints name of regs in
		     header, and all referenced regs in each line.  */
		  if (reg >= cie->ncols
		      || cie->col_type[reg] == DW_CFA_unreferenced)
		    fc->col_type[reg] = DW_CFA_undefined;
		  else
		    fc->col_type[reg] = cie->col_type[reg];
		}
	    }
	  start = tmp;
	}

      all_nops = true;

      /* Now we know what registers are used, make a second pass over
	 the chunk, this time actually printing out the info.  */

      while (start < block_end)
	{
	  unsigned op, opa;
	  unsigned long ul, roffs;
	  /* Note: It is tempting to use an unsigned long for 'reg' but there
	     are various functions, notably frame_space_needed() that assume that
	     reg is an unsigned int.  */
	  unsigned int reg;
	  dwarf_signed_vma l;
	  dwarf_vma ofs;
	  dwarf_vma vma;
	  const char *reg_prefix = "";

	  op = *start++;
	  opa = op & 0x3f;
	  if (op & 0xc0)
	    op &= 0xc0;

	  /* Make a note if something other than DW_CFA_nop happens.  */
	  if (op != DW_CFA_nop)
	    all_nops = false;

	  /* Warning: if you add any more cases to this switch, be
	     sure to add them to the corresponding switch above.  */
	  switch (op)
	    {
	    case DW_CFA_advance_loc:
	      if (do_debug_frames_interp)
		frame_display_row (fc, &need_col_headers, &max_regs);
	      else
		printf ("  DW_CFA_advance_loc: %d to %s\n",
			opa * fc->code_factor,
			dwarf_vmatoa_1 (NULL,
					fc->pc_begin + opa * fc->code_factor,
					fc->ptr_size));
	      fc->pc_begin += opa * fc->code_factor;
	      break;

	    case DW_CFA_offset:
	      READ_ULEB (roffs, start, block_end);
	      if (opa >= fc->ncols)
		reg_prefix = bad_reg;
	      if (! do_debug_frames_interp || *reg_prefix != '\0')
		printf ("  DW_CFA_offset: %s%s at cfa%+ld\n",
			reg_prefix, regname (opa, 0),
			roffs * fc->data_factor);
	      if (*reg_prefix == '\0')
		{
		  fc->col_type[opa] = DW_CFA_offset;
		  fc->col_offset[opa] = roffs * fc->data_factor;
		}
	      break;

	    case DW_CFA_restore:
	      if (opa >= fc->ncols)
		reg_prefix = bad_reg;
	      if (! do_debug_frames_interp || *reg_prefix != '\0')
		printf ("  DW_CFA_restore: %s%s\n",
			reg_prefix, regname (opa, 0));
	      if (*reg_prefix != '\0')
		break;

	      if (opa >= cie->ncols
		  || cie->col_type[opa] == DW_CFA_unreferenced)
		{
		  fc->col_type[opa] = DW_CFA_undefined;
		  fc->col_offset[opa] = 0;
		}
	      else
		{
		  fc->col_type[opa] = cie->col_type[opa];
		  fc->col_offset[opa] = cie->col_offset[opa];
		}
	      break;

	    case DW_CFA_set_loc:
	      vma = get_encoded_value (&start, fc->fde_encoding, section,
				       block_end);
	      if (do_debug_frames_interp)
		frame_display_row (fc, &need_col_headers, &max_regs);
	      else
		printf ("  DW_CFA_set_loc: %s\n",
			dwarf_vmatoa_1 (NULL, vma, fc->ptr_size));
	      fc->pc_begin = vma;
	      break;

	    case DW_CFA_advance_loc1:
	      SAFE_BYTE_GET_AND_INC (ofs, start, 1, block_end);
	      if (do_debug_frames_interp)
		frame_display_row (fc, &need_col_headers, &max_regs);
	      else
		printf ("  DW_CFA_advance_loc1: %ld to %s\n",
			(unsigned long) (ofs * fc->code_factor),
			dwarf_vmatoa_1 (NULL,
					fc->pc_begin + ofs * fc->code_factor,
					fc->ptr_size));
	      fc->pc_begin += ofs * fc->code_factor;
	      break;

	    case DW_CFA_advance_loc2:
	      SAFE_BYTE_GET_AND_INC (ofs, start, 2, block_end);
	      if (do_debug_frames_interp)
		frame_display_row (fc, &need_col_headers, &max_regs);
	      else
		printf ("  DW_CFA_advance_loc2: %ld to %s\n",
			(unsigned long) (ofs * fc->code_factor),
			dwarf_vmatoa_1 (NULL,
					fc->pc_begin + ofs * fc->code_factor,
					fc->ptr_size));
	      fc->pc_begin += ofs * fc->code_factor;
	      break;

	    case DW_CFA_advance_loc4:
	      SAFE_BYTE_GET_AND_INC (ofs, start, 4, block_end);
	      if (do_debug_frames_interp)
		frame_display_row (fc, &need_col_headers, &max_regs);
	      else
		printf ("  DW_CFA_advance_loc4: %ld to %s\n",
			(unsigned long) (ofs * fc->code_factor),
			dwarf_vmatoa_1 (NULL,
					fc->pc_begin + ofs * fc->code_factor,
					fc->ptr_size));
	      fc->pc_begin += ofs * fc->code_factor;
	      break;

	    case DW_CFA_offset_extended:
	      READ_ULEB (reg, start, block_end);
	      READ_ULEB (roffs, start, block_end);
	      if (reg >= fc->ncols)
		reg_prefix = bad_reg;
	      if (! do_debug_frames_interp || *reg_prefix != '\0')
		printf ("  DW_CFA_offset_extended: %s%s at cfa%+ld\n",
			reg_prefix, regname (reg, 0),
			roffs * fc->data_factor);
	      if (*reg_prefix == '\0')
		{
		  fc->col_type[reg] = DW_CFA_offset;
		  fc->col_offset[reg] = roffs * fc->data_factor;
		}
	      break;

	    case DW_CFA_val_offset:
	      READ_ULEB (reg, start, block_end);
	      READ_ULEB (roffs, start, block_end);
	      if (reg >= fc->ncols)
		reg_prefix = bad_reg;
	      if (! do_debug_frames_interp || *reg_prefix != '\0')
		printf ("  DW_CFA_val_offset: %s%s is cfa%+ld\n",
			reg_prefix, regname (reg, 0),
			roffs * fc->data_factor);
	      if (*reg_prefix == '\0')
		{
		  fc->col_type[reg] = DW_CFA_val_offset;
		  fc->col_offset[reg] = roffs * fc->data_factor;
		}
	      break;

	    case DW_CFA_restore_extended:
	      READ_ULEB (reg, start, block_end);
	      if (reg >= fc->ncols)
		reg_prefix = bad_reg;
	      if (! do_debug_frames_interp || *reg_prefix != '\0')
		printf ("  DW_CFA_restore_extended: %s%s\n",
			reg_prefix, regname (reg, 0));
	      if (*reg_prefix != '\0')
		break;

	      if (reg >= cie->ncols
		  || cie->col_type[reg] == DW_CFA_unreferenced)
		{
		  fc->col_type[reg] = DW_CFA_undefined;
		  fc->col_offset[reg] = 0;
		}
	      else
		{
		  fc->col_type[reg] = cie->col_type[reg];
		  fc->col_offset[reg] = cie->col_offset[reg];
		}
	      break;

	    case DW_CFA_undefined:
	      READ_ULEB (reg, start, block_end);
	      if (reg >= fc->ncols)
		reg_prefix = bad_reg;
	      if (! do_debug_frames_interp || *reg_prefix != '\0')
		printf ("  DW_CFA_undefined: %s%s\n",
			reg_prefix, regname (reg, 0));
	      if (*reg_prefix == '\0')
		{
		  fc->col_type[reg] = DW_CFA_undefined;
		  fc->col_offset[reg] = 0;
		}
	      break;

	    case DW_CFA_same_value:
	      READ_ULEB (reg, start, block_end);
	      if (reg >= fc->ncols)
		reg_prefix = bad_reg;
	      if (! do_debug_frames_interp || *reg_prefix != '\0')
		printf ("  DW_CFA_same_value: %s%s\n",
			reg_prefix, regname (reg, 0));
	      if (*reg_prefix == '\0')
		{
		  fc->col_type[reg] = DW_CFA_same_value;
		  fc->col_offset[reg] = 0;
		}
	      break;

	    case DW_CFA_register:
	      READ_ULEB (reg, start, block_end);
	      READ_ULEB (roffs, start, block_end);
	      if (reg >= fc->ncols)
		reg_prefix = bad_reg;
	      if (! do_debug_frames_interp || *reg_prefix != '\0')
		{
		  printf ("  DW_CFA_register: %s%s in ",
			  reg_prefix, regname (reg, 0));
		  puts (regname (roffs, 0));
		}
	      if (*reg_prefix == '\0')
		{
		  fc->col_type[reg] = DW_CFA_register;
		  fc->col_offset[reg] = roffs;
		}
	      break;

	    case DW_CFA_remember_state:
	      if (! do_debug_frames_interp)
		printf ("  DW_CFA_remember_state\n");
	      rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
	      rs->cfa_offset = fc->cfa_offset;
	      rs->cfa_reg = fc->cfa_reg;
	      rs->ra = fc->ra;
	      rs->cfa_exp = fc->cfa_exp;
	      rs->ncols = fc->ncols;
	      rs->col_type = (short int *) xcmalloc (rs->ncols,
						     sizeof (* rs->col_type));
	      rs->col_offset = (int *) xcmalloc (rs->ncols, sizeof (* rs->col_offset));
	      memcpy (rs->col_type, fc->col_type, rs->ncols * sizeof (* fc->col_type));
	      memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (* fc->col_offset));
	      rs->next = remembered_state;
	      remembered_state = rs;
	      break;

	    case DW_CFA_restore_state:
	      if (! do_debug_frames_interp)
		printf ("  DW_CFA_restore_state\n");
	      rs = remembered_state;
	      if (rs)
		{
		  remembered_state = rs->next;
		  fc->cfa_offset = rs->cfa_offset;
		  fc->cfa_reg = rs->cfa_reg;
		  fc->ra = rs->ra;
		  fc->cfa_exp = rs->cfa_exp;
		  if (frame_need_space (fc, rs->ncols - 1) < 0)
		    {
		      warn (_("Invalid column number in saved frame state\n"));
		      fc->ncols = 0;
		      break;
		    }
		  memcpy (fc->col_type, rs->col_type, rs->ncols * sizeof (* rs->col_type));
		  memcpy (fc->col_offset, rs->col_offset,
			  rs->ncols * sizeof (* rs->col_offset));
		  free (rs->col_type);
		  free (rs->col_offset);
		  free (rs);
		}
	      else if (do_debug_frames_interp)
		printf ("Mismatched DW_CFA_restore_state\n");
	      break;

	    case DW_CFA_def_cfa:
	      READ_ULEB (fc->cfa_reg, start, block_end);
	      READ_ULEB (fc->cfa_offset, start, block_end);
	      fc->cfa_exp = 0;
	      if (! do_debug_frames_interp)
		printf ("  DW_CFA_def_cfa: %s ofs %d\n",
			regname (fc->cfa_reg, 0), (int) fc->cfa_offset);
	      break;

	    case DW_CFA_def_cfa_register:
	      READ_ULEB (fc->cfa_reg, start, block_end);
	      fc->cfa_exp = 0;
	      if (! do_debug_frames_interp)
		printf ("  DW_CFA_def_cfa_register: %s\n",
			regname (fc->cfa_reg, 0));
	      break;

	    case DW_CFA_def_cfa_offset:
	      READ_ULEB (fc->cfa_offset, start, block_end);
	      if (! do_debug_frames_interp)
		printf ("  DW_CFA_def_cfa_offset: %d\n", (int) fc->cfa_offset);
	      break;

	    case DW_CFA_nop:
	      if (! do_debug_frames_interp)
		printf ("  DW_CFA_nop\n");
	      break;

	    case DW_CFA_def_cfa_expression:
	      READ_ULEB (ul, start, block_end);
	      if (ul > (size_t) (block_end - start))
		{
		  printf (_("  DW_CFA_def_cfa_expression: <corrupt len %lu>\n"), ul);
		  break;
		}
	      if (! do_debug_frames_interp)
		{
		  printf ("  DW_CFA_def_cfa_expression (");
		  decode_location_expression (start, eh_addr_size, 0, -1,
					      ul, 0, section);
		  printf (")\n");
		}
	      fc->cfa_exp = 1;
	      start += ul;
	      break;

	    case DW_CFA_expression:
	      READ_ULEB (reg, start, block_end);
	      READ_ULEB (ul, start, block_end);
	      if (reg >= fc->ncols)
		reg_prefix = bad_reg;
	      /* PR 17512: file: 069-133014-0.006.  */
	      /* PR 17512: file: 98c02eb4.  */
	      if (ul > (size_t) (block_end - start))
		{
		  printf (_("  DW_CFA_expression: <corrupt len %lu>\n"), ul);
		  break;
		}
	      if (! do_debug_frames_interp || *reg_prefix != '\0')
		{
		  printf ("  DW_CFA_expression: %s%s (",
			  reg_prefix, regname (reg, 0));
		  decode_location_expression (start, eh_addr_size, 0, -1,
					      ul, 0, section);
		  printf (")\n");
		}
	      if (*reg_prefix == '\0')
		fc->col_type[reg] = DW_CFA_expression;
	      start += ul;
	      break;

	    case DW_CFA_val_expression:
	      READ_ULEB (reg, start, block_end);
	      READ_ULEB (ul, start, block_end);
	      if (reg >= fc->ncols)
		reg_prefix = bad_reg;
	      if (ul > (size_t) (block_end - start))
		{
		  printf ("  DW_CFA_val_expression: <corrupt len %lu>\n", ul);
		  break;
		}
	      if (! do_debug_frames_interp || *reg_prefix != '\0')
		{
		  printf ("  DW_CFA_val_expression: %s%s (",
			  reg_prefix, regname (reg, 0));
		  decode_location_expression (start, eh_addr_size, 0, -1,
					      ul, 0, section);
		  printf (")\n");
		}
	      if (*reg_prefix == '\0')
		fc->col_type[reg] = DW_CFA_val_expression;
	      start += ul;
	      break;

	    case DW_CFA_offset_extended_sf:
	      READ_ULEB (reg, start, block_end);
	      READ_SLEB (l, start, block_end);
	      if (reg >= fc->ncols)
		reg_prefix = bad_reg;
	      if (! do_debug_frames_interp || *reg_prefix != '\0')
		printf ("  DW_CFA_offset_extended_sf: %s%s at cfa%+ld\n",
			reg_prefix, regname (reg, 0),
			(long)(l * fc->data_factor));
	      if (*reg_prefix == '\0')
		{
		  fc->col_type[reg] = DW_CFA_offset;
		  fc->col_offset[reg] = l * fc->data_factor;
		}
	      break;

	    case DW_CFA_val_offset_sf:
	      READ_ULEB (reg, start, block_end);
	      READ_SLEB (l, start, block_end);
	      if (reg >= fc->ncols)
		reg_prefix = bad_reg;
	      if (! do_debug_frames_interp || *reg_prefix != '\0')
		printf ("  DW_CFA_val_offset_sf: %s%s is cfa%+ld\n",
			reg_prefix, regname (reg, 0),
			(long)(l * fc->data_factor));
	      if (*reg_prefix == '\0')
		{
		  fc->col_type[reg] = DW_CFA_val_offset;
		  fc->col_offset[reg] = l * fc->data_factor;
		}
	      break;

	    case DW_CFA_def_cfa_sf:
	      READ_ULEB (fc->cfa_reg, start, block_end);
	      READ_SLEB (l, start, block_end);
	      l *= fc->data_factor;
	      fc->cfa_offset = l;
	      fc->cfa_exp = 0;
	      if (! do_debug_frames_interp)
		printf ("  DW_CFA_def_cfa_sf: %s ofs %ld\n",
			regname (fc->cfa_reg, 0), (long) l);
	      break;

	    case DW_CFA_def_cfa_offset_sf:
	      READ_SLEB (l, start, block_end);
	      l *= fc->data_factor;
	      fc->cfa_offset = l;
	      if (! do_debug_frames_interp)
		printf ("  DW_CFA_def_cfa_offset_sf: %ld\n", (long) l);
	      break;

	    case DW_CFA_MIPS_advance_loc8:
	      SAFE_BYTE_GET_AND_INC (ofs, start, 8, block_end);
	      if (do_debug_frames_interp)
		frame_display_row (fc, &need_col_headers, &max_regs);
	      else
		printf ("  DW_CFA_MIPS_advance_loc8: %ld to %s\n",
			(unsigned long) (ofs * fc->code_factor),
			dwarf_vmatoa_1 (NULL,
					fc->pc_begin + ofs * fc->code_factor,
					fc->ptr_size));
	      fc->pc_begin += ofs * fc->code_factor;
	      break;

	    case DW_CFA_GNU_window_save:
	      if (! do_debug_frames_interp)
		printf ("  DW_CFA_GNU_window_save\n");
	      break;

	    case DW_CFA_GNU_args_size:
	      READ_ULEB (ul, start, block_end);
	      if (! do_debug_frames_interp)
		printf ("  DW_CFA_GNU_args_size: %ld\n", ul);
	      break;

	    case DW_CFA_GNU_negative_offset_extended:
	      READ_ULEB (reg, start, block_end);
	      READ_SLEB (l, start, block_end);
	      l = - l;
	      if (reg >= fc->ncols)
		reg_prefix = bad_reg;
	      if (! do_debug_frames_interp || *reg_prefix != '\0')
		printf ("  DW_CFA_GNU_negative_offset_extended: %s%s at cfa%+ld\n",
			reg_prefix, regname (reg, 0),
			(long)(l * fc->data_factor));
	      if (*reg_prefix == '\0')
		{
		  fc->col_type[reg] = DW_CFA_offset;
		  fc->col_offset[reg] = l * fc->data_factor;
		}
	      break;

	    default:
	      if (op >= DW_CFA_lo_user && op <= DW_CFA_hi_user)
		printf (_("  DW_CFA_??? (User defined call frame op: %#x)\n"), op);
	      else
		warn (_("Unsupported or unknown Dwarf Call Frame Instruction number: %#x\n"), op);
	      start = block_end;
	    }
	}

      /* Interpret the CFA - as long as it is not completely full of NOPs.  */
      if (do_debug_frames_interp && ! all_nops)
	frame_display_row (fc, &need_col_headers, &max_regs);

      if (fde_fc.col_type != NULL)
	{
	  free (fde_fc.col_type);
	  fde_fc.col_type = NULL;
	}
      if (fde_fc.col_offset != NULL)
	{
	  free (fde_fc.col_offset);
	  fde_fc.col_offset = NULL;
	}

      start = block_end;
      eh_addr_size = saved_eh_addr_size;
    }

  printf ("\n");

  while (remembered_state != NULL)
    {
      rs = remembered_state;
      remembered_state = rs->next;
      free (rs->col_type);
      free (rs->col_offset);
      rs->next = NULL; /* Paranoia.  */
      free (rs);
    }

  while (chunks != NULL)
    {
      rs = chunks;
      chunks = rs->next;
      free (rs->col_type);
      free (rs->col_offset);
      rs->next = NULL; /* Paranoia.  */
      free (rs);
    }

  while (forward_refs != NULL)
    {
      rs = forward_refs;
      forward_refs = rs->next;
      free (rs->col_type);
      free (rs->col_offset);
      rs->next = NULL; /* Paranoia.  */
      free (rs);
    }

  return 1;
}

Project: binutils-gdb
File: dwarf.c

read_leb128 (unsigned char *data,
	     const unsigned char *const end,
	     bool sign,
	     unsigned int *length_return,
	     int *status_return)
{
  dwarf_vma result = 0;
  unsigned int num_read = 0;
  unsigned int shift = 0;
  int status = 1;

  while (data < end)
    {
      unsigned char byte = *data++;
      unsigned char lost, mask;

      num_read++;

      if (shift < CHAR_BIT * sizeof (result))
	{
	  result |= ((dwarf_vma) (byte & 0x7f)) << shift;
	  /* These bits overflowed.  */
	  lost = byte ^ (result >> shift);
	  /* And this is the mask of possible overflow bits.  */
	  mask = 0x7f ^ ((dwarf_vma) 0x7f << shift >> shift);
	  shift += 7;
	}
      else
	{
	  lost = byte;
	  mask = 0x7f;
	}
      if ((lost & mask) != (sign && (dwarf_signed_vma) result < 0 ? mask : 0))
	status |= 2;

      if ((byte & 0x80) == 0)
	{
	  status &= ~1;
	  if (sign && shift < CHAR_BIT * sizeof (result) && (byte & 0x40))
	    result |= -((dwarf_vma) 1 << shift);
	  break;
	}
    }

  if (length_return != NULL)
    *length_return = num_read;
  if (status_return != NULL)
    *status_return = status;

  return result;
}

Project: binutils-gdb
File: dwarf.c

display_debug_ranges (struct dwarf_section *section,
		      void *file ATTRIBUTE_UNUSED)
{
  unsigned char *       start = section->start;
  unsigned char *       last_start = start;
  dwarf_vma             bytes = section->size;
  unsigned char *       section_begin = start;
  unsigned char *       finish = start + bytes;
  unsigned int          num_range_list, i;
  struct range_entry *  range_entries;
  struct range_entry *  range_entry_fill;
  int                   is_rnglists = strstr (section->name, "debug_rnglists") != NULL;
  /* Initialize it due to a false compiler warning.  */
  unsigned char         address_size = 0;
  dwarf_vma             last_offset = 0;
  unsigned int          offset_size = 0;

  if (bytes == 0)
    {
      printf (_("\nThe %s section is empty.\n"), section->name);
      return 0;
    }

  introduce (section, false);

  if (is_rnglists)
    {
      dwarf_vma       initial_length;
      unsigned char   segment_selector_size;
      unsigned int    offset_entry_count;
      unsigned short  version;

      /* 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;
	    }
	}

      /* 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 (_("  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;
	}

      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);
		}
	    }
	}
    }
  
  if (load_debug_info (file) == 0)
    {
      warn (_("Unable to load/parse the .debug_info section, so cannot interpret the %s section.\n"),
	    section->name);
      return 0;
    }

  num_range_list = 0;
  for (i = 0; i < num_debug_info_entries; i++)
    {
      if (debug_information [i].dwarf_version < 5 && is_rnglists)
	/* Skip .debug_rnglists reference.  */
	continue;
      if (debug_information [i].dwarf_version >= 5 && !is_rnglists)
	/* Skip .debug_range reference.  */
	continue;
      num_range_list += debug_information [i].num_range_lists;
    }

  if (num_range_list == 0)
    {
      /* This can happen when the file was compiled with -gsplit-debug
	 which removes references to range lists from the primary .o file.  */
      printf (_("No range lists in .debug_info section.\n"));
      return 1;
    }

  range_entries = (struct range_entry *)
      xmalloc (sizeof (*range_entries) * num_range_list);
  range_entry_fill = range_entries;

  for (i = 0; i < num_debug_info_entries; i++)
    {
      debug_info *debug_info_p = &debug_information[i];
      unsigned int j;

      if (debug_information [i].dwarf_version < 5 && is_rnglists)
	/* Skip .debug_rnglists reference.  */
	continue;
      if (debug_information [i].dwarf_version >= 5 && !is_rnglists)
	/* Skip .debug_range reference.  */
	continue;

      for (j = 0; j < debug_info_p->num_range_lists; j++)
	{
	  range_entry_fill->ranges_offset = debug_info_p->range_lists[j];
	  range_entry_fill->debug_info_p = debug_info_p;
	  range_entry_fill++;
	}
    }

  qsort (range_entries, num_range_list, sizeof (*range_entries),
	 range_entry_compar);

  if (dwarf_check != 0 && range_entries[0].ranges_offset != 0)
    warn (_("Range lists in %s section start at 0x%lx\n"),
	  section->name, (unsigned long) range_entries[0].ranges_offset);

  putchar ('\n');
  printf (_("    Offset   Begin    End\n"));

  for (i = 0; i < num_range_list; i++)
    {
      struct range_entry *range_entry = &range_entries[i];
      debug_info *debug_info_p = range_entry->debug_info_p;
      unsigned int pointer_size;
      dwarf_vma offset;
      unsigned char *next;
      dwarf_vma base_address;

      pointer_size = (is_rnglists ? address_size : debug_info_p->pointer_size);
      offset = range_entry->ranges_offset;
      base_address = debug_info_p->base_address;

      /* PR 17512: file: 001-101485-0.001:0.1.  */
      if (pointer_size < 2 || pointer_size > 8)
	{
	  warn (_("Corrupt pointer size (%d) in debug entry at offset %8.8lx\n"),
		pointer_size, (unsigned long) offset);
	  continue;
	}

      if (offset > (size_t) (finish - section_begin))
	{
	  warn (_("Corrupt offset (%#8.8lx) in range entry %u\n"),
		(unsigned long) offset, i);
	  continue;
	}

      next = section_begin + offset + debug_info_p->rnglists_base;

      /* If multiple DWARF entities reference the same range then we will
         have multiple entries in the `range_entries' list for the same
         offset.  Thanks to the sort above these will all be consecutive in
         the `range_entries' list, so we can easily ignore duplicates
         here.  */
      if (i > 0 && last_offset == offset)
        continue;
      last_offset = offset;

      if (dwarf_check != 0 && i > 0)
	{
	  if (start < next)
	    warn (_("There is a hole [0x%lx - 0x%lx] in %s section.\n"),
		  (unsigned long) (start - section_begin),
		  (unsigned long) (next - section_begin), section->name);
	  else if (start > next)
	    {
	      if (next == last_start)
		continue;
	      warn (_("There is an overlap [0x%lx - 0x%lx] in %s section.\n"),
		    (unsigned long) (start - section_begin),
		    (unsigned long) (next - section_begin), section->name);
	    }
	}

      start = next;
      last_start = next;

      if (is_rnglists)
	display_debug_rnglists_list
	  (start, finish, pointer_size, offset, base_address, offset_size);
      else
	display_debug_ranges_list
	  (start, finish, pointer_size, offset, base_address);
    }
  putchar ('\n');

  free (range_entries);

  return 1;
}

Project: binutils-gdb
File: dwarf.c

load_separate_debug_info (const char *            main_filename,
			  struct dwarf_section *  xlink,
			  parse_func_type         parse_func,
			  check_func_type         check_func,
			  void *                  func_data,
                          void *                  file ATTRIBUTE_UNUSED)
{
  const char *   separate_filename;
  char *         debug_filename;
  char *         canon_dir;
  size_t         canon_dirlen;
  size_t         dirlen;
  char *         canon_filename;
  char *         canon_debug_filename;
  bool		 self;

  if ((separate_filename = parse_func (xlink, func_data)) == NULL)
    {
      warn (_("Corrupt debuglink section: %s\n"),
	    xlink->name ? xlink->name : xlink->uncompressed_name);
      return NULL;
    }

  /* Attempt to locate the separate file.
     This should duplicate the logic in bfd/opncls.c:find_separate_debug_file().  */

  canon_filename = lrealpath (main_filename);
  canon_dir = xstrdup (canon_filename);

  for (canon_dirlen = strlen (canon_dir); canon_dirlen > 0; canon_dirlen--)
    if (IS_DIR_SEPARATOR (canon_dir[canon_dirlen - 1]))
      break;
  canon_dir[canon_dirlen] = '\0';

#ifndef DEBUGDIR
#define DEBUGDIR "/lib/debug"
#endif
#ifndef EXTRA_DEBUG_ROOT1
#define EXTRA_DEBUG_ROOT1 "/usr/lib/debug"
#endif
#ifndef EXTRA_DEBUG_ROOT2
#define EXTRA_DEBUG_ROOT2 "/usr/lib/debug/usr"
#endif

  debug_filename = (char *) malloc (strlen (DEBUGDIR) + 1
				    + canon_dirlen
				    + strlen (".debug/")
#ifdef EXTRA_DEBUG_ROOT1
				    + strlen (EXTRA_DEBUG_ROOT1)
#endif
#ifdef EXTRA_DEBUG_ROOT2
				    + strlen (EXTRA_DEBUG_ROOT2)
#endif
				    + strlen (separate_filename)
				    + 1);
  if (debug_filename == NULL)
    {
      warn (_("Out of memory"));
      free (canon_dir);
      free (canon_filename);
      return NULL;
    }

  /* First try in the current directory.  */
  sprintf (debug_filename, "%s", separate_filename);
  if (check_func (debug_filename, func_data))
    goto found;

  /* Then try in a subdirectory called .debug.  */
  sprintf (debug_filename, ".debug/%s", separate_filename);
  if (check_func (debug_filename, func_data))
    goto found;

  /* Then try in the same directory as the original file.  */
  sprintf (debug_filename, "%s%s", canon_dir, separate_filename);
  if (check_func (debug_filename, func_data))
    goto found;

  /* And the .debug subdirectory of that directory.  */
  sprintf (debug_filename, "%s.debug/%s", canon_dir, separate_filename);
  if (check_func (debug_filename, func_data))
    goto found;

#ifdef EXTRA_DEBUG_ROOT1
  /* Try the first extra debug file root.  */
  sprintf (debug_filename, "%s/%s", EXTRA_DEBUG_ROOT1, separate_filename);
  if (check_func (debug_filename, func_data))
    goto found;

  /* Try the first extra debug file root.  */
  sprintf (debug_filename, "%s/%s/%s", EXTRA_DEBUG_ROOT1, canon_dir, separate_filename);
  if (check_func (debug_filename, func_data))
    goto found;
#endif

#ifdef EXTRA_DEBUG_ROOT2
  /* Try the second extra debug file root.  */
  sprintf (debug_filename, "%s/%s", EXTRA_DEBUG_ROOT2, separate_filename);
  if (check_func (debug_filename, func_data))
    goto found;
#endif

  /* Then try in the global debug_filename directory.  */
  strcpy (debug_filename, DEBUGDIR);
  dirlen = strlen (DEBUGDIR) - 1;
  if (dirlen > 0 && DEBUGDIR[dirlen] != '/')
    strcat (debug_filename, "/");
  strcat (debug_filename, (const char *) separate_filename);

  if (check_func (debug_filename, func_data))
    goto found;

#if HAVE_LIBDEBUGINFOD
  {
    char * tmp_filename;

    if (use_debuginfod
	&& debuginfod_fetch_separate_debug_info (xlink,
						 & tmp_filename,
						 file))
      {
        /* File successfully downloaded from server, replace
           debug_filename with the file's path.  */
        free (debug_filename);
        debug_filename = tmp_filename;
        goto found;
      }
  }
#endif

  if (do_debug_links)
    {
      /* Failed to find the file.  */
      warn (_("could not find separate debug file '%s'\n"),
	    separate_filename);
      warn (_("tried: %s\n"), debug_filename);

#ifdef EXTRA_DEBUG_ROOT2
      sprintf (debug_filename, "%s/%s", EXTRA_DEBUG_ROOT2,
	       separate_filename);
      warn (_("tried: %s\n"), debug_filename);
#endif

#ifdef EXTRA_DEBUG_ROOT1
      sprintf (debug_filename, "%s/%s/%s", EXTRA_DEBUG_ROOT1,
	       canon_dir, separate_filename);
      warn (_("tried: %s\n"), debug_filename);

      sprintf (debug_filename, "%s/%s", EXTRA_DEBUG_ROOT1,
	       separate_filename);
      warn (_("tried: %s\n"), debug_filename);
#endif

      sprintf (debug_filename, "%s.debug/%s", canon_dir,
	       separate_filename);
      warn (_("tried: %s\n"), debug_filename);

      sprintf (debug_filename, "%s%s", canon_dir, separate_filename);
      warn (_("tried: %s\n"), debug_filename);

      sprintf (debug_filename, ".debug/%s", separate_filename);
      warn (_("tried: %s\n"), debug_filename);

      sprintf (debug_filename, "%s", separate_filename);
      warn (_("tried: %s\n"), debug_filename);

#if HAVE_LIBDEBUGINFOD
      if (use_debuginfod)
	{
	  char *urls = getenv (DEBUGINFOD_URLS_ENV_VAR);

	  if (urls == NULL)
	    urls = "";

	  warn (_("tried: DEBUGINFOD_URLS=%s\n"), urls);
	}
#endif
    }

  free (canon_dir);
  free (debug_filename);
  free (canon_filename);
  return NULL;

 found:
  free (canon_dir);

  canon_debug_filename = lrealpath (debug_filename);
  self = strcmp (canon_debug_filename, canon_filename) == 0;
  free (canon_filename);
  free (canon_debug_filename);
  if (self)
    {
      free (debug_filename);
      return NULL;
    }

  void * debug_handle;

  /* Now open the file.... */
  if ((debug_handle = open_debug_file (debug_filename)) == NULL)
    {
      warn (_("failed to open separate debug file: %s\n"), debug_filename);
      free (debug_filename);
      return NULL;
    }

  /* FIXME: We do not check to see if there are any other separate debug info
     files that would also match.  */

  if (do_debug_links)
    printf (_("\n%s: Found separate debug info file: %s\n"), main_filename, debug_filename);
  add_separate_debug_file (debug_filename, debug_handle);

  /* Do not free debug_filename - it might be referenced inside
     the structure returned by open_debug_file().  */
  return debug_handle;
}

Project: binutils-gdb
File: dwarf.c

display_debug_macro (struct dwarf_section *section,
		     void *file)
{
  unsigned char *start = section->start;
  unsigned char *end = start + section->size;
  unsigned char *curr = start;
  unsigned char *extended_op_buf[256];
  bool is_dwo = false;
  const char *suffix = strrchr (section->name, '.');

  if (suffix && strcmp (suffix, ".dwo") == 0)
    is_dwo = true;

  load_debug_section_with_follow (str, file);
  load_debug_section_with_follow (line, file);
  load_debug_section_with_follow (str_index, file);
  
  introduce (section, false);

  while (curr < end)
    {
      unsigned int lineno, version, flags;
      unsigned int offset_size;
      const unsigned char *string;
      dwarf_vma line_offset = 0, sec_offset = curr - start, offset;
      unsigned char **extended_ops = NULL;

      SAFE_BYTE_GET_AND_INC (version, curr, 2, end);
      if (version != 4 && version != 5)
	{
	  error (_("Expected to find a version number of 4 or 5 in section %s but found %d instead\n"),
		 section->name, version);
	  return 0;
	}

      SAFE_BYTE_GET_AND_INC (flags, curr, 1, end);
      offset_size = (flags & 1) ? 8 : 4;
      printf (_("  Offset:                      0x%lx\n"),
	      (unsigned long) sec_offset);
      printf (_("  Version:                     %d\n"), version);
      printf (_("  Offset size:                 %d\n"), offset_size);
      if (flags & 2)
	{
	  SAFE_BYTE_GET_AND_INC (line_offset, curr, offset_size, end);
	  printf (_("  Offset into .debug_line:     0x%lx\n"),
		  (unsigned long) line_offset);
	}
      if (flags & 4)
	{
	  unsigned int i, count, op;
	  dwarf_vma nargs, n;

	  SAFE_BYTE_GET_AND_INC (count, curr, 1, end);

	  memset (extended_op_buf, 0, sizeof (extended_op_buf));
	  extended_ops = extended_op_buf;
	  if (count)
	    {
	      printf (_("  Extension opcode arguments:\n"));
	      for (i = 0; i < count; i++)
		{
		  SAFE_BYTE_GET_AND_INC (op, curr, 1, end);
		  extended_ops[op] = curr;
		  READ_ULEB (nargs, curr, end);
		  if (nargs == 0)
		    printf (_("    DW_MACRO_%02x has no arguments\n"), op);
		  else
		    {
		      printf (_("    DW_MACRO_%02x arguments: "), op);
		      for (n = 0; n < nargs; n++)
			{
			  unsigned int form;

			  SAFE_BYTE_GET_AND_INC (form, curr, 1, end);
			  printf ("%s%s", get_FORM_name (form),
				  n == nargs - 1 ? "\n" : ", ");
			  switch (form)
			    {
			    case DW_FORM_data1:
			    case DW_FORM_data2:
			    case DW_FORM_data4:
			    case DW_FORM_data8:
			    case DW_FORM_sdata:
			    case DW_FORM_udata:
			    case DW_FORM_block:
			    case DW_FORM_block1:
			    case DW_FORM_block2:
			    case DW_FORM_block4:
			    case DW_FORM_flag:
			    case DW_FORM_string:
			    case DW_FORM_strp:
			    case DW_FORM_sec_offset:
			      break;
			    default:
			      error (_("Invalid extension opcode form %s\n"),
				     get_FORM_name (form));
			      return 0;
			    }
			}
		    }
		}
	    }
	}
      printf ("\n");

      while (1)
	{
	  unsigned int op;

	  if (curr >= end)
	    {
	      error (_(".debug_macro section not zero terminated\n"));
	      return 0;
	    }

	  SAFE_BYTE_GET_AND_INC (op, curr, 1, end);
	  if (op == 0)
	    break;

	  switch (op)
	    {
	    case DW_MACRO_define:
	      READ_ULEB (lineno, curr, end);
	      string = curr;
	      curr += strnlen ((char *) string, end - string);
	      printf (_(" DW_MACRO_define - lineno : %d macro : %*s\n"),
		      lineno, (int) (curr - string), string);
	      if (curr < end)
		curr++;
	      break;

	    case DW_MACRO_undef:
	      READ_ULEB (lineno, curr, end);
	      string = curr;
	      curr += strnlen ((char *) string, end - string);
	      printf (_(" DW_MACRO_undef - lineno : %d macro : %*s\n"),
		      lineno, (int) (curr - string), string);
	      if (curr < end)
		curr++;
	      break;

	    case DW_MACRO_start_file:
	      {
		unsigned int filenum;
		unsigned char *file_name = NULL, *dir_name = NULL;

		READ_ULEB (lineno, curr, end);
		READ_ULEB (filenum, curr, end);

		if ((flags & 2) == 0)
		  error (_("DW_MACRO_start_file used, but no .debug_line offset provided.\n"));
		else
		  file_name
		    = get_line_filename_and_dirname (line_offset, filenum,
						     &dir_name);
		if (file_name == NULL)
		  printf (_(" DW_MACRO_start_file - lineno: %d filenum: %d\n"),
			  lineno, filenum);
		else
		  printf (_(" DW_MACRO_start_file - lineno: %d filenum: %d filename: %s%s%s\n"),
			  lineno, filenum,
			  dir_name != NULL ? (const char *) dir_name : "",
			  dir_name != NULL ? "/" : "", file_name);
	      }
	      break;

	    case DW_MACRO_end_file:
	      printf (_(" DW_MACRO_end_file\n"));
	      break;

	    case DW_MACRO_define_strp:
	      READ_ULEB (lineno, curr, end);
	      if (version == 4 && is_dwo)
		READ_ULEB (offset, curr, end);
	      else
		SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
	      string = fetch_indirect_string (offset);
	      printf (_(" DW_MACRO_define_strp - lineno : %d macro : %s\n"),
		      lineno, string);
	      break;

	    case DW_MACRO_undef_strp:
	      READ_ULEB (lineno, curr, end);
	      if (version == 4 && is_dwo)
		READ_ULEB (offset, curr, end);
	      else
		SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
	      string = fetch_indirect_string (offset);
	      printf (_(" DW_MACRO_undef_strp - lineno : %d macro : %s\n"),
		      lineno, string);
	      break;

	    case DW_MACRO_import:
	      SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
	      printf (_(" DW_MACRO_import - offset : 0x%lx\n"),
		      (unsigned long) offset);
	      break;

	    case DW_MACRO_define_sup:
	      READ_ULEB (lineno, curr, end);
	      SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
	      printf (_(" DW_MACRO_define_sup - lineno : %d macro offset : 0x%lx\n"),
		      lineno, (unsigned long) offset);
	      break;

	    case DW_MACRO_undef_sup:
	      READ_ULEB (lineno, curr, end);
	      SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
	      printf (_(" DW_MACRO_undef_sup - lineno : %d macro offset : 0x%lx\n"),
		      lineno, (unsigned long) offset);
	      break;

	    case DW_MACRO_import_sup:
	      SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
	      printf (_(" DW_MACRO_import_sup - offset : 0x%lx\n"),
		      (unsigned long) offset);
	      break;

	    case DW_MACRO_define_strx:
	    case DW_MACRO_undef_strx:
	      READ_ULEB (lineno, curr, end);
	      READ_ULEB (offset, curr, end);
	      string = (const unsigned char *)
		fetch_indexed_string (offset, NULL, offset_size, false, 0);
	      if (op == DW_MACRO_define_strx)
		printf (" DW_MACRO_define_strx ");
	      else
		printf (" DW_MACRO_undef_strx ");
	      if (do_wide)
		printf (_("(with offset %s) "), dwarf_vmatoa ("x", offset));
	      printf (_("lineno : %d macro : %s\n"),
		      lineno, string);
	      break;

	    default:
	      if (op >= DW_MACRO_lo_user && op <= DW_MACRO_hi_user)
		{
		  printf (_(" <Target Specific macro op: %#x - UNHANDLED"), op);
		  break;
		}

	      if (extended_ops == NULL || extended_ops[op] == NULL)
		{
		  error (_(" Unknown macro opcode %02x seen\n"), op);
		  return 0;
		}
	      else
		{
		  /* Skip over unhandled opcodes.  */
		  dwarf_vma nargs, n;
		  unsigned char *desc = extended_ops[op];
		  READ_ULEB (nargs, desc, end);
		  if (nargs == 0)
		    {
		      printf (_(" DW_MACRO_%02x\n"), op);
		      break;
		    }
		  printf (_(" DW_MACRO_%02x -"), op);
		  for (n = 0; n < nargs; n++)
		    {
		      int val;

		      /* DW_FORM_implicit_const is not expected here.  */
		      SAFE_BYTE_GET_AND_INC (val, desc, 1, end);
		      curr
			= read_and_display_attr_value (0, val, 0,
						       start, curr, end, 0, 0,
						       offset_size, version,
						       NULL, 0, section,
						       NULL, ' ', -1);
		      if (n != nargs - 1)
			printf (",");
		    }
		  printf ("\n");
		}
	      break;
	    }
	}

      printf ("\n");
    }

  return 1;
}

Project: binutils-gdb
File: dwarf.c

display_debug_ranges_list (unsigned char *  start,
			   unsigned char *  finish,
			   unsigned int     pointer_size,
			   dwarf_vma        offset,
			   dwarf_vma        base_address)
{
  while (start < finish)
    {
      dwarf_vma begin;
      dwarf_vma end;

      SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, finish);
      if (start >= finish)
	break;
      SAFE_SIGNED_BYTE_GET_AND_INC (end, start, pointer_size, finish);

      printf ("    ");
      print_dwarf_vma (offset, 4);

      if (begin == 0 && end == 0)
	{
	  printf (_("<End of list>\n"));
	  break;
	}

      /* Check base address specifiers.  */
      if (is_max_address (begin, pointer_size)
	  && !is_max_address (end, pointer_size))
	{
	  base_address = end;
	  print_dwarf_vma (begin, pointer_size);
	  print_dwarf_vma (end, pointer_size);
	  printf ("(base address)\n");
	  continue;
	}

      print_dwarf_vma (begin + base_address, pointer_size);
      print_dwarf_vma (end + base_address, pointer_size);

      if (begin == end)
	fputs (_("(start == end)"), stdout);
      else if (begin > end)
	fputs (_("(start > end)"), stdout);

      putchar ('\n');
    }
}

Project: binutils-gdb
File: dwarf.c

add_abbrev (unsigned long  number,
	    unsigned long  tag,
	    int            children,
	    abbrev_list *  list)
{
  abbrev_entry *  entry;

  entry = (abbrev_entry *) xmalloc (sizeof (*entry));

  entry->number     = number;
  entry->tag        = tag;
  entry->children   = children;
  entry->first_attr = NULL;
  entry->last_attr  = NULL;
  entry->next       = NULL;

  assert (list != NULL);

  if (list->first_abbrev == NULL)
    list->first_abbrev = entry;
  else
    list->last_abbrev->next = entry;

  list->last_abbrev = entry;
}

Project: binutils-gdb
File: dwarf.c

try_build_id_prefix (const char * prefix, char * filename, const unsigned char * data, unsigned long id_len)
{
  char * f = filename;

  f += sprintf (f, "%s.build-id/%02x/", prefix, (unsigned) *data++);
  id_len --;
  while (id_len --)
    f += sprintf (f, "%02x", (unsigned) *data++);
  strcpy (f, ".debug");

  return open_debug_file (filename);
}

Project: binutils-gdb
File: dwarf.c

display_trace_info (struct dwarf_section *section, void *file)
{
  return process_debug_info (section, file, section->abbrev_sec, false, true);
}

Project: binutils-gdb
File: dwarf.c

init_dwarf_regnames_iamcu (void)
{
  dwarf_regnames = dwarf_regnames_iamcu;
  dwarf_regnames_count = ARRAY_SIZE (dwarf_regnames_iamcu);
  dwarf_regnames_lookup_func = regname_internal_by_table_only;
}

Project: binutils-gdb
File: dwarf.c

find_debug_info_for_offset (dwarf_vma offset)
{
  unsigned int i;

  if (num_debug_info_entries == DEBUG_INFO_UNAVAILABLE)
    return NULL;

  for (i = 0; i < num_debug_info_entries; i++)
    if (debug_information[i].cu_offset == offset)
      return debug_information + i;

  return NULL;
}

Project: binutils-gdb
File: dwarf.c

add_dwo_id (const char * id, dwarf_vma cu_offset)
{
  add_dwo_info (id, cu_offset, DWO_ID);
}

Project: binutils-gdb
File: dwarf.c

display_debug_addr (struct dwarf_section *section,
		    void *file)
{
  debug_info **debug_addr_info;
  unsigned char *entry;
  unsigned char *end;
  unsigned int i;
  unsigned int count;
  unsigned char * header;

  if (section->size == 0)
    {
      printf (_("\nThe %s section is empty.\n"), section->name);
      return 0;
    }

  if (load_debug_info (file) == 0)
    {
      warn (_("Unable to load/parse the .debug_info section, so cannot interpret the %s section.\n"),
	    section->name);
      return 0;
    }

  introduce (section, false);

  /* PR  17531: file: cf38d01b.
     We use xcalloc because a corrupt file may not have initialised all of the
     fields in the debug_info structure, which means that the sort below might
     try to move uninitialised data.  */
  debug_addr_info = (debug_info **) xcalloc ((num_debug_info_entries + 1),
					     sizeof (debug_info *));

  count = 0;
  for (i = 0; i < num_debug_info_entries; i++)
    if (debug_information [i].addr_base != DEBUG_INFO_UNAVAILABLE)
      {
	/* PR 17531: file: cf38d01b.  */
	if (debug_information[i].addr_base >= section->size)
	  warn (_("Corrupt address base (%lx) found in debug section %u\n"),
		(unsigned long) debug_information[i].addr_base, i);
	else
	  debug_addr_info [count++] = debug_information + i;
      }

  /* Add a sentinel to make iteration convenient.  */
  debug_addr_info [count] = (debug_info *) xmalloc (sizeof (debug_info));
  debug_addr_info [count]->addr_base = section->size;
  qsort (debug_addr_info, count, sizeof (debug_info *), comp_addr_base);

  header = section->start;
  for (i = 0; i < count; i++)
    {
      unsigned int idx;
      unsigned int address_size = debug_addr_info [i]->pointer_size;

      printf (_("  For compilation unit at offset 0x%s:\n"),
	      dwarf_vmatoa ("x", debug_addr_info [i]->cu_offset));

      printf (_("\tIndex\tAddress\n"));
      entry = section->start + debug_addr_info [i]->addr_base;
      if (debug_addr_info [i]->dwarf_version >= 5)
	{
	  size_t           header_size = entry - header;
	  unsigned char *  curr_header = header;
	  dwarf_vma        length;
	  int              version;
	  int              segment_selector_size;

	  if (header_size != 8 && header_size != 16)
	    {
	      warn (_("Corrupt %s section: expecting header size of 8 or 16, but found %ld instead\n"),
		    section->name, (long) header_size);
	      return 0;
	    }

	  SAFE_BYTE_GET_AND_INC (length, curr_header, 4, entry);
	  if (length == 0xffffffff)
	    SAFE_BYTE_GET_AND_INC (length, curr_header, 8, entry);
	  end = curr_header + length;

	  SAFE_BYTE_GET_AND_INC (version, curr_header, 2, entry);
	  if (version != 5)
	    warn (_("Corrupt %s section: expecting version number 5 in header but found %d instead\n"),
		  section->name, version);

	  SAFE_BYTE_GET_AND_INC (address_size, curr_header, 1, entry);
	  SAFE_BYTE_GET_AND_INC (segment_selector_size, curr_header, 1, entry);
	  address_size += segment_selector_size;
	}
      else
	end = section->start + debug_addr_info [i + 1]->addr_base;
      header = end;
      idx = 0;
      while (entry < end)
	{
	  dwarf_vma base = byte_get (entry, address_size);
	  printf (_("\t%d:\t"), idx);
	  print_dwarf_vma (base, address_size);
	  printf ("\n");
	  entry += address_size;
	  idx++;
	}
    }
  printf ("\n");

  free (debug_addr_info);
  return 1;
}

Project: binutils-gdb
File: dwarf.c

debuginfod_fetch_separate_debug_info (struct dwarf_section * section,
                                      char ** filename,
                                      void * file)
{
  size_t build_id_len;
  unsigned char * build_id;

  if (strcmp (section->uncompressed_name, ".gnu_debuglink") == 0)
    {
      /* Get the build-id of file.  */
      build_id = get_build_id (file);
      build_id_len = 0;
    }
  else if (strcmp (section->uncompressed_name, ".gnu_debugaltlink") == 0)
    {
      /* Get the build-id of the debugaltlink file.  */
      unsigned int filelen;

      filelen = strnlen ((const char *)section->start, section->size);
      if (filelen == section->size)
        /* Corrupt debugaltlink.  */
        return false;

      build_id = section->start + filelen + 1;
      build_id_len = section->size - (filelen + 1);

      if (build_id_len == 0)
        return false;
    }
  else
    return false;

  if (build_id)
    {
      int fd;
      debuginfod_client * client;

      client = debuginfod_begin ();
      if (client == NULL)
        return false;

      /* Query debuginfod servers for the target file. If found its path
         will be stored in filename.  */
      fd = debuginfod_find_debuginfo (client, build_id, build_id_len, filename);
      debuginfod_end (client);

      /* Only free build_id if we allocated space for a hex string
         in get_build_id ().  */
      if (build_id_len == 0)
        free (build_id);

      if (fd >= 0)
        {
          /* File successfully retrieved. Close fd since we want to
             use open_debug_file () on filename instead.  */
          close (fd);
          return true;
        }
    }

  return false;
}

Project: binutils-gdb
File: dwarf.c

get_IDX_name (unsigned long idx)
{
  const char *name = get_DW_IDX_name ((unsigned int) idx);

  if (name == NULL)
    {
      static char buffer[100];

      snprintf (buffer, sizeof (buffer), _("Unknown IDX value: %lx"), idx);
      return buffer;
    }

  return name;
}

Project: binutils-gdb
File: dwarf.c

add_dwo_info (const char * value, dwarf_vma cu_offset, dwo_type type)
{
  dwo_info * dwinfo = xmalloc (sizeof * dwinfo);

  dwinfo->type   = type;
  dwinfo->value  = value;
  dwinfo->cu_offset = cu_offset;
  dwinfo->next   = first_dwo_info;
  first_dwo_info = dwinfo;
}

Project: binutils-gdb
File: dwarf.c

load_debug_info (void * file)
{
  /* If we have already tried and failed to load the .debug_info
     section then do not bother to repeat the task.  */
  if (num_debug_info_entries == DEBUG_INFO_UNAVAILABLE)
    return 0;

  /* If we already have the information there is nothing else to do.  */
  if (num_debug_info_entries > 0)
    return num_debug_info_entries;

  /* If this is a DWARF package file, load the CU and TU indexes.  */
  (void) load_cu_tu_indexes (file);

  if (load_debug_section_with_follow (info, file)
      && process_debug_info (&debug_displays [info].section, file, abbrev, true, false))
    return num_debug_info_entries;

  if (load_debug_section_with_follow (info_dwo, file)
      && process_debug_info (&debug_displays [info_dwo].section, file,
			     abbrev_dwo, true, false))
    return num_debug_info_entries;

  num_debug_info_entries = DEBUG_INFO_UNAVAILABLE;
  return 0;
}

Project: binutils-gdb
File: dwarf.c

display_debug_rnglists_list (unsigned char * start,
			     unsigned char * finish,
			     unsigned int    pointer_size,
			     dwarf_vma       offset,
			     dwarf_vma       base_address,
			     unsigned int    offset_size)
{
  unsigned char *next = start;
  unsigned int debug_addr_section_hdr_len;

  if (offset_size == 4)
    debug_addr_section_hdr_len = 8;
  else
    debug_addr_section_hdr_len = 16;

  while (1)
    {
      dwarf_vma off = offset + (start - next);
      enum dwarf_range_list_entry rlet;
      /* Initialize it due to a false compiler warning.  */
      dwarf_vma begin = -1, length, end = -1;

      if (start >= finish)
	{
	  warn (_("Range list starting at offset 0x%s is not terminated.\n"),
		dwarf_vmatoa ("x", offset));
	  break;
	}

      printf ("    ");
      print_dwarf_vma (off, 4);

      SAFE_BYTE_GET_AND_INC (rlet, start, 1, finish);

      switch (rlet)
	{
	case DW_RLE_end_of_list:
	  printf (_("<End of list>\n"));
	  break;
	case DW_RLE_base_addressx:
	  READ_ULEB (base_address, start, finish);
	  print_dwarf_vma (base_address, pointer_size);
	  printf (_("(base address index) "));
	  base_address = fetch_indexed_addr ((base_address * pointer_size)
			                     + debug_addr_section_hdr_len, pointer_size);
	  print_dwarf_vma (base_address, pointer_size);
	  printf (_("(base address)\n"));
	  break;
	case DW_RLE_startx_endx:
	  READ_ULEB (begin, start, finish);
	  READ_ULEB (end, start, finish);
	  begin = fetch_indexed_addr ((begin * pointer_size)
			              + debug_addr_section_hdr_len, pointer_size);
	  end   = fetch_indexed_addr ((begin * pointer_size)
			              + debug_addr_section_hdr_len, pointer_size);
	  break;
	case DW_RLE_startx_length:
	  READ_ULEB (begin, start, finish);
	  READ_ULEB (length, start, finish);
	  begin = fetch_indexed_addr ((begin * pointer_size)
			              + debug_addr_section_hdr_len, pointer_size);
	  end = begin + length;
	  break;
	case DW_RLE_offset_pair:
	  READ_ULEB (begin, start, finish);
	  READ_ULEB (end, start, finish);
	  break;
	case DW_RLE_base_address:
	  SAFE_BYTE_GET_AND_INC (base_address, start, pointer_size, finish);
	  print_dwarf_vma (base_address, pointer_size);
	  printf (_("(base address)\n"));
	  break;
	case DW_RLE_start_end:
	  SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, finish);
	  SAFE_BYTE_GET_AND_INC (end, start, pointer_size, finish);
	  break;
	case DW_RLE_start_length:
	  SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, finish);
	  READ_ULEB (length, start, finish);
	  end = begin + length;
	  break;
	default:
	  error (_("Invalid range list entry type %d\n"), rlet);
	  rlet = DW_RLE_end_of_list;
	  break;
	}

      if (rlet == DW_RLE_end_of_list)
	break;
      if (rlet == DW_RLE_base_address || rlet == DW_RLE_base_addressx)
	continue;

      /* Only a DW_RLE_offset_pair needs the base address added.  */
      if (rlet == DW_RLE_offset_pair)
	{
	  begin += base_address;
	  end += base_address;
	}

      print_dwarf_vma (begin, pointer_size);
      print_dwarf_vma (end, pointer_size);

      if (begin == end)
	fputs (_("(start == end)"), stdout);
      else if (begin > end)
	fputs (_("(start > end)"), stdout);

      putchar ('\n');
    }
}

Project: binutils-gdb
File: dwarf.c

display_debug_lines (struct dwarf_section *section, void *file)
{
  unsigned char *data = section->start;
  unsigned char *end = data + section->size;
  int retValRaw = 1;
  int retValDecoded = 1;

  if (do_debug_lines == 0)
    do_debug_lines |= FLAG_DEBUG_LINES_RAW;

  if (do_debug_lines & FLAG_DEBUG_LINES_RAW)
    retValRaw = display_debug_lines_raw (section, data, end, file);

  if (do_debug_lines & FLAG_DEBUG_LINES_DECODED)
    retValDecoded = display_debug_lines_decoded (section, data, data, end, file);

  if (!retValRaw || !retValDecoded)
    return 0;

  return 1;
}

Project: binutils-gdb
File: dwarf.c

end_cu_tu_entry (void)
{
  if (shndx_pool_used >= shndx_pool_size)
    {
      error (_("Internal error: out of space in the shndx pool.\n"));
      return;
    }
  shndx_pool [shndx_pool_used++] = 0;
}

Project: binutils-gdb
File: dwarf.c

regname (unsigned int regno, int name_only_p)
{
  static char reg[64];

  const char *name = NULL;

  if (dwarf_regnames_lookup_func != NULL)
    name = dwarf_regnames_lookup_func (regno);

  if (name != NULL)
    {
      if (name_only_p)
	return name;
      snprintf (reg, sizeof (reg), "r%d (%s)", regno, name);
    }
  else
    snprintf (reg, sizeof (reg), "r%d", regno);
  return reg;
}

Project: binutils-gdb
File: dwarf.c

get_gdb_index_symbol_kind_name (gdb_index_symbol_kind kind)
{
  /* See gdb/gdb-index.h.  */
  static const char * const kinds[] =
  {
    N_ ("no info"),
    N_ ("type"),
    N_ ("variable"),
    N_ ("function"),
    N_ ("other"),
    N_ ("unused5"),
    N_ ("unused6"),
    N_ ("unused7")
  };

  return _ (kinds[kind]);
}

Project: binutils-gdb
File: dwarf.c

init_dwarf_regnames_s390 (void)
{
  dwarf_regnames = dwarf_regnames_s390;
  dwarf_regnames_count = ARRAY_SIZE (dwarf_regnames_s390);
  dwarf_regnames_lookup_func = regname_internal_by_table_only;
}

Project: binutils-gdb
File: dwarf.c

display_debug_aranges (struct dwarf_section *section,
		       void *file ATTRIBUTE_UNUSED)
{
  unsigned char *start = section->start;
  unsigned char *end = start + section->size;

  introduce (section, false);

  /* It does not matter if this load fails,
     we test for that later on.  */
  load_debug_info (file);

  while (start < end)
    {
      unsigned char *hdrptr;
      DWARF2_Internal_ARange arange;
      unsigned char *addr_ranges;
      dwarf_vma length;
      dwarf_vma address;
      dwarf_vma     sec_off;
      unsigned char address_size;
      unsigned int  offset_size;
      unsigned char *end_ranges;

      hdrptr = start;
      sec_off = hdrptr - section->start;

      SAFE_BYTE_GET_AND_INC (arange.ar_length, hdrptr, 4, end);
      if (arange.ar_length == 0xffffffff)
	{
	  SAFE_BYTE_GET_AND_INC (arange.ar_length, hdrptr, 8, end);
	  offset_size = 8;
	}
      else
	offset_size = 4;

      if (arange.ar_length > (size_t) (end - hdrptr))
	{
	  warn (_("Debug info is corrupted, %s header at %#lx has length %s\n"),
		section->name,
		(unsigned long) sec_off,
		dwarf_vmatoa ("x", arange.ar_length));
	  break;
	}
      end_ranges = hdrptr + arange.ar_length;

      SAFE_BYTE_GET_AND_INC (arange.ar_version, hdrptr, 2, end_ranges);
      SAFE_BYTE_GET_AND_INC (arange.ar_info_offset, hdrptr, offset_size,
			     end_ranges);

      if (num_debug_info_entries != DEBUG_INFO_UNAVAILABLE
	  && num_debug_info_entries > 0
	  && find_debug_info_for_offset (arange.ar_info_offset) == NULL)
	warn (_(".debug_info offset of 0x%lx in %s section does not point to a CU header.\n"),
	      (unsigned long) arange.ar_info_offset, section->name);

      SAFE_BYTE_GET_AND_INC (arange.ar_pointer_size, hdrptr, 1, end_ranges);
      SAFE_BYTE_GET_AND_INC (arange.ar_segment_size, hdrptr, 1, end_ranges);

      if (arange.ar_version != 2 && arange.ar_version != 3)
	{
	  /* PR 19872: A version number of 0 probably means that there is
	     padding at the end of the .debug_aranges section.  Gold puts
	     it there when performing an incremental link, for example.
	     So do not generate a warning in this case.  */
	  if (arange.ar_version)
	    warn (_("Only DWARF 2 and 3 aranges are currently supported.\n"));
	  break;
	}

      printf (_("  Length:                   %ld\n"),
	      (long) arange.ar_length);
      printf (_("  Version:                  %d\n"), arange.ar_version);
      printf (_("  Offset into .debug_info:  0x%lx\n"),
	      (unsigned long) arange.ar_info_offset);
      printf (_("  Pointer Size:             %d\n"), arange.ar_pointer_size);
      printf (_("  Segment Size:             %d\n"), arange.ar_segment_size);

      address_size = arange.ar_pointer_size + arange.ar_segment_size;

      /* PR 17512: file: 001-108546-0.001:0.1.  */
      if (address_size == 0 || address_size > 8)
	{
	  error (_("Invalid address size in %s section!\n"),
		 section->name);
	  break;
	}

      /* The DWARF spec does not require that the address size be a power
	 of two, but we do.  This will have to change if we ever encounter
	 an uneven architecture.  */
      if ((address_size & (address_size - 1)) != 0)
	{
	  warn (_("Pointer size + Segment size is not a power of two.\n"));
	  break;
	}

      if (address_size > 4)
	printf (_("\n    Address            Length\n"));
      else
	printf (_("\n    Address    Length\n"));

      addr_ranges = hdrptr;

      /* Must pad to an alignment boundary that is twice the address size.  */
      addr_ranges += (2 * address_size - 1
		      - (hdrptr - start - 1) % (2 * address_size));

      while (2 * address_size <= end_ranges - addr_ranges)
	{
	  SAFE_BYTE_GET_AND_INC (address, addr_ranges, address_size,
				 end_ranges);
	  SAFE_BYTE_GET_AND_INC (length, addr_ranges, address_size,
				 end_ranges);
	  printf ("    ");
	  print_dwarf_vma (address, address_size);
	  print_dwarf_vma (length, address_size);
	  putchar ('\n');
	}

      start = end_ranges;
    }

  printf ("\n");

  return 1;
}

Project: binutils-gdb
File: dwarf.c

display_debug_macinfo (struct dwarf_section *section,
		       void *file ATTRIBUTE_UNUSED)
{
  unsigned char *start = section->start;
  unsigned char *end = start + section->size;
  unsigned char *curr = start;
  enum dwarf_macinfo_record_type op;

  introduce (section, false);

  while (curr < end)
    {
      unsigned int lineno;
      const unsigned char *string;

      op = (enum dwarf_macinfo_record_type) *curr;
      curr++;

      switch (op)
	{
	case DW_MACINFO_start_file:
	  {
	    unsigned int filenum;

	    READ_ULEB (lineno, curr, end);
	    READ_ULEB (filenum, curr, end);
	    printf (_(" DW_MACINFO_start_file - lineno: %d filenum: %d\n"),
		    lineno, filenum);
	  }
	  break;

	case DW_MACINFO_end_file:
	  printf (_(" DW_MACINFO_end_file\n"));
	  break;

	case DW_MACINFO_define:
	  READ_ULEB (lineno, curr, end);
	  string = curr;
	  curr += strnlen ((char *) string, end - string);
	  printf (_(" DW_MACINFO_define - lineno : %d macro : %*s\n"),
		  lineno, (int) (curr - string), string);
	  if (curr < end)
	    curr++;
	  break;

	case DW_MACINFO_undef:
	  READ_ULEB (lineno, curr, end);
	  string = curr;
	  curr += strnlen ((char *) string, end - string);
	  printf (_(" DW_MACINFO_undef - lineno : %d macro : %*s\n"),
		  lineno, (int) (curr - string), string);
	  if (curr < end)
	    curr++;
	  break;

	case DW_MACINFO_vendor_ext:
	  {
	    unsigned int constant;

	    READ_ULEB (constant, curr, end);
	    string = curr;
	    curr += strnlen ((char *) string, end - string);
	    printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %*s\n"),
		    constant, (int) (curr - string), string);
	    if (curr < end)
	      curr++;
	  }
	  break;
	}
    }

  return 1;
}

Project: binutils-gdb
File: dwarf.c

process_abbrev_set (struct dwarf_section *section,
		    dwarf_vma abbrev_base,
		    dwarf_vma abbrev_size,
		    dwarf_vma abbrev_offset,
		    abbrev_list *list)
{
  if (abbrev_base >= section->size
      || abbrev_size > section->size - abbrev_base)
    {
      /* PR 17531: file:4bcd9ce9.  */
      warn (_("Debug info is corrupted, abbrev size (%lx) is larger than "
	      "abbrev section size (%lx)\n"),
	      (unsigned long) (abbrev_base + abbrev_size),
	      (unsigned long) section->size);
      return NULL;
    }
  if (abbrev_offset >= abbrev_size)
    {
      warn (_("Debug info is corrupted, abbrev offset (%lx) is larger than "
	      "abbrev section size (%lx)\n"),
	    (unsigned long) abbrev_offset,
	    (unsigned long) abbrev_size);
      return NULL;
    }

  unsigned char *start = section->start + abbrev_base;
  unsigned char *end = start + abbrev_size;
  start += abbrev_offset;
  while (start < end)
    {
      unsigned long entry;
      unsigned long tag;
      unsigned long attribute;
      int children;

      READ_ULEB (entry, start, end);

      /* A single zero is supposed to end the set according
	 to the standard.  If there's more, then signal that to
	 the caller.  */
      if (start == end)
	return NULL;
      if (entry == 0)
	return start;

      READ_ULEB (tag, start, end);
      if (start == end)
	return NULL;

      children = *start++;

      add_abbrev (entry, tag, children, list);

      do
	{
	  unsigned long form;
	  /* Initialize it due to a false compiler warning.  */
	  dwarf_signed_vma implicit_const = -1;

	  READ_ULEB (attribute, start, end);
	  if (start == end)
	    break;

	  READ_ULEB (form, start, end);
	  if (start == end)
	    break;

	  if (form == DW_FORM_implicit_const)
	    {
	      READ_SLEB (implicit_const, start, end);
	      if (start == end)
		break;
	    }

	  add_abbrev_attr (attribute, form, implicit_const, list);
	}
      while (attribute != 0);
    }

  /* Report the missing single zero which ends the section.  */
  error (_(".debug_abbrev section not zero terminated\n"));

  return NULL;
}

Project: binutils-gdb
File: dwarf.c

display_debug_not_supported (struct dwarf_section *section,
			     void *file ATTRIBUTE_UNUSED)
{
  printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
	    section->name);

  return 1;
}

Project: binutils-gdb
File: dwarf.c

get_AT_name (unsigned long attribute)
{
  const char *name;

  if (attribute == 0)
    return "DW_AT value: 0";

  /* One value is shared by the MIPS and HP extensions:  */
  if (attribute == DW_AT_MIPS_fde)
    return "DW_AT_MIPS_fde or DW_AT_HP_unmodifiable";

  name = get_DW_AT_name (attribute);

  if (name == NULL)
    {
      static char buffer[100];

      snprintf (buffer, sizeof (buffer), _("Unknown AT value: %lx"),
		attribute);
      return buffer;
    }

  return name;
}

Project: binutils-gdb
File: dwarf.c

prealloc_cu_tu_list (unsigned int nshndx)
{
  if (shndx_pool == NULL)
    {
      shndx_pool_size = nshndx;
      shndx_pool_used = 0;
      shndx_pool = (unsigned int *) xcmalloc (shndx_pool_size,
					      sizeof (unsigned int));
    }
  else
    {
      shndx_pool_size = shndx_pool_used + nshndx;
      shndx_pool = (unsigned int *) xcrealloc (shndx_pool, shndx_pool_size,
					       sizeof (unsigned int));
    }
}

Project: binutils-gdb
File: dwarf.c

init_dwarf_regnames_aarch64 (void)
{
  dwarf_regnames = dwarf_regnames_aarch64;
  dwarf_regnames_count = ARRAY_SIZE (dwarf_regnames_aarch64);
  dwarf_regnames_lookup_func = regname_internal_by_table_only;
}

Project: binutils-gdb
File: dwarf.c

fetch_indexed_string (dwarf_vma           idx,
		      struct cu_tu_set *  this_set,
		      dwarf_vma           offset_size,
		      bool                dwo,
		      dwarf_vma           str_offsets_base)
{
  enum dwarf_section_display_enum str_sec_idx = dwo ? str_dwo : str;
  enum dwarf_section_display_enum idx_sec_idx = dwo ? str_index_dwo : str_index;
  struct dwarf_section *index_section = &debug_displays [idx_sec_idx].section;
  struct dwarf_section *str_section = &debug_displays [str_sec_idx].section;
  dwarf_vma index_offset;
  dwarf_vma str_offset;
  const char * ret;

  if (index_section->start == NULL)
    return (dwo ? _("<no .debug_str_offsets.dwo section>")
		: _("<no .debug_str_offsets section>"));

  if (str_section->start == NULL)
    return (dwo ? _("<no .debug_str.dwo section>")
		: _("<no .debug_str section>"));

  index_offset = idx * offset_size;

  if (this_set != NULL)
    index_offset += this_set->section_offsets [DW_SECT_STR_OFFSETS];

  index_offset += str_offsets_base;

  if (index_offset + offset_size > index_section->size)
    {
      warn (_("string index of %s converts to an offset of 0x%s which is too big for section %s"),
	    dwarf_vmatoa ("d", idx),
	    dwarf_vmatoa ("x", index_offset),
	    str_section->name);

      return _("<string index too big>");
    }

  /* FIXME: If we are being paranoid then we should also check to see if
     IDX references an entry beyond the end of the string table pointed to
     by STR_OFFSETS_BASE.  (Since there can be more than one string table
     in a DWARF string section).  */

  str_offset = byte_get (index_section->start + index_offset, offset_size);

  str_offset -= str_section->address;
  if (str_offset >= str_section->size)
    {
      warn (_("indirect offset too big: 0x%s\n"),
	    dwarf_vmatoa ("x", str_offset));
      return _("<indirect index offset is too big>");
    }

  ret = (const char *) str_section->start + str_offset;

  /* Unfortunately we cannot rely upon str_section ending with a NUL byte.
     Since our caller is expecting to receive a well formed C string we test
     for the lack of a terminating byte here.  */
  if (strnlen (ret, str_section->size - str_offset)
      == str_section->size - str_offset)
    return _("<no NUL byte at end of section>");

  return ret;
}

Project: binutils-gdb
File: dwarf.c

check_gnu_debugaltlink (const char * filename, void * data ATTRIBUTE_UNUSED)
{
  void * sep_data = open_debug_file (filename);

  if (sep_data == NULL)
    return false;

  /* FIXME: We should now extract the build-id in the separate file
     and check it...  */

  return true;
}

Project: binutils-gdb
File: dwarf.c

xcmalloc (size_t nmemb, size_t size)
{
  /* Check for overflow.  */
  if (nmemb >= ~(size_t) 0 / size)
    {
      fprintf (stderr,
	       _("Attempt to allocate an array with an excessive number of elements: 0x%lx\n"),
	       (long) nmemb);
      xexit (1);
    }

  return xmalloc (nmemb * size);
}

Project: binutils-gdb
File: dwarf.c

load_debug_section_with_follow (enum dwarf_section_display_enum sec_enum,
				void * handle)
{
  if (load_debug_section (sec_enum, handle))
    {
      if (debug_displays[sec_enum].section.filename == NULL)
	{
	  /* See if we can associate a filename with this section.  */
	  separate_info * i;

	  for (i = first_separate_info; i != NULL; i = i->next)
	    if (i->handle == handle)
	      {
		debug_displays[sec_enum].section.filename = i->filename;
		break;
	      }
	}

      return true;
    }

  if (do_follow_links)
    {
      separate_info * i;

      for (i = first_separate_info; i != NULL; i = i->next)
	{
	  if (load_debug_section (sec_enum, i->handle))
	    {
	      debug_displays[sec_enum].section.filename = i->filename;

	      /* FIXME: We should check to see if any of the remaining debug info
		 files also contain this section, and, umm, do something about it.  */
	      return true;
	    }
	}
    }

  return false;
}

Project: binutils-gdb
File: dwarf.c

free_all_abbrevs (void)
{
  abbrev_list *  list;

  for (list = abbrev_lists; list != NULL;)
    {
      abbrev_list *   next = list->next;
      abbrev_entry *  abbrv;

      for (abbrv = list->first_abbrev; abbrv != NULL;)
	{
	  abbrev_entry *  next_abbrev = abbrv->next;
	  abbrev_attr *   attr;

	  for (attr = abbrv->first_attr; attr;)
	    {
	      abbrev_attr *next_attr = attr->next;

	      free (attr);
	      attr = next_attr;
	    }

	  free (abbrv);
	  abbrv = next_abbrev;
	}

      free (list);
      list = next;
    }

  abbrev_lists = NULL;
}

Project: binutils-gdb
File: dwarf.c

add_abbrev_attr (unsigned long    attribute,
		 unsigned long    form,
		 dwarf_signed_vma implicit_const,
		 abbrev_list *    list)
{
  abbrev_attr *attr;

  attr = (abbrev_attr *) xmalloc (sizeof (*attr));

  attr->attribute      = attribute;
  attr->form           = form;
  attr->implicit_const = implicit_const;
  attr->next           = NULL;

  assert (list != NULL && list->last_abbrev != NULL);

  if (list->last_abbrev->first_attr == NULL)
    list->last_abbrev->first_attr = attr;
  else
    list->last_abbrev->last_attr->next = attr;

  list->last_abbrev->last_attr = attr;
}

Project: binutils-gdb
File: dwarf.c

check_for_and_load_links (void * file, const char * filename)
{
  void * handle = NULL;

  if (load_debug_section (gnu_debugaltlink, file))
    {
      Build_id_data build_id_data;

      handle = load_separate_debug_info (filename,
					 & debug_displays[gnu_debugaltlink].section,
					 parse_gnu_debugaltlink,
					 check_gnu_debugaltlink,
					 & build_id_data,
					 file);
      if (handle)
	{
	  assert (handle == first_separate_info->handle);
	  check_for_and_load_links (first_separate_info->handle,
				    first_separate_info->filename);
	}
    }

  if (load_debug_section (gnu_debuglink, file))
    {
      unsigned long crc32;

      handle = load_separate_debug_info (filename,
					 & debug_displays[gnu_debuglink].section,
					 parse_gnu_debuglink,
					 check_gnu_debuglink,
					 & crc32,
					 file);
      if (handle)
	{
	  assert (handle == first_separate_info->handle);
	  check_for_and_load_links (first_separate_info->handle,
				    first_separate_info->filename);
	}
    }

  load_debug_sup_file (filename, file);

  load_build_id_debug_file (filename, file);
}

Project: binutils-gdb
File: dwarf.c

add_dwo_name (const char * name, dwarf_vma cu_offset)
{
  add_dwo_info (name, cu_offset, DWO_NAME);
}

Project: binutils-gdb
File: dwarf.c

display_debug_pubnames_worker (struct dwarf_section *section,
			       void *file ATTRIBUTE_UNUSED,
			       int is_gnu)
{
  DWARF2_Internal_PubNames names;
  unsigned char *start = section->start;
  unsigned char *end = start + section->size;

  /* It does not matter if this load fails,
     we test for that later on.  */
  load_debug_info (file);

  introduce (section, false);

  while (start < end)
    {
      unsigned char *data;
      unsigned long sec_off = start - section->start;
      unsigned int offset_size;

      SAFE_BYTE_GET_AND_INC (names.pn_length, start, 4, end);
      if (names.pn_length == 0xffffffff)
	{
	  SAFE_BYTE_GET_AND_INC (names.pn_length, start, 8, end);
	  offset_size = 8;
	}
      else
	offset_size = 4;

      if (names.pn_length > (size_t) (end - start))
	{
	  warn (_("Debug info is corrupted, %s header at %#lx has length %s\n"),
		section->name,
		sec_off,
		dwarf_vmatoa ("x", names.pn_length));
	  break;
	}

      data = start;
      start += names.pn_length;

      SAFE_BYTE_GET_AND_INC (names.pn_version, data, 2, start);
      SAFE_BYTE_GET_AND_INC (names.pn_offset, data, offset_size, start);

      if (num_debug_info_entries != DEBUG_INFO_UNAVAILABLE
	  && num_debug_info_entries > 0
	  && find_debug_info_for_offset (names.pn_offset) == NULL)
	warn (_(".debug_info offset of 0x%lx in %s section does not point to a CU header.\n"),
	      (unsigned long) names.pn_offset, section->name);

      SAFE_BYTE_GET_AND_INC (names.pn_size, data, offset_size, start);

      printf (_("  Length:                              %ld\n"),
	      (long) names.pn_length);
      printf (_("  Version:                             %d\n"),
	      names.pn_version);
      printf (_("  Offset into .debug_info section:     0x%lx\n"),
	      (unsigned long) names.pn_offset);
      printf (_("  Size of area in .debug_info section: %ld\n"),
	      (long) names.pn_size);

      if (names.pn_version != 2 && names.pn_version != 3)
	{
	  static int warned = 0;

	  if (! warned)
	    {
	      warn (_("Only DWARF 2 and 3 pubnames are currently supported\n"));
	      warned = 1;
	    }

	  continue;
	}

      if (is_gnu)
	printf (_("\n    Offset  Kind          Name\n"));
      else
	printf (_("\n    Offset\tName\n"));

      while (1)
	{
	  bfd_size_type maxprint;
	  dwarf_vma offset;

	  SAFE_BYTE_GET_AND_INC (offset, data, offset_size, start);

	  if (offset == 0)
	    break;

	  if (data >= start)
	    break;
	  maxprint = (start - data) - 1;

	  if (is_gnu)
	    {
	      unsigned int kind_data;
	      gdb_index_symbol_kind kind;
	      const char *kind_name;
	      int is_static;

	      SAFE_BYTE_GET_AND_INC (kind_data, data, 1, start);
	      maxprint --;
	      /* GCC computes the kind as the upper byte in the CU index
		 word, and then right shifts it by the CU index size.
		 Left shift KIND to where the gdb-index.h accessor macros
		 can use it.  */
	      kind_data <<= GDB_INDEX_CU_BITSIZE;
	      kind = GDB_INDEX_SYMBOL_KIND_VALUE (kind_data);
	      kind_name = get_gdb_index_symbol_kind_name (kind);
	      is_static = GDB_INDEX_SYMBOL_STATIC_VALUE (kind_data);
	      printf ("    %-6lx  %s,%-10s  %.*s\n",
		      (unsigned long) offset, is_static ? _("s") : _("g"),
		      kind_name, (int) maxprint, data);
	    }
	  else
	    printf ("    %-6lx\t%.*s\n",
		    (unsigned long) offset, (int) maxprint, data);

	  data += strnlen ((char *) data, maxprint);
	  if (data < start)
	    data++;
	  if (data >= start)
	    break;
	}
    }

  printf ("\n");
  return 1;
}

Project: binutils-gdb
File: dwarf.c

get_encoded_value (unsigned char **pdata,
		   int encoding,
		   struct dwarf_section *section,
		   unsigned char * end)
{
  unsigned char * data = * pdata;
  unsigned int size = size_of_encoded_value (encoding);
  dwarf_vma val;

  if (data >= end || size > (size_t) (end - data))
    {
      warn (_("Encoded value extends past end of section\n"));
      * pdata = end;
      return 0;
    }

  /* PR 17512: file: 002-829853-0.004.  */
  if (size > 8)
    {
      warn (_("Encoded size of %d is too large to read\n"), size);
      * pdata = end;
      return 0;
    }

  /* PR 17512: file: 1085-5603-0.004.  */
  if (size == 0)
    {
      warn (_("Encoded size of 0 is too small to read\n"));
      * pdata = end;
      return 0;
    }

  if (encoding & DW_EH_PE_signed)
    val = byte_get_signed (data, size);
  else
    val = byte_get (data, size);

  if ((encoding & 0x70) == DW_EH_PE_pcrel)
    val += section->address + (data - section->start);

  * pdata = data + size;
  return val;
}

Project: binutils-gdb
File: dwarf.c

process_debug_info (struct dwarf_section * section,
		    void *file,
		    enum dwarf_section_display_enum abbrev_sec,
		    bool do_loc,
		    bool do_types)
{
  unsigned char *start = section->start;
  unsigned char *end = start + section->size;
  unsigned char *section_begin;
  unsigned int unit;
  unsigned int num_units = 0;

  /* First scan the section to get the number of comp units.
     Length sanity checks are done here.  */
  for (section_begin = start, num_units = 0; section_begin < end;
       num_units ++)
    {
      dwarf_vma length;

      /* Read the first 4 bytes.  For a 32-bit DWARF section, this
	 will be the length.  For a 64-bit DWARF section, it'll be
	 the escape code 0xffffffff followed by an 8 byte length.  */
      SAFE_BYTE_GET_AND_INC (length, section_begin, 4, end);

      if (length == 0xffffffff)
	SAFE_BYTE_GET_AND_INC (length, section_begin, 8, end);
      else if (length >= 0xfffffff0 && length < 0xffffffff)
	{
	  warn (_("Reserved length value (0x%s) found in section %s\n"),
		dwarf_vmatoa ("x", length), section->name);
	  return false;
	}

      /* Negative values are illegal, they may even cause infinite
	 looping.  This can happen if we can't accurately apply
	 relocations to an object file, or if the file is corrupt.  */
      if (length > (size_t) (end - section_begin))
	{
	  warn (_("Corrupt unit length (got 0x%s expected at most 0x%s) in section %s\n"),
		dwarf_vmatoa ("x", length),
		dwarf_vmatoa ("x", end - section_begin),
		section->name);
	  return false;
	}
      section_begin += length;
    }

  if (num_units == 0)
    {
      error (_("No comp units in %s section ?\n"), section->name);
      return false;
    }

  if ((do_loc || do_debug_loc || do_debug_ranges || do_debug_info)
      && num_debug_info_entries == 0
      && ! do_types)
    {

      /* Then allocate an array to hold the information.  */
      debug_information = (debug_info *) cmalloc (num_units,
						  sizeof (* debug_information));
      if (debug_information == NULL)
	{
	  error (_("Not enough memory for a debug info array of %u entries\n"),
		 num_units);
	  alloc_num_debug_info_entries = num_debug_info_entries = 0;
	  return false;
	}

      /* PR 17531: file: 92ca3797.
	 We cannot rely upon the debug_information array being initialised
	 before it is used.  A corrupt file could easily contain references
	 to a unit for which information has not been made available.  So
	 we ensure that the array is zeroed here.  */
      memset (debug_information, 0, num_units * sizeof (*debug_information));

      alloc_num_debug_info_entries = num_units;
    }

  if (!do_loc)
    {
      load_debug_section_with_follow (str, file);
      load_debug_section_with_follow (line_str, file);
      load_debug_section_with_follow (str_dwo, file);
      load_debug_section_with_follow (str_index, file);
      load_debug_section_with_follow (str_index_dwo, file);
      load_debug_section_with_follow (debug_addr, file);
    }

  load_debug_section_with_follow (abbrev_sec, file);
  load_debug_section_with_follow (loclists, file);
  load_debug_section_with_follow (rnglists, file);
  
  if (debug_displays [abbrev_sec].section.start == NULL)
    {
      warn (_("Unable to locate %s section!\n"),
	    debug_displays [abbrev_sec].section.uncompressed_name);
      return false;
    }

  if (!do_loc && dwarf_start_die == 0)
    introduce (section, false);

  free_all_abbrevs ();
  free (cu_abbrev_map);
  cu_abbrev_map = NULL;
  next_free_abbrev_map_entry = 0;

  /* In order to be able to resolve DW_FORM_ref_attr forms we need
     to load *all* of the abbrevs for all CUs in this .debug_info
     section.  This does effectively mean that we (partially) read
     every CU header twice.  */
  for (section_begin = start; start < end;)
    {
      DWARF2_Internal_CompUnit  compunit;
      unsigned char *           hdrptr;
      dwarf_vma                 abbrev_base;
      size_t                    abbrev_size;
      dwarf_vma                 cu_offset;
      unsigned int              offset_size;
      struct cu_tu_set *        this_set;
      abbrev_list *             list;
      unsigned char *end_cu;

      hdrptr = start;
      cu_offset = start - section_begin;

      SAFE_BYTE_GET_AND_INC (compunit.cu_length, hdrptr, 4, end);

      if (compunit.cu_length == 0xffffffff)
	{
	  SAFE_BYTE_GET_AND_INC (compunit.cu_length, hdrptr, 8, end);
	  offset_size = 8;
	}
      else
	offset_size = 4;
      end_cu = hdrptr + compunit.cu_length;

      SAFE_BYTE_GET_AND_INC (compunit.cu_version, hdrptr, 2, end_cu);

      this_set = find_cu_tu_set_v2 (cu_offset, do_types);

      if (compunit.cu_version < 5)
	{
	  compunit.cu_unit_type = DW_UT_compile;
	  /* Initialize it due to a false compiler warning.  */
	  compunit.cu_pointer_size = -1;
	}
      else
	{
	  SAFE_BYTE_GET_AND_INC (compunit.cu_unit_type, hdrptr, 1, end_cu);
	  do_types = (compunit.cu_unit_type == DW_UT_type);

	  SAFE_BYTE_GET_AND_INC (compunit.cu_pointer_size, hdrptr, 1, end_cu);
	}

      SAFE_BYTE_GET_AND_INC (compunit.cu_abbrev_offset, hdrptr, offset_size,
			     end_cu);

      if (compunit.cu_unit_type == DW_UT_split_compile
	  || compunit.cu_unit_type == DW_UT_skeleton)
	{
	  uint64_t dwo_id;
	  SAFE_BYTE_GET_AND_INC (dwo_id, hdrptr, 8, end_cu);
	}

      if (this_set == NULL)
	{
	  abbrev_base = 0;
	  abbrev_size = debug_displays [abbrev_sec].section.size;
	}
      else
	{
	  abbrev_base = this_set->section_offsets [DW_SECT_ABBREV];
	  abbrev_size = this_set->section_sizes [DW_SECT_ABBREV];
	}

      list = find_abbrev_list_by_abbrev_offset (abbrev_base,
						compunit.cu_abbrev_offset);
      if (list == NULL)
	{
	  unsigned char *  next;

	  list = new_abbrev_list (abbrev_base,
				  compunit.cu_abbrev_offset);
	  next = process_abbrev_set (&debug_displays[abbrev_sec].section,
				     abbrev_base, abbrev_size,
				     compunit.cu_abbrev_offset, list);
	  list->start_of_next_abbrevs = next;
	}

      start = end_cu;
      record_abbrev_list_for_cu (cu_offset, start - section_begin, list);
    }

  for (start = section_begin, unit = 0; start < end; unit++)
    {
      DWARF2_Internal_CompUnit compunit;
      unsigned char *hdrptr;
      unsigned char *tags;
      int level, last_level, saved_level;
      dwarf_vma cu_offset;
      unsigned int offset_size;
      dwarf_vma signature = 0;
      dwarf_vma type_offset = 0;
      struct cu_tu_set *this_set;
      dwarf_vma abbrev_base;
      size_t abbrev_size;
      abbrev_list * list = NULL;
      unsigned char *end_cu;

      hdrptr = start;
      cu_offset = start - section_begin;

      SAFE_BYTE_GET_AND_INC (compunit.cu_length, hdrptr, 4, end);

      if (compunit.cu_length == 0xffffffff)
	{
	  SAFE_BYTE_GET_AND_INC (compunit.cu_length, hdrptr, 8, end);
	  offset_size = 8;
	}
      else
	offset_size = 4;
      end_cu = hdrptr + compunit.cu_length;

      SAFE_BYTE_GET_AND_INC (compunit.cu_version, hdrptr, 2, end_cu);

      this_set = find_cu_tu_set_v2 (cu_offset, do_types);

      if (compunit.cu_version < 5)
	{
	  compunit.cu_unit_type = DW_UT_compile;
	  /* Initialize it due to a false compiler warning.  */
	  compunit.cu_pointer_size = -1;
	}
      else
	{
	  SAFE_BYTE_GET_AND_INC (compunit.cu_unit_type, hdrptr, 1, end_cu);
	  do_types = (compunit.cu_unit_type == DW_UT_type);

	  SAFE_BYTE_GET_AND_INC (compunit.cu_pointer_size, hdrptr, 1, end_cu);
	}

      SAFE_BYTE_GET_AND_INC (compunit.cu_abbrev_offset, hdrptr, offset_size, end_cu);

      if (this_set == NULL)
	{
	  abbrev_base = 0;
	  abbrev_size = debug_displays [abbrev_sec].section.size;
	}
      else
	{
	  abbrev_base = this_set->section_offsets [DW_SECT_ABBREV];
	  abbrev_size = this_set->section_sizes [DW_SECT_ABBREV];
	}

      if (compunit.cu_version < 5)
	SAFE_BYTE_GET_AND_INC (compunit.cu_pointer_size, hdrptr, 1, end_cu);

      bool do_dwo_id = false;
      uint64_t dwo_id = 0;
      if (compunit.cu_unit_type == DW_UT_split_compile
	  || compunit.cu_unit_type == DW_UT_skeleton)
	{
	  SAFE_BYTE_GET_AND_INC (dwo_id, hdrptr, 8, end_cu);
	  do_dwo_id = true;
	}

      /* PR 17512: file: 001-108546-0.001:0.1.  */
      if (compunit.cu_pointer_size < 2 || compunit.cu_pointer_size > 8)
	{
	  warn (_("Invalid pointer size (%d) in compunit header, using %d instead\n"),
		compunit.cu_pointer_size, offset_size);
	  compunit.cu_pointer_size = offset_size;
	}

      if (do_types)
	{
	  SAFE_BYTE_GET_AND_INC (signature, hdrptr, 8, end_cu);
	  SAFE_BYTE_GET_AND_INC (type_offset, hdrptr, offset_size, end_cu);
	}

      if (dwarf_start_die >= (size_t) (end_cu - section_begin))
	{
	  start = end_cu;
	  continue;
	}

      if ((do_loc || do_debug_loc || do_debug_ranges || do_debug_info)
	  && num_debug_info_entries == 0
	  && alloc_num_debug_info_entries > unit
	  && ! do_types)
	{
	  debug_information [unit].cu_offset = cu_offset;
	  debug_information [unit].pointer_size
	    = compunit.cu_pointer_size;
	  debug_information [unit].offset_size = offset_size;
	  debug_information [unit].dwarf_version = compunit.cu_version;
	  debug_information [unit].base_address = 0;
	  debug_information [unit].addr_base = DEBUG_INFO_UNAVAILABLE;
	  debug_information [unit].ranges_base = DEBUG_INFO_UNAVAILABLE;
	  debug_information [unit].loc_offsets = NULL;
	  debug_information [unit].have_frame_base = NULL;
	  debug_information [unit].max_loc_offsets = 0;
	  debug_information [unit].num_loc_offsets = 0;
	  debug_information [unit].loclists_base = 0;
	  debug_information [unit].range_lists = NULL;
	  debug_information [unit].max_range_lists= 0;
	  debug_information [unit].num_range_lists = 0;
	  debug_information [unit].rnglists_base = 0;
	  debug_information [unit].str_offsets_base = 0;
	}

      if (!do_loc && dwarf_start_die == 0)
	{
	  printf (_("  Compilation Unit @ offset 0x%s:\n"),
		  dwarf_vmatoa ("x", cu_offset));
	  printf (_("   Length:        0x%s (%s)\n"),
		  dwarf_vmatoa ("x", compunit.cu_length),
		  offset_size == 8 ? "64-bit" : "32-bit");
	  printf (_("   Version:       %d\n"), compunit.cu_version);
	  if (compunit.cu_version >= 5)
	    {
	      const char *name = get_DW_UT_name (compunit.cu_unit_type);

	      printf (_("   Unit Type:     %s (%x)\n"),
		      name ? name : "???",
		      compunit.cu_unit_type);
	    }
	  printf (_("   Abbrev Offset: 0x%s\n"),
		  dwarf_vmatoa ("x", compunit.cu_abbrev_offset));
	  printf (_("   Pointer Size:  %d\n"), compunit.cu_pointer_size);
	  if (do_types)
	    {
	      printf (_("   Signature:     0x%s\n"),
		      dwarf_vmatoa ("x", signature));
	      printf (_("   Type Offset:   0x%s\n"),
		      dwarf_vmatoa ("x", type_offset));
	    }
	  if (do_dwo_id)
	    printf (_("   DWO ID:        0x%s\n"), dwarf_vmatoa ("x", dwo_id));
	  if (this_set != NULL)
	    {
	      dwarf_vma *offsets = this_set->section_offsets;
	      size_t *sizes = this_set->section_sizes;

	      printf (_("   Section contributions:\n"));
	      printf (_("    .debug_abbrev.dwo:       0x%s  0x%s\n"),
		      dwarf_vmatoa ("x", offsets [DW_SECT_ABBREV]),
		      dwarf_vmatoa ("x", sizes [DW_SECT_ABBREV]));
	      printf (_("    .debug_line.dwo:         0x%s  0x%s\n"),
		      dwarf_vmatoa ("x", offsets [DW_SECT_LINE]),
		      dwarf_vmatoa ("x", sizes [DW_SECT_LINE]));
	      printf (_("    .debug_loc.dwo:          0x%s  0x%s\n"),
		      dwarf_vmatoa ("x", offsets [DW_SECT_LOC]),
		      dwarf_vmatoa ("x", sizes [DW_SECT_LOC]));
	      printf (_("    .debug_str_offsets.dwo:  0x%s  0x%s\n"),
		      dwarf_vmatoa ("x", offsets [DW_SECT_STR_OFFSETS]),
		      dwarf_vmatoa ("x", sizes [DW_SECT_STR_OFFSETS]));
	    }
	}

      tags = hdrptr;
      start = end_cu;

      if (compunit.cu_version < 2 || compunit.cu_version > 5)
	{
	  warn (_("CU at offset %s contains corrupt or "
		  "unsupported version number: %d.\n"),
		dwarf_vmatoa ("x", cu_offset), compunit.cu_version);
	  continue;
	}

      if (compunit.cu_unit_type != DW_UT_compile
	  && compunit.cu_unit_type != DW_UT_partial
	  && compunit.cu_unit_type != DW_UT_type
	  && compunit.cu_unit_type != DW_UT_split_compile
	  && compunit.cu_unit_type != DW_UT_skeleton)
	{
	  warn (_("CU at offset %s contains corrupt or "
		  "unsupported unit type: %d.\n"),
		dwarf_vmatoa ("x", cu_offset), compunit.cu_unit_type);
	  continue;
	}

      /* Process the abbrevs used by this compilation unit.  */
      list = find_abbrev_list_by_abbrev_offset (abbrev_base,
						compunit.cu_abbrev_offset);
      if (list == NULL)
	{
	  unsigned char *next;

	  list = new_abbrev_list (abbrev_base,
				  compunit.cu_abbrev_offset);
	  next = process_abbrev_set (&debug_displays[abbrev_sec].section,
				     abbrev_base, abbrev_size,
				     compunit.cu_abbrev_offset, list);
	  list->start_of_next_abbrevs = next;
	}

      level = 0;
      last_level = level;
      saved_level = -1;
      while (tags < start)
	{
	  unsigned long abbrev_number;
	  unsigned long die_offset;
	  abbrev_entry *entry;
	  abbrev_attr *attr;
	  int do_printing = 1;

	  die_offset = tags - section_begin;

	  READ_ULEB (abbrev_number, tags, start);

	  /* A null DIE marks the end of a list of siblings or it may also be
	     a section padding.  */
	  if (abbrev_number == 0)
	    {
	      /* Check if it can be a section padding for the last CU.  */
	      if (level == 0 && start == end)
		{
		  unsigned char *chk;

		  for (chk = tags; chk < start; chk++)
		    if (*chk != 0)
		      break;
		  if (chk == start)
		    break;
		}

	      if (!do_loc && die_offset >= dwarf_start_die
		  && (dwarf_cutoff_level == -1
		      || level < dwarf_cutoff_level))
		printf (_(" <%d><%lx>: Abbrev Number: 0\n"),
			level, die_offset);

	      --level;
	      if (level < 0)
		{
		  static unsigned num_bogus_warns = 0;

		  if (num_bogus_warns < 3)
		    {
		      warn (_("Bogus end-of-siblings marker detected at offset %lx in %s section\n"),
			    die_offset, section->name);
		      num_bogus_warns ++;
		      if (num_bogus_warns == 3)
			warn (_("Further warnings about bogus end-of-sibling markers suppressed\n"));
		    }
		}
	      if (dwarf_start_die != 0 && level < saved_level)
		return true;
	      continue;
	    }

	  if (!do_loc)
	    {
	      if (dwarf_start_die != 0 && die_offset < dwarf_start_die)
		do_printing = 0;
	      else
		{
		  if (dwarf_start_die != 0 && die_offset == dwarf_start_die)
		    saved_level = level;
		  do_printing = (dwarf_cutoff_level == -1
				 || level < dwarf_cutoff_level);
		  if (do_printing)
		    printf (_(" <%d><%lx>: Abbrev Number: %lu"),
			    level, die_offset, abbrev_number);
		  else if (dwarf_cutoff_level == -1
			   || last_level < dwarf_cutoff_level)
		    printf (_(" <%d><%lx>: ...\n"), level, die_offset);
		  last_level = level;
		}
	    }

	  /* Scan through the abbreviation list until we reach the
	     correct entry.  */
	  if (list == NULL)
	    continue;

	  for (entry = list->first_abbrev; entry != NULL; entry = entry->next)
	    if (entry->number == abbrev_number)
	      break;

	  if (entry == NULL)
	    {
	      if (!do_loc && do_printing)
		{
		  printf ("\n");
		  fflush (stdout);
		}
	      warn (_("DIE at offset 0x%lx refers to abbreviation number %lu which does not exist\n"),
		    die_offset, abbrev_number);
	      return false;
	    }

	  if (!do_loc && do_printing)
	    printf (" (%s)\n", get_TAG_name (entry->tag));

	  switch (entry->tag)
	    {
	    default:
	      need_base_address = 0;
	      break;
	    case DW_TAG_compile_unit:
	      need_base_address = 1;	
	      need_dwo_info = do_loc;
	      break;
	    case DW_TAG_entry_point:
	    case DW_TAG_subprogram:
	      need_base_address = 0;
	      /* Assuming that there is no DW_AT_frame_base.  */
	      have_frame_base = 0;
	      break;
	    }

	  debug_info *debug_info_p =
	    (debug_information && unit < alloc_num_debug_info_entries)
	    ? debug_information + unit : NULL;

	  assert (!debug_info_p
		  || (debug_info_p->num_loc_offsets
		      == debug_info_p->num_loc_views));

	  for (attr = entry->first_attr;
	       attr && attr->attribute;
	       attr = attr->next)
	    {
	      if (! do_loc && do_printing)
		/* Show the offset from where the tag was extracted.  */
		printf ("    <%lx>", (unsigned long)(tags - section_begin));
	      tags = read_and_display_attr (attr->attribute,
					    attr->form,
					    attr->implicit_const,
					    section_begin,
					    tags,
					    start,
					    cu_offset,
					    compunit.cu_pointer_size,
					    offset_size,
					    compunit.cu_version,
					    debug_info_p,
					    do_loc || ! do_printing,
					    section,
					    this_set,
					    level);
	    }

	  /* If a locview attribute appears before a location one,
	     make sure we don't associate it with an earlier
	     loclist. */
	  if (debug_info_p)
	    switch (debug_info_p->num_loc_offsets - debug_info_p->num_loc_views)
	      {
	      case 1:
		debug_info_p->loc_views [debug_info_p->num_loc_views] = vm1;
		debug_info_p->num_loc_views++;
		assert (debug_info_p->num_loc_views
			== debug_info_p->num_loc_offsets);
		break;

	      case 0:
		break;

	      case -1:
		warn(_("DIE has locviews without loclist\n"));
		debug_info_p->num_loc_views--;
		break;

	      default:
		assert (0);
	    }

	  if (entry->children)
	    ++level;
	}
    }

  /* Set num_debug_info_entries here so that it can be used to check if
     we need to process .debug_loc and .debug_ranges sections.  */
  if ((do_loc || do_debug_loc || do_debug_ranges || do_debug_info)
      && num_debug_info_entries == 0
      && ! do_types)
    {
      if (num_units > alloc_num_debug_info_entries)
	num_debug_info_entries = alloc_num_debug_info_entries;
      else
	num_debug_info_entries = num_units;
    }

  if (!do_loc)
    printf ("\n");

  return true;
}

Project: binutils-gdb
File: dwarf.c

is_max_address (dwarf_vma addr, unsigned int pointer_size)
{
  dwarf_vma mask = ~(~(dwarf_vma) 1 << (pointer_size * 8 - 1));
  return ((addr & mask) == mask);
}

Project: binutils-gdb
File: dwarf.c

display_debug_gnu_pubnames (struct dwarf_section *section, void *file)
{
  return display_debug_pubnames_worker (section, file, 1);
}

Project: binutils-gdb
File: dwarf.c

check_gnu_debuglink (const char * pathname, void * crc_pointer)
{
  static unsigned char buffer [8 * 1024];
  FILE *         f;
  bfd_size_type  count;
  unsigned long  crc = 0;
  void *         sep_data;

  sep_data = open_debug_file (pathname);
  if (sep_data == NULL)
    return false;

  /* Yes - we are opening the file twice...  */
  f = fopen (pathname, "rb");
  if (f == NULL)
    {
      /* Paranoia: This should never happen.  */
      close_debug_file (sep_data);
      warn (_("Unable to reopen separate debug info file: %s\n"), pathname);
      return false;
    }

  while ((count = fread (buffer, 1, sizeof (buffer), f)) > 0)
    crc = calc_gnu_debuglink_crc32 (crc, buffer, count);

  fclose (f);

  if (crc != * (unsigned long *) crc_pointer)
    {
      close_debug_file (sep_data);
      warn (_("Separate debug info file %s found, but CRC does not match - ignoring\n"),
	    pathname);
      return false;
    }

  return true;
}

Project: binutils-gdb
File: dwarf.c

new_abbrev_list (dwarf_vma abbrev_base, dwarf_vma abbrev_offset)
{
  abbrev_list * list = (abbrev_list *) xcalloc (sizeof * list, 1);

  list->abbrev_base = abbrev_base;
  list->abbrev_offset = abbrev_offset;

  list->next = abbrev_lists;
  abbrev_lists = list;

  return list;
}

Project: binutils-gdb
File: dwarf.c

find_cu_tu_set_v2 (dwarf_vma cu_offset, int do_types)
{
  struct cu_tu_set *p;
  unsigned int nsets;
  unsigned int dw_sect;

  if (do_types)
    {
      p = tu_sets;
      nsets = tu_count;
      dw_sect = DW_SECT_TYPES;
    }
  else
    {
      p = cu_sets;
      nsets = cu_count;
      dw_sect = DW_SECT_INFO;
    }
  while (nsets > 0)
    {
      if (p->section_offsets [dw_sect] == cu_offset)
	return p;
      p++;
      nsets--;
    }
  return NULL;
}

Project: binutils-gdb
File: dwarf.c

print_dwarf_vma (dwarf_vma value, unsigned num_bytes)
{
  printf ("%s ", dwarf_vmatoa_1 (NULL, value, num_bytes));
}

Project: binutils-gdb
File: dwarf.c

print_dwarf_view (dwarf_vma value, unsigned num_bytes, int force)
{
  int len;
  if (!num_bytes)
    len = 4;
  else
    len = num_bytes * 2;

  assert (value == (unsigned long) value);
  if (value || force)
    printf ("v%0*lx ", len - 1, (unsigned long) value);
  else
    printf ("%*s", len + 1, "");
}

Project: binutils-gdb
File: dwarf.c

load_dwo_file (const char * main_filename, const char * name, const char * dir, const char * id ATTRIBUTE_UNUSED)
{
  char * separate_filename;
  void * separate_handle;

  if (IS_ABSOLUTE_PATH (name))
    separate_filename = strdup (name);
  else
    /* FIXME: Skip adding / if dwo_dir ends in /.  */
    separate_filename = concat (dir, "/", name, NULL);
  if (separate_filename == NULL)
    {
      warn (_("Out of memory allocating dwo filename\n"));
      return NULL;
    }

  if ((separate_handle = open_debug_file (separate_filename)) == NULL)
    {
      warn (_("Unable to load dwo file: %s\n"), separate_filename);
      free (separate_filename);
      return NULL;
    }

  /* FIXME: We should check the dwo_id.  */

  printf (_("%s: Found separate debug object file: %s\n\n"), main_filename, separate_filename);

  add_separate_debug_file (separate_filename, separate_handle);
  /* Note - separate_filename will be freed in free_debug_memory().  */
  return separate_handle;
}

Project: binutils-gdb
File: dwarf.c

dwarf_select_sections_all (void)
{
  do_debug_info = 1;
  do_debug_abbrevs = 1;
  do_debug_lines = FLAG_DEBUG_LINES_RAW;
  do_debug_pubnames = 1;
  do_debug_pubtypes = 1;
  do_debug_aranges = 1;
  do_debug_ranges = 1;
  do_debug_frames = 1;
  do_debug_macinfo = 1;
  do_debug_str = 1;
  do_debug_loc = 1;
  do_gdb_index = 1;
  do_trace_info = 1;
  do_trace_abbrevs = 1;
  do_trace_aranges = 1;
  do_debug_addr = 1;
  do_debug_cu_index = 1;
  do_follow_links = 1;
  do_debug_links = 1;
  do_debug_str_offsets = 1;
}

Project: binutils-gdb
File: dwarf.c

display_loc_list (struct dwarf_section *section,
		  unsigned char **start_ptr,
		  unsigned int debug_info_entry,
		  dwarf_vma offset,
		  dwarf_vma base_address,
		  unsigned char **vstart_ptr,
		  int has_frame_base)
{
  unsigned char *start = *start_ptr, *vstart = *vstart_ptr;
  unsigned char *section_end = section->start + section->size;
  dwarf_vma    cu_offset;
  unsigned int pointer_size;
  unsigned int offset_size;
  int dwarf_version;
  dwarf_vma begin;
  dwarf_vma end;
  unsigned short length;
  int need_frame_base;

  if (debug_info_entry >= num_debug_info_entries)
    {
      warn (_("No debug information available for loc lists of entry: %u\n"),
	    debug_info_entry);
      return;
    }

  cu_offset = debug_information [debug_info_entry].cu_offset;
  pointer_size = debug_information [debug_info_entry].pointer_size;
  offset_size = debug_information [debug_info_entry].offset_size;
  dwarf_version = debug_information [debug_info_entry].dwarf_version;

  if (pointer_size < 2 || pointer_size > 8)
    {
      warn (_("Invalid pointer size (%d) in debug info for entry %d\n"),
	    pointer_size, debug_info_entry);
      return;
    }

  while (1)
    {
      dwarf_vma off = offset + (start - *start_ptr);
      dwarf_vma vbegin = vm1, vend = vm1;

      if (2 * pointer_size > (size_t) (section_end - start))
	{
	  warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
		(unsigned long) offset);
	  break;
	}

      printf ("    ");
      print_dwarf_vma (off, 4);

      SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, section_end);
      SAFE_BYTE_GET_AND_INC (end, start, pointer_size, section_end);

      if (begin == 0 && end == 0)
	{
	  /* PR 18374: In a object file we can have a location list that
	     starts with a begin and end of 0 because there are relocations
	     that need to be applied to the addresses.  Actually applying
	     the relocations now does not help as they will probably resolve
	     to 0, since the object file has not been fully linked.  Real
	     end of list markers will not have any relocations against them.  */
	  if (! reloc_at (section, off)
	      && ! reloc_at (section, off + pointer_size))
	    {
	      printf (_("<End of list>\n"));
	      break;
	    }
	}

      /* Check base address specifiers.  */
      if (is_max_address (begin, pointer_size)
          && !is_max_address (end, pointer_size))
	{
	  base_address = end;
	  print_dwarf_vma (begin, pointer_size);
	  print_dwarf_vma (end, pointer_size);
	  printf (_("(base address)\n"));
	  continue;
	}

      if (vstart)
	{
	  off = offset + (vstart - *start_ptr);

	  READ_ULEB (vbegin, vstart, section_end);
	  print_dwarf_view (vbegin, pointer_size, 1);

	  READ_ULEB (vend, vstart, section_end);
	  print_dwarf_view (vend, pointer_size, 1);

	  printf (_("views at %8.8lx for:\n    %*s "),
		  (unsigned long) off, 8, "");
	}

      if (2 > (size_t) (section_end - start))
	{
	  warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
		(unsigned long) offset);
	  break;
	}

      SAFE_BYTE_GET_AND_INC (length, start, 2, section_end);

      if (length > (size_t) (section_end - start))
	{
	  warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
		(unsigned long) offset);
	  break;
	}

      print_dwarf_vma (begin + base_address, pointer_size);
      print_dwarf_vma (end + base_address, pointer_size);

      putchar ('(');
      need_frame_base = decode_location_expression (start,
						    pointer_size,
						    offset_size,
						    dwarf_version,
						    length,
						    cu_offset, section);
      putchar (')');

      if (need_frame_base && !has_frame_base)
	printf (_(" [without DW_AT_frame_base]"));

      if (begin == end && vbegin == vend)
	fputs (_(" (start == end)"), stdout);
      else if (begin > end || (begin == end && vbegin > vend))
	fputs (_(" (start > end)"), stdout);

      putchar ('\n');

      start += length;
    }

  *start_ptr = start;
  *vstart_ptr = vstart;
}

Project: binutils-gdb
File: dwarf.c

display_debug_lines_raw (struct dwarf_section *  section,
			 unsigned char *         data,
			 unsigned char *         end,
			 void *                  file)
{
  unsigned char *start = section->start;
  int verbose_view = 0;

  introduce (section, true);

  while (data < end)
    {
      static DWARF2_Internal_LineInfo saved_linfo;
      DWARF2_Internal_LineInfo linfo;
      unsigned char *standard_opcodes;
      unsigned char *end_of_sequence;
      int i;

      if (startswith (section->name, ".debug_line.")
	  /* Note: the following does not apply to .debug_line.dwo sections.
	     These are full debug_line sections.  */
	  && strcmp (section->name, ".debug_line.dwo") != 0)
	{
	  /* Sections named .debug_line.<foo> are fragments of a .debug_line
	     section containing just the Line Number Statements.  They are
	     created by the assembler and intended to be used alongside gcc's
	     -ffunction-sections command line option.  When the linker's
	     garbage collection decides to discard a .text.<foo> section it
	     can then also discard the line number information in .debug_line.<foo>.

	     Since the section is a fragment it does not have the details
	     needed to fill out a LineInfo structure, so instead we use the
	     details from the last full debug_line section that we processed.  */
	  end_of_sequence = end;
	  standard_opcodes = NULL;
	  linfo = saved_linfo;
	  /* PR 17531: file: 0522b371.  */
	  if (linfo.li_line_range == 0)
	    {
	      warn (_("Partial .debug_line. section encountered without a prior full .debug_line section\n"));
	      return 0;
	    }
	  reset_state_machine (linfo.li_default_is_stmt);
	}
      else
	{
	  unsigned char * hdrptr;

	  if ((hdrptr = read_debug_line_header (section, data, end, & linfo,
						& end_of_sequence)) == NULL)
	    return 0;

	  printf (_("  Offset:                      0x%lx\n"), (long)(data - start));
	  printf (_("  Length:                      %ld\n"), (long) linfo.li_length);
	  printf (_("  DWARF Version:               %d\n"), linfo.li_version);
	  if (linfo.li_version >= 5)
	    {
	      printf (_("  Address size (bytes):        %d\n"), linfo.li_address_size);
	      printf (_("  Segment selector (bytes):    %d\n"), linfo.li_segment_size);
	    }
	  printf (_("  Prologue Length:             %d\n"), (int) linfo.li_prologue_length);
	  printf (_("  Minimum Instruction Length:  %d\n"), linfo.li_min_insn_length);
	  if (linfo.li_version >= 4)
	    printf (_("  Maximum Ops per Instruction: %d\n"), linfo.li_max_ops_per_insn);
	  printf (_("  Initial value of 'is_stmt':  %d\n"), linfo.li_default_is_stmt);
	  printf (_("  Line Base:                   %d\n"), linfo.li_line_base);
	  printf (_("  Line Range:                  %d\n"), linfo.li_line_range);
	  printf (_("  Opcode Base:                 %d\n"), linfo.li_opcode_base);

	  /* PR 17512: file: 1665-6428-0.004.  */
	  if (linfo.li_line_range == 0)
	    {
	      warn (_("Line range of 0 is invalid, using 1 instead\n"));
	      linfo.li_line_range = 1;
	    }

	  reset_state_machine (linfo.li_default_is_stmt);

	  /* Display the contents of the Opcodes table.  */
	  standard_opcodes = hdrptr;

	  /* PR 17512: file: 002-417945-0.004.  */
	  if (standard_opcodes + linfo.li_opcode_base >= end)
	    {
	      warn (_("Line Base extends beyond end of section\n"));
	      return 0;
	    }

	  printf (_("\n Opcodes:\n"));

	  for (i = 1; i < linfo.li_opcode_base; i++)
	    printf (ngettext ("  Opcode %d has %d arg\n",
			      "  Opcode %d has %d args\n",
			      standard_opcodes[i - 1]),
		    i, standard_opcodes[i - 1]);

	  /* Display the contents of the Directory table.  */
	  data = standard_opcodes + linfo.li_opcode_base - 1;

	  if (linfo.li_version >= 5)
	    {
	      load_debug_section_with_follow (line_str, file);

	      data = display_formatted_table (data, start, end, &linfo, section,
					      true);
	      data = display_formatted_table (data, start, end, &linfo, section,
					      false);
	    }
	  else
	    {
	      if (*data == 0)
		printf (_("\n The Directory Table is empty.\n"));
	      else
		{
		  unsigned int last_dir_entry = 0;

		  printf (_("\n The Directory Table (offset 0x%lx):\n"),
			  (long)(data - start));

		  while (data < end && *data != 0)
		    {
		      printf ("  %d\t%.*s\n", ++last_dir_entry, (int) (end - data), data);

		      data += strnlen ((char *) data, end - data);
		      if (data < end)
			data++;
		    }

		  /* PR 17512: file: 002-132094-0.004.  */
		  if (data >= end - 1)
		    break;
		}

	      /* Skip the NUL at the end of the table.  */
	      if (data < end)
		data++;

	      /* Display the contents of the File Name table.  */
	      if (data >= end || *data == 0)
		printf (_("\n The File Name Table is empty.\n"));
	      else
		{
		  printf (_("\n The File Name Table (offset 0x%lx):\n"),
			  (long)(data - start));
		  printf (_("  Entry\tDir\tTime\tSize\tName\n"));

		  while (data < end && *data != 0)
		    {
		      unsigned char *name;
		      dwarf_vma val;

		      printf ("  %d\t", ++state_machine_regs.last_file_entry);
		      name = data;
		      data += strnlen ((char *) data, end - data);
		      if (data < end)
			data++;

		      READ_ULEB (val, data, end);
		      printf ("%s\t", dwarf_vmatoa ("u", val));
		      READ_ULEB (val, data, end);
		      printf ("%s\t", dwarf_vmatoa ("u", val));
		      READ_ULEB (val, data, end);
		      printf ("%s\t", dwarf_vmatoa ("u", val));
		      printf ("%.*s\n", (int)(end - name), name);

		      if (data >= end)
			{
			  warn (_("Corrupt file name table entry\n"));
			  break;
			}
		    }
		}

	      /* Skip the NUL at the end of the table.  */
	      if (data < end)
		data++;
	    }

	  putchar ('\n');
	  saved_linfo = linfo;
	}

      /* Now display the statements.  */
      if (data >= end_of_sequence)
	printf (_(" No Line Number Statements.\n"));
      else
	{
	  printf (_(" Line Number Statements:\n"));

	  while (data < end_of_sequence)
	    {
	      unsigned char op_code;
	      dwarf_signed_vma adv;
	      dwarf_vma uladv;

	      printf ("  [0x%08lx]", (long)(data - start));

	      op_code = *data++;

	      if (op_code >= linfo.li_opcode_base)
		{
		  op_code -= linfo.li_opcode_base;
		  uladv = (op_code / linfo.li_line_range);
		  if (linfo.li_max_ops_per_insn == 1)
		    {
		      uladv *= linfo.li_min_insn_length;
		      state_machine_regs.address += uladv;
		      if (uladv)
			state_machine_regs.view = 0;
		      printf (_("  Special opcode %d: "
				"advance Address by %s to 0x%s%s"),
			      op_code, dwarf_vmatoa ("u", uladv),
			      dwarf_vmatoa ("x", state_machine_regs.address),
			      verbose_view && uladv
			      ? _(" (reset view)") : "");
		    }
		  else
		    {
		      unsigned addrdelta
			= ((state_machine_regs.op_index + uladv)
			    / linfo.li_max_ops_per_insn)
			* linfo.li_min_insn_length;

		      state_machine_regs.address += addrdelta;
		      state_machine_regs.op_index
			= (state_machine_regs.op_index + uladv)
			% linfo.li_max_ops_per_insn;
		      if (addrdelta)
			state_machine_regs.view = 0;
		      printf (_("  Special opcode %d: "
				"advance Address by %s to 0x%s[%d]%s"),
			      op_code, dwarf_vmatoa ("u", uladv),
			      dwarf_vmatoa ("x", state_machine_regs.address),
			      state_machine_regs.op_index,
			      verbose_view && addrdelta
			      ? _(" (reset view)") : "");
		    }
		  adv = (op_code % linfo.li_line_range) + linfo.li_line_base;
		  state_machine_regs.line += adv;
		  printf (_(" and Line by %s to %d"),
			  dwarf_vmatoa ("d", adv), state_machine_regs.line);
		  if (verbose_view || state_machine_regs.view)
		    printf (_(" (view %u)\n"), state_machine_regs.view);
		  else
		    putchar ('\n');
		  state_machine_regs.view++;
		}
	      else
		switch (op_code)
		  {
		  case DW_LNS_extended_op:
		    data += process_extended_line_op (data,
						      linfo.li_default_is_stmt,
						      end);
		    break;

		  case DW_LNS_copy:
		    printf (_("  Copy"));
		    if (verbose_view || state_machine_regs.view)
		      printf (_(" (view %u)\n"), state_machine_regs.view);
		    else
		      putchar ('\n');
		    state_machine_regs.view++;
		    break;

		  case DW_LNS_advance_pc:
		    READ_ULEB (uladv, data, end);
		    if (linfo.li_max_ops_per_insn == 1)
		      {
			uladv *= linfo.li_min_insn_length;
			state_machine_regs.address += uladv;
			if (uladv)
			  state_machine_regs.view = 0;
			printf (_("  Advance PC by %s to 0x%s%s\n"),
				dwarf_vmatoa ("u", uladv),
				dwarf_vmatoa ("x", state_machine_regs.address),
				verbose_view && uladv
				? _(" (reset view)") : "");
		      }
		    else
		      {
			unsigned addrdelta
			  = ((state_machine_regs.op_index + uladv)
			     / linfo.li_max_ops_per_insn)
			  * linfo.li_min_insn_length;
			state_machine_regs.address
			  += addrdelta;
			state_machine_regs.op_index
			  = (state_machine_regs.op_index + uladv)
			  % linfo.li_max_ops_per_insn;
			if (addrdelta)
			  state_machine_regs.view = 0;
			printf (_("  Advance PC by %s to 0x%s[%d]%s\n"),
				dwarf_vmatoa ("u", uladv),
				dwarf_vmatoa ("x", state_machine_regs.address),
				state_machine_regs.op_index,
				verbose_view && addrdelta
				? _(" (reset view)") : "");
		      }
		    break;

		  case DW_LNS_advance_line:
		    READ_SLEB (adv, data, end);
		    state_machine_regs.line += adv;
		    printf (_("  Advance Line by %s to %d\n"),
			    dwarf_vmatoa ("d", adv),
			    state_machine_regs.line);
		    break;

		  case DW_LNS_set_file:
		    READ_ULEB (uladv, data, end);
		    printf (_("  Set File Name to entry %s in the File Name Table\n"),
			    dwarf_vmatoa ("u", uladv));
		    state_machine_regs.file = uladv;
		    break;

		  case DW_LNS_set_column:
		    READ_ULEB (uladv, data, end);
		    printf (_("  Set column to %s\n"),
			    dwarf_vmatoa ("u", uladv));
		    state_machine_regs.column = uladv;
		    break;

		  case DW_LNS_negate_stmt:
		    adv = state_machine_regs.is_stmt;
		    adv = ! adv;
		    printf (_("  Set is_stmt to %s\n"), dwarf_vmatoa ("d", adv));
		    state_machine_regs.is_stmt = adv;
		    break;

		  case DW_LNS_set_basic_block:
		    printf (_("  Set basic block\n"));
		    state_machine_regs.basic_block = 1;
		    break;

		  case DW_LNS_const_add_pc:
		    uladv = ((255 - linfo.li_opcode_base) / linfo.li_line_range);
		    if (linfo.li_max_ops_per_insn)
		      {
			uladv *= linfo.li_min_insn_length;
			state_machine_regs.address += uladv;
			if (uladv)
			  state_machine_regs.view = 0;
			printf (_("  Advance PC by constant %s to 0x%s%s\n"),
				dwarf_vmatoa ("u", uladv),
				dwarf_vmatoa ("x", state_machine_regs.address),
				verbose_view && uladv
				? _(" (reset view)") : "");
		      }
		    else
		      {
			unsigned addrdelta
			  = ((state_machine_regs.op_index + uladv)
			     / linfo.li_max_ops_per_insn)
			  * linfo.li_min_insn_length;
			state_machine_regs.address
			  += addrdelta;
			state_machine_regs.op_index
			  = (state_machine_regs.op_index + uladv)
			  % linfo.li_max_ops_per_insn;
			if (addrdelta)
			  state_machine_regs.view = 0;
			printf (_("  Advance PC by constant %s to 0x%s[%d]%s\n"),
				dwarf_vmatoa ("u", uladv),
				dwarf_vmatoa ("x", state_machine_regs.address),
				state_machine_regs.op_index,
				verbose_view && addrdelta
				? _(" (reset view)") : "");
		      }
		    break;

		  case DW_LNS_fixed_advance_pc:
		    SAFE_BYTE_GET_AND_INC (uladv, data, 2, end);
		    state_machine_regs.address += uladv;
		    state_machine_regs.op_index = 0;
		    printf (_("  Advance PC by fixed size amount %s to 0x%s\n"),
			    dwarf_vmatoa ("u", uladv),
			    dwarf_vmatoa ("x", state_machine_regs.address));
		    /* Do NOT reset view.  */
		    break;

		  case DW_LNS_set_prologue_end:
		    printf (_("  Set prologue_end to true\n"));
		    break;

		  case DW_LNS_set_epilogue_begin:
		    printf (_("  Set epilogue_begin to true\n"));
		    break;

		  case DW_LNS_set_isa:
		    READ_ULEB (uladv, data, end);
		    printf (_("  Set ISA to %s\n"), dwarf_vmatoa ("u", uladv));
		    break;

		  default:
		    printf (_("  Unknown opcode %d with operands: "), op_code);

		    if (standard_opcodes != NULL)
		      for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
			{
			  READ_ULEB (uladv, data, end);
			  printf ("0x%s%s", dwarf_vmatoa ("x", uladv),
				  i == 1 ? "" : ", ");
			}
		    putchar ('\n');
		    break;
		  }
	    }
	  putchar ('\n');
	}
    }

  return 1;
}

Project: binutils-gdb
File: dwarf.c

frame_need_space (Frame_Chunk *fc, unsigned int reg)
{
  unsigned int prev = fc->ncols;

  if (reg < (unsigned int) fc->ncols)
    return 0;

  if (dwarf_regnames_count > 0
      && reg > dwarf_regnames_count)
    return -1;

  fc->ncols = reg + 1;
  /* PR 17512: file: 10450-2643-0.004.
     If reg == -1 then this can happen...  */
  if (fc->ncols == 0)
    return -1;

  /* PR 17512: file: 2844a11d.  */
  if (fc->ncols > 1024 && dwarf_regnames_count == 0)
    {
      error (_("Unfeasibly large register number: %u\n"), reg);
      fc->ncols = 0;
      /* FIXME: 1024 is an arbitrary limit.  Increase it if
	 we ever encounter a valid binary that exceeds it.  */
      return -1;
    }

  fc->col_type = (short int *) xcrealloc (fc->col_type, fc->ncols,
					  sizeof (short int));
  fc->col_offset = (int *) xcrealloc (fc->col_offset, fc->ncols, sizeof (int));
  /* PR 17512: file:002-10025-0.005.  */
  if (fc->col_type == NULL || fc->col_offset == NULL)
    {
      error (_("Out of memory allocating %u columns in dwarf frame arrays\n"),
	     fc->ncols);
      fc->ncols = 0;
      return -1;
    }

  while (prev < fc->ncols)
    {
      fc->col_type[prev] = DW_CFA_unreferenced;
      fc->col_offset[prev] = 0;
      prev++;
    }
  return 1;
}

Project: binutils-gdb
File: dwarf.c

display_augmentation_data (const unsigned char * data, const bfd_size_type len)
{
  bfd_size_type i;

  i = printf (_("  Augmentation data:    "));
  display_data (i, data, len);
}

Project: binutils-gdb
File: dwarf.c

read_and_print_leb128 (unsigned char *data,
		       unsigned int *bytes_read,
		       unsigned const char *end,
		       bool is_signed)
{
  int status;
  dwarf_vma val = read_leb128 (data, end, is_signed, bytes_read, &status);
  if (status != 0)
    report_leb_status (status);
  else
    printf ("%s", dwarf_vmatoa (is_signed ? "d" : "u", val));
}

Project: binutils-gdb
File: dwarf.c

add_dwo_dir (const char * dir, dwarf_vma cu_offset)
{
  add_dwo_info (dir, cu_offset, DWO_DIR);
}

Project: binutils-gdb
File: dwarf.c

display_loc_list_dwo (struct dwarf_section *section,
		      unsigned char **start_ptr,
		      unsigned int debug_info_entry,
		      dwarf_vma offset,
		      unsigned char **vstart_ptr,
		      int has_frame_base)
{
  unsigned char *start = *start_ptr, *vstart = *vstart_ptr;
  unsigned char *section_end = section->start + section->size;
  dwarf_vma    cu_offset;
  unsigned int pointer_size;
  unsigned int offset_size;
  int dwarf_version;
  int entry_type;
  unsigned short length;
  int need_frame_base;
  unsigned int idx;

  if (debug_info_entry >= num_debug_info_entries)
    {
      warn (_("No debug information for loc lists of entry: %u\n"),
	    debug_info_entry);
      return;
    }

  cu_offset = debug_information [debug_info_entry].cu_offset;
  pointer_size = debug_information [debug_info_entry].pointer_size;
  offset_size = debug_information [debug_info_entry].offset_size;
  dwarf_version = debug_information [debug_info_entry].dwarf_version;

  if (pointer_size < 2 || pointer_size > 8)
    {
      warn (_("Invalid pointer size (%d) in debug info for entry %d\n"),
	    pointer_size, debug_info_entry);
      return;
    }

  while (1)
    {
      printf ("    ");
      print_dwarf_vma (offset + (start - *start_ptr), 4);

      if (start >= section_end)
	{
	  warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
		(unsigned long) offset);
	  break;
	}

      SAFE_BYTE_GET_AND_INC (entry_type, start, 1, section_end);

      if (vstart)
	switch (entry_type)
	  {
	  default:
	    break;

	  case 2:
	  case 3:
	  case 4:
	    {
	      dwarf_vma view;
	      dwarf_vma off = offset + (vstart - *start_ptr);

	      READ_ULEB (view, vstart, section_end);
	      print_dwarf_view (view, 8, 1);

	      READ_ULEB (view, vstart, section_end);
	      print_dwarf_view (view, 8, 1);

	      printf (_("views at %8.8lx for:\n    %*s "),
		      (unsigned long) off, 8, "");

	    }
	    break;
	  }

      switch (entry_type)
	{
	case 0: /* A terminating entry.  */
	  *start_ptr = start;
	  *vstart_ptr = vstart;
	  printf (_("<End of list>\n"));
	  return;
	case 1: /* A base-address entry.  */
	  READ_ULEB (idx, start, section_end);
	  print_addr_index (idx, 8);
	  printf ("%*s", 9 + (vstart ? 2 * 6 : 0), "");
	  printf (_("(base address selection entry)\n"));
	  continue;
	case 2: /* A start/end entry.  */
	  READ_ULEB (idx, start, section_end);
	  print_addr_index (idx, 8);
	  READ_ULEB (idx, start, section_end);
	  print_addr_index (idx, 8);
	  break;
	case 3: /* A start/length entry.  */
	  READ_ULEB (idx, start, section_end);
	  print_addr_index (idx, 8);
	  SAFE_BYTE_GET_AND_INC (idx, start, 4, section_end);
	  printf ("%08x ", idx);
	  break;
	case 4: /* An offset pair entry.  */
	  SAFE_BYTE_GET_AND_INC (idx, start, 4, section_end);
	  printf ("%08x ", idx);
	  SAFE_BYTE_GET_AND_INC (idx, start, 4, section_end);
	  printf ("%08x ", idx);
	  break;
	default:
	  warn (_("Unknown location list entry type 0x%x.\n"), entry_type);
	  *start_ptr = start;
	  *vstart_ptr = vstart;
	  return;
	}

      if (2 > (size_t) (section_end - start))
	{
	  warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
		(unsigned long) offset);
	  break;
	}

      SAFE_BYTE_GET_AND_INC (length, start, 2, section_end);
      if (length > (size_t) (section_end - start))
	{
	  warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
		(unsigned long) offset);
	  break;
	}

      putchar ('(');
      need_frame_base = decode_location_expression (start,
						    pointer_size,
						    offset_size,
						    dwarf_version,
						    length,
						    cu_offset, section);
      putchar (')');

      if (need_frame_base && !has_frame_base)
	printf (_(" [without DW_AT_frame_base]"));

      putchar ('\n');

      start += length;
    }

  *start_ptr = start;
  *vstart_ptr = vstart;
}

Project: binutils-gdb
File: dwarf.c

dwarf_select_sections_by_names (const char *names)
{
  const char *p;
  int result = 0;

  p = names;
  while (*p)
    {
      const debug_dump_long_opts *entry;

      for (entry = debug_option_table; entry->option; entry++)
	{
	  size_t len = strlen (entry->option);

	  if (strncmp (p, entry->option, len) == 0
	      && (p[len] == ',' || p[len] == '\0'))
	    {
	      * entry->variable = entry->val;
	      result |= entry->val;

	      p += len;
	      break;
	    }
	}

      if (entry->option == NULL)
	{
	  warn (_("Unrecognized debug option '%s'\n"), p);
	  p = strchr (p, ',');
	  if (p == NULL)
	    break;
	}

      if (*p == ',')
	p++;
    }

  /* The --debug-dump=frames-interp option also enables the
     --debug-dump=frames option.  */
  if (do_debug_frames_interp)
    do_debug_frames = 1;

  return result;
}