Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Functions
genlink.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  generic_link_hash_entry
struct  generic_write_global_symbol_info

Defines

#define _bfd_generic_link_hash_lookup(table, string, create, copy, follow)
#define _bfd_generic_link_hash_traverse(table, func, info)
#define _bfd_generic_hash_table(p)   ((struct generic_link_hash_table *) ((p)->hash))
#define _bfd_generic_link_get_symbols(abfd)   ((abfd)->outsymbols)
#define _bfd_generic_link_get_symcount(abfd)   ((abfd)->symcount)

Functions

bfd_boolean _bfd_generic_link_output_symbols (bfd *, bfd *, struct bfd_link_info *, size_t *)
bfd_boolean _bfd_generic_link_write_global_symbol (struct generic_link_hash_entry *, void *)
struct bfd_hash_entry_bfd_generic_link_hash_newfunc (struct bfd_hash_entry *, struct bfd_hash_table *, const char *)

Class Documentation

struct generic_link_hash_entry

Definition at line 41 of file genlink.h.

Collaboration diagram for generic_link_hash_entry:
Class Members
asymbol * sym
bfd_boolean written
struct generic_link_hash_table

Definition at line 52 of file genlink.h.

struct generic_write_global_symbol_info

Definition at line 92 of file genlink.h.

Collaboration diagram for generic_write_global_symbol_info:
Class Members
struct bfd_link_info * info
bfd * output_bfd
size_t * psymalloc

Define Documentation

#define _bfd_generic_hash_table (   p)    ((struct generic_link_hash_table *) ((p)->hash))

Definition at line 74 of file genlink.h.

#define _bfd_generic_link_get_symbols (   abfd)    ((abfd)->outsymbols)

Definition at line 80 of file genlink.h.

Definition at line 81 of file genlink.h.

#define _bfd_generic_link_hash_lookup (   table,
  string,
  create,
  copy,
  follow 
)
Value:
((struct generic_link_hash_entry *) \
   bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow)))

Definition at line 59 of file genlink.h.

#define _bfd_generic_link_hash_traverse (   table,
  func,
  info 
)
Value:
(bfd_link_hash_traverse                                        \
   (&(table)->root,                                            \
    (bfd_boolean (*) (struct bfd_link_hash_entry *, void *)) (func),  \
    (info)))

Definition at line 65 of file genlink.h.


Function Documentation

Definition at line 672 of file linker.c.

