Ejemplo n.º 1
0
Archivo: rddbg.c Proyecto: CromFr/gdb
static bfd_boolean
read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
				   void *dhandle, bfd_boolean *pfound)
{
  static struct
    {
      const char *secname;
      const char *strsecname;
    }
  names[] =
    {
      { ".stab", ".stabstr" },
      { "LC_SYMTAB.stabs", "LC_SYMTAB.stabstr" },
      { "$GDB_SYMBOLS$", "$GDB_STRINGS$" }
    };
  unsigned int i;
  void *shandle;

  *pfound = FALSE;
  shandle = NULL;

  for (i = 0; i < sizeof names / sizeof names[0]; i++)
    {
      asection *sec, *strsec;

      sec = bfd_get_section_by_name (abfd, names[i].secname);
      strsec = bfd_get_section_by_name (abfd, names[i].strsecname);
      if (sec != NULL && strsec != NULL)
	{
	  bfd_size_type stabsize, strsize;
	  bfd_byte *stabs, *strings;
	  bfd_byte *stab;
	  bfd_size_type stroff, next_stroff;

	  stabsize = bfd_section_size (abfd, sec);
	  stabs = (bfd_byte *) xmalloc (stabsize);
	  if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize))
	    {
	      fprintf (stderr, "%s: %s: %s\n",
		       bfd_get_filename (abfd), names[i].secname,
		       bfd_errmsg (bfd_get_error ()));
	      return FALSE;
	    }

	  strsize = bfd_section_size (abfd, strsec);
	  strings = (bfd_byte *) xmalloc (strsize + 1);
	  if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize))
	    {
	      fprintf (stderr, "%s: %s: %s\n",
		       bfd_get_filename (abfd), names[i].strsecname,
		       bfd_errmsg (bfd_get_error ()));
	      return FALSE;
	    }
	  /* Zero terminate the strings table, just in case.  */
	  strings [strsize] = 0;
	  if (shandle == NULL)
	    {
	      shandle = start_stab (dhandle, abfd, TRUE, syms, symcount);
	      if (shandle == NULL)
		return FALSE;
	    }

	  *pfound = TRUE;

	  stroff = 0;
	  next_stroff = 0;
	  /* PR 17512: file: 078-60391-0.001:0.1.  */
	  for (stab = stabs; stab <= (stabs + stabsize) - 12; stab += 12)
	    {
	      unsigned int strx;
	      int type;
	      int other ATTRIBUTE_UNUSED;
	      int desc;
	      bfd_vma value;

	      /* This code presumes 32 bit values.  */

	      strx = bfd_get_32 (abfd, stab);
	      type = bfd_get_8 (abfd, stab + 4);
	      other = bfd_get_8 (abfd, stab + 5);
	      desc = bfd_get_16 (abfd, stab + 6);
	      value = bfd_get_32 (abfd, stab + 8);

	      if (type == 0)
		{
		  /* Special type 0 stabs indicate the offset to the
		     next string table.  */
		  stroff = next_stroff;
		  next_stroff += value;
		}
	      else
		{
		  size_t len;
		  char *f, *s;

		  if (stroff + strx >= strsize)
		    {
		      fprintf (stderr, _("%s: %s: stab entry %ld is corrupt, strx = 0x%x, type = %d\n"),
			       bfd_get_filename (abfd), names[i].secname,
			       (long) (stab - stabs) / 12, strx, type);
		      continue;
		    }

		  s = (char *) strings + stroff + strx;
		  f = NULL;

		  /* PR 17512: file: 002-87578-0.001:0.1.
		     It is possible to craft a file where, without the 'strlen (s) > 0',
		     an attempt to read the byte before 'strings' would occur.  */
		  while ((len = strlen (s)) > 0
			 && s[len  - 1] == '\\'
			 && stab + 12 < stabs + stabsize)
		    {
		      char *p;

		      stab += 12;
		      p = s + len - 1;
		      *p = '\0';
		      strx = stroff + bfd_get_32 (abfd, stab);
		      if (strx >= strsize)
			{
			  fprintf (stderr, _("%s: %s: stab entry %ld is corrupt\n"),
				   bfd_get_filename (abfd), names[i].secname,
				   (long) (stab - stabs) / 12);
			  break;
			}
		      else
			s = concat (s, (char *) strings + strx,
				    (const char *) NULL);

		      /* We have to restore the backslash, because, if
			 the linker is hashing stabs strings, we may
			 see the same string more than once.  */
		      *p = '\\';

		      if (f != NULL)
			free (f);
		      f = s;
		    }

		  save_stab (type, desc, value, s);

		  if (! parse_stab (dhandle, shandle, type, desc, value, s))
		    {
		      stab_context ();
		      free_saved_stabs ();
		      return FALSE;
		    }

		  /* Don't free f, since I think the stabs code
		     expects strings to hang around.  This should be
		     straightened out.  FIXME.  */
		}
	    }

	  free_saved_stabs ();
	  free (stabs);

	  /* Don't free strings, since I think the stabs code expects
	     the strings to hang around.  This should be straightened
	     out.  FIXME.  */
	}
    }

  if (shandle != NULL)
    {
      if (! finish_stab (dhandle, shandle))
	return FALSE;
    }

  return TRUE;
}
Ejemplo n.º 2
0
static void
extra_case (bfd *in_abfd,
            struct bfd_link_info *link_info,
            struct bfd_link_order *link_order,
            arelent *reloc,
            bfd_byte *data,
            unsigned int *src_ptr,
            unsigned int *dst_ptr)
{
  asection * input_section = link_order->u.indirect.section;

  switch (reloc->howto->type)
    {
    case R_IMM8:
      bfd_put_8 (in_abfd,
		 bfd_coff_reloc16_get_value (reloc, link_info, input_section),
		 data + *dst_ptr);
      (*dst_ptr) += 1;
      (*src_ptr) += 1;
      break;

    case R_IMM32:
      /* If no flags are set, assume immediate value.  */
      if (! (*reloc->sym_ptr_ptr)->section->flags)
	{
	  bfd_put_32 (in_abfd,
		      bfd_coff_reloc16_get_value (reloc, link_info,
						  input_section),
		      data + *dst_ptr);
	}
      else
	{
	  bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
						    input_section);
	  /* Addresses are 23 bit, and the layout of those in a 32-bit
	     value is as follows:
	       1AAAAAAA xxxxxxxx AAAAAAAA AAAAAAAA
	     (A - address bits,  x - ignore).  */
	  dst = (dst & 0xffff) | ((dst & 0xff0000) << 8) | 0x80000000;
	  bfd_put_32 (in_abfd, dst, data + *dst_ptr);
	}
      (*dst_ptr) += 4;
      (*src_ptr) += 4;
      break;

    case R_IMM4L:
      bfd_put_8 (in_abfd,
		 ((bfd_get_8 (in_abfd, data + *dst_ptr) & 0xf0)
		  | (0x0f
		     & bfd_coff_reloc16_get_value (reloc, link_info,
						   input_section))),
		 data + *dst_ptr);
      (*dst_ptr) += 1;
      (*src_ptr) += 1;
      break;

    case R_IMM16:
      bfd_put_16 (in_abfd,
		  bfd_coff_reloc16_get_value (reloc, link_info, input_section),
		  data + *dst_ptr);
      (*dst_ptr) += 2;
      (*src_ptr) += 2;
      break;

    case R_JR:
      {
	bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
						  input_section);
	bfd_vma dot = (link_order->offset
		       + *dst_ptr
		       + input_section->output_section->vma);
	/* -1L, since we are in the odd byte of the word, and the pc has been
	 * incremented: */
	ptrdiff_t gap = ((ptrdiff_t)(dst - dot) - 1L); 

	if (gap & 1L)
	  abort();
	gap /= 2L;
	if ((gap > 128L) || (gap < -128L))
	  {
	    if (!((*link_info->callbacks->reloc_overflow)
		  (link_info, NULL,
		   bfd_asymbol_name(*reloc->sym_ptr_ptr),
		   reloc->howto->name, reloc->addend, input_section->owner,
		   input_section, reloc->address)))
	      abort();
	  }
	bfd_put_8(in_abfd, gap, (data + *dst_ptr));
	(*dst_ptr)++;
	(*src_ptr)++;
	break;
      }

    case R_DISP7:
      {
	bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
						  input_section);
	bfd_vma dot = (link_order->offset
		       + *dst_ptr
		       + input_section->output_section->vma);
	/* -1L, since we are in the odd byte of the word, and the pc has been
	 * incremented: */
	ptrdiff_t gap = ((ptrdiff_t)(dst - dot) - 1L);

	if (gap & 1L)
	  abort();
	gap /= 2L;

	if ((gap > 0L) || (gap < -127L))
	  {
	    if (!((*link_info->callbacks->reloc_overflow)
		  (link_info, NULL,
		   bfd_asymbol_name(*reloc->sym_ptr_ptr),
		   reloc->howto->name, reloc->addend, input_section->owner,
		   input_section, reloc->address)))
	      abort();
	  }
	bfd_put_8(in_abfd,
                  (bfd_get_8(in_abfd, data + *dst_ptr) & 0x80) + (-gap & 0x7f),
                  (data + *dst_ptr));
	(*dst_ptr)++;
	(*src_ptr)++;
	break;
      }

    case R_CALLR:
      {
	bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
						  input_section);
	bfd_vma dot = (link_order->offset
		       + *dst_ptr
		       + input_section->output_section->vma);
	ptrdiff_t gap = ((ptrdiff_t)(dst - dot) - 2L);

	if (gap & 1L)
	  abort();
	if ((gap > 4096L) || (gap < -4095L))
	  {
	    if (!((*link_info->callbacks->reloc_overflow)
		  (link_info, NULL,
		   bfd_asymbol_name(*reloc->sym_ptr_ptr),
		   reloc->howto->name, reloc->addend, input_section->owner,
		   input_section, reloc->address)))
	      abort();
	  }
	gap /= 2L;
	bfd_put_16(in_abfd,
                   ((bfd_get_16(in_abfd, (data + *dst_ptr)) & 0xf000)
		    | (-gap & 0x0fff)),
                   (data + *dst_ptr));
	(*dst_ptr) += 2;
	(*src_ptr) += 2;
	break;
      }

    case R_REL16:
      {
	bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
						  input_section);
	bfd_vma dot = (link_order->offset
		       + *dst_ptr
		       + input_section->output_section->vma);
	ptrdiff_t gap = ((ptrdiff_t)(dst - dot) - 2L);

	if ((gap > 32767L) || (gap < -32768L))
	  {
	    if (!((*link_info->callbacks->reloc_overflow)
		  (link_info, NULL,
		   bfd_asymbol_name(*reloc->sym_ptr_ptr),
		   reloc->howto->name, reloc->addend, input_section->owner,
		   input_section, reloc->address)))
	      abort();
	  }
	bfd_put_16(in_abfd, (bfd_vma)gap, (data + *dst_ptr));
	(*dst_ptr) += 2;
	(*src_ptr) += 2;
	break;
      }

    default:
      abort();
    }
}
Ejemplo n.º 3
0
   useless for a relocation, so we just get the offset value and place
   a version of this within the object code.
   tic30_aout_final_link_relocate will then calculate the required
   relocation to add on to the value in the object code.  */

static bfd_reloc_status_type
tic30_aout_fix_pcrel_16 (bfd *abfd,
			 arelent *reloc_entry,
			 asymbol *symbol ATTRIBUTE_UNUSED,
			 void * data,
			 asection *input_section ATTRIBUTE_UNUSED,
			 bfd *output_bfd ATTRIBUTE_UNUSED,
			 char **error_message ATTRIBUTE_UNUSED)
{
  bfd_vma relocation = 1;
  bfd_byte offset_data = bfd_get_8 (abfd, (bfd_byte *) data + reloc_entry->address - 1);

  /* The byte before the location of the fix contains bits 23-16 of
     the pcrel instruction.  Bit 21 is set for a delayed instruction
     which requires on offset of 3 instead of 1.  */
  if (offset_data & 0x20)
    relocation -= 3;
  else
    relocation -= 1;
  bfd_put_16 (abfd, relocation, (bfd_byte *) data + reloc_entry->address);
  return bfd_reloc_ok;
}

/* This function is used as a callback for 16-bit relocs.  This is
   required for relocations between segments.  A line in aoutx.h
   requires that any relocations for the data section should point to
Ejemplo n.º 4
0
static bfd_boolean
read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
				   void *dhandle, bfd_boolean *pfound)
{
  static struct
    {
      const char *secname;
      const char *strsecname;
    } names[] = { { ".stab", ".stabstr" },
		  { "LC_SYMTAB.stabs", "LC_SYMTAB.stabstr" } };
  unsigned int i;
  void *shandle;

  *pfound = FALSE;
  shandle = NULL;

  for (i = 0; i < sizeof names / sizeof names[0]; i++)
    {
      asection *sec, *strsec;

      sec = bfd_get_section_by_name (abfd, names[i].secname);
      strsec = bfd_get_section_by_name (abfd, names[i].strsecname);
      if (sec != NULL && strsec != NULL)
	{
	  bfd_size_type stabsize, strsize;
	  bfd_byte *stabs, *strings;
	  bfd_byte *stab;
	  bfd_size_type stroff, next_stroff;

	  stabsize = bfd_section_size (abfd, sec);
	  stabs = (bfd_byte *) xmalloc (stabsize);
	  if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize))
	    {
	      fprintf (stderr, "%s: %s: %s\n",
		       bfd_get_filename (abfd), names[i].secname,
		       bfd_errmsg (bfd_get_error ()));
	      return FALSE;
	    }

	  strsize = bfd_section_size (abfd, strsec);
	  strings = (bfd_byte *) xmalloc (strsize);
	  if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize))
	    {
	      fprintf (stderr, "%s: %s: %s\n",
		       bfd_get_filename (abfd), names[i].strsecname,
		       bfd_errmsg (bfd_get_error ()));
	      return FALSE;
	    }

	  if (shandle == NULL)
	    {
	      shandle = start_stab (dhandle, abfd, TRUE, syms, symcount);
	      if (shandle == NULL)
		return FALSE;
	    }

	  *pfound = TRUE;

	  stroff = 0;
	  next_stroff = 0;
	  for (stab = stabs; stab < (stabs + stabsize); stab += 12)
	    {
	      unsigned int strx;
	      int type;
	      int other;
	      int desc;
	      bfd_vma value;

	      /* This code presumes 32 bit values: */
	      strx = bfd_get_32(abfd, stab);
	      type = bfd_get_8(abfd, stab + 4);
	      other = bfd_get_8(abfd, stab + 5);
	      desc = bfd_get_16(abfd, stab + 6);
	      value = bfd_get_32(abfd, stab + 8);

	      if (type == 0)
		{
		  /* Special type 0 stabs indicate the offset to the
		     next string table.  */
		  stroff = next_stroff;
		  next_stroff += value;
		}
	      else
		{
		  char *f, *s;

		  f = NULL;

		  if ((stroff + strx) > strsize)
		    {
		      fprintf(stderr,
                              "%s: %s: stab entry %ld is corrupt, strx = 0x%x, type = %d, other = %d\n",
                              bfd_get_filename(abfd), names[i].secname,
                              (long)(stab - stabs) / 12, strx, type,
                              other);
		      continue;
		    }

		  s = (char *) strings + stroff + strx;

		  while (s[strlen (s) - 1] == '\\'
			 && stab + 12 < stabs + stabsize)
		    {
		      char *p;

		      stab += 12;
		      p = s + strlen (s) - 1;
		      *p = '\0';
		      s = concat (s,
				  ((char *) strings
				   + stroff
				   + bfd_get_32 (abfd, stab)),
				  (const char *) NULL);

		      /* We have to restore the backslash, because, if
			 the linker is hashing stabs strings, we may
			 see the same string more than once.  */
		      *p = '\\';

		      if (f != NULL)
			free (f);
		      f = s;
		    }

		  save_stab (type, desc, value, s);

		  if (! parse_stab (dhandle, shandle, type, desc, value, s))
		    {
		      stab_context ();
		      free_saved_stabs ();
		      return FALSE;
		    }

		  /* Don't free f, since I think the stabs code
		     expects strings to hang around.  This should be
		     straightened out.  FIXME.  */
		}
	    }

	  free_saved_stabs ();
	  free (stabs);

	  /* Don't free strings, since I think the stabs code expects
	     the strings to hang around.  This should be straightened
	     out.  FIXME.  */
	}
    }

  if (shandle != NULL)
    {
      if (! finish_stab (dhandle, shandle))
	return FALSE;
    }

  return TRUE;
}