Beispiel #1
0
static long
remove_useless_symbols (asymbol ** symbols, long count)
{
  asymbol **in_ptr = symbols, **out_ptr = symbols;

  while (-- count >= 0)
    {
      asymbol *sym = *in_ptr ++;

      if (strstr (sym->name, "gcc2_compiled"))
	continue;
      if (sym->name == NULL || sym->name[0] == '\0')
	continue;
      if (sym->flags & (BSF_DEBUGGING))
	continue;
      if (bfd_is_und_section (sym->section)
	  || bfd_is_com_section (sym->section))
	continue;
      
      if (sym->name[0] == '.' && sym->name[1] == 'L')
	continue;

      /* If the symbol ends in ^A or ^B it is
	 an assembler generated local label.  */
      if (sym->name[strlen (sym->name) - 1] < 32)
	continue;

      *out_ptr++ = sym;
    }
  return out_ptr - symbols;
}
Beispiel #2
0
bfd_vma
bfd_coff_reloc16_get_value (arelent *reloc,
			    struct bfd_link_info *link_info,
			    asection *input_section)
{
  bfd_vma value;
  asymbol *symbol = *(reloc->sym_ptr_ptr);
  /* A symbol holds a pointer to a section, and an offset from the
     base of the section.  To relocate, we find where the section will
     live in the output and add that in.  */

  if (bfd_is_und_section (symbol->section)
      || bfd_is_com_section (symbol->section))
    {
      struct bfd_link_hash_entry *h;

      /* The symbol is undefined in this BFD.  Look it up in the
	 global linker hash table.  FIXME: This should be changed when
	 we convert this stuff to use a specific final_link function
	 and change the interface to bfd_relax_section to not require
	 the generic symbols.  */
      h = bfd_wrapped_link_hash_lookup (input_section->owner, link_info,
					bfd_asymbol_name (symbol),
					FALSE, FALSE, TRUE);
      if (h != (struct bfd_link_hash_entry *) NULL
	  && (h->type == bfd_link_hash_defined
	      || h->type == bfd_link_hash_defweak))
	value = (h->u.def.value
		 + h->u.def.section->output_section->vma
		 + h->u.def.section->output_offset);
      else if (h != (struct bfd_link_hash_entry *) NULL
	       && h->type == bfd_link_hash_common)
	value = h->u.c.size;
      else if (h != (struct bfd_link_hash_entry *) NULL
	       && h->type == bfd_link_hash_undefweak)
	/* This is a GNU extension.  */
	value = 0;
      else
	{
	  if (!((*link_info->callbacks->undefined_symbol)
		(link_info, bfd_asymbol_name (symbol),
		 input_section->owner, input_section, reloc->address,
		 TRUE)))
	    abort ();
	  value = 0;
	}
    }
  else
    {
      value = symbol->value
	+ symbol->section->output_offset
	+ symbol->section->output_section->vma;
    }

  /* Add the value contained in the relocation.  */
  value += reloc->addend;

  return value;
}
Beispiel #3
0
void
add_cref (const char *name,
          bfd *abfd,
          asection *section,
          bfd_vma value ATTRIBUTE_UNUSED)
{
    struct cref_hash_entry *h;
    struct cref_ref *r;

    if (! cref_initialized)
    {
        if (!bfd_hash_table_init (&cref_table.root, cref_hash_newfunc,
                                  sizeof (struct cref_hash_entry)))
            einfo (_("%X%P: bfd_hash_table_init of cref table failed: %E\n"));
        cref_initialized = TRUE;
    }

    h = cref_hash_lookup (&cref_table, name, TRUE, FALSE);
    if (h == NULL)
        einfo (_("%X%P: cref_hash_lookup failed: %E\n"));

    for (r = h->refs; r != NULL; r = r->next)
        if (r->abfd == abfd)
            break;

    if (r == NULL)
    {
        r = bfd_hash_allocate (&cref_table.root, sizeof *r);
        if (r == NULL)
            einfo (_("%X%P: cref alloc failed: %E\n"));
        r->next = h->refs;
        h->refs = r;
        r->abfd = abfd;
        r->def = FALSE;
        r->common = FALSE;
        r->undef = FALSE;
    }

    if (bfd_is_und_section (section))
        r->undef = TRUE;
    else if (bfd_is_com_section (section))
        r->common = TRUE;
    else
        r->def = TRUE;
}
Beispiel #4
0
long
remove_useless_symbols_local (asymbol *symbols, long count)
{
  asymbol *in_ptr = symbols, *out_ptr = symbols;

  while (--count >= 0)
  {
    asymbol *sym = in_ptr++;

    if (sym->name == NULL || sym->name[0] == '\0')
      continue;
    if (sym->flags & (BSF_DEBUGGING | BSF_SECTION_SYM))
      continue;
    if (bfd_is_und_section (sym->section)
        || bfd_is_com_section (sym->section))
      continue;

    *out_ptr++ = *sym;
  }
  return out_ptr - symbols;
}
Beispiel #5
0
void ELFFile::remove_useless_symbols ()
{
    long count = this->sorted_symcount;
    asymbol** in_ptr = this->sorted_syms;
    asymbol** out_ptr = this->sorted_syms;

    while (--count >= 0)
    {
        asymbol *sym = *in_ptr++;

        if (sym->name == NULL || sym->name[0] == '\0')
            continue;
        if (sym->flags & (BSF_DEBUGGING | BSF_SECTION_SYM))
            continue;
        if (bfd_is_und_section (sym->section)
                || bfd_is_com_section (sym->section))
            continue;

        *out_ptr++ = sym;
    }
    this->sorted_symcount = out_ptr - this->sorted_syms;
}
Beispiel #6
0
static long
remove_useless_symbols (asymbol ** symbols, long count)
{
  register asymbol **in_ptr = symbols, **out_ptr = symbols;

  while (--count >= 0)
    {
      asymbol *sym = *in_ptr++;

      if (strstr (sym->name, "gcc2_compiled"))
	continue;
      if (sym->name == NULL || sym->name[0] == '\0')
	continue;
      if (sym->flags & (BSF_DEBUGGING))
	continue;
      if (bfd_is_und_section (sym->section)
	  || bfd_is_com_section (sym->section))
	continue;

      *out_ptr++ = sym;
    }
  return out_ptr - symbols;
}
Beispiel #7
0
/* To determine which symbols should be resolved LDPR_PREVAILING_DEF
   and which LDPR_PREVAILING_DEF_IRONLY, we notice all the symbols as
   the linker adds them to the linker hash table.  Mark those
   referenced from a non-IR file with non_ir_ref.  We have to
   notice_all symbols, because we won't necessarily know until later
   which ones will be contributed by IR files.  */
static bfd_boolean
plugin_notice (struct bfd_link_info *info,
	       struct bfd_link_hash_entry *h,
	       bfd *abfd,
	       asection *section,
	       bfd_vma value,
	       flagword flags,
	       const char *string)
{
  if (h != NULL)
    {
      bfd *sym_bfd;

      /* No further processing if this def/ref is from an IR dummy BFD.  */
      if (is_ir_dummy_bfd (abfd))
	return TRUE;

      /* Making an indirect symbol counts as a reference unless this
	 is a brand new symbol.  */
      if (bfd_is_ind_section (section)
	  || (flags & BSF_INDIRECT) != 0)
	{
	  if (h->type != bfd_link_hash_new)
	    {
	      struct bfd_link_hash_entry *inh;

	      h->non_ir_ref = TRUE;
	      inh = bfd_wrapped_link_hash_lookup (abfd, info, string, FALSE,
						  FALSE, FALSE);
	      if (inh != NULL)
		inh->non_ir_ref = TRUE;
	    }
	}

      /* Nothing to do here for warning symbols.  */
      else if ((flags & BSF_WARNING) != 0)
	;

      /* Nothing to do here for constructor symbols.  */
      else if ((flags & BSF_CONSTRUCTOR) != 0)
	;

      /* If this is a ref, set non_ir_ref.  */
      else if (bfd_is_und_section (section))
	h->non_ir_ref = TRUE;

      /* Otherwise, it must be a new def.  Ensure any symbol defined
	 in an IR dummy BFD takes on a new value from a real BFD.
	 Weak symbols are not normally overridden by a new weak
	 definition, and strong symbols will normally cause multiple
	 definition errors.  Avoid this by making the symbol appear
	 to be undefined.  */
      else if (((h->type == bfd_link_hash_defweak
		 || h->type == bfd_link_hash_defined)
		&& is_ir_dummy_bfd (sym_bfd = h->u.def.section->owner))
	       || (h->type == bfd_link_hash_common
		   && is_ir_dummy_bfd (sym_bfd = h->u.c.p->section->owner)))
	{
	  h->type = bfd_link_hash_undefweak;
	  h->u.undef.abfd = sym_bfd;
	}
    }

  /* Continue with cref/nocrossref/trace-sym processing.  */
  if (h == NULL
      || orig_notice_all
      || (info->notice_hash != NULL
	  && bfd_hash_lookup (info->notice_hash, h->root.string,
			      FALSE, FALSE) != NULL))
    return (*orig_callbacks->notice) (info, h,
				      abfd, section, value, flags, string);
  return TRUE;
}
Beispiel #8
0
/*
FUNCTION
	bfd_decode_symclass

DESCRIPTION
	Return a character corresponding to the symbol
	class of @var{symbol}, or '?' for an unknown class.

SYNOPSIS
	int bfd_decode_symclass (asymbol *symbol);
*/
int
bfd_decode_symclass (asymbol *symbol)
{
  char c;

  if (symbol->section && bfd_is_com_section (symbol->section))
    return 'C';
  if (bfd_is_und_section (symbol->section))
    {
      if (symbol->flags & BSF_WEAK)
	{
	  /* If weak, determine if it's specifically an object
	     or non-object weak.  */
	  if (symbol->flags & BSF_OBJECT)
	    return 'v';
	  else
	    return 'w';
	}
      else
	return 'U';
    }
  if (bfd_is_ind_section (symbol->section))
    return 'I';
  if (symbol->flags & BSF_GNU_INDIRECT_FUNCTION)
    return 'i';
  if (symbol->flags & BSF_WEAK)
    {
      /* If weak, determine if it's specifically an object
	 or non-object weak.  */
      if (symbol->flags & BSF_OBJECT)
	return 'V';
      else
	return 'W';
    }
  if (symbol->flags & BSF_GNU_UNIQUE)
    return 'u';
  if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL)))
    return '?';

  if (bfd_is_abs_section (symbol->section))
    c = 'a';
  else if (symbol->section)
    {
      c = coff_section_type (symbol->section->name);
      if (c == '?')
	c = decode_section_type (symbol->section);
    }
  else
    return '?';
  if (symbol->flags & BSF_GLOBAL)
    c = TOUPPER (c);
  return c;

  /* We don't have to handle these cases just yet, but we will soon:
     N_SETV: 'v';
     N_SETA: 'l';
     N_SETT: 'x';
     N_SETD: 'z';
     N_SETB: 's';
     N_INDR: 'i';
     */
}
Beispiel #9
0
/* To determine which symbols should be resolved LDPR_PREVAILING_DEF
   and which LDPR_PREVAILING_DEF_IRONLY, we notice all the symbols as
   the linker adds them to the linker hash table.  Mark those
   referenced from a non-IR file with non_ir_ref.  We have to
   notice_all symbols, because we won't necessarily know until later
   which ones will be contributed by IR files.  */
static bfd_boolean
plugin_notice (struct bfd_link_info *info,
               struct bfd_link_hash_entry *h,
               struct bfd_link_hash_entry *inh,
               bfd *abfd,
               asection *section,
               bfd_vma value,
               flagword flags)
{
    struct bfd_link_hash_entry *orig_h = h;

    if (h != NULL)
    {
        bfd *sym_bfd;

        if (h->type == bfd_link_hash_warning)
            h = h->u.i.link;

        /* Nothing to do here if this def/ref is from an IR dummy BFD.  */
        if (is_ir_dummy_bfd (abfd))
            ;

        /* Making an indirect symbol counts as a reference unless this
        is a brand new symbol.  */
        else if (bfd_is_ind_section (section)
                 || (flags & BSF_INDIRECT) != 0)
        {
            /* ??? Some of this is questionable.  See comments in
               _bfd_generic_link_add_one_symbol for case IND.  */
            if (h->type != bfd_link_hash_new)
            {
                h->non_ir_ref = TRUE;
                inh->non_ir_ref = TRUE;
            }
            else if (inh->type == bfd_link_hash_new)
                inh->non_ir_ref = TRUE;
        }

        /* Nothing to do here for warning symbols.  */
        else if ((flags & BSF_WARNING) != 0)
            ;

        /* Nothing to do here for constructor symbols.  */
        else if ((flags & BSF_CONSTRUCTOR) != 0)
            ;

        /* If this is a ref, set non_ir_ref.  */
        else if (bfd_is_und_section (section))
        {
            /* Replace the undefined dummy bfd with the real one.  */
            if ((h->type == bfd_link_hash_undefined
                    || h->type == bfd_link_hash_undefweak)
                    && (h->u.undef.abfd == NULL
                        || (h->u.undef.abfd->flags & BFD_PLUGIN) != 0))
                h->u.undef.abfd = abfd;
            h->non_ir_ref = TRUE;
        }

        /* Otherwise, it must be a new def.  */
        else
        {
            /* A common symbol should be merged with other commons or
               defs with the same name.  In particular, a common ought
               to be overridden by a def in a -flto object.  In that
               sense a common is also a ref.  */
            if (bfd_is_com_section (section))
                h->non_ir_ref = TRUE;

            /* Ensure any symbol defined in an IR dummy BFD takes on a
               new value from a real BFD.  Weak symbols are not normally
               overridden by a new weak definition, and strong symbols
               will normally cause multiple definition errors.  Avoid
               this by making the symbol appear to be undefined.  */
            if (((h->type == bfd_link_hash_defweak
                    || h->type == bfd_link_hash_defined)
                    && is_ir_dummy_bfd (sym_bfd = h->u.def.section->owner))
                    || (h->type == bfd_link_hash_common
                        && is_ir_dummy_bfd (sym_bfd = h->u.c.p->section->owner)))
            {
                h->type = bfd_link_hash_undefweak;
                h->u.undef.abfd = sym_bfd;
            }
        }
    }

    /* Continue with cref/nocrossref/trace-sym processing.  */
    if (orig_h == NULL
            || orig_notice_all
            || (info->notice_hash != NULL
                && bfd_hash_lookup (info->notice_hash, orig_h->root.string,
                                    FALSE, FALSE) != NULL))
        return (*orig_callbacks->notice) (info, orig_h, inh,
                                          abfd, section, value, flags);
    return TRUE;
}
Beispiel #10
0
static void
NAME(lynx,swap_std_reloc_out) (bfd *abfd,
			       arelent *g,
			       struct reloc_std_external *natptr)
{
  int r_index;
  asymbol *sym = *(g->sym_ptr_ptr);
  int r_extern;
  unsigned int r_length;
  int r_pcrel;
  int r_baserel, r_jmptable, r_relative;
  asection *output_section = sym->section->output_section;

  PUT_WORD (abfd, g->address, natptr->r_address);

  r_length = g->howto->size;	/* Size as a power of two */
  r_pcrel = (int) g->howto->pc_relative;	/* Relative to PC? */
  /* r_baserel, r_jmptable, r_relative???  FIXME-soon */
  r_baserel = 0;
  r_jmptable = 0;
  r_relative = 0;

  /* name was clobbered by aout_write_syms to be symbol index */

  /* If this relocation is relative to a symbol then set the
     r_index to the symbols index, and the r_extern bit.

     Absolute symbols can come in in two ways, either as an offset
     from the abs section, or as a symbol which has an abs value.
     check for that here
  */

  if (bfd_is_com_section (output_section)
      || bfd_is_abs_section (output_section)
      || bfd_is_und_section (output_section))
    {
      if (bfd_abs_section_ptr->symbol == sym)
	{
	  /* Whoops, looked like an abs symbol, but is really an offset
	     from the abs section */
	  r_index = 0;
	  r_extern = 0;
	}
      else
	{
	  /* Fill in symbol */
	  r_extern = 1;
	  r_index = (*g->sym_ptr_ptr)->KEEPIT;
	}
    }
  else
    {
      /* Just an ordinary section */
      r_extern = 0;
      r_index = output_section->target_index;
    }