{
  /* Allocate the structure if it has not already been allocated by a
     subclass.  */
  if (entry == NULL)
    {
      entry =
       bfd_hash_allocate (table, sizeof (struct generic_link_hash_entry));
      if (entry == NULL)
       return entry;
    }

  /* Call the allocation method of the superclass.  */
  entry = _bfd_link_hash_newfunc (entry, table, string);
  if (entry)
    {
      struct generic_link_hash_entry *ret;

      /* Set local fields.  */
      ret = (struct generic_link_hash_entry *) entry;
      ret->written = FALSE;
      ret->sym = NULL;
    }

  return entry;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2156 of file linker.c.

{
  asymbol **sym_ptr;
  asymbol **sym_end;

  if (! generic_link_read_symbols (input_bfd))
    return FALSE;

  /* Create a filename symbol if we are supposed to.  */
  if (info->create_object_symbols_section != NULL)
    {
      asection *sec;

      for (sec = input_bfd->sections; sec != NULL; sec = sec->next)
       {
         if (sec->output_section == info->create_object_symbols_section)
           {
             asymbol *newsym;

             newsym = bfd_make_empty_symbol (input_bfd);
             if (!newsym)
              return FALSE;
             newsym->name = input_bfd->filename;
             newsym->value = 0;
             newsym->flags = BSF_LOCAL | BSF_FILE;
             newsym->section = sec;

             if (! generic_add_output_symbol (output_bfd, psymalloc,
                                          newsym))
              return FALSE;

             break;
           }
       }
    }

  /* Adjust the values of the globally visible symbols, and write out
     local symbols.  */
  sym_ptr = _bfd_generic_link_get_symbols (input_bfd);
  sym_end = sym_ptr + _bfd_generic_link_get_symcount (input_bfd);
  for (; sym_ptr < sym_end; sym_ptr++)
    {
      asymbol *sym;
      struct generic_link_hash_entry *h;
      bfd_boolean output;

      h = NULL;
      sym = *sym_ptr;
      if ((sym->flags & (BSF_INDIRECT
                      | BSF_WARNING
                      | BSF_GLOBAL
                      | BSF_CONSTRUCTOR
                      | BSF_WEAK)) != 0
         || bfd_is_und_section (bfd_get_section (sym))
         || bfd_is_com_section (bfd_get_section (sym))
         || bfd_is_ind_section (bfd_get_section (sym)))
       {
         if (sym->udata.p != NULL)
           h = sym->udata.p;
         else if ((sym->flags & BSF_CONSTRUCTOR) != 0)
           {
             /* This case normally means that the main linker code
                 deliberately ignored this constructor symbol.  We
                 should just pass it through.  This will screw up if
                 the constructor symbol is from a different,
                 non-generic, object file format, but the case will
                 only arise when linking with -r, which will probably
                 fail anyhow, since there will be no way to represent
                 the relocs in the output format being used.  */
             h = NULL;
           }
         else if (bfd_is_und_section (bfd_get_section (sym)))
           h = ((struct generic_link_hash_entry *)
               bfd_wrapped_link_hash_lookup (output_bfd, info,
                                          bfd_asymbol_name (sym),
                                          FALSE, FALSE, TRUE));
         else
           h = _bfd_generic_link_hash_lookup (_bfd_generic_hash_table (info),
                                          bfd_asymbol_name (sym),
                                          FALSE, FALSE, TRUE);

         if (h != NULL)
           {
             /* Force all references to this symbol to point to
               the same area in memory.  It is possible that
               this routine will be called with a hash table
               other than a generic hash table, so we double
               check that.  */
             if (info->hash->creator == input_bfd->xvec)
              {
                if (h->sym != NULL)
                  *sym_ptr = sym = h->sym;
              }

             switch (h->root.type)
              {
              default:
              case bfd_link_hash_new:
                abort ();
              case bfd_link_hash_undefined:
                break;
              case bfd_link_hash_undefweak:
                sym->flags |= BSF_WEAK;
                break;
              case bfd_link_hash_indirect:
                h = (struct generic_link_hash_entry *) h->root.u.i.link;
                /* fall through */
              case bfd_link_hash_defined:
                sym->flags |= BSF_GLOBAL;
                sym->flags &=~ BSF_CONSTRUCTOR;
                sym->value = h->root.u.def.value;
                sym->section = h->root.u.def.section;
                break;
              case bfd_link_hash_defweak:
                sym->flags |= BSF_WEAK;
                sym->flags &=~ BSF_CONSTRUCTOR;
                sym->value = h->root.u.def.value;
                sym->section = h->root.u.def.section;
                break;
              case bfd_link_hash_common:
                sym->value = h->root.u.c.size;
                sym->flags |= BSF_GLOBAL;
                if (! bfd_is_com_section (sym->section))
                  {
                    BFD_ASSERT (bfd_is_und_section (sym->section));
                    sym->section = bfd_com_section_ptr;
                  }
                /* We do not set the section of the symbol to
                   h->root.u.c.p->section.  That value was saved so
                   that we would know where to allocate the symbol
                   if it was defined.  In this case the type is
                   still bfd_link_hash_common, so we did not define
                   it, so we do not want to use that section.  */
                break;
              }
           }
       }

      /* This switch is straight from the old code in
        write_file_locals in ldsym.c.  */
      if (info->strip == strip_all
         || (info->strip == strip_some
             && bfd_hash_lookup (info->keep_hash, bfd_asymbol_name (sym),
                              FALSE, FALSE) == NULL))
       output = FALSE;
      else if ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
       {
         /* If this symbol is marked as occurring now, rather
            than at the end, output it now.  This is used for
            COFF C_EXT FCN symbols.  FIXME: There must be a
            better way.  */
         if (bfd_asymbol_bfd (sym) == input_bfd
             && (sym->flags & BSF_NOT_AT_END) != 0)
           output = TRUE;
         else
           output = FALSE;
       }
      else if (bfd_is_ind_section (sym->section))
       output = FALSE;
      else if ((sym->flags & BSF_DEBUGGING) != 0)
       {
         if (info->strip == strip_none)
           output = TRUE;
         else
           output = FALSE;
       }
      else if (bfd_is_und_section (sym->section)
              || bfd_is_com_section (sym->section))
       output = FALSE;
      else if ((sym->flags & BSF_LOCAL) != 0)
       {
         if ((sym->flags & BSF_WARNING) != 0)
           output = FALSE;
         else
           {
             switch (info->discard)
              {
              default:
              case discard_all:
                output = FALSE;
                break;
              case discard_sec_merge:
                output = TRUE;
                if (info->relocatable
                    || ! (sym->section->flags & SEC_MERGE))
                  break;
                /* FALLTHROUGH */
              case discard_l:
                if (bfd_is_local_label (input_bfd, sym))
                  output = FALSE;
                else
                  output = TRUE;
                break;
              case discard_none:
                output = TRUE;
                break;
              }
           }
       }
      else if ((sym->flags & BSF_CONSTRUCTOR))
       {
         if (info->strip != strip_all)
           output = TRUE;
         else
           output = FALSE;
       }
      else
       abort ();

      /* If this symbol is in a section which is not being included
        in the output file, then we don't want to output the
        symbol.  */
      if (!bfd_is_abs_section (sym->section)
         && bfd_section_removed_from_list (output_bfd,
                                       sym->section->output_section))
       output = FALSE;

      if (output)
       {
         if (! generic_add_output_symbol (output_bfd, psymalloc, sym))
           return FALSE;
         if (h != NULL)
           h->written = TRUE;
       }
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2453 of file linker.c.

{
  struct generic_write_global_symbol_info *wginfo = data;
  asymbol *sym;

  if (h->root.type == bfd_link_hash_warning)
    h = (struct generic_link_hash_entry *) h->root.u.i.link;

  if (h->written)
    return TRUE;

  h->written = TRUE;

  if (wginfo->info->strip == strip_all
      || (wginfo->info->strip == strip_some
         && bfd_hash_lookup (wginfo->info->keep_hash, h->root.root.string,
                           FALSE, FALSE) == NULL))
    return TRUE;

  if (h->sym != NULL)
    sym = h->sym;
  else
    {
      sym = bfd_make_empty_symbol (wginfo->output_bfd);
      if (!sym)
       return FALSE;
      sym->name = h->root.root.string;
      sym->flags = 0;
    }

  set_symbol_from_hash (sym, &h->root);

  sym->flags |= BSF_GLOBAL;

  if (! generic_add_output_symbol (wginfo->output_bfd, wginfo->psymalloc,
                               sym))
    {
      /* FIXME: No way to return failure.  */
      abort ();
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function: