Example #1
0
int
_bfd_sh64_crange_qsort_cmpb (const void *p1, const void *p2)
{
  bfd_vma a1 = bfd_getb32 (p1);
  bfd_vma a2 = bfd_getb32 (p2);

  /* Preserve order if there's ambiguous contents.  */
  if (a1 == a2)
    return (char *) p1 - (char *) p2;

  return a1 - a2;
}
Example #2
0
int
_bfd_sh64_crange_bsearch_cmpb (const void *p1, const void *p2)
{
  bfd_vma a1 = *(bfd_vma *) p1;
  bfd_vma a2 = (bfd_vma) bfd_getb32 (p2);
  bfd_size_type size
    = (bfd_size_type) bfd_getb32 (SH64_CRANGE_CR_SIZE_OFFSET + (char *) p2);

  if (a1 >= a2 + size)
    return 1;
  if (a1 < a2)
    return -1;
  return 0;
}
Example #3
0
static int
print_insn_nios2 (bfd_vma address, disassemble_info *info,
		  enum bfd_endian endianness)
{
  bfd_byte buffer[INSNLEN];
  int status;

  status = (*info->read_memory_func) (address, buffer, INSNLEN, info);
  if (status == 0)
    {
      unsigned long insn;
      if (endianness == BFD_ENDIAN_BIG)
	insn = (unsigned long) bfd_getb32 (buffer);
      else
	insn = (unsigned long) bfd_getl32 (buffer);
      return nios2_disassemble (address, insn, info);
    }

  /* We might have a 16-bit R2 instruction at the end of memory.  Try that.  */
  if (info->mach == bfd_mach_nios2r2)
    {
      status = (*info->read_memory_func) (address, buffer, 2, info);
      if (status == 0)
	{
	  unsigned long insn;
	  if (endianness == BFD_ENDIAN_BIG)
	    insn = (unsigned long) bfd_getb16 (buffer);
	  else
	    insn = (unsigned long) bfd_getl16 (buffer);
	  return nios2_disassemble (address, insn, info);
	}
    }

  /* If we got here, we couldn't read anything.  */
  (*info->memory_error_func) (status, address, info);
  return -1;
}
Example #4
0
static int
print_insn_nios2 (bfd_vma address, disassemble_info *info,
		  enum bfd_endian endianness)
{
  bfd_byte buffer[INSNLEN];
  int status;

  status = (*info->read_memory_func) (address, buffer, INSNLEN, info);
  if (status == 0)
    {
      unsigned long insn;
      if (endianness == BFD_ENDIAN_BIG)
	insn = (unsigned long) bfd_getb32 (buffer);
      else
	insn = (unsigned long) bfd_getl32 (buffer);
      status = nios2_disassemble (address, insn, info);
    }
  else
    {
      (*info->memory_error_func) (status, address, info);
      status = -1;
    }
  return status;
}
Example #5
0
int
print_insn_moxie (bfd_vma addr, struct disassemble_info * info)
{
  int length = 2;
  int status;
  stream = info->stream;
  const moxie_opc_info_t * opcode;
  bfd_byte buffer[4];
  unsigned short iword;
  fpr = info->fprintf_func;

  if ((status = info->read_memory_func (addr, buffer, 2, info)))
    goto fail;

  if (info->endian == BFD_ENDIAN_BIG)
    iword = bfd_getb16 (buffer);
  else
    iword = bfd_getl16 (buffer);

  /* Form 1 instructions have the high bit set to 0.  */
  if ((iword & (1<<15)) == 0)
    {
      /* Extract the Form 1 opcode.  */
      opcode = &moxie_form1_opc_info[iword >> 8];
      switch (opcode->itype)
	{
	case MOXIE_F1_NARG:
	  fpr (stream, "%s", opcode->name);
	  break;
	case MOXIE_F1_A:
	  fpr (stream, "%s\t%s", opcode->name,
	       reg_names[OP_A(iword)]);
	  break;
	case MOXIE_F1_AB:
	  fpr (stream, "%s\t%s, %s", opcode->name,
	       reg_names[OP_A(iword)],
	       reg_names[OP_B(iword)]);
	  break;
	case MOXIE_F1_A4:
	  {
	    unsigned imm;
	    if ((status = info->read_memory_func (addr + 2, buffer, 4, info)))
	      goto fail;
	    if (info->endian == BFD_ENDIAN_BIG)
	      imm = bfd_getb32 (buffer);
	    else
	      imm = bfd_getl32 (buffer);
	    fpr (stream, "%s\t%s, 0x%x", opcode->name,
		 reg_names[OP_A(iword)], imm);
	    length = 6;
	  }
	  break;
	case MOXIE_F1_4:
	  {
	    unsigned imm;
	    if ((status = info->read_memory_func (addr + 2, buffer, 4, info)))
	      goto fail;
	    if (info->endian == BFD_ENDIAN_BIG)
	      imm = bfd_getb32 (buffer);
	    else
	      imm = bfd_getl32 (buffer);
	    fpr (stream, "%s\t0x%x", opcode->name, imm);
	    length = 6;
	  }
	  break;
	case MOXIE_F1_M:
	  {
	    unsigned imm;
	    if ((status = info->read_memory_func (addr + 2, buffer, 4, info)))
	      goto fail;
	    if (info->endian == BFD_ENDIAN_BIG)
	      imm = bfd_getb32 (buffer);
	    else
	      imm = bfd_getl32 (buffer);
	    fpr (stream, "%s\t", opcode->name);
	    info->print_address_func ((bfd_vma) imm, info);
	    length = 6;
	  }
	  break;
	case MOXIE_F1_AiB:
	  fpr (stream, "%s\t(%s), %s", opcode->name,
	       reg_names[OP_A(iword)], reg_names[OP_B(iword)]);
	  break;
	case MOXIE_F1_ABi:
	  fpr (stream, "%s\t%s, (%s)", opcode->name,
	       reg_names[OP_A(iword)], reg_names[OP_B(iword)]);
	  break;
	case MOXIE_F1_4A:
	  {
	    unsigned imm;
	    if ((status = info->read_memory_func (addr + 2, buffer, 4, info)))
	      goto fail;
	    if (info->endian == BFD_ENDIAN_BIG)
	      imm = bfd_getb32 (buffer);
	    else
	      imm = bfd_getl32 (buffer);
	    fpr (stream, "%s\t0x%x, %s",
		 opcode->name, imm, reg_names[OP_A(iword)]);
	    length = 6;
	  }
	  break;
	case MOXIE_F1_AiB4:
	  {
	    unsigned imm;
	    if ((status = info->read_memory_func (addr+2, buffer, 4, info)))
	      goto fail;
	    if (info->endian == BFD_ENDIAN_BIG)
	      imm = bfd_getb32 (buffer);
	    else
	      imm = bfd_getl32 (buffer);
	    fpr (stream, "%s\t0x%x(%s), %s", opcode->name,
		 imm,
		 reg_names[OP_A(iword)],
		 reg_names[OP_B(iword)]);
	    length = 6;
	  }
	  break;
	case MOXIE_F1_ABi4:
	  {
	    unsigned imm;
	    if ((status = info->read_memory_func (addr+2, buffer, 4, info)))
	      goto fail;
	    if (info->endian == BFD_ENDIAN_BIG)
	      imm = bfd_getb32 (buffer);
	    else
	      imm = bfd_getl32 (buffer);
	    fpr (stream, "%s\t%s, 0x%x(%s)",
		 opcode->name,
		 reg_names[OP_A(iword)],
		 imm,
		 reg_names[OP_B(iword)]);
	    length = 6;
	  }
	  break;
        case MOXIE_BAD:
	  fpr (stream, "bad");
	  break;
	default:
	  abort();
	}
    }
Example #6
0
static int
bfd_pef_parse_traceback_table (bfd *abfd,
			       asection *section,
			       unsigned char *buf,
			       size_t len,
			       size_t pos,
			       asymbol *sym,
			       FILE *file)
{
  struct traceback_table table;
  size_t offset;
  const char *s;
  asymbol tmpsymbol;

  if (sym == NULL)
    sym = & tmpsymbol;

  sym->name = NULL;
  sym->value = 0;
  sym->the_bfd = abfd;
  sym->section = section;
  sym->flags = 0;
  sym->udata.i = 0;

  /* memcpy is fine since all fields are unsigned char.  */
  if ((pos + 8) > len)
    return -1;
  memcpy (&table, buf + pos, 8);

  /* Calling code relies on returned symbols having a name and
     correct offset.  */
  if ((table.lang != TB_C) && (table.lang != TB_CPLUSPLUS))
    return -1;

  if (! (table.flags2 & TB_NAME_PRESENT))
    return -1;

  if (! (table.flags1 & TB_HAS_TBOFF))
    return -1;

  offset = 8;

  if ((table.flags5 & TB_FLOATPARAMS) || (table.fixedparams))
    offset += 4;

  if (table.flags1 & TB_HAS_TBOFF)
    {
      struct traceback_table_tboff off;

      if ((pos + offset + 4) > len)
	return -1;
      off.tb_offset = bfd_getb32 (buf + pos + offset);
      offset += 4;

      /* Need to subtract 4 because the offset includes the 0x0L
	 preceding the table.  */
      if (file != NULL)
	fprintf (file, " [offset = 0x%lx]", off.tb_offset);

      if ((file == NULL) && ((off.tb_offset + 4) > (pos + offset)))
	return -1;

      sym->value = pos - off.tb_offset - 4;
    }

  if (table.flags2 & TB_INT_HNDL)
    offset += 4;

  if (table.flags1 & TB_HAS_CTL)
    {
      struct traceback_table_anchors anchors;

      if ((pos + offset + 4) > len)
	return -1;
      anchors.ctl_info = bfd_getb32 (buf + pos + offset);
      offset += 4;

      if (anchors.ctl_info > 1024)
	return -1;

      offset += anchors.ctl_info * 4;
    }

  if (table.flags2 & TB_NAME_PRESENT)
    {
      struct traceback_table_routine name;
      char *namebuf;

      if ((pos + offset + 2) > len)
	return -1;
      name.name_len = bfd_getb16 (buf + pos + offset);
      offset += 2;

      if (name.name_len > 4096)
	return -1;

      if ((pos + offset + name.name_len) > len)
	return -1;

      namebuf = bfd_alloc (abfd, name.name_len + 1);
      if (namebuf == NULL)
	return -1;

      memcpy (namebuf, buf + pos + offset, name.name_len);
      namebuf[name.name_len] = '\0';

      /* Strip leading period inserted by compiler.  */
      if (namebuf[0] == '.')
	memmove (namebuf, namebuf + 1, name.name_len + 1);

      sym->name = namebuf;

      for (s = sym->name; (*s != '\0'); s++)
	if (! ISPRINT (*s))
	  return -1;

      offset += name.name_len;
    }

  if (table.flags2 & TB_USES_ALLOCA)
    offset += 4;

  if (table.flags4 & TB_HAS_VEC_INFO)
    offset += 4;

  if (file != NULL)
    fprintf (file, " [length = 0x%lx]", (unsigned long) offset);

  return offset;
}
Example #7
0
static void
build_link_order (lang_statement_union_type *statement)
{
  switch (statement->header.type)
    {
    case lang_data_statement_enum:
      {
	asection *output_section;
	struct bfd_link_order *link_order;
	bfd_vma value;
	bfd_boolean big_endian = FALSE;

	output_section = statement->data_statement.output_section;
	ASSERT (output_section->owner == link_info.output_bfd);

	if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
	      || ((output_section->flags & SEC_LOAD) != 0
		  && (output_section->flags & SEC_THREAD_LOCAL))))
	  break;

	link_order = bfd_new_link_order (link_info.output_bfd, output_section);
	if (link_order == NULL)
	  einfo (_("%F%P: bfd_new_link_order failed\n"));

	link_order->type = bfd_data_link_order;
	link_order->offset = statement->data_statement.output_offset;
	link_order->u.data.contents = (bfd_byte *) xmalloc (QUAD_SIZE);

	value = statement->data_statement.value;

	/* If the endianness of the output BFD is not known, then we
	   base the endianness of the data on the first input file.
	   By convention, the bfd_put routines for an unknown
	   endianness are big endian, so we must swap here if the
	   input file is little endian.  */
	if (bfd_big_endian (link_info.output_bfd))
	  big_endian = TRUE;
	else if (bfd_little_endian (link_info.output_bfd))
	  big_endian = FALSE;
	else
	  {
	    bfd_boolean swap;

	    swap = FALSE;
	    if (command_line.endian == ENDIAN_BIG)
	      big_endian = TRUE;
	    else if (command_line.endian == ENDIAN_LITTLE)
	      {
		big_endian = FALSE;
		swap = TRUE;
	      }
	    else if (command_line.endian == ENDIAN_UNSET)
	      {
		big_endian = TRUE;
		{
		  LANG_FOR_EACH_INPUT_STATEMENT (s)
		  {
		    if (s->the_bfd != NULL)
		      {
			if (bfd_little_endian (s->the_bfd))
			  {
			    big_endian = FALSE;
			    swap = TRUE;
			  }
			break;
		      }
		  }
		}
	      }

	    if (swap)
	      {
		bfd_byte buffer[8];

		switch (statement->data_statement.type)
		  {
		  case QUAD:
		  case SQUAD:
		    if (sizeof (bfd_vma) >= QUAD_SIZE)
		      {
			bfd_putl64 (value, buffer);
			value = bfd_getb64 (buffer);
			break;
		      }
		    /* Fall through.  */
		  case LONG:
		    bfd_putl32 (value, buffer);
		    value = bfd_getb32 (buffer);
		    break;
		  case SHORT:
		    bfd_putl16 (value, buffer);
		    value = bfd_getb16 (buffer);
		    break;
		  case BYTE:
		    break;
		  default:
		    abort ();
		  }
	      }
	  }

	ASSERT (output_section->owner == link_info.output_bfd);
	switch (statement->data_statement.type)
	  {
	  case QUAD:
	  case SQUAD:
	    if (sizeof (bfd_vma) >= QUAD_SIZE)
	      bfd_put_64 (link_info.output_bfd, value,
			  link_order->u.data.contents);
	    else
	      {
		bfd_vma high;

		if (statement->data_statement.type == QUAD)
		  high = 0;
		else if ((value & 0x80000000) == 0)
		  high = 0;
		else
		  high = (bfd_vma) -1;
		bfd_put_32 (link_info.output_bfd, high,
			    (link_order->u.data.contents
			     + (big_endian ? 0 : 4)));
		bfd_put_32 (link_info.output_bfd, value,
			    (link_order->u.data.contents
			     + (big_endian ? 4 : 0)));
	      }
	    link_order->size = QUAD_SIZE;
	    break;
	  case LONG:
	    bfd_put_32 (link_info.output_bfd, value,
			link_order->u.data.contents);
	    link_order->size = LONG_SIZE;
	    break;
	  case SHORT:
	    bfd_put_16 (link_info.output_bfd, value,
			link_order->u.data.contents);
	    link_order->size = SHORT_SIZE;
	    break;
	  case BYTE:
	    bfd_put_8 (link_info.output_bfd, value,
		       link_order->u.data.contents);
	    link_order->size = BYTE_SIZE;
	    break;
	  default:
	    abort ();
	  }
	link_order->u.data.size = link_order->size;
      }
      break;

    case lang_reloc_statement_enum:
      {
	lang_reloc_statement_type *rs;
	asection *output_section;
	struct bfd_link_order *link_order;

	rs = &statement->reloc_statement;

	output_section = rs->output_section;
	ASSERT (output_section->owner == link_info.output_bfd);

	if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
	      || ((output_section->flags & SEC_LOAD) != 0
		  && (output_section->flags & SEC_THREAD_LOCAL))))
	  break;

	link_order = bfd_new_link_order (link_info.output_bfd, output_section);
	if (link_order == NULL)
	  einfo (_("%F%P: bfd_new_link_order failed\n"));

	link_order->offset = rs->output_offset;
	link_order->size = bfd_get_reloc_size (rs->howto);

	link_order->u.reloc.p = (struct bfd_link_order_reloc *)
	  xmalloc (sizeof (struct bfd_link_order_reloc));

	link_order->u.reloc.p->reloc = rs->reloc;
	link_order->u.reloc.p->addend = rs->addend_value;

	if (rs->name == NULL)
	  {
	    link_order->type = bfd_section_reloc_link_order;
	    if (rs->section->owner == link_info.output_bfd)
	      link_order->u.reloc.p->u.section = rs->section;
	    else
	      {
		link_order->u.reloc.p->u.section = rs->section->output_section;
		link_order->u.reloc.p->addend += rs->section->output_offset;
	      }
	  }
	else
	  {
	    link_order->type = bfd_symbol_reloc_link_order;
	    link_order->u.reloc.p->u.name = rs->name;
	  }
      }
      break;

    case lang_input_section_enum:
      {
	/* Create a new link_order in the output section with this
	   attached */
	asection *i = statement->input_section.section;

	if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
	    && (i->flags & SEC_EXCLUDE) == 0)
	  {
	    asection *output_section = i->output_section;
	    struct bfd_link_order *link_order;

	    ASSERT (output_section->owner == link_info.output_bfd);

	    if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
		  || ((output_section->flags & SEC_LOAD) != 0
		      && (output_section->flags & SEC_THREAD_LOCAL))))
	      break;

	    link_order = bfd_new_link_order (link_info.output_bfd,
					     output_section);
	    if (link_order == NULL)
	      einfo (_("%F%P: bfd_new_link_order failed\n"));

	    if ((i->flags & SEC_NEVER_LOAD) != 0
		&& (i->flags & SEC_DEBUGGING) == 0)
	      {
		/* We've got a never load section inside one which is
		   going to be output, we'll change it into a fill.  */
		link_order->type = bfd_data_link_order;
		link_order->u.data.contents = (unsigned char *) "";
		link_order->u.data.size = 1;
	      }
	    else
	      {
		link_order->type = bfd_indirect_link_order;
		link_order->u.indirect.section = i;
		ASSERT (i->output_section == output_section);
	      }
	    link_order->size = i->size;
	    link_order->offset = i->output_offset;
	  }
      }
      break;

    case lang_padding_statement_enum:
      /* Make a new link_order with the right filler */
      {
	asection *output_section;
	struct bfd_link_order *link_order;

	output_section = statement->padding_statement.output_section;
	ASSERT (statement->padding_statement.output_section->owner
		== link_info.output_bfd);

	if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
	      || ((output_section->flags & SEC_LOAD) != 0
		  && (output_section->flags & SEC_THREAD_LOCAL))))
	  break;

	link_order = bfd_new_link_order (link_info.output_bfd,
					 output_section);
	if (link_order == NULL)
	  einfo (_("%F%P: bfd_new_link_order failed\n"));
	link_order->type = bfd_data_link_order;
	link_order->size = statement->padding_statement.size;
	link_order->offset = statement->padding_statement.output_offset;
	link_order->u.data.contents = statement->padding_statement.fill->data;
	link_order->u.data.size = statement->padding_statement.fill->size;
      }
      break;

    default:
      /* All the other ones fall through */
      break;
    }