  /* now the fun stuff */
  if (bfd_header_big_endian (abfd))
    {
      natptr->r_index[0] = r_index >> 16;
      natptr->r_index[1] = r_index >> 8;
      natptr->r_index[2] = r_index;
      natptr->r_type[0] =
	(r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
	| (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
	| (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
	| (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
	| (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
	| (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
    }
  else
    {
bfd_reloc_status_type
pmbfd_perform_relocation(bfd *abfd, pmbfd_arelent *r, asymbol *psym, asection *input_section)
{
Elf32_Word     pc;
int64_t        val, msk;
int32_t        oval,nval;
int16_t        sval;
int8_t         bval;
int64_t        llim,ulim;
Elf32_Rela     *rela = &r->rela32;
uint8_t        type  = ELF32_R_TYPE(rela->r_info);
struct sparc_rel_desc *dsc;

	if ( R_SPARC_NONE == type ) {
		/* No-op; BFD uses a zero dst_mask... */
		return bfd_reloc_ok;
	}

	/* use R_SPARC_NONE as a dummy for 'unsupported' */
	dsc = type >= sizeof(sparc_rels) ? &sparc_rels[R_SPARC_NONE] : &sparc_rels[type];

	if ( 0 == dsc->nbytes ) {
		ERRPR("pmbfd_perform_relocation_sparc(): unsupported relocation type : %"PRIu8"\n", type);
		return bfd_reloc_notsupported;
	}

	if ( bfd_is_und_section(bfd_get_section(psym)) )
		return bfd_reloc_undefined;

	pc  = bfd_get_section_vma(abfd, input_section) + rela->r_offset;

	if ( ! dsc->unaligned && (pc & (dsc->nbytes - 1)) ) {
		ERRPR("pmbfd_perform_relocation_sparc(): location to relocate (0x%08"PRIx32") not properly aligned\n", pc);
		return bfd_reloc_other;
	}

	val = (int64_t)bfd_asymbol_value(psym) + (int64_t)rela->r_addend;

	if ( dsc->pc_relative )
		val -= (int64_t)pc;

	val >>= dsc->shift;

	/* works also if the left shift is 32 */
	msk = (1LL << dsc->width);
	msk--;

	switch ( dsc->sparc_rel_check ) {
		default:
		case sparc_rel_check_none: ulim = ~(1LL<<63);  llim = ~ulim; break;
		case sparc_rel_check_unsg: ulim = msk;         llim = 0;     break;
		case sparc_rel_check_bits: ulim = msk;         llim = ~ulim; break;
		case sparc_rel_check_sign: ulim = msk>>1;      llim = ~ulim; break;
	}

#if (DEBUG & DEBUG_RELOC)
	fprintf(stderr,"Relocating val: 0x%08"PRIx64", ulim: 0x%08"PRIx64", pc: 0x%08"PRIx32", sym: 0x%08lx\n",
		val, ulim, pc, bfd_asymbol_value(psym));
#endif

	if ( val < llim || val > ulim ) {
		return bfd_reloc_overflow;
	}

	if ( 1 == dsc->nbytes ) {
		memcpy(&bval, (void*)pc, sizeof(bval));
		oval = bval;
	} else if ( 2 == dsc->nbytes ) {
		memcpy(&sval, (void*)pc, sizeof(sval));
		oval = sval;
	} else {
		memcpy(&oval, (void*)pc, sizeof(oval));
	}

	nval = ( oval & ~msk ) | (val & msk);

	/* patch back */
	if ( 1 == dsc->nbytes ) {
		bval = nval;
		memcpy((void*)pc, &bval, sizeof(bval));
	} else if ( 2 == dsc->nbytes ) {
		sval = nval;
		memcpy((void*)pc, &sval, sizeof(sval));
	} else {
		memcpy((void*)pc, &nval, sizeof(nval));
	}

	return bfd_reloc_ok;
}
Beispiel #12
0
int
_bfd_vms_write_gsd (bfd *abfd, int objtype ATTRIBUTE_UNUSED)
{
  asection *section;
  asymbol *symbol;
  unsigned int symnum;
  int last_index = -1;
  char dummy_name[10];
  char *sname;
  flagword new_flags, old_flags;

#if defined(VMS_DEBUG) && VMS_DEBUG
  vms_debug (2, "vms_write_gsd (%p, %d)\n", abfd, objtype);
#endif

  /* Output sections.  */
  section = abfd->sections;
#if defined(VMS_DEBUG) && VMS_DEBUG
  vms_debug (3, "%d sections found\n", abfd->section_count);
#endif

  /* Egsd is quadword aligned.  */
  _bfd_vms_output_alignment (abfd, 8);

  _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
  _bfd_vms_output_long (abfd, 0);
  /* Prepare output for subrecords.  */
  _bfd_vms_output_push (abfd);

  while (section != 0)
    {
#if defined(VMS_DEBUG) && VMS_DEBUG
      vms_debug (3, "Section #%d %s, %d bytes\n", section->index, section->name, (int)section->size);
#endif

      /* 13 bytes egsd, max 31 chars name -> should be 44 bytes.  */
      if (_bfd_vms_output_check (abfd, 64) < 0)
	{
	  _bfd_vms_output_pop (abfd);
	  _bfd_vms_output_end (abfd);
	  _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
	  _bfd_vms_output_long (abfd, 0);
	  /* Prepare output for subrecords.  */
	  _bfd_vms_output_push (abfd);
	}

      /* Create dummy sections to keep consecutive indices.  */
      while (section->index - last_index > 1)
	{
#if defined(VMS_DEBUG) && VMS_DEBUG
	  vms_debug (3, "index %d, last %d\n", section->index, last_index);
#endif
	  _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
	  _bfd_vms_output_short (abfd, 0);
	  _bfd_vms_output_short (abfd, 0);
	  _bfd_vms_output_long (abfd, 0);
	  sprintf (dummy_name, ".DUMMY%02d", last_index);
	  _bfd_vms_output_counted (abfd, dummy_name);
	  _bfd_vms_output_flush (abfd);
	  last_index++;
	}

      /* Don't know if this is necessary for the linker but for now it keeps
	 vms_slurp_gsd happy  */
      sname = (char *)section->name;
      if (*sname == '.')
	{
	  sname++;
	  if ((*sname == 't') && (strcmp (sname, "text") == 0))
	    sname = PRIV (is_vax)?VAX_CODE_NAME:EVAX_CODE_NAME;
	  else if ((*sname == 'd') && (strcmp (sname, "data") == 0))
	    sname = PRIV (is_vax)?VAX_DATA_NAME:EVAX_DATA_NAME;
	  else if ((*sname == 'b') && (strcmp (sname, "bss") == 0))
	    sname = EVAX_BSS_NAME;
	  else if ((*sname == 'l') && (strcmp (sname, "link") == 0))
	    sname = EVAX_LINK_NAME;
	  else if ((*sname == 'r') && (strcmp (sname, "rdata") == 0))
	    sname = EVAX_READONLY_NAME;
	  else if ((*sname == 'l') && (strcmp (sname, "literal") == 0))
	    sname = EVAX_LITERAL_NAME;
	  else if ((*sname == 'c') && (strcmp (sname, "comm") == 0))
	    sname = EVAX_COMMON_NAME;
	  else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0))
	    sname = EVAX_LOCAL_NAME;
	}
      else
	sname = _bfd_vms_length_hash_symbol (abfd, sname, EOBJ_S_C_SECSIZ);

      _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
      _bfd_vms_output_short (abfd, section->alignment_power & 0xff);
      if (bfd_is_com_section (section))
	new_flags = (EGPS_S_V_OVR | EGPS_S_V_REL | EGPS_S_V_GBL | EGPS_S_V_RD | EGPS_S_V_WRT | EGPS_S_V_NOMOD | EGPS_S_V_COM);
      else
	new_flags = vms_esecflag_by_name (evax_section_flags, sname,
					  section->size > 0);

      _bfd_vms_output_short (abfd, new_flags);
      _bfd_vms_output_long (abfd, (unsigned long) section->size);
      _bfd_vms_output_counted (abfd, sname);
      _bfd_vms_output_flush (abfd);

      last_index = section->index;
      section = section->next;
    }

  /* Output symbols.  */
#if defined(VMS_DEBUG) && VMS_DEBUG
  vms_debug (3, "%d symbols found\n", abfd->symcount);
#endif

  bfd_set_start_address (abfd, (bfd_vma) -1);

  for (symnum = 0; symnum < abfd->symcount; symnum++)
    {
      char *hash;

      symbol = abfd->outsymbols[symnum];
      if (*(symbol->name) == '_')
	{
	  if (strcmp (symbol->name, "__main") == 0)
	    bfd_set_start_address (abfd, (bfd_vma)symbol->value);
	}
      old_flags = symbol->flags;

      if (old_flags & BSF_FILE)
	continue;

      if (((old_flags & (BSF_GLOBAL | BSF_WEAK)) == 0)	/* Not xdef...  */
	  && (!bfd_is_und_section (symbol->section)))	/* ...and not xref.  */
	continue;					/* Dont output.  */

      /* 13 bytes egsd, max 64 chars name -> should be 77 bytes.  */
      if (_bfd_vms_output_check (abfd, 80) < 0)
	{
	  _bfd_vms_output_pop (abfd);
	  _bfd_vms_output_end (abfd);
	  _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
	  _bfd_vms_output_long (abfd, 0);
	  /* Prepare output for subrecords.  */
	  _bfd_vms_output_push (abfd);
	}

      _bfd_vms_output_begin (abfd, EGSD_S_C_SYM, -1);

      /* Data type, alignment.  */
      _bfd_vms_output_short (abfd, 0);

      new_flags = 0;

      if (old_flags & BSF_WEAK)
	new_flags |= EGSY_S_V_WEAK;
      if (bfd_is_com_section (symbol->section))
	new_flags |= (EGSY_S_V_WEAK | EGSY_S_V_COMM);

      if (old_flags & BSF_FUNCTION)
	{
	  new_flags |= EGSY_S_V_NORM;
	  new_flags |= EGSY_S_V_REL;
	}
      if (old_flags & (BSF_GLOBAL | BSF_WEAK))
	{
	  new_flags |= EGSY_S_V_DEF;
	  if (!bfd_is_abs_section (symbol->section))
	    new_flags |= EGSY_S_V_REL;
	}
      _bfd_vms_output_short (abfd, new_flags);

      if (old_flags & (BSF_GLOBAL | BSF_WEAK))
	{
	  /* Symbol definition.  */
	  uquad code_address = 0;
	  unsigned long ca_psindx = 0;
	  unsigned long psindx;

	  if ((old_flags & BSF_FUNCTION) && symbol->udata.p != NULL)
	    {
	      code_address = ((asymbol *) (symbol->udata.p))->value;
	      ca_psindx = ((asymbol *) (symbol->udata.p))->section->index;
	    }
	  psindx = symbol->section->index;

	  _bfd_vms_output_quad (abfd, symbol->value);
	  _bfd_vms_output_quad (abfd, code_address);
	  _bfd_vms_output_long (abfd, ca_psindx);
	  _bfd_vms_output_long (abfd, psindx);
	}
      hash = _bfd_vms_length_hash_symbol (abfd, symbol->name, EOBJ_S_C_SYMSIZ);
      _bfd_vms_output_counted (abfd, hash);

      _bfd_vms_output_flush (abfd);

    }

  _bfd_vms_output_alignment (abfd, 8);
  _bfd_vms_output_pop (abfd);
  _bfd_vms_output_end (abfd);

  return 0;
}
Beispiel #13
0
/*
 * Implementation
 */
void
jit_init_debug(const char *progname)
{
#if DISASSEMBLER
    bfd_init();

    if (progname)
	disasm_bfd = bfd_openr(progname, NULL);
    if (disasm_bfd == NULL) {
#if defined(__linux__)
	disasm_bfd = bfd_openr("/proc/self/exe", NULL);
	if (disasm_bfd == NULL)
#endif
	    return;
    }
    bfd_check_format(disasm_bfd, bfd_object);
    bfd_check_format(disasm_bfd, bfd_archive);
    disasm_print = disassembler(disasm_bfd);
    assert(disasm_print);
    INIT_DISASSEMBLE_INFO(disasm_info, disasm_stream, fprintf);
#  if defined(__i386__) || defined(__x86_64__)
    disasm_info.arch = bfd_arch_i386;
#    if defined(__x86_64__)
#      if __WORDSIZE == 32
    disasm_info.mach = bfd_mach_x64_32;
#      else
    disasm_info.mach = bfd_mach_x86_64;
#      endif
#    else
    disasm_info.mach = bfd_mach_i386_i386;
#    endif
#  endif
#  if defined(__powerpc__)
    disasm_info.arch = bfd_arch_powerpc;
    disasm_info.mach = bfd_mach_ppc64;
#    if HAVE_DISASSEMBLE_INIT_FOR_TARGET
    disassemble_init_for_target(&disasm_info);
#    elif HAVE_DISASSEMBLE_INIT_POWERPC
    disassemble_init_powerpc(&disasm_info);
#    endif
#    if defined(__powerpc64__)
    disasm_info.disassembler_options = "64";
#    endif
#    if HAVE_DISASSEMBLE_INIT_FOR_TARGET
    disassemble_init_for_target(&disasm_info);
#    elif HAVE_DISASSEMBLE_INIT_POWERPC
    disassemble_init_powerpc(&disasm_info);
#    endif
#  endif
#  if defined(__sparc__)
    disasm_info.endian = disasm_info.display_endian = BFD_ENDIAN_BIG;
#  endif
#  if defined(__s390__) || defined(__s390x__)
    disasm_info.arch = bfd_arch_s390;
#    if __WORDSIZE == 32
    disasm_info.mach = bfd_mach_s390_31;
#    else
    disasm_info.mach = bfd_mach_s390_64;
#    endif
    disasm_info.endian = disasm_info.display_endian = BFD_ENDIAN_BIG;
    disasm_info.disassembler_options = "zarch";
#  endif
#  if defined(__alpha__)
    disasm_info.arch = bfd_arch_alpha;
    disasm_info.mach = bfd_mach_alpha_ev6;
#  endif
    disasm_info.print_address_func = disasm_print_address;

    if (bfd_get_file_flags(disasm_bfd) & HAS_SYMS) {
	asymbol		**in;
	asymbol		**out;
	asymbol		 *symbol;
	long		  offset;
	long		  sym_count;
	long		  dyn_count;
	long		  sym_storage;
	long		  dyn_storage;

	if ((sym_storage = bfd_get_symtab_upper_bound(disasm_bfd)) >= 0) {

	    if (bfd_get_file_flags(disasm_bfd) & DYNAMIC) {
		dyn_storage = bfd_get_dynamic_symtab_upper_bound(disasm_bfd);
#  if defined(__alpha__)
		/* XXX */
		if (dyn_storage < 0)
		    dyn_storage = 0;
#  else
		assert(dyn_storage >= 0);
#  endif
	    }
	    else
		dyn_storage = 0;

	    jit_alloc((jit_pointer_t *)&disasm_symbols,
		      (sym_storage + dyn_storage) * sizeof(asymbol *));
	    sym_count = bfd_canonicalize_symtab(disasm_bfd, disasm_symbols);
	    assert(sym_count >= 0);
	    if (dyn_storage) {
		dyn_count = bfd_canonicalize_dynamic_symtab(disasm_bfd,
							    disasm_symbols +
							    sym_count);
		assert(dyn_count >= 0);
	    }
	    else
		dyn_count = 0;
	    disasm_num_symbols = sym_count + dyn_count;

	    disasm_num_synthetic = bfd_get_synthetic_symtab(disasm_bfd,
							    sym_count,
							    disasm_symbols,
							    dyn_count,
							    disasm_symbols +
							    sym_count,
							    &disasm_synthetic);
	    if (disasm_num_synthetic > 0) {
		jit_realloc((jit_pointer_t *)&disasm_symbols,
			    (sym_storage + dyn_storage) * sizeof(asymbol *),
			    (sym_storage + dyn_storage + disasm_num_synthetic) *
			    sizeof(asymbol *));
		for (offset = 0; offset < disasm_num_synthetic; offset++)
		    disasm_symbols[disasm_num_symbols++] =
			disasm_synthetic + offset;
	    }

	    /* remove symbols not useful for disassemble */
	    in = out = disasm_symbols;
	    for (offset = 0; offset < disasm_num_symbols; offset++) {
		symbol = *in++;
		if (symbol->name &&
		    symbol->name[0] != '\0' &&
		    !(symbol->flags & (BSF_DEBUGGING | BSF_SECTION_SYM)) &&
		    !bfd_is_und_section(symbol->section) &&
		    !bfd_is_com_section(symbol->section))
		    *out++ = symbol;
	    }
	    disasm_num_symbols = out - disasm_symbols;
	    qsort(disasm_symbols, disasm_num_symbols,
		  sizeof(asymbol *), disasm_compare_symbols);
	}
    }
#endif
}