Ejemplo n.º 1
0
	/*******************************************************
		Function: ld_slookup_mext

		Return pointer to ?? struct.
	 *******************************************************/
void *
ld_slookup_mext(char *name, bfd_boolean is_extern)
{
    bfd *abfd = p_current_bfd;
    struct elf_link_hash_entry *p_hash = NULL;

    if (!is_extern)
    	p_hash = elf_link_hash_lookup (  elf_hash_table (&link_info), 
    	    	    	    	    name, 
				    FALSE, 
				    FALSE, 
				    FALSE);
    else
    	p_hash = ((struct elf_link_hash_entry *)
    	    bfd_wrapped_link_hash_lookup(   abfd, 
    	    	    	    	    	    &link_info, 
					    name, 
					    FALSE, 
					    FALSE, 
					    FALSE));

    return p_hash;


}
Ejemplo n.º 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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
/* Get the symbol resolution info for a plugin-claimed input file.  */
static enum ld_plugin_status
get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms,
	     int def_ironly_exp)
{
  const bfd *abfd = handle;
  int n;

  ASSERT (called_plugin);
  for (n = 0; n < nsyms; n++)
    {
      struct bfd_link_hash_entry *blhe;
      asection *owner_sec;
      int res;

      if (syms[n].def != LDPK_UNDEF)
	blhe = bfd_link_hash_lookup (link_info.hash, syms[n].name,
				     FALSE, FALSE, TRUE);
      else
	blhe = bfd_wrapped_link_hash_lookup (link_info.output_bfd, &link_info,
					     syms[n].name, FALSE, FALSE, TRUE);
      if (!blhe)
	{
	  res = LDPR_UNKNOWN;
	  goto report_symbol;
	}

      /* Determine resolution from blhe type and symbol's original type.  */
      if (blhe->type == bfd_link_hash_undefined
	  || blhe->type == bfd_link_hash_undefweak)
	{
	  res = LDPR_UNDEF;
	  goto report_symbol;
	}
      if (blhe->type != bfd_link_hash_defined
	  && blhe->type != bfd_link_hash_defweak
	  && blhe->type != bfd_link_hash_common)
	{
	  /* We should not have a new, indirect or warning symbol here.  */
	  einfo ("%P%F: %s: plugin symbol table corrupt (sym type %d)\n",
		 called_plugin->name, blhe->type);
	}

      /* Find out which section owns the symbol.  Since it's not undef,
	 it must have an owner; if it's not a common symbol, both defs
	 and weakdefs keep it in the same place. */
      owner_sec = (blhe->type == bfd_link_hash_common
		   ? blhe->u.c.p->section
		   : blhe->u.def.section);


      /* If it was originally undefined or common, then it has been
	 resolved; determine how.  */
      if (syms[n].def == LDPK_UNDEF
	  || syms[n].def == LDPK_WEAKUNDEF
	  || syms[n].def == LDPK_COMMON)
	{
	  if (owner_sec->owner == link_info.output_bfd)
	    res = LDPR_RESOLVED_EXEC;
	  else if (owner_sec->owner == abfd)
	    res = LDPR_PREVAILING_DEF_IRONLY;
	  else if (is_ir_dummy_bfd (owner_sec->owner))
	    res = LDPR_RESOLVED_IR;
	  else if (owner_sec->owner != NULL
		   && (owner_sec->owner->flags & DYNAMIC) != 0)
	    res = LDPR_RESOLVED_DYN;
	  else
	    res = LDPR_RESOLVED_EXEC;
	}

      /* Was originally def, or weakdef.  Does it prevail?  If the
	 owner is the original dummy bfd that supplied it, then this
	 is the definition that has prevailed.  */
      else if (owner_sec->owner == link_info.output_bfd)
	res = LDPR_PREEMPTED_REG;
      else if (owner_sec->owner == abfd)
	res = LDPR_PREVAILING_DEF_IRONLY;

      /* Was originally def, weakdef, or common, but has been pre-empted.  */
      else if (is_ir_dummy_bfd (owner_sec->owner))
	res = LDPR_PREEMPTED_IR;
      else
	res = LDPR_PREEMPTED_REG;

      if (res == LDPR_PREVAILING_DEF_IRONLY)
	{
	  /* We need to know if the sym is referenced from non-IR files.  Or
	     even potentially-referenced, perhaps in a future final link if
	     this is a partial one, perhaps dynamically at load-time if the
	     symbol is externally visible.  */
	  if (blhe->non_ir_ref)
	    res = LDPR_PREVAILING_DEF;
	  else if (is_visible_from_outside (&syms[n], blhe))
	    res = def_ironly_exp;
	}

    report_symbol:
      syms[n].resolution = res;
      if (report_plugin_symbols)
	einfo (_("%P: %B: symbol `%s' "
		 "definition: %d, visibility: %d, resolution: %d\n"),
	       abfd, syms[n].name,
	       syms[n].def, syms[n].visibility, res);
    }
  return LDPS_OK;
}