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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [bfd/] [linker.c] - Diff between revs 157 and 225

Show entire file | Details | Blame | View Log

Rev 157 Rev 225
Line 1... Line 1...
/* linker.c -- BFD linker routines
/* linker.c -- BFD linker routines
   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
   2003, 2004, 2005, 2006, 2007, 2008
   2003, 2004, 2005, 2006, 2007, 2008, 2009
   Free Software Foundation, Inc.
   Free Software Foundation, Inc.
   Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support
   Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support
 
 
   This file is part of BFD, the Binary File Descriptor library.
   This file is part of BFD, the Binary File Descriptor library.
 
 
Line 442... Line 442...
{
{
  /* Allocate the structure if it has not already been allocated by a
  /* Allocate the structure if it has not already been allocated by a
     subclass.  */
     subclass.  */
  if (entry == NULL)
  if (entry == NULL)
    {
    {
      entry = bfd_hash_allocate (table, sizeof (struct bfd_link_hash_entry));
      entry = (struct bfd_hash_entry *)
 
          bfd_hash_allocate (table, sizeof (struct bfd_link_hash_entry));
      if (entry == NULL)
      if (entry == NULL)
        return entry;
        return entry;
    }
    }
 
 
  /* Call the allocation method of the superclass.  */
  /* Call the allocation method of the superclass.  */
Line 546... Line 547...
 
 
          /* This symbol is being wrapped.  We want to replace all
          /* This symbol is being wrapped.  We want to replace all
             references to SYM with references to __wrap_SYM.  */
             references to SYM with references to __wrap_SYM.  */
 
 
          amt = strlen (l) + sizeof WRAP + 1;
          amt = strlen (l) + sizeof WRAP + 1;
          n = bfd_malloc (amt);
          n = (char *) bfd_malloc (amt);
          if (n == NULL)
          if (n == NULL)
            return NULL;
            return NULL;
 
 
          n[0] = prefix;
          n[0] = prefix;
          n[1] = '\0';
          n[1] = '\0';
Line 577... Line 578...
          /* This is a reference to __real_SYM, where SYM is being
          /* This is a reference to __real_SYM, where SYM is being
             wrapped.  We want to replace all references to __real_SYM
             wrapped.  We want to replace all references to __real_SYM
             with references to SYM.  */
             with references to SYM.  */
 
 
          amt = strlen (l + sizeof REAL - 1) + 2;
          amt = strlen (l + sizeof REAL - 1) + 2;
          n = bfd_malloc (amt);
          n = (char *) bfd_malloc (amt);
          if (n == NULL)
          if (n == NULL)
            return NULL;
            return NULL;
 
 
          n[0] = prefix;
          n[0] = prefix;
          n[1] = '\0';
          n[1] = '\0';
