OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [ld/] [plugin.c] - Diff between revs 157 and 163

Show entire file | Details | Blame | View Log

Rev 157 Rev 163
Line 114... Line 114...
  LDPT_REGISTER_CLEANUP_HOOK,
  LDPT_REGISTER_CLEANUP_HOOK,
  LDPT_ADD_SYMBOLS,
  LDPT_ADD_SYMBOLS,
  LDPT_GET_INPUT_FILE,
  LDPT_GET_INPUT_FILE,
  LDPT_RELEASE_INPUT_FILE,
  LDPT_RELEASE_INPUT_FILE,
  LDPT_GET_SYMBOLS,
  LDPT_GET_SYMBOLS,
 
  LDPT_GET_SYMBOLS_V2,
  LDPT_ADD_INPUT_FILE,
  LDPT_ADD_INPUT_FILE,
  LDPT_ADD_INPUT_LIBRARY,
  LDPT_ADD_INPUT_LIBRARY,
  LDPT_SET_EXTRA_LIBRARY_PATH
  LDPT_SET_EXTRA_LIBRARY_PATH
};
};
 
 
Line 439... Line 440...
}
}
 
 
/* Return TRUE if a defined symbol might be reachable from outside the
/* Return TRUE if a defined symbol might be reachable from outside the
   universe of claimed objects.  */
   universe of claimed objects.  */
static inline bfd_boolean
static inline bfd_boolean
is_visible_from_outside (struct ld_plugin_symbol *lsym, asection *section,
is_visible_from_outside (struct ld_plugin_symbol *lsym,
                         struct bfd_link_hash_entry *blhe)
                         struct bfd_link_hash_entry *blhe)
{
{
  struct bfd_sym_chain *sym;
  struct bfd_sym_chain *sym;
 
 
  /* Section's owner may be NULL if it is the absolute
 
     section, fortunately is_ir_dummy_bfd handles that.  */
 
  if (!is_ir_dummy_bfd (section->owner))
 
    return TRUE;
 
  if (link_info.relocatable)
  if (link_info.relocatable)
    return TRUE;
    return TRUE;
  if (link_info.export_dynamic || link_info.shared)
  if (link_info.export_dynamic || !link_info.executable)
    {
    {
 
      /* Check if symbol is hidden by version script.  */
 
      if (bfd_hide_sym_by_version (link_info.version_info,
 
                                   blhe->root.string))
 
        return FALSE;
      /* Only ELF symbols really have visibility.  */
      /* Only ELF symbols really have visibility.  */
      if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour)
      if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour)
        {
        {
          struct elf_link_hash_entry *el = (struct elf_link_hash_entry *)blhe;
          struct elf_link_hash_entry *el = (struct elf_link_hash_entry *)blhe;
          int vis = ELF_ST_VISIBILITY (el->other);
          int vis = ELF_ST_VISIBILITY (el->other);
Line 483... Line 484...
  return FALSE;
  return FALSE;
}
}
 
 
/* Get the symbol resolution info for a plugin-claimed input file.  */
/* Get the symbol resolution info for a plugin-claimed input file.  */
static enum ld_plugin_status
static enum ld_plugin_status
get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms)
get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms,
 
             int def_ironly_exp)
{
{
  const bfd *abfd = handle;
  const bfd *abfd = handle;
  int n;
  int n;
 
 
  ASSERT (called_plugin);
  ASSERT (called_plugin);
  for (n = 0; n < nsyms; n++)
  for (n = 0; n < nsyms; n++)
    {
    {
      struct bfd_link_hash_entry *blhe;
      struct bfd_link_hash_entry *blhe;
      bfd_boolean ironly;
 
      asection *owner_sec;
      asection *owner_sec;
 
      int res;
 
 
      if (syms[n].def != LDPK_UNDEF)
      if (syms[n].def != LDPK_UNDEF)
        blhe = bfd_link_hash_lookup (link_info.hash, syms[n].name,
        blhe = bfd_link_hash_lookup (link_info.hash, syms[n].name,
                                     FALSE, FALSE, TRUE);
                                     FALSE, FALSE, TRUE);
      else
      else
        blhe = bfd_wrapped_link_hash_lookup (link_info.output_bfd, &link_info,
        blhe = bfd_wrapped_link_hash_lookup (link_info.output_bfd, &link_info,
                                             syms[n].name, FALSE, FALSE, TRUE);
                                             syms[n].name, FALSE, FALSE, TRUE);
      if (!blhe)
      if (!blhe)
        {
        {
          syms[n].resolution = LDPR_UNKNOWN;
          res = LDPR_UNKNOWN;
          goto report_symbol;
          goto report_symbol;
        }
        }
 
 
      /* Determine resolution from blhe type and symbol's original type.  */
      /* Determine resolution from blhe type and symbol's original type.  */
      if (blhe->type == bfd_link_hash_undefined
      if (blhe->type == bfd_link_hash_undefined
          || blhe->type == bfd_link_hash_undefweak)
          || blhe->type == bfd_link_hash_undefweak)
        {
        {
          syms[n].resolution = LDPR_UNDEF;
          res = LDPR_UNDEF;
          goto report_symbol;
          goto report_symbol;
        }
        }
      if (blhe->type != bfd_link_hash_defined
      if (blhe->type != bfd_link_hash_defined
          && blhe->type != bfd_link_hash_defweak
          && blhe->type != bfd_link_hash_defweak
          && blhe->type != bfd_link_hash_common)
          && blhe->type != bfd_link_hash_common)
Line 528... Line 532...
         and weakdefs keep it in the same place. */
         and weakdefs keep it in the same place. */
      owner_sec = (blhe->type == bfd_link_hash_common
      owner_sec = (blhe->type == bfd_link_hash_common
                   ? blhe->u.c.p->section
                   ? blhe->u.c.p->section
                   : blhe->u.def.section);
                   : blhe->u.def.section);
 
 
      /* 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.  */
 
      ironly = !(blhe->non_ir_ref
 
                 || is_visible_from_outside (&syms[n], owner_sec, blhe));
 
 
 
      /* If it was originally undefined or common, then it has been
      /* If it was originally undefined or common, then it has been
         resolved; determine how.  */
         resolved; determine how.  */
      if (syms[n].def == LDPK_UNDEF
      if (syms[n].def == LDPK_UNDEF
          || syms[n].def == LDPK_WEAKUNDEF
          || syms[n].def == LDPK_WEAKUNDEF
          || syms[n].def == LDPK_COMMON)
          || syms[n].def == LDPK_COMMON)
        {
        {
          if (owner_sec->owner == link_info.output_bfd)
          if (owner_sec->owner == link_info.output_bfd)
            syms[n].resolution = LDPR_RESOLVED_EXEC;
            res = LDPR_RESOLVED_EXEC;
          else if (owner_sec->owner == abfd)
          else if (owner_sec->owner == abfd)
            syms[n].resolution = (ironly
            res = LDPR_PREVAILING_DEF_IRONLY;
                                  ? LDPR_PREVAILING_DEF_IRONLY
 
                                  : LDPR_PREVAILING_DEF);
 
          else if (is_ir_dummy_bfd (owner_sec->owner))
          else if (is_ir_dummy_bfd (owner_sec->owner))
            syms[n].resolution = LDPR_RESOLVED_IR;
            res = LDPR_RESOLVED_IR;
          else if (owner_sec->owner != NULL
          else if (owner_sec->owner != NULL
                   && (owner_sec->owner->flags & DYNAMIC) != 0)
                   && (owner_sec->owner->flags & DYNAMIC) != 0)
            syms[n].resolution =  LDPR_RESOLVED_DYN;
            res = LDPR_RESOLVED_DYN;
          else
          else
            syms[n].resolution = LDPR_RESOLVED_EXEC;
            res = LDPR_RESOLVED_EXEC;
          goto report_symbol;
 
        }
        }
 
 
      /* Was originally def, or weakdef.  Does it prevail?  If the
      /* Was originally def, or weakdef.  Does it prevail?  If the
         owner is the original dummy bfd that supplied it, then this
         owner is the original dummy bfd that supplied it, then this
         is the definition that has prevailed.  */
         is the definition that has prevailed.  */
      if (owner_sec->owner == link_info.output_bfd)
      else if (owner_sec->owner == link_info.output_bfd)
        syms[n].resolution = LDPR_PREEMPTED_REG;
        res = LDPR_PREEMPTED_REG;
      else if (owner_sec->owner == abfd)
      else if (owner_sec->owner == abfd)
        {
        res = LDPR_PREVAILING_DEF_IRONLY;
          syms[n].resolution = (ironly
 
                                ? LDPR_PREVAILING_DEF_IRONLY
 
                                : LDPR_PREVAILING_DEF);
 
          goto report_symbol;
 
        }
 
 
 
      /* Was originally def, weakdef, or common, but has been pre-empted.  */
      /* Was originally def, weakdef, or common, but has been pre-empted.  */
      syms[n].resolution = (is_ir_dummy_bfd (owner_sec->owner)
      else if (is_ir_dummy_bfd (owner_sec->owner))
                            ? LDPR_PREEMPTED_IR
        res = LDPR_PREEMPTED_IR;
                            : LDPR_PREEMPTED_REG);
      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:
    report_symbol:
 
      syms[n].resolution = res;
      if (report_plugin_symbols)
      if (report_plugin_symbols)
        einfo (_("%P: %B: symbol `%s' "
        einfo (_("%P: %B: symbol `%s' "
                 "definition: %d, visibility: %d, resolution: %d\n"),
                 "definition: %d, visibility: %d, resolution: %d\n"),
               abfd, syms[n].name,
               abfd, syms[n].name,
               syms[n].def, syms[n].visibility, syms[n].resolution);
               syms[n].def, syms[n].visibility, res);
    }
    }
  return LDPS_OK;
  return LDPS_OK;
}
}
 
 
 
