コード例 #1
0
/* Support for core dump NOTE sections.  */
static bfd_boolean
cgc32_am33lin_grok_prstatus (bfd *abfd, Cgc_Internal_Note *note)
{
  int offset;
  unsigned int size;

  switch (note->descsz)
    {
      default:
	return FALSE;

      case 184:
      case 188:		/* Linux/am33 */
	/* pr_cursig */
	cgc_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);

	/* pr_pid */
	cgc_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);

	/* pr_reg */
	offset = 72;
	size = 112;

	break;
    }

  /* Make a ".reg/999" section.  */
  return _bfd_cgccore_make_pseudosection (abfd, ".reg", size,
					  note->descpos + offset);
}
コード例 #2
0
static bfd_boolean
tilegx_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
{
  int offset;
  size_t size;

  if (note->descsz != TILEGX_PRSTATUS_SIZEOF)
    return FALSE;

  /* pr_cursig */
  elf_tdata (abfd)->core->signal =
    bfd_get_16 (abfd, note->descdata + TILEGX_PRSTATUS_OFFSET_PR_CURSIG);

  /* pr_pid */
  elf_tdata (abfd)->core->pid =
    bfd_get_32 (abfd, note->descdata + TILEGX_PRSTATUS_OFFSET_PR_PID);

  /* pr_reg */
  offset = TILEGX_PRSTATUS_OFFSET_PR_REG;
  size   = TILEGX_GREGSET_T_SIZE;

  /* Make a ".reg/999" section.  */
  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
					  size, note->descpos + offset);
}
コード例 #3
0
ファイル: elf-eh-frame.c プロジェクト: Wonseok/okl4_3.0
static bfd_vma
read_value (bfd *abfd, bfd_byte *buf, int width, int is_signed)
{
  bfd_vma value;

  switch (width)
    {
    case 2:
      if (is_signed)
	value = bfd_get_signed_16 (abfd, buf);
      else
	value = bfd_get_16 (abfd, buf);
      break;
    case 4:
      if (is_signed)
	value = bfd_get_signed_32 (abfd, buf);
      else
	value = bfd_get_32 (abfd, buf);
      break;
    case 8:
      if (is_signed)
	value = bfd_get_signed_64 (abfd, buf);
      else
	value = bfd_get_64 (abfd, buf);
      break;
    default:
      BFD_FAIL ();
      return 0;
    }

  return value;
}
コード例 #4
0
static void
pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd,
			     struct pex64_unwind_info *ui,
			     struct pex64_runtime_function *rf)
{
  unsigned int i;
  unsigned int tmp; /* At least 32 bits.  */
  int save_allowed;

  if (ui->CountOfCodes == 0 || ui->rawUnwindCodes == NULL)
    return;

  /* According to UNWIND_CODE documentation:
      If an FP reg is used, the any unwind code taking an offset must only be
      used after the FP reg is established in the prolog.
     But there are counter examples of that in system dlls...  */
  save_allowed = TRUE;

  i = 0;

  if (ui->Version == 2
      && PEX64_UNWCODE_CODE (ui->rawUnwindCodes[1]) == UWOP_EPILOG)
    {
      /* Display epilog opcode (whose docoding is not fully documented).
         Looks to be designed to speed-up unwinding, as there is no need
	 to decode instruction flow if outside an epilog.  */
      unsigned int func_size = rf->rva_EndAddress - rf->rva_BeginAddress;

      fprintf (file, "\tv2 epilog (length: %02x) at pc+:",
	       ui->rawUnwindCodes[0]);
      if (PEX64_UNWCODE_INFO (ui->rawUnwindCodes[1]))
	fprintf (file, " 0x%x", func_size - ui->rawUnwindCodes[0]);
      i++;
      for (; i < ui->CountOfCodes; i++)
	{
	  const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
	  unsigned int off;

	  if (PEX64_UNWCODE_CODE (dta[1]) != UWOP_EPILOG)
	    break;
	  off = dta[0] | (PEX64_UNWCODE_INFO (dta[1]) << 8);
	  if (off == 0)
	    fprintf (file, " [pad]");
	  else
	    fprintf (file, " 0x%x", func_size - off);
	}
      fputc ('\n', file);
    }

  for (; i < ui->CountOfCodes; i++)
    {
      const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
      unsigned int info = PEX64_UNWCODE_INFO (dta[1]);
      int unexpected = FALSE;

      fprintf (file, "\t  pc+0x%02x: ", (unsigned int) dta[0]);
      switch (PEX64_UNWCODE_CODE (dta[1]))
	{
	case UWOP_PUSH_NONVOL:
	  fprintf (file, "push %s", pex_regs[info]);
	  break;
	case UWOP_ALLOC_LARGE:
	  if (info == 0)
	    {
	      tmp = bfd_get_16 (abfd, &dta[2]) * 8;
	      i++;
	    }
	  else
	    {
	      tmp = bfd_get_32 (abfd, &dta[2]);
	      i += 2;
	    }
	  fprintf (file, "alloc large area: rsp = rsp - 0x%x", tmp);
	  break;
	case UWOP_ALLOC_SMALL:
	  fprintf (file, "alloc small area: rsp = rsp - 0x%x", (info + 1) * 8);
	  break;
	case UWOP_SET_FPREG:
	  /* According to the documentation, info field is unused.  */
	  fprintf (file, "FPReg: %s = rsp + 0x%x (info = 0x%x)",
		   pex_regs[ui->FrameRegister],
		   (unsigned int) ui->FrameOffset * 16, info);
	  unexpected = ui->FrameRegister == 0;
	  save_allowed = FALSE;
	  break;
	case UWOP_SAVE_NONVOL:
	  tmp = bfd_get_16 (abfd, &dta[2]) * 8;
	  i++;
	  fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
	  unexpected = !save_allowed;
	  break;
	case UWOP_SAVE_NONVOL_FAR:
	  tmp = bfd_get_32 (abfd, &dta[2]);
	  i += 2;
	  fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
	  unexpected = !save_allowed;
	  break;
	case UWOP_SAVE_XMM:
	  if (ui->Version == 1)
	    {
	      tmp = bfd_get_16 (abfd, &dta[2]) * 8;
	      i++;
	      fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
	      unexpected = !save_allowed;
	    }
	  else if (ui->Version == 2)
	    {
	      fprintf (file, "epilog %02x %01x", dta[0], info);
	      unexpected = TRUE;
	    }
	  break;
	case UWOP_SAVE_XMM_FAR:
	  tmp = bfd_get_32 (abfd, &dta[2]) * 8;
	  i += 2;
	  fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
	  unexpected = !save_allowed;
	  break;
	case UWOP_SAVE_XMM128:
	  tmp = bfd_get_16 (abfd, &dta[2]) * 16;
	  i++;
	  fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
	  unexpected = !save_allowed;
	  break;
	case UWOP_SAVE_XMM128_FAR:
	  tmp = bfd_get_32 (abfd, &dta[2]) * 16;
	  i += 2;
	  fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
	  unexpected = !save_allowed;
	  break;
	case UWOP_PUSH_MACHFRAME:
	  fprintf (file, "interrupt entry (SS, old RSP, EFLAGS, CS, RIP");
	  if (info == 0)
	    fprintf (file, ")");
	  else if (info == 1)
	    fprintf (file, ",ErrorCode)");
	  else
	    fprintf (file, ", unknown(%u))", info);
	  break;
	default:
	  /* PR 17512: file: 2245-7442-0.004.  */
	  fprintf (file, _("Unknown: %x"), PEX64_UNWCODE_CODE (dta[1]));
	  break;
      }
      if (unexpected)
	fprintf (file, " [Unexpected!]");
      fputc ('\n', file);
    }
}
コード例 #5
0
ファイル: elf32-sh64-com.c プロジェクト: DonCN/haiku
static bfd_boolean
sh64_address_in_cranges (asection *cranges, bfd_vma addr,
			 sh64_elf_crange *rangep)
{
  bfd_byte *cranges_contents;
  bfd_byte *found_rangep;
  bfd_size_type cranges_size = cranges->size;

  /* If the size is not a multiple of the cranges entry size, then
     something is badly wrong.  */
  if ((cranges_size % SH64_CRANGE_SIZE) != 0)
    return FALSE;

  /* If this section has relocations, then we can't do anything sane.  */
  if (bfd_get_section_flags (cranges->owner, cranges) & SEC_RELOC)
    return FALSE;

  /* Has some kind soul (or previous call) left processed, sorted contents
     for us?  */
  if ((bfd_get_section_flags (cranges->owner, cranges) & SEC_IN_MEMORY)
      && elf_section_data (cranges)->this_hdr.sh_type == SHT_SH5_CR_SORTED)
    cranges_contents = cranges->contents;
  else
    {
      if (!bfd_malloc_and_get_section (cranges->owner, cranges,
				       &cranges_contents))
	goto error_return;

      /* Is it sorted?  */
      if (elf_section_data (cranges)->this_hdr.sh_type
	  != SHT_SH5_CR_SORTED)
	/* Nope.  Lets sort it.  */
	qsort (cranges_contents, cranges_size / SH64_CRANGE_SIZE,
	       SH64_CRANGE_SIZE,
	       bfd_big_endian (cranges->owner)
	       ? _bfd_sh64_crange_qsort_cmpb : _bfd_sh64_crange_qsort_cmpl);

      /* Let's keep it around.  */
      cranges->contents = cranges_contents;
      bfd_set_section_flags (cranges->owner, cranges,
			     bfd_get_section_flags (cranges->owner, cranges)
			     | SEC_IN_MEMORY);

      /* It's sorted now.  */
      elf_section_data (cranges)->this_hdr.sh_type = SHT_SH5_CR_SORTED;
    }

  /* Try and find a matching range.  */
  found_rangep
    = bsearch (&addr, cranges_contents, cranges_size / SH64_CRANGE_SIZE,
	       SH64_CRANGE_SIZE,
	       bfd_big_endian (cranges->owner)
	       ? _bfd_sh64_crange_bsearch_cmpb
	       : _bfd_sh64_crange_bsearch_cmpl);

  /* Fill in a few return values if we found a matching range.  */
  if (found_rangep)
    {
      enum sh64_elf_cr_type cr_type
	= bfd_get_16 (cranges->owner,
		      SH64_CRANGE_CR_TYPE_OFFSET + found_rangep);
      bfd_vma cr_addr
	= bfd_get_32 (cranges->owner,
		      SH64_CRANGE_CR_ADDR_OFFSET
		      + (char *) found_rangep);
      bfd_size_type cr_size
	= bfd_get_32 (cranges->owner,
		      SH64_CRANGE_CR_SIZE_OFFSET
		      + (char *) found_rangep);

      rangep->cr_addr = cr_addr;
      rangep->cr_size = cr_size;
      rangep->cr_type = cr_type;

      return TRUE;
    }

  /* There is a .cranges section, but it does not have a descriptor
     matching this address.  */
  return FALSE;

error_return:
  if (cranges_contents != NULL)
    free (cranges_contents);
  return FALSE;
}
コード例 #6
0
/* Insert the addend/value into the instruction or data object being
   relocated.  */
bfd_reloc_status_type
_bfd_aarch64_elf_put_addend (bfd *abfd,
			     bfd_byte *address, bfd_reloc_code_real_type r_type,
			     reloc_howto_type *howto, bfd_signed_vma addend)
{
  bfd_reloc_status_type status = bfd_reloc_ok;
  bfd_signed_vma old_addend = addend;
  bfd_vma contents;
  int size;

  size = bfd_get_reloc_size (howto);
  switch (size)
    {
    case 2:
      contents = bfd_get_16 (abfd, address);
      break;
    case 4:
      if (howto->src_mask != 0xffffffff)
	/* Must be 32-bit instruction, always little-endian.  */
	contents = bfd_getl32 (address);
      else
	/* Must be 32-bit data (endianness dependent).  */
	contents = bfd_get_32 (abfd, address);
      break;
    case 8:
      contents = bfd_get_64 (abfd, address);
      break;
    default:
      abort ();
    }

  switch (howto->complain_on_overflow)
    {
    case complain_overflow_dont:
      break;
    case complain_overflow_signed:
      status = aarch64_signed_overflow (addend,
					howto->bitsize + howto->rightshift);
      break;
    case complain_overflow_unsigned:
      status = aarch64_unsigned_overflow (addend,
					  howto->bitsize + howto->rightshift);
      break;
    case complain_overflow_bitfield:
    default:
      abort ();
    }

  addend >>= howto->rightshift;

  switch (r_type)
    {
    case BFD_RELOC_AARCH64_JUMP26:
    case BFD_RELOC_AARCH64_CALL26:
      contents = reencode_branch_ofs_26 (contents, addend);
      break;

    case BFD_RELOC_AARCH64_BRANCH19:
      contents = reencode_cond_branch_ofs_19 (contents, addend);
      break;

    case BFD_RELOC_AARCH64_TSTBR14:
      contents = reencode_tst_branch_ofs_14 (contents, addend);
      break;

    case BFD_RELOC_AARCH64_LD_LO19_PCREL:
    case BFD_RELOC_AARCH64_GOT_LD_PREL19:
      if (old_addend & ((1 << howto->rightshift) - 1))
	return bfd_reloc_overflow;
      contents = reencode_ld_lit_ofs_19 (contents, addend);
      break;

    case BFD_RELOC_AARCH64_TLSDESC_CALL:
      break;

    case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
    case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
    case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
    case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
    case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
    case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
    case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
      contents = reencode_adr_imm (contents, addend);
      break;

    case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
    case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
    case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
    case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
    case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
    case BFD_RELOC_AARCH64_ADD_LO12:
      /* Corresponds to: add rd, rn, #uimm12 to provide the low order
         12 bits of the page offset following
         BFD_RELOC_AARCH64_ADR_HI21_PCREL which computes the
         (pc-relative) page base.  */
      contents = reencode_add_imm (contents, addend);
      break;

    case BFD_RELOC_AARCH64_LDST8_LO12:
    case BFD_RELOC_AARCH64_LDST16_LO12:
    case BFD_RELOC_AARCH64_LDST32_LO12:
    case BFD_RELOC_AARCH64_LDST64_LO12:
    case BFD_RELOC_AARCH64_LDST128_LO12:
    case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
    case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
    case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
    case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
    case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
    case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
      if (old_addend & ((1 << howto->rightshift) - 1))
	return bfd_reloc_overflow;
      /* Used for ldr*|str* rt, [rn, #uimm12] to provide the low order
         12 bits of the page offset following BFD_RELOC_AARCH64_ADR_HI21_PCREL
         which computes the (pc-relative) page base.  */
      contents = reencode_ldst_pos_imm (contents, addend);
      break;

      /* Group relocations to create high bits of a 16, 32, 48 or 64
         bit signed data or abs address inline. Will change
         instruction to MOVN or MOVZ depending on sign of calculated
         value.  */

    case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
    case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
    case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
    case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
    case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
    case BFD_RELOC_AARCH64_MOVW_G0_S:
    case BFD_RELOC_AARCH64_MOVW_G1_S:
    case BFD_RELOC_AARCH64_MOVW_G2_S:
      /* NOTE: We can only come here with movz or movn.  */
      if (addend < 0)
	{
	  /* Force use of MOVN.  */
	  addend = ~addend;
	  contents = reencode_movzn_to_movn (contents);
	}
      else
	{
	  /* Force use of MOVZ.  */
	  contents = reencode_movzn_to_movz (contents);
	}
      /* fall through */

      /* Group relocations to create a 16, 32, 48 or 64 bit unsigned
         data or abs address inline.  */

    case BFD_RELOC_AARCH64_MOVW_G0:
    case BFD_RELOC_AARCH64_MOVW_G0_NC:
    case BFD_RELOC_AARCH64_MOVW_G1:
    case BFD_RELOC_AARCH64_MOVW_G1_NC:
    case BFD_RELOC_AARCH64_MOVW_G2:
    case BFD_RELOC_AARCH64_MOVW_G2_NC:
    case BFD_RELOC_AARCH64_MOVW_G3:
      contents = reencode_movw_imm (contents, addend);
      break;

    default:
      /* Repack simple data */
      if (howto->dst_mask & (howto->dst_mask + 1))
	return bfd_reloc_notsupported;

      contents = ((contents & ~howto->dst_mask) | (addend & howto->dst_mask));
      break;
    }

  switch (size)
    {
    case 2:
      bfd_put_16 (abfd, contents, address);
      break;
    case 4:
      if (howto->dst_mask != 0xffffffff)
	/* must be 32-bit instruction, always little-endian */
	bfd_putl32 (contents, address);
      else
	/* must be 32-bit data (endianness dependent) */
	bfd_put_32 (abfd, contents, address);
      break;
    case 8:
      bfd_put_64 (abfd, contents, address);
      break;
    default:
      abort ();
    }

  return status;
}
コード例 #7
0
ファイル: rddbg.c プロジェクト: 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;
}
コード例 #8
0
}			


static bfd_reloc_status_type 
DEFUN(howto_hvrt16,(abfd, reloc_entry, symbol_in, data,
		    ignore_input_section, ignore_bfd),
      bfd *abfd AND
      arelent *reloc_entry AND
      asymbol *symbol_in AND
      PTR data AND
      asection *ignore_input_section AND
      bfd *ignore_bfd)
{
  long relocation = 0;
  bfd_vma addr = reloc_entry->address;
  long x = bfd_get_16(abfd, (bfd_byte *)data + addr);

  HOWTO_PREPARE(relocation, symbol_in);

  x = (x + relocation + reloc_entry->addend) >> 16;

  bfd_put_16(abfd, x, (bfd_byte *)data + addr);
  return bfd_reloc_ok;
}



static reloc_howto_type howto_table[] = 
{
  HOWTO(R_PCR16L,02,1,16,true, 0,complain_overflow_signed, 0, "PCR16L",false,0x0000ffff,0x0000ffff,true),
  HOWTO(R_PCR26L,02,2,26,true, 0,complain_overflow_signed, 0, "PCR26L",false,0x03ffffff,0x03ffffff,true),
コード例 #9
0
ファイル: dwarf1.c プロジェクト: 0x7678/playbook-dev-tools
static bfd_boolean
parse_die (bfd *             abfd,
	   struct die_info * aDieInfo,
	   bfd_byte *        aDiePtr,
	   bfd_byte *        aDiePtrEnd)
{
  bfd_byte *this_die = aDiePtr;
  bfd_byte *xptr = this_die;

  memset (aDieInfo, 0, sizeof (* aDieInfo));

  /* First comes the length.  */
  aDieInfo->length = bfd_get_32 (abfd, (bfd_byte *) xptr);
  xptr += 4;
  if (aDieInfo->length == 0
      || (this_die + aDieInfo->length) >= aDiePtrEnd)
    return FALSE;
  if (aDieInfo->length < 6)
    {
      /* Just padding bytes.  */
      aDieInfo->tag = TAG_padding;
      return TRUE;
    }

  /* Then the tag.  */
  aDieInfo->tag = bfd_get_16 (abfd, (bfd_byte *) xptr);
  xptr += 2;

  /* Then the attributes.  */
  while (xptr < (this_die + aDieInfo->length))
    {
      unsigned short attr;

      /* Parse the attribute based on its form.  This section
         must handle all dwarf1 forms, but need only handle the
	 actual attributes that we care about.  */
      attr = bfd_get_16 (abfd, (bfd_byte *) xptr);
      xptr += 2;

      switch (FORM_FROM_ATTR (attr))
	{
	case FORM_DATA2:
	  xptr += 2;
	  break;
	case FORM_DATA4:
	case FORM_REF:
	  if (attr == AT_sibling)
	    aDieInfo->sibling = bfd_get_32 (abfd, (bfd_byte *) xptr);
	  else if (attr == AT_stmt_list)
	    {
	      aDieInfo->stmt_list_offset = bfd_get_32 (abfd, (bfd_byte *) xptr);
	      aDieInfo->has_stmt_list = 1;
	    }
	  xptr += 4;
	  break;
	case FORM_DATA8:
	  xptr += 8;
	  break;
	case FORM_ADDR:
	  if (attr == AT_low_pc)
	    aDieInfo->low_pc = bfd_get_32 (abfd, (bfd_byte *) xptr);
	  else if (attr == AT_high_pc)
	    aDieInfo->high_pc = bfd_get_32 (abfd, (bfd_byte *) xptr);
	  xptr += 4;
	  break;
	case FORM_BLOCK2:
	  xptr += 2 + bfd_get_16 (abfd, (bfd_byte *) xptr);
	  break;
	case FORM_BLOCK4:
	  xptr += 4 + bfd_get_32 (abfd, (bfd_byte *) xptr);
	  break;
	case FORM_STRING:
	  if (attr == AT_name)
	    aDieInfo->name = (char *) xptr;
	  xptr += strlen ((char *) xptr) + 1;
	  break;
	}
    }

  return TRUE;
}
コード例 #10
0
ファイル: coff-z8k.c プロジェクト: cooljeanius/apple-gdb-1824
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();
    }
}
コード例 #11
0
ファイル: rddbg.c プロジェクト: dougmencken/apple-gdb-1824
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;
}