Line 676... Line 677...
{
{
  /* Allocate the structure if it has not already been allocated by a
  /* Allocate the structure if it has not already been allocated by a
     subclass.  */
     subclass.  */
  if (entry == NULL)
  if (entry == NULL)
    {
    {
      entry =
      entry = (struct bfd_hash_entry *)
        bfd_hash_allocate (table, sizeof (struct generic_link_hash_entry));
        bfd_hash_allocate (table, sizeof (struct generic_link_hash_entry));
      if (entry == NULL)
      if (entry == NULL)
        return entry;
        return entry;
    }
    }
 
 
Line 705... Line 706...
_bfd_generic_link_hash_table_create (bfd *abfd)
_bfd_generic_link_hash_table_create (bfd *abfd)
{
{
  struct generic_link_hash_table *ret;
  struct generic_link_hash_table *ret;
  bfd_size_type amt = sizeof (struct generic_link_hash_table);
  bfd_size_type amt = sizeof (struct generic_link_hash_table);
 
 
  ret = bfd_malloc (amt);
  ret = (struct generic_link_hash_table *) bfd_malloc (amt);
  if (ret == NULL)
  if (ret == NULL)
    return NULL;
    return NULL;
  if (! _bfd_link_hash_table_init (&ret->root, abfd,
  if (! _bfd_link_hash_table_init (&ret->root, abfd,
                                   _bfd_generic_link_hash_newfunc,
                                   _bfd_generic_link_hash_newfunc,
                                   sizeof (struct generic_link_hash_entry)))
                                   sizeof (struct generic_link_hash_entry)))
Line 735... Line 736...
   around for the entire link to ensure that we only read them once.
   around for the entire link to ensure that we only read them once.
   If we read them multiple times, we might wind up with relocs and
   If we read them multiple times, we might wind up with relocs and
   the hash table pointing to different instances of the symbol
   the hash table pointing to different instances of the symbol
   structure.  */
   structure.  */
 
 
static bfd_boolean
bfd_boolean
generic_link_read_symbols (bfd *abfd)
bfd_generic_link_read_symbols (bfd *abfd)
{
{
  if (bfd_get_outsymbols (abfd) == NULL)
  if (bfd_get_outsymbols (abfd) == NULL)
    {
    {
      long symsize;
      long symsize;
      long symcount;
      long symcount;
 
 
      symsize = bfd_get_symtab_upper_bound (abfd);
      symsize = bfd_get_symtab_upper_bound (abfd);
      if (symsize < 0)
      if (symsize < 0)
        return FALSE;
        return FALSE;
      bfd_get_outsymbols (abfd) = bfd_alloc (abfd, symsize);
      bfd_get_outsymbols (abfd) = (struct bfd_symbol **) bfd_alloc (abfd,
 
                                                                    symsize);
      if (bfd_get_outsymbols (abfd) == NULL && symsize != 0)
      if (bfd_get_outsymbols (abfd) == NULL && symsize != 0)
        return FALSE;
        return FALSE;
      symcount = bfd_canonicalize_symtab (abfd, bfd_get_outsymbols (abfd));
      symcount = bfd_canonicalize_symtab (abfd, bfd_get_outsymbols (abfd));
      if (symcount < 0)
      if (symcount < 0)
        return FALSE;
        return FALSE;
Line 832... Line 834...
                                 bfd_boolean collect)
                                 bfd_boolean collect)
{
{
  bfd_size_type symcount;
  bfd_size_type symcount;
  struct bfd_symbol **outsyms;
  struct bfd_symbol **outsyms;
 
 
  if (! generic_link_read_symbols (abfd))
  if (!bfd_generic_link_read_symbols (abfd))
    return FALSE;
    return FALSE;
  symcount = _bfd_generic_link_get_symcount (abfd);
  symcount = _bfd_generic_link_get_symcount (abfd);
  outsyms = _bfd_generic_link_get_symbols (abfd);
  outsyms = _bfd_generic_link_get_symbols (abfd);
  return generic_link_add_symbol_list (abfd, info, symcount, outsyms, collect);
  return generic_link_add_symbol_list (abfd, info, symcount, outsyms, collect);
}
}
Line 878... Line 880...
  struct archive_hash_entry *ret = (struct archive_hash_entry *) entry;
  struct archive_hash_entry *ret = (struct archive_hash_entry *) entry;
 
 
  /* Allocate the structure if it has not already been allocated by a
  /* Allocate the structure if it has not already been allocated by a
     subclass.  */
     subclass.  */
  if (ret == NULL)
  if (ret == NULL)
    ret = bfd_hash_allocate (table, sizeof (struct archive_hash_entry));
    ret = (struct archive_hash_entry *)
 
        bfd_hash_allocate (table, sizeof (struct archive_hash_entry));
  if (ret == NULL)
  if (ret == NULL)
    return NULL;
    return NULL;
 
 
  /* Call the allocation method of the superclass.  */
  /* Call the allocation method of the superclass.  */
  ret = ((struct archive_hash_entry *)
  ret = ((struct archive_hash_entry *)
Line 1049... Line 1052...
          /* If we haven't found the exact symbol we're looking for,
          /* If we haven't found the exact symbol we're looking for,
             let's look for its import thunk */
             let's look for its import thunk */
          if (info->pei386_auto_import)
          if (info->pei386_auto_import)
            {
            {
              bfd_size_type amt = strlen (h->root.string) + 10;
              bfd_size_type amt = strlen (h->root.string) + 10;
              char *buf = bfd_malloc (amt);
              char *buf = (char *) bfd_malloc (amt);
              if (buf == NULL)
              if (buf == NULL)
                return FALSE;
                return FALSE;
 
 
              sprintf (buf, "__imp_%s", h->root.string);
              sprintf (buf, "__imp_%s", h->root.string);
              arh = archive_hash_lookup (&arsym_hash, buf, FALSE, FALSE);
              arh = archive_hash_lookup (&arsym_hash, buf, FALSE, FALSE);
Line 1162... Line 1165...
{
{
  asymbol **pp, **ppend;
  asymbol **pp, **ppend;
 
 
  *pneeded = FALSE;
  *pneeded = FALSE;
 
 
  if (! generic_link_read_symbols (abfd))
  if (!bfd_generic_link_read_symbols (abfd))
    return FALSE;
    return FALSE;
 
 
  pp = _bfd_generic_link_get_symbols (abfd);
  pp = _bfd_generic_link_get_symbols (abfd);
  ppend = pp + _bfd_generic_link_get_symcount (abfd);
  ppend = pp + _bfd_generic_link_get_symcount (abfd);
  for (; pp < ppend; pp++)
  for (; pp < ppend; pp++)
Line 1240... Line 1243...
             this function differently.  This symbol is already on the
             this function differently.  This symbol is already on the
             undefs list.  We add the section to a common section
             undefs list.  We add the section to a common section
             attached to symbfd to ensure that it is in a BFD which
             attached to symbfd to ensure that it is in a BFD which
             will be linked in.  */
             will be linked in.  */
          h->type = bfd_link_hash_common;
          h->type = bfd_link_hash_common;
          h->u.c.p =
          h->u.c.p = (struct bfd_link_hash_common_entry *)
            bfd_hash_allocate (&info->hash->table,
            bfd_hash_allocate (&info->hash->table,
                               sizeof (struct bfd_link_hash_common_entry));
                               sizeof (struct bfd_link_hash_common_entry));
          if (h->u.c.p == NULL)
          if (h->u.c.p == NULL)
            return FALSE;
            return FALSE;
 
 
Line 1689... Line 1692...
        case COM:
        case COM:
          /* We have found a common definition for a symbol.  */
          /* We have found a common definition for a symbol.  */
          if (h->type == bfd_link_hash_new)
          if (h->type == bfd_link_hash_new)
            bfd_link_add_undef (info->hash, h);
            bfd_link_add_undef (info->hash, h);
          h->type = bfd_link_hash_common;
          h->type = bfd_link_hash_common;
          h->u.c.p =
          h->u.c.p = (struct bfd_link_hash_common_entry *)
            bfd_hash_allocate (&info->hash->table,
            bfd_hash_allocate (&info->hash->table,
                               sizeof (struct bfd_link_hash_common_entry));
                               sizeof (struct bfd_link_hash_common_entry));
          if (h->u.c.p == NULL)
          if (h->u.c.p == NULL)
            return FALSE;
            return FALSE;
 
 
Line 1970... Line 1973...
            else
            else
              {
              {
                char *w;
                char *w;
                size_t len = strlen (string) + 1;
                size_t len = strlen (string) + 1;
 
 
                w = bfd_hash_allocate (&info->hash->table, len);
                w = (char *) bfd_hash_allocate (&info->hash->table, len);
                if (w == NULL)
                if (w == NULL)
                  return FALSE;
                  return FALSE;
                memcpy (w, string, len);
                memcpy (w, string, len);
                sub->u.i.warning = w;
                sub->u.i.warning = w;
              }
              }
Line 2057... Line 2060...
                  input_bfd = input_section->owner;
                  input_bfd = input_section->owner;
                  relsize = bfd_get_reloc_upper_bound (input_bfd,
                  relsize = bfd_get_reloc_upper_bound (input_bfd,
                                                       input_section);
                                                       input_section);
                  if (relsize < 0)
                  if (relsize < 0)
                    return FALSE;
                    return FALSE;
                  relocs = bfd_malloc (relsize);
                  relocs = (arelent **) bfd_malloc (relsize);
                  if (!relocs && relsize != 0)
                  if (!relocs && relsize != 0)
                    return FALSE;
                    return FALSE;
                  symbols = _bfd_generic_link_get_symbols (input_bfd);
                  symbols = _bfd_generic_link_get_symbols (input_bfd);
                  reloc_count = bfd_canonicalize_reloc (input_bfd,
                  reloc_count = bfd_canonicalize_reloc (input_bfd,
                                                        input_section,
                                                        input_section,
Line 2079... Line 2082...
            {
            {
              bfd_size_type amt;
              bfd_size_type amt;
 
 
              amt = o->reloc_count;
              amt = o->reloc_count;
              amt *= sizeof (arelent *);
              amt *= sizeof (arelent *);
              o->orelocation = bfd_alloc (abfd, amt);
              o->orelocation = (struct reloc_cache_entry **) bfd_alloc (abfd, amt);
              if (!o->orelocation)
              if (!o->orelocation)
                return FALSE;
                return FALSE;
              o->flags |= SEC_RELOC;
              o->flags |= SEC_RELOC;
              /* Reset the count so that it can be used as an index
              /* Reset the count so that it can be used as an index
                 when putting in the output relocs.  */
                 when putting in the output relocs.  */
Line 2133... Line 2136...
        *psymalloc = 124;
        *psymalloc = 124;
      else
      else
        *psymalloc *= 2;
        *psymalloc *= 2;
      amt = *psymalloc;
      amt = *psymalloc;
      amt *= sizeof (asymbol *);
      amt *= sizeof (asymbol *);
      newsyms = bfd_realloc (bfd_get_outsymbols (output_bfd), amt);
      newsyms = (asymbol **) bfd_realloc (bfd_get_outsymbols (output_bfd), amt);
      if (newsyms == NULL)
      if (newsyms == NULL)
        return FALSE;
        return FALSE;
      bfd_get_outsymbols (output_bfd) = newsyms;
      bfd_get_outsymbols (output_bfd) = newsyms;
    }
    }
 
 
Line 2157... Line 2160...
                                  size_t *psymalloc)
                                  size_t *psymalloc)
{
{
  asymbol **sym_ptr;
  asymbol **sym_ptr;
  asymbol **sym_end;
  asymbol **sym_end;
 
 
  if (! generic_link_read_symbols (input_bfd))
  if (!bfd_generic_link_read_symbols (input_bfd))
    return FALSE;
    return FALSE;
 
 
  /* Create a filename symbol if we are supposed to.  */
  /* Create a filename symbol if we are supposed to.  */
  if (info->create_object_symbols_section != NULL)
  if (info->create_object_symbols_section != NULL)
    {
    {
Line 2210... Line 2213...
          || bfd_is_und_section (bfd_get_section (sym))
          || bfd_is_und_section (bfd_get_section (sym))
          || bfd_is_com_section (bfd_get_section (sym))
          || bfd_is_com_section (bfd_get_section (sym))
          || bfd_is_ind_section (bfd_get_section (sym)))
          || bfd_is_ind_section (bfd_get_section (sym)))
        {
        {
          if (sym->udata.p != NULL)
          if (sym->udata.p != NULL)
            h = sym->udata.p;
            h = (struct generic_link_hash_entry *) sym->udata.p;
          else if ((sym->flags & BSF_CONSTRUCTOR) != 0)
          else if ((sym->flags & BSF_CONSTRUCTOR) != 0)
            {
            {
              /* This case normally means that the main linker code
              /* This case normally means that the main linker code
                 deliberately ignored this constructor symbol.  We
                 deliberately ignored this constructor symbol.  We
                 should just pass it through.  This will screw up if
                 should just pass it through.  This will screw up if
Line 2449... Line 2452...
 
 
bfd_boolean
bfd_boolean
_bfd_generic_link_write_global_symbol (struct generic_link_hash_entry *h,
_bfd_generic_link_write_global_symbol (struct generic_link_hash_entry *h,
                                       void *data)
                                       void *data)
{
{
  struct generic_write_global_symbol_info *wginfo = data;
  struct generic_write_global_symbol_info *wginfo =
 
      (struct generic_write_global_symbol_info *) data;
  asymbol *sym;
  asymbol *sym;
 
 
  if (h->root.type == bfd_link_hash_warning)
  if (h->root.type == bfd_link_hash_warning)
    h = (struct generic_link_hash_entry *) h->root.u.i.link;
    h = (struct generic_link_hash_entry *) h->root.u.i.link;
 
 
Line 2506... Line 2510...
  if (! info->relocatable)
  if (! info->relocatable)
    abort ();
    abort ();
  if (sec->orelocation == NULL)
  if (sec->orelocation == NULL)
    abort ();
    abort ();
 
 
  r = bfd_alloc (abfd, sizeof (arelent));
  r = (arelent *) bfd_alloc (abfd, sizeof (arelent));
  if (r == NULL)
  if (r == NULL)
    return FALSE;
    return FALSE;
 
 
  r->address = link_order->offset;
  r->address = link_order->offset;
  r->howto = bfd_reloc_type_lookup (abfd, link_order->u.reloc.p->reloc);
  r->howto = bfd_reloc_type_lookup (abfd, link_order->u.reloc.p->reloc);
Line 2554... Line 2558...
      bfd_byte *buf;
      bfd_byte *buf;
      bfd_boolean ok;
      bfd_boolean ok;
      file_ptr loc;
      file_ptr loc;
 
 
      size = bfd_get_reloc_size (r->howto);
      size = bfd_get_reloc_size (r->howto);
      buf = bfd_zmalloc (size);
      buf = (bfd_byte *) bfd_zmalloc (size);
      if (buf == NULL)
      if (buf == NULL)
        return FALSE;
        return FALSE;
      rstat = _bfd_relocate_contents (r->howto, abfd,
      rstat = _bfd_relocate_contents (r->howto, abfd,
                                      (bfd_vma) link_order->u.reloc.p->addend,
                                      (bfd_vma) link_order->u.reloc.p->addend,
                                      buf);
                                      buf);
Line 2602... Line 2606...
 
 
struct bfd_link_order *
struct bfd_link_order *
bfd_new_link_order (bfd *abfd, asection *section)
bfd_new_link_order (bfd *abfd, asection *section)
{
{
  bfd_size_type amt = sizeof (struct bfd_link_order);
  bfd_size_type amt = sizeof (struct bfd_link_order);
  struct bfd_link_order *new;
  struct bfd_link_order *new_lo;
 
 
  new = bfd_zalloc (abfd, amt);
  new_lo = (struct bfd_link_order *) bfd_zalloc (abfd, amt);
  if (!new)
  if (!new_lo)
    return NULL;
    return NULL;
 
 
  new->type = bfd_undefined_link_order;
  new_lo->type = bfd_undefined_link_order;
 
 
  if (section->map_tail.link_order != NULL)
  if (section->map_tail.link_order != NULL)
    section->map_tail.link_order->next = new;
    section->map_tail.link_order->next = new_lo;
  else
  else
    section->map_head.link_order = new;
    section->map_head.link_order = new_lo;
  section->map_tail.link_order = new;
  section->map_tail.link_order = new_lo;
 
 
  return new;
  return new_lo;
}
}
 
 
/* Default link order processing routine.  Note that we can not handle
/* Default link order processing routine.  Note that we can not handle
   the reloc_link_order types here, since they depend upon the details
   the reloc_link_order types here, since they depend upon the details
   of how the particular backends generates relocs.  */
   of how the particular backends generates relocs.  */
Line 2669... Line 2673...
  fill = link_order->u.data.contents;
  fill = link_order->u.data.contents;
  fill_size = link_order->u.data.size;
  fill_size = link_order->u.data.size;
  if (fill_size != 0 && fill_size < size)
  if (fill_size != 0 && fill_size < size)
    {
    {
      bfd_byte *p;
      bfd_byte *p;
      fill = bfd_malloc (size);
      fill = (bfd_byte *) bfd_malloc (size);
      if (fill == NULL)
      if (fill == NULL)
        return FALSE;
        return FALSE;
      p = fill;
      p = fill;
      if (fill_size == 1)
      if (fill_size == 1)
        memset (p, (int) link_order->u.data.contents[0], (size_t) size);
        memset (p, (int) link_order->u.data.contents[0], (size_t) size);
Line 2750... Line 2754...
 
 
      /* Get the canonical symbols.  The generic linker will always
      /* Get the canonical symbols.  The generic linker will always
         have retrieved them by this point, but we are being called by
         have retrieved them by this point, but we are being called by
         a specific linker, presumably because we are linking
         a specific linker, presumably because we are linking
         different types of object files together.  */
         different types of object files together.  */
      if (! generic_link_read_symbols (input_bfd))
      if (!bfd_generic_link_read_symbols (input_bfd))
        return FALSE;
        return FALSE;
 
 
      /* Since we have been called by a specific linker, rather than
      /* Since we have been called by a specific linker, rather than
         the generic linker, the values of the symbols will not be
         the generic linker, the values of the symbols will not be
         right.  They will be the values as seen in the input file,
         right.  They will be the values as seen in the input file,
Line 2779... Line 2783...
              || bfd_is_ind_section (bfd_get_section (sym)))
              || bfd_is_ind_section (bfd_get_section (sym)))
            {
            {
              /* sym->udata may have been set by
              /* sym->udata may have been set by
                 generic_link_add_symbol_list.  */
                 generic_link_add_symbol_list.  */
              if (sym->udata.p != NULL)
              if (sym->udata.p != NULL)
                h = sym->udata.p;
                h = (struct bfd_link_hash_entry *) sym->udata.p;
              else if (bfd_is_und_section (bfd_get_section (sym)))
              else if (bfd_is_und_section (bfd_get_section (sym)))
                h = bfd_wrapped_link_hash_lookup (output_bfd, info,
                h = bfd_wrapped_link_hash_lookup (output_bfd, info,
                                                  bfd_asymbol_name (sym),
                                                  bfd_asymbol_name (sym),
                                                  FALSE, FALSE, TRUE);
                                                  FALSE, FALSE, TRUE);
              else
              else
Line 2794... Line 2798...
                set_symbol_from_hash (sym, h);
                set_symbol_from_hash (sym, h);
            }
            }
        }
        }
    }
    }
 
 
 
  if ((output_section->flags & (SEC_GROUP | SEC_LINKER_CREATED)) == SEC_GROUP
 
      && input_section->size != 0)
 
    {
 
      /* Group section contents are set by bfd_elf_set_group_contents.  */
 
      if (!output_bfd->output_has_begun)
 
        {
 
          /* FIXME: This hack ensures bfd_elf_set_group_contents is called.  */
 
          if (!bfd_set_section_contents (output_bfd, output_section, "", 0, 1))
 
            goto error_return;
 
        }
 
      new_contents = output_section->contents;
 
      BFD_ASSERT (new_contents != NULL);
 
      BFD_ASSERT (input_section->output_offset == 0);
 
    }
 
  else
 
    {
  /* Get and relocate the section contents.  */
  /* Get and relocate the section contents.  */
  sec_size = (input_section->rawsize > input_section->size
  sec_size = (input_section->rawsize > input_section->size
              ? input_section->rawsize
              ? input_section->rawsize
              : input_section->size);
              : input_section->size);
  contents = bfd_malloc (sec_size);
      contents = (bfd_byte *) bfd_malloc (sec_size);
  if (contents == NULL && sec_size != 0)
  if (contents == NULL && sec_size != 0)
    goto error_return;
    goto error_return;
  new_contents = (bfd_get_relocated_section_contents
  new_contents = (bfd_get_relocated_section_contents
                  (output_bfd, info, link_order, contents, info->relocatable,
                      (output_bfd, info, link_order, contents,
 
                       info->relocatable,
                   _bfd_generic_link_get_symbols (input_bfd)));
                   _bfd_generic_link_get_symbols (input_bfd)));
  if (!new_contents)
  if (!new_contents)
    goto error_return;
    goto error_return;
 
    }
 
 
  /* Output the section contents.  */
  /* Output the section contents.  */
  loc = input_section->output_offset * bfd_octets_per_byte (output_bfd);
  loc = input_section->output_offset * bfd_octets_per_byte (output_bfd);
  if (! bfd_set_section_contents (output_bfd, output_section,
  if (! bfd_set_section_contents (output_bfd, output_section,
                                  new_contents, loc, input_section->size))
                                  new_contents, loc, input_section->size))
Line 2929... Line 2951...
{
{
  struct bfd_section_already_linked *l;
  struct bfd_section_already_linked *l;
 
 
  /* Allocate the memory from the same obstack as the hash table is
  /* Allocate the memory from the same obstack as the hash table is
     kept in.  */
     kept in.  */
  l = bfd_hash_allocate (&_bfd_section_already_linked_table, sizeof *l);
  l = (struct bfd_section_already_linked *)
 
      bfd_hash_allocate (&_bfd_section_already_linked_table, sizeof *l);
  if (l == NULL)
  if (l == NULL)
    return FALSE;
    return FALSE;
  l->sec = sec;
  l->sec = sec;
  l->next = already_linked_list->entry;
  l->next = already_linked_list->entry;
  already_linked_list->entry = l;
  already_linked_list->entry = l;
Line 2944... Line 2967...
already_linked_newfunc (struct bfd_hash_entry *entry ATTRIBUTE_UNUSED,
already_linked_newfunc (struct bfd_hash_entry *entry ATTRIBUTE_UNUSED,
                        struct bfd_hash_table *table,
                        struct bfd_hash_table *table,
                        const char *string ATTRIBUTE_UNUSED)
                        const char *string ATTRIBUTE_UNUSED)
{
{
  struct bfd_section_already_linked_hash_entry *ret =
  struct bfd_section_already_linked_hash_entry *ret =
 
    (struct bfd_section_already_linked_hash_entry *)
    bfd_hash_allocate (table, sizeof *ret);
    bfd_hash_allocate (table, sizeof *ret);
 
 
  if (ret == NULL)
  if (ret == NULL)
    return NULL;
    return NULL;
 
 
Line 3075... Line 3099...
        }
        }
    }
    }
 
 
  /* This is the first section with this name.  Record it.  */
  /* This is the first section with this name.  Record it.  */
  if (! bfd_section_already_linked_table_insert (already_linked_list, sec))
  if (! bfd_section_already_linked_table_insert (already_linked_list, sec))
    info->callbacks->einfo (_("%F%P: already_linked_table: %E"));
    info->callbacks->einfo (_("%F%P: already_linked_table: %E\n"));
}
}
 
 
/* Convert symbols in excluded output sections to use a kept section.  */
/* Convert symbols in excluded output sections to use a kept section.  */
 
 
static bfd_boolean
static bfd_boolean
Line 3129... Line 3153...
                op = bfd_abs_section_ptr;
                op = bfd_abs_section_ptr;
            }
            }
          else if (op == NULL)
          else if (op == NULL)
            op = op1;
            op = op1;
          else if (((op1->flags ^ op->flags)
          else if (((op1->flags ^ op->flags)
                    & (SEC_ALLOC | SEC_THREAD_LOCAL)) != 0)
                    & (SEC_ALLOC | SEC_THREAD_LOCAL | SEC_LOAD)) != 0)
            {
            {
              if (((op->flags ^ s->flags)
              if (((op->flags ^ s->flags)
                   & (SEC_ALLOC | SEC_THREAD_LOCAL)) != 0)
                   & (SEC_ALLOC | SEC_THREAD_LOCAL)) != 0
 
                  /* We prefer to choose a loaded section.  Section S
 
                     doesn't have SEC_LOAD set (it being excluded, that
 
                     part of the flag processing didn't happen) so we
 
                     can't compare that flag to those of OP and OP1.  */
 
                  || ((op1->flags & SEC_LOAD) != 0
 
                      && (op->flags & SEC_LOAD) == 0))
                op = op1;
                op = op1;
            }
            }
          else if (((op1->flags ^ op->flags) & SEC_READONLY) != 0)
          else if (((op1->flags ^ op->flags) & SEC_READONLY) != 0)
            {
            {
              if (((op->flags ^ s->flags) & SEC_READONLY) != 0)
              if (((op->flags ^ s->flags) & SEC_READONLY) != 0)
Line 3167... Line 3197...
_bfd_fix_excluded_sec_syms (bfd *obfd, struct bfd_link_info *info)
_bfd_fix_excluded_sec_syms (bfd *obfd, struct bfd_link_info *info)
{
{
  bfd_link_hash_traverse (info->hash, fix_syms, obfd);
  bfd_link_hash_traverse (info->hash, fix_syms, obfd);
}
}
 
 
 No newline at end of file
 No newline at end of file
 
/*
 
FUNCTION
 
        bfd_generic_define_common_symbol
 
 
 
SYNOPSIS
 
        bfd_boolean bfd_generic_define_common_symbol
 
          (bfd *output_bfd, struct bfd_link_info *info,
 
           struct bfd_link_hash_entry *h);
 
 
 
DESCRIPTION
 
        Convert common symbol @var{h} into a defined symbol.
 
        Return TRUE on success and FALSE on failure.
 
 
 
.#define bfd_define_common_symbol(output_bfd, info, h) \
 
.       BFD_SEND (output_bfd, _bfd_define_common_symbol, (output_bfd, info, h))
 
.
 
*/
 
 
 
bfd_boolean
 
bfd_generic_define_common_symbol (bfd *output_bfd,
 
                                  struct bfd_link_info *info ATTRIBUTE_UNUSED,
 
                                  struct bfd_link_hash_entry *h)
 
{
 
  unsigned int power_of_two;
 
  bfd_vma alignment, size;
 
  asection *section;
 
 
 
  BFD_ASSERT (h != NULL && h->type == bfd_link_hash_common);
 
 
 
  size = h->u.c.size;
 
  power_of_two = h->u.c.p->alignment_power;
 
  section = h->u.c.p->section;
 
 
 
  /* Increase the size of the section to align the common symbol.
 
     The alignment must be a power of two.  */
 
  alignment = bfd_octets_per_byte (output_bfd) << power_of_two;
 
  BFD_ASSERT (alignment != 0 && (alignment & -alignment) == alignment);
 
  section->size += alignment - 1;
 
  section->size &= -alignment;
 
 
 
  /* Adjust the section's overall alignment if necessary.  */
 
  if (power_of_two > section->alignment_power)
 
    section->alignment_power = power_of_two;
 
 
 
  /* Change the symbol from common to defined.  */
 
  h->type = bfd_link_hash_defined;
 
  h->u.def.section = section;
 
  h->u.def.value = section->size;
 
 
 
  /* Increase the size of the section.  */
 
  section->size += size;
 
 
 
  /* Make sure the section is allocated in memory, and make sure that
 
     it is no longer a common section.  */
 
  section->flags |= SEC_ALLOC;
 
  section->flags &= ~SEC_IS_COMMON;
 
  return TRUE;
 
}
 
 
 
/*
 
FUNCTION
 
        bfd_find_version_for_sym
 
 
 
SYNOPSIS
 
        struct bfd_elf_version_tree * bfd_find_version_for_sym
 
          (struct bfd_elf_version_tree *verdefs,
 
           const char *sym_name, bfd_boolean *hide);
 
 
 
DESCRIPTION
 
        Search an elf version script tree for symbol versioning
 
        info and export / don't-export status for a given symbol.
 
        Return non-NULL on success and NULL on failure; also sets
 
        the output @samp{hide} boolean parameter.
 
 
 
*/
 
 
 
struct bfd_elf_version_tree *
 
bfd_find_version_for_sym (struct bfd_elf_version_tree *verdefs,
 
                          const char *sym_name,
 
                          bfd_boolean *hide)
 
{
 
  struct bfd_elf_version_tree *t;
 
  struct bfd_elf_version_tree *local_ver, *global_ver, *exist_ver;
 
  struct bfd_elf_version_tree *star_local_ver, *star_global_ver;
 
 
 
  local_ver = NULL;
 
  global_ver = NULL;
 
  star_local_ver = NULL;
 
  star_global_ver = NULL;
 
  exist_ver = NULL;
 
  for (t = verdefs; t != NULL; t = t->next)
 
    {
 
      if (t->globals.list != NULL)
 
        {
 
          struct bfd_elf_version_expr *d = NULL;
 
 
 
          while ((d = (*t->match) (&t->globals, d, sym_name)) != NULL)
 
            {
 
              if (d->literal || strcmp (d->pattern, "*") != 0)
 
                global_ver = t;
 
              else
 
                star_global_ver = t;
 
              if (d->symver)
 
                exist_ver = t;
 
              d->script = 1;
 
              /* If the match is a wildcard pattern, keep looking for
 
                 a more explicit, perhaps even local, match.  */
 
              if (d->literal)
 
                break;
 
            }
 
 
 
          if (d != NULL)
 
            break;
 
        }
 
 
 
      if (t->locals.list != NULL)
 
        {
 
          struct bfd_elf_version_expr *d = NULL;
 
 
 
          while ((d = (*t->match) (&t->locals, d, sym_name)) != NULL)
 
            {
 
              if (d->literal || strcmp (d->pattern, "*") != 0)
 
                local_ver = t;
 
              else
 
                star_local_ver = t;
 
              /* If the match is a wildcard pattern, keep looking for
 
                 a more explicit, perhaps even global, match.  */
 
              if (d->literal)
 
                {
 
                  /* An exact match overrides a global wildcard.  */
 
                  global_ver = NULL;
 
                  star_global_ver = NULL;
 
                  break;
 
                }
 
            }
 
 
 
          if (d != NULL)
 
            break;
 
        }
 
    }
 
 
 
  if (global_ver == NULL && local_ver == NULL)
 
    global_ver = star_global_ver;
 
 
 
  if (global_ver != NULL)
 
    {
 
      /* If we already have a versioned symbol that matches the
 
         node for this symbol, then we don't want to create a
 
         duplicate from the unversioned symbol.  Instead hide the
 
         unversioned symbol.  */
 
      *hide = exist_ver == global_ver;
 
      return global_ver;
 
    }
 
 
 
  if (local_ver == NULL)
 
    local_ver = star_local_ver;
 
 
 
  if (local_ver != NULL)
 
    {
 
      *hide = TRUE;
 
      return local_ver;
 
    }
 
 
 
  return NULL;
 
}
 
 
 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.