static enum ld_plugin_status
 
get_symbols_v1 (const void *handle, int nsyms, struct ld_plugin_symbol *syms)
 
{
 
  return get_symbols (handle, nsyms, syms, LDPR_PREVAILING_DEF);
 
}
 
 
 
static enum ld_plugin_status
 
get_symbols_v2 (const void *handle, int nsyms, struct ld_plugin_symbol *syms)
 
{
 
  return get_symbols (handle, nsyms, syms, LDPR_PREVAILING_DEF_IRONLY_EXP);
 
}
 
 
/* Add a new (real) input file generated by a plugin.  */
/* Add a new (real) input file generated by a plugin.  */
static enum ld_plugin_status
static enum ld_plugin_status
add_input_file (const char *pathname)
add_input_file (const char *pathname)
{
{
  ASSERT (called_plugin);
  ASSERT (called_plugin);
Line 652... Line 668...
  va_end (args);
  va_end (args);
  return LDPS_OK;
  return LDPS_OK;
}
}
 
 
/* Helper to size leading part of tv array and set it up. */
/* Helper to size leading part of tv array and set it up. */
static size_t
static void
set_tv_header (struct ld_plugin_tv *tv)
set_tv_header (struct ld_plugin_tv *tv)
{
{
  size_t i;
  size_t i;
 
 
  /* Version info.  */
  /* Version info.  */
  static const unsigned int major = (unsigned)(BFD_VERSION / 100000000UL);
  static const unsigned int major = (unsigned)(BFD_VERSION / 100000000UL);
  static const unsigned int minor = (unsigned)(BFD_VERSION / 1000000UL) % 100;
  static const unsigned int minor = (unsigned)(BFD_VERSION / 1000000UL) % 100;
 
 
  if (!tv)
 
    return tv_header_size;
 
 
 
  for (i = 0; i < tv_header_size; i++)
  for (i = 0; i < tv_header_size; i++)
    {
    {
      tv[i].tv_tag = tv_header_tags[i];
      tv[i].tv_tag = tv_header_tags[i];
#define TVU(x) tv[i].tv_u.tv_ ## x
#define TVU(x) tv[i].tv_u.tv_ ## x
      switch (tv[i].tv_tag)
      switch (tv[i].tv_tag)
Line 682... Line 695...
          TVU(val) = major * 100 + minor;
          TVU(val) = major * 100 + minor;
          break;
          break;
        case LDPT_LINKER_OUTPUT:
        case LDPT_LINKER_OUTPUT:
          TVU(val) = (link_info.relocatable
          TVU(val) = (link_info.relocatable
                      ? LDPO_REL
                      ? LDPO_REL
                      : (link_info.shared ? LDPO_DYN : LDPO_EXEC));
                      : link_info.executable ? LDPO_EXEC : LDPO_DYN);
          break;
          break;
        case LDPT_OUTPUT_NAME:
        case LDPT_OUTPUT_NAME:
          TVU(string) = output_filename;
          TVU(string) = output_filename;
          break;
          break;
        case LDPT_REGISTER_CLAIM_FILE_HOOK:
        case LDPT_REGISTER_CLAIM_FILE_HOOK:
Line 706... Line 719...
          break;
          break;
        case LDPT_RELEASE_INPUT_FILE:
        case LDPT_RELEASE_INPUT_FILE:
          TVU(release_input_file) = release_input_file;
          TVU(release_input_file) = release_input_file;
          break;
          break;
        case LDPT_GET_SYMBOLS:
        case LDPT_GET_SYMBOLS:
          TVU(get_symbols) = get_symbols;
          TVU(get_symbols) = get_symbols_v1;
 
          break;
 
        case LDPT_GET_SYMBOLS_V2:
 
          TVU(get_symbols) = get_symbols_v2;
          break;
          break;
        case LDPT_ADD_INPUT_FILE:
        case LDPT_ADD_INPUT_FILE:
          TVU(add_input_file) = add_input_file;
          TVU(add_input_file) = add_input_file;
          break;
          break;
        case LDPT_ADD_INPUT_LIBRARY:
        case LDPT_ADD_INPUT_LIBRARY:
Line 724... Line 740...
             a new case to set up its value is a bug.  */
             a new case to set up its value is a bug.  */
          FAIL ();
          FAIL ();
        }
        }
#undef TVU
#undef TVU
    }
    }
  return tv_header_size;
 
}
}
 
 
/* Append the per-plugin args list and trailing LDPT_NULL to tv.  */
/* Append the per-plugin args list and trailing LDPT_NULL to tv.  */
static void
static void
set_tv_plugin_args (plugin_t *plugin, struct ld_plugin_tv *tv)
set_tv_plugin_args (plugin_t *plugin, struct ld_plugin_tv *tv)
Line 998... Line 1013...
    return (*orig_callbacks->notice) (info, h,
    return (*orig_callbacks->notice) (info, h,
                                      abfd, section, value, flags, string);
                                      abfd, section, value, flags, string);
  return TRUE;
  return TRUE;
}
}
 
 
 No newline at end of file
 No newline at end of file
 
/* Return true if bfd is a dynamic library that should be reloaded.  */
 
 
 
bfd_boolean
 
plugin_should_reload (bfd *abfd)
 
{
 
  return ((abfd->flags & DYNAMIC) != 0
 
          && bfd_get_flavour (abfd) == bfd_target_elf_flavour
 
          && bfd_get_format (abfd) == bfd_object
 
          && (elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0);
 
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.