Example #8
0
static void
som_symtab_read (bfd *abfd, struct objfile *objfile,
		 struct section_offsets *section_offsets)
{
  struct cleanup *cleanup;
  struct gdbarch *gdbarch = get_objfile_arch (objfile);
  unsigned int number_of_symbols;
  int val, dynamic;
  char *stringtab;
  asection *shlib_info;
  struct som_external_symbol_dictionary_record *buf, *bufp, *endbufp;
  char *symname;
  CONST int symsize = sizeof (struct som_external_symbol_dictionary_record);


#define text_offset ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile))
#define data_offset ANOFFSET (section_offsets, SECT_OFF_DATA (objfile))

  number_of_symbols = bfd_get_symcount (abfd);

  /* Allocate a buffer to read in the debug info.
     We avoid using alloca because the memory size could be so large
     that we could hit the stack size limit.  */
  buf = xmalloc (symsize * number_of_symbols);
  cleanup = make_cleanup (xfree, buf);
  bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET);
  val = bfd_bread (buf, symsize * number_of_symbols, abfd);
  if (val != symsize * number_of_symbols)
    error (_("Couldn't read symbol dictionary!"));

  /* Allocate a buffer to read in the som stringtab section of
     the debugging info.  Again, we avoid using alloca because
     the data could be so large that we could potentially hit
     the stack size limitat.  */
  stringtab = xmalloc (obj_som_stringtab_size (abfd));
  make_cleanup (xfree, stringtab);
  bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET);
  val = bfd_bread (stringtab, obj_som_stringtab_size (abfd), abfd);
  if (val != obj_som_stringtab_size (abfd))
    error (_("Can't read in HP string table."));

  /* We need to determine if objfile is a dynamic executable (so we
     can do the right thing for ST_ENTRY vs ST_CODE symbols).

     There's nothing in the header which easily allows us to do
     this.

     This code used to rely upon the existence of a $SHLIB_INFO$
     section to make this determination.  HP claims that it is
     more accurate to check for a nonzero text offset, but they
     have not provided any information about why that test is
     more accurate.  */
  dynamic = (text_offset != 0);

  endbufp = buf + number_of_symbols;
  for (bufp = buf; bufp < endbufp; ++bufp)
    {
      enum minimal_symbol_type ms_type;
      unsigned int flags = bfd_getb32 (bufp->flags);
      unsigned int symbol_type
	= (flags >> SOM_SYMBOL_TYPE_SH) & SOM_SYMBOL_TYPE_MASK;
      unsigned int symbol_scope
	= (flags >> SOM_SYMBOL_SCOPE_SH) & SOM_SYMBOL_SCOPE_MASK;
      CORE_ADDR symbol_value = bfd_getb32 (bufp->symbol_value);
      asection *section = NULL;

      QUIT;

      /* Compute the section.  */
      switch (symbol_scope)
	{
	case SS_EXTERNAL:
	  if (symbol_type != ST_STORAGE)
	    section = bfd_und_section_ptr;
	  else
	    section = bfd_com_section_ptr;
	  break;

	case SS_UNSAT:
	  if (symbol_type != ST_STORAGE)
	    section = bfd_und_section_ptr;
	  else
	    section = bfd_com_section_ptr;
	  break;

	case SS_UNIVERSAL:
	  section = bfd_section_from_som_symbol (abfd, bufp);
	  break;

	case SS_LOCAL:
	  section = bfd_section_from_som_symbol (abfd, bufp);
	  break;
	}

      switch (symbol_scope)
	{
	case SS_UNIVERSAL:
	case SS_EXTERNAL:
	  switch (symbol_type)
	    {
	    case ST_SYM_EXT:
	    case ST_ARG_EXT:
	      continue;

	    case ST_CODE:
	    case ST_PRI_PROG:
	    case ST_SEC_PROG:
	    case ST_MILLICODE:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      ms_type = mst_text;
	      symbol_value += text_offset;
	      symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value);
	      break;

	    case ST_ENTRY:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      /* For a dynamic executable, ST_ENTRY symbols are
	         the stubs, while the ST_CODE symbol is the real
	         function.  */
	      if (dynamic)
		ms_type = mst_solib_trampoline;
	      else
		ms_type = mst_text;
	      symbol_value += text_offset;
	      symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value);
	      break;

	    case ST_STUB:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      ms_type = mst_solib_trampoline;
	      symbol_value += text_offset;
	      symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value);
	      break;

	    case ST_DATA:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      symbol_value += data_offset;
	      ms_type = mst_data;
	      break;
	    default:
	      continue;
	    }
	  break;

#if 0
	  /* SS_GLOBAL and SS_LOCAL are two names for the same thing (!).  */
	case SS_GLOBAL:
#endif
	case SS_LOCAL:
	  switch (symbol_type)
	    {
	    case ST_SYM_EXT:
	    case ST_ARG_EXT:
	      continue;

	    case ST_CODE:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      ms_type = mst_file_text;
	      symbol_value += text_offset;
	      symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value);

	    check_strange_names:
	      /* Utah GCC 2.5, FSF GCC 2.6 and later generate correct local
	         label prefixes for stabs, constant data, etc.  So we need
	         only filter out L$ symbols which are left in due to
	         limitations in how GAS generates SOM relocations.

	         When linking in the HPUX C-library the HP linker has
	         the nasty habit of placing section symbols from the literal
	         subspaces in the middle of the program's text.  Filter
	         those out as best we can.  Check for first and last character
	         being '$'.

	         And finally, the newer HP compilers emit crud like $PIC_foo$N
	         in some circumstance (PIC code I guess).  It's also claimed
	         that they emit D$ symbols too.  What stupidity.  */
	      if ((symname[0] == 'L' && symname[1] == '$')
	      || (symname[0] == '$' && symname[strlen (symname) - 1] == '$')
		  || (symname[0] == 'D' && symname[1] == '$')
		  || (strncmp (symname, "L0\001", 3) == 0)
		  || (strncmp (symname, "$PIC", 4) == 0))
		continue;
	      break;

	    case ST_PRI_PROG:
	    case ST_SEC_PROG:
	    case ST_MILLICODE:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      ms_type = mst_file_text;
	      symbol_value += text_offset;
	      symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value);
	      break;

	    case ST_ENTRY:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      /* SS_LOCAL symbols in a shared library do not have
		 export stubs, so we do not have to worry about
		 using mst_file_text vs mst_solib_trampoline here like
		 we do for SS_UNIVERSAL and SS_EXTERNAL symbols above.  */
	      ms_type = mst_file_text;
	      symbol_value += text_offset;
	      symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value);
	      break;

	    case ST_STUB:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      ms_type = mst_solib_trampoline;
	      symbol_value += text_offset;
	      symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value);
	      break;


	    case ST_DATA:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      symbol_value += data_offset;
	      ms_type = mst_file_data;
	      goto check_strange_names;

	    default:
	      continue;
	    }
	  break;

	  /* This can happen for common symbols when -E is passed to the
	     final link.  No idea _why_ that would make the linker force
	     common symbols to have an SS_UNSAT scope, but it does.

	     This also happens for weak symbols, but their type is
	     ST_DATA.  */
	case SS_UNSAT:
	  switch (symbol_type)
	    {
	    case ST_STORAGE:
	    case ST_DATA:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      symbol_value += data_offset;
	      ms_type = mst_data;
	      break;

	    default:
	      continue;
	    }
	  break;

	default:
	  continue;
	}

      if (bfd_getb32 (bufp->name) > obj_som_stringtab_size (abfd))
	error (_("Invalid symbol data; bad HP string table offset: %s"),
	       plongest (bfd_getb32 (bufp->name)));

      if (bfd_is_const_section (section))
	{
	  struct obj_section *iter;

	  ALL_OBJFILE_OSECTIONS (objfile, iter)
	    {
	      if (bfd_is_const_section (iter->the_bfd_section))
		continue;

	      if (obj_section_addr (iter) <= symbol_value
		  && symbol_value < obj_section_endaddr (iter))
		{
		  section = iter->the_bfd_section;
		  break;
		}
	    }
	}

      prim_record_minimal_symbol_and_info (symname, symbol_value, ms_type,
					   gdb_bfd_section_index (objfile->obfd,
								  section),
					   objfile);
    }

  do_cleanups (cleanup);
}
Example #9
0
int
print_insn_spu (bfd_vma memaddr, struct disassemble_info *info)
{
    bfd_byte buffer[4];
    int value;
    int hex_value;
    int status;
    unsigned int insn;
    const struct spu_opcode *index;
    enum spu_insns tag;

    status = (*info->read_memory_func) (memaddr, buffer, 4, info);
    if (status != 0)
    {
        (*info->memory_error_func) (status, memaddr, info);
        return -1;
    }

    insn = bfd_getb32 (buffer);

    index = get_index_for_opcode (insn);

    if (index == 0)
    {
        (*info->fprintf_func) (info->stream, ".long 0x%x", insn);
    }
    else
    {
        int i;
        int paren = 0;
        tag = (enum spu_insns)(index - spu_opcodes);
        (*info->fprintf_func) (info->stream, "%s", index->mnemonic);
        if (tag == M_BI || tag == M_BISL || tag == M_IRET || tag == M_BISLED
                || tag == M_BIHNZ || tag == M_BIHZ || tag == M_BINZ || tag == M_BIZ
                || tag == M_SYNC || tag == M_HBR)
        {
            int fb = (insn >> (32-18)) & 0x7f;
            if (fb & 0x40)
                (*info->fprintf_func) (info->stream, tag == M_SYNC ? "c" : "p");
            if (fb & 0x20)
                (*info->fprintf_func) (info->stream, "d");
            if (fb & 0x10)
                (*info->fprintf_func) (info->stream, "e");
        }
        if (index->arg[0] != 0)
            (*info->fprintf_func) (info->stream, "\t");
        hex_value = 0;
        for (i = 1;  i <= index->arg[0]; i++)
        {
            int arg = index->arg[i];
            if (arg != A_P && !paren && i > 1)
                (*info->fprintf_func) (info->stream, ",");

            switch (arg)
            {
            case A_T:
                (*info->fprintf_func) (info->stream, "$%d",
                                       DECODE_INSN_RT (insn));
                break;
            case A_A:
                (*info->fprintf_func) (info->stream, "$%d",
                                       DECODE_INSN_RA (insn));
                break;
            case A_B:
                (*info->fprintf_func) (info->stream, "$%d",
                                       DECODE_INSN_RB (insn));
                break;
            case A_C:
                (*info->fprintf_func) (info->stream, "$%d",
                                       DECODE_INSN_RC (insn));
                break;
            case A_S:
                (*info->fprintf_func) (info->stream, "$sp%d",
                                       DECODE_INSN_RA (insn));
                break;
            case A_H:
                (*info->fprintf_func) (info->stream, "$ch%d",
                                       DECODE_INSN_RA (insn));
                break;
            case A_P:
                paren++;
                (*info->fprintf_func) (info->stream, "(");
                break;
            case A_U7A:
                (*info->fprintf_func) (info->stream, "%d",
                                       173 - DECODE_INSN_U8 (insn));
                break;
            case A_U7B:
                (*info->fprintf_func) (info->stream, "%d",
                                       155 - DECODE_INSN_U8 (insn));
                break;
            case A_S3:
            case A_S6:
            case A_S7:
            case A_S7N:
            case A_U3:
            case A_U5:
            case A_U6:
            case A_U7:
                hex_value = DECODE_INSN_I7 (insn);
                (*info->fprintf_func) (info->stream, "%d", hex_value);
                break;
            case A_S11:
                (*info->print_address_func) (memaddr + DECODE_INSN_I9a (insn) * 4,
                                             info);
                break;
            case A_S11I:
                (*info->print_address_func) (memaddr + DECODE_INSN_I9b (insn) * 4,
                                             info);
                break;
            case A_S10:
            case A_S10B:
                hex_value = DECODE_INSN_I10 (insn);
                (*info->fprintf_func) (info->stream, "%d", hex_value);
                break;
            case A_S14:
                hex_value = DECODE_INSN_I10 (insn) * 16;
                (*info->fprintf_func) (info->stream, "%d", hex_value);
                break;
            case A_S16:
                hex_value = DECODE_INSN_I16 (insn);
                (*info->fprintf_func) (info->stream, "%d", hex_value);
                break;
            case A_X16:
                hex_value = DECODE_INSN_U16 (insn);
                (*info->fprintf_func) (info->stream, "%u", hex_value);
                break;
            case A_R18:
                value = DECODE_INSN_I16 (insn) * 4;
                if (value == 0)
                    (*info->fprintf_func) (info->stream, "%d", value);
                else
                {
                    hex_value = memaddr + value;
                    (*info->print_address_func) (hex_value & 0x3ffff, info);
                }
                break;
            case A_S18:
                value = DECODE_INSN_U16 (insn) * 4;
                if (value == 0)
                    (*info->fprintf_func) (info->stream, "%d", value);
                else
                    (*info->print_address_func) (value, info);
                break;
            case A_U18:
                value = DECODE_INSN_U18 (insn);
                if (value == 0 || !(*info->symbol_at_address_func)(0, info))
                {
                    hex_value = value;
                    (*info->fprintf_func) (info->stream, "%u", value);
                }
                else
                    (*info->print_address_func) (value, info);
                break;
            case A_U14:
                hex_value = DECODE_INSN_U14 (insn);
                (*info->fprintf_func) (info->stream, "%u", hex_value);
                break;
            }
            if (arg != A_P && paren)
            {
                (*info->fprintf_func) (info->stream, ")");
                paren--;
            }
        }
        if (hex_value > 16)
            (*info->fprintf_func) (info->stream, "\t# %x", hex_value);
    }
int
print_insn_dlx (bfd_vma memaddr, struct disassemble_info* info)
{
  bfd_byte buffer[4];
  int insn_idx;
  unsigned long insn_word;
  unsigned long dlx_insn_type[] =
  {
    (unsigned long) dlx_r_type,
    (unsigned long) dlx_load_type,
    (unsigned long) dlx_store_type,
    (unsigned long) dlx_aluI_type,
    (unsigned long) dlx_br_type,
    (unsigned long) dlx_jmp_type,
    (unsigned long) dlx_jr_type,
    (unsigned long) NULL
  };
  int dlx_insn_type_num = ((sizeof dlx_insn_type) / (sizeof (unsigned long))) - 1;
  int status =
    (*info->read_memory_func) (memaddr, (bfd_byte *) &buffer[0], 4, info);

  if (status != 0)
    {
      (*info->memory_error_func) (status, memaddr, info);
      return -1;
    }

  /* Now decode the insn    */
  insn_word = bfd_getb32 (buffer);
  opc  = dlx_get_opcode (insn_word);
  rs1  = dlx_get_rs1 (insn_word);
  rs2  = dlx_get_rs2 (insn_word);
  rd   = dlx_get_rdR (insn_word);
  func = dlx_get_func (insn_word);
  imm16= dlx_get_imm16 (insn_word);
  imm26= dlx_get_imm26 (insn_word);

#if 0
  printf ("print_insn_big_dlx: opc = 0x%02x\n"
	  "                    rs1 = 0x%02x\n"
	  "                    rs2 = 0x%02x\n"
	  "                    rd  = 0x%02x\n"
	  "                  func  = 0x%08x\n"
	  "                 imm16  = 0x%08x\n"
	  "                 imm26  = 0x%08x\n",
	  opc, rs1, rs2, rd, func, imm16, imm26);
#endif

  /* Scan through all the insn type and print the insn out.  */
  current_insn_addr = (unsigned long) memaddr;

  for (insn_idx = 0; dlx_insn_type[insn_idx] != 0x0; insn_idx++)
    switch (((dlx_insn) (dlx_insn_type[insn_idx])) (info))
      {
	/* Found the correct opcode   */
      case R_TYPE:
      case ILD_TYPE:
      case IST_TYPE:
      case IAL_TYPE:
      case IBR_TYPE:
      case IJ_TYPE:
      case IJR_TYPE:
	return 4;

	/* Wrong insn type check next one. */
      default:
      case NIL:
	continue;

	/* All rest of the return code are not recongnized, treat it as error */
	/* we should never get here,  I hope! */
      case R_ERROR:
	return -1;
      }

  if (insn_idx ==  dlx_insn_type_num)
    /* Well, does not recoganize this opcode.  */
    (*info->fprintf_func) (info->stream, "<%s>", "Unrecognized Opcode");

  return 4;
}
Example #11
0
static void
download (char *target_name, char *args, int from_tty,
	  void (*write_routine) (bfd *from_bfd, asection *from_sec,
				 file_ptr from_addr, bfd_vma to_addr, int len),
	  void (*start_routine) (bfd_vma entry))
{
  struct cleanup *old_chain;
  asection *section;
  bfd *pbfd;
  bfd_vma entry;
  int i;
#define WRITESIZE 1024
  char *filename;
  int quiet;
  int nostart;

  quiet = 0;
  nostart = 0;
  filename = NULL;

  while (*args != '\000')
    {
      char *arg;

      while (isspace (*args))
	args++;

      arg = args;

      while ((*args != '\000') && !isspace (*args))
	args++;

      if (*args != '\000')
	*args++ = '\000';

      if (*arg != '-')
	filename = arg;
      else if (strncmp (arg, "-quiet", strlen (arg)) == 0)
	quiet = 1;
      else if (strncmp (arg, "-nostart", strlen (arg)) == 0)
	nostart = 1;
      else
	error ("unknown option `%s'", arg);
    }

  if (!filename)
    filename = get_exec_file (1);

  pbfd = bfd_openr (filename, gnutarget);
  if (pbfd == NULL)
    {
      perror_with_name (filename);
      return;
    }
  old_chain = make_cleanup_bfd_close (pbfd);

  if (!bfd_check_format (pbfd, bfd_object))
    error ("\"%s\" is not an object file: %s", filename,
	   bfd_errmsg (bfd_get_error ()));

  for (section = pbfd->sections; section; section = section->next)
    {
      if (bfd_get_section_flags (pbfd, section) & SEC_LOAD)
	{
	  bfd_vma section_address;
	  bfd_size_type section_size;
	  file_ptr fptr;
	  const char *section_name;

	  section_name = bfd_get_section_name (pbfd, section);

	  section_address = bfd_get_section_vma (pbfd, section);

	  /* Adjust sections from a.out files, since they don't
	     carry their addresses with.  */
	  if (bfd_get_flavour (pbfd) == bfd_target_aout_flavour)
	    {
	      if (strcmp (section_name, ".text") == 0)
		section_address = bfd_get_start_address (pbfd);
	      else if (strcmp (section_name, ".data") == 0)
		{
		  /* Read the first 8 bytes of the data section.
		     There should be the string 'DaTa' followed by
		     a word containing the actual section address. */
		  struct data_marker
		    {
		      char signature[4];	/* 'DaTa' */
		      unsigned char sdata[4];	/* &sdata */
		    }
		  marker;
		  bfd_get_section_contents (pbfd, section, &marker, 0,
					    sizeof (marker));
		  if (strncmp (marker.signature, "DaTa", 4) == 0)
		    {
		      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
			section_address = bfd_getb32 (marker.sdata);
		      else
			section_address = bfd_getl32 (marker.sdata);
		    }
		}
	    }

	  section_size = bfd_get_section_size_before_reloc (section);

	  if (!quiet)
	    printf_filtered ("[Loading section %s at 0x%x (%d bytes)]\n",
			     bfd_get_section_name (pbfd, section),
			     section_address,
			     section_size);

	  fptr = 0;
	  while (section_size > 0)
	    {
	      int count;
	      static char inds[] = "|/-\\";
	      static int k = 0;

	      QUIT;

	      count = min (section_size, WRITESIZE);

	      write_routine (pbfd, section, fptr, section_address, count);

	      if (!quiet)
		{
		  printf_unfiltered ("\r%c", inds[k++ % 4]);
		  gdb_flush (gdb_stdout);
		}

	      section_address += count;
	      fptr += count;
	      section_size -= count;
	    }
	}
    }

  if (!nostart)
    {
      entry = bfd_get_start_address (pbfd);

      if (!quiet)
	printf_unfiltered ("[Starting %s at 0x%x]\n", filename, entry);

      start_routine (entry);
    }

  do_cleanups (old_chain);
}