[BACK]Return to elf32-nios2.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils.old / dist / bfd

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/external/gpl3/binutils.old/dist/bfd/elf32-nios2.c between version 1.3 and 1.4

version 1.3, 2018/04/14 15:49:39 version 1.4, 2020/04/03 17:51:04
Line 1 
Line 1 
 /* 32-bit ELF support for Nios II.  /* 32-bit ELF support for Nios II.
    Copyright (C) 2012-2016 Free Software Foundation, Inc.     Copyright (C) 2012-2018 Free Software Foundation, Inc.
    Contributed by Nigel Gray (ngray@altera.com).     Contributed by Nigel Gray (ngray@altera.com).
    Contributed by Mentor Graphics, Inc.     Contributed by Mentor Graphics, Inc.
   
Line 31 
Line 31 
 #include "elf/nios2.h"  #include "elf/nios2.h"
 #include "opcode/nios2.h"  #include "opcode/nios2.h"
 #include "elf32-nios2.h"  #include "elf32-nios2.h"
   #include "libiberty.h"
   
 /* Use RELA relocations.  */  /* Use RELA relocations.  */
 #ifndef USE_RELA  #ifndef USE_RELA
Line 1400  static reloc_howto_type elf_nios2_r2_how
Line 1401  static reloc_howto_type elf_nios2_r2_how
          TRUE,           TRUE,
          6,           6,
          complain_overflow_signed,           complain_overflow_signed,
          bfd_elf_generic_reloc,         /* FIXME? */           bfd_elf_generic_reloc,         /* FIXME? */
          "R_NIOS2_R2_I10_1_PCREL",           "R_NIOS2_R2_I10_1_PCREL",
          FALSE,           FALSE,
          0xffc0,           0xffc0,
Line 1578  lookup_howto (unsigned int rtype, bfd *a
Line 1579  lookup_howto (unsigned int rtype, bfd *a
   int i;    int i;
   /* R2 relocations are a superset of R1, so use that for the lookup    /* R2 relocations are a superset of R1, so use that for the lookup
      table.  */       table.  */
   int r1_howto_tbl_size = (int) (sizeof (elf_nios2_r1_howto_table_rel)    int r1_howto_tbl_size = (int) ARRAY_SIZE (elf_nios2_r1_howto_table_rel);
                                  / sizeof (elf_nios2_r1_howto_table_rel[0]));    int r2_howto_tbl_size = (int) ARRAY_SIZE (elf_nios2_r2_howto_table_rel);
   int r2_howto_tbl_size = (int) (sizeof (elf_nios2_r2_howto_table_rel)  
                                  / sizeof (elf_nios2_r2_howto_table_rel[0]));  
   
   if (!initialized)    if (!initialized)
     {      {
Line 1597  lookup_howto (unsigned int rtype, bfd *a
Line 1596  lookup_howto (unsigned int rtype, bfd *a
         }          }
     }      }
   
   BFD_ASSERT (rtype <= R_NIOS2_ILLEGAL);    if (rtype > R_NIOS2_ILLEGAL)
       return NULL;
   i = elf_code_to_howto_index[rtype];    i = elf_code_to_howto_index[rtype];
   if (BFD_IS_R2 (abfd))    if (BFD_IS_R2 (abfd))
     {      {
       if (i >= r2_howto_tbl_size)        if (i >= r2_howto_tbl_size)
         return 0;          return NULL;
       return elf_nios2_r2_howto_table_rel + i;        return elf_nios2_r2_howto_table_rel + i;
     }      }
   else    else
     {      {
       if (i >= r1_howto_tbl_size)        if (i >= r1_howto_tbl_size)
         return 0;          return NULL;
       return elf_nios2_r1_howto_table_rel + i;        return elf_nios2_r1_howto_table_rel + i;
     }      }
 }  }
Line 1620  struct elf_reloc_map
Line 1620  struct elf_reloc_map
   enum elf_nios2_reloc_type elf_val;    enum elf_nios2_reloc_type elf_val;
 };  };
   
 static const struct elf_reloc_map nios2_reloc_map[] = {  static const struct elf_reloc_map nios2_reloc_map[] =
   {
   {BFD_RELOC_NONE, R_NIOS2_NONE},    {BFD_RELOC_NONE, R_NIOS2_NONE},
   {BFD_RELOC_NIOS2_S16, R_NIOS2_S16},    {BFD_RELOC_NIOS2_S16, R_NIOS2_S16},
   {BFD_RELOC_NIOS2_U16, R_NIOS2_U16},    {BFD_RELOC_NIOS2_U16, R_NIOS2_U16},
Line 1726  struct elf32_nios2_stub_hash_entry
Line 1727  struct elf32_nios2_stub_hash_entry
    bfd_hash_lookup ((table), (string), (create), (copy)))     bfd_hash_lookup ((table), (string), (create), (copy)))
   
   
 /* The Nios II linker needs to keep track of the number of relocs that it  
    decides to copy as dynamic relocs in check_relocs for each symbol.  
    This is so that it can later discard them if they are found to be  
    unnecessary.  We store the information in a field extending the  
    regular ELF linker hash table.  */  
   
 struct elf32_nios2_dyn_relocs  
 {  
   struct elf32_nios2_dyn_relocs *next;  
   
   /* The input section of the reloc.  */  
   asection *sec;  
   
   /* Total number of relocs copied for the input section.  */  
   bfd_size_type count;  
   
   /* Number of pc-relative relocs copied for the input section.  */  
   bfd_size_type pc_count;  
 };  
   
 /* Nios II ELF linker hash entry.  */  /* Nios II ELF linker hash entry.  */
   
 struct elf32_nios2_link_hash_entry  struct elf32_nios2_link_hash_entry
Line 1757  struct elf32_nios2_link_hash_entry
Line 1738  struct elf32_nios2_link_hash_entry
   struct elf32_nios2_stub_hash_entry *hsh_cache;    struct elf32_nios2_stub_hash_entry *hsh_cache;
   
   /* Track dynamic relocs copied for this symbol.  */    /* Track dynamic relocs copied for this symbol.  */
   struct elf32_nios2_dyn_relocs *dyn_relocs;    struct elf_dyn_relocs *dyn_relocs;
   
 #define GOT_UNKNOWN     0  #define GOT_UNKNOWN     0
 #define GOT_NORMAL      1  #define GOT_NORMAL      1
Line 1820  struct elf32_nios2_link_hash_table
Line 1801  struct elf32_nios2_link_hash_table
     Elf_Internal_Sym **all_local_syms;      Elf_Internal_Sym **all_local_syms;
   
     /* Short-cuts to get to dynamic linker sections.  */      /* Short-cuts to get to dynamic linker sections.  */
     asection *sdynbss;  
     asection *srelbss;  
     asection *sbss;      asection *sbss;
   
     /* GOT pointer symbol _gp_got.  */      /* GOT pointer symbol _gp_got.  */
Line 2225  nios2_add_stub (const char *stub_name,
Line 2204  nios2_add_stub (const char *stub_name,
                                 TRUE, FALSE);                                  TRUE, FALSE);
   if (hsh == NULL)    if (hsh == NULL)
     {      {
       (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),        /* xgettext:c-format */
                              section->owner,        _bfd_error_handler (_("%pB: cannot create stub entry %s"),
                              stub_name);                            section->owner,
                             stub_name);
       return NULL;        return NULL;
     }      }
   
Line 2916  nios2_elf32_build_stubs (struct bfd_link
Line 2896  nios2_elf32_build_stubs (struct bfd_link
    object file when linking.  */     object file when linking.  */
   
 static bfd_boolean  static bfd_boolean
 nios2_elf32_merge_private_bfd_data (bfd *ibfd, bfd *obfd)  nios2_elf32_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 {  {
     bfd *obfd = info->output_bfd;
   flagword old_flags;    flagword old_flags;
   flagword new_flags;    flagword new_flags;
   
Line 2925  nios2_elf32_merge_private_bfd_data (bfd 
Line 2906  nios2_elf32_merge_private_bfd_data (bfd 
     return TRUE;      return TRUE;
   
   /* Check if we have the same endianness.  */    /* Check if we have the same endianness.  */
   if (! _bfd_generic_verify_endian_match (ibfd, obfd))    if (! _bfd_generic_verify_endian_match (ibfd, info))
     return FALSE;      return FALSE;
   
   new_flags = elf_elfheader (ibfd)->e_flags;    new_flags = elf_elfheader (ibfd)->e_flags;
Line 2945  nios2_elf32_merge_private_bfd_data (bfd 
Line 2926  nios2_elf32_merge_private_bfd_data (bfd 
         case EF_NIOS2_ARCH_R2:          case EF_NIOS2_ARCH_R2:
           if (bfd_big_endian (ibfd))            if (bfd_big_endian (ibfd))
             {              {
               (*_bfd_error_handler)                _bfd_error_handler
                 (_("error: %B: Big-endian R2 is not supported."), ibfd);                  (_("error: %pB: big-endian R2 is not supported"), ibfd);
               bfd_set_error (bfd_error_bad_value);                bfd_set_error (bfd_error_bad_value);
               return FALSE;                return FALSE;
             }              }
Line 2960  nios2_elf32_merge_private_bfd_data (bfd 
Line 2941  nios2_elf32_merge_private_bfd_data (bfd 
     {      {
       /* So far, the only incompatible flags denote incompatible        /* So far, the only incompatible flags denote incompatible
          architectures.  */           architectures.  */
       (*_bfd_error_handler)        _bfd_error_handler
         (_("error: %B: Conflicting CPU architectures %d/%d"),          /* xgettext:c-format */
           (_("error: %pB: conflicting CPU architectures %d/%d"),
          ibfd, new_flags, old_flags);           ibfd, new_flags, old_flags);
       bfd_set_error (bfd_error_bad_value);        bfd_set_error (bfd_error_bad_value);
       return FALSE;        return FALSE;
     }      }
   
   /* Merge Tag_compatibility attributes and any common GNU ones.  */    /* Merge Tag_compatibility attributes and any common GNU ones.  */
   _bfd_elf_merge_object_attributes (ibfd, obfd);    _bfd_elf_merge_object_attributes (ibfd, info);
   
   return TRUE;    return TRUE;
 }  }
   
   
 /* Implement bfd_elf32_bfd_reloc_type_lookup:  /* Implement bfd_elf32_bfd_reloc_type_lookup:
    Given a BFD reloc type, return a howto structure.  */     Given a BFD reloc type, return a howto structure.  */
   
 static reloc_howto_type *  static reloc_howto_type *
 nios2_elf32_bfd_reloc_type_lookup (bfd *abfd,  nios2_elf32_bfd_reloc_type_lookup (bfd *abfd,
                                    bfd_reloc_code_real_type code)                                     bfd_reloc_code_real_type code)
 {  {
   int i;    int i;
   
   for (i = 0;    for (i = 0; i < (int) ARRAY_SIZE (nios2_reloc_map); ++i)
        i < (int) (sizeof (nios2_reloc_map) / sizeof (struct elf_reloc_map));  
        ++i)  
     if (nios2_reloc_map[i].bfd_val == code)      if (nios2_reloc_map[i].bfd_val == code)
       return lookup_howto (nios2_reloc_map[i].elf_val, abfd);        return lookup_howto (nios2_reloc_map[i].elf_val, abfd);
   return NULL;    return NULL;
Line 2992  nios2_elf32_bfd_reloc_type_lookup (bfd *
Line 2972  nios2_elf32_bfd_reloc_type_lookup (bfd *
   
 /* Implement bfd_elf32_bfd_reloc_name_lookup:  /* Implement bfd_elf32_bfd_reloc_name_lookup:
    Given a reloc name, return a howto structure.  */     Given a reloc name, return a howto structure.  */
   
 static reloc_howto_type *  static reloc_howto_type *
 nios2_elf32_bfd_reloc_name_lookup (bfd *abfd,  nios2_elf32_bfd_reloc_name_lookup (bfd *abfd,
                                    const char *r_name)                                     const char *r_name)
Line 3003  nios2_elf32_bfd_reloc_name_lookup (bfd *
Line 2984  nios2_elf32_bfd_reloc_name_lookup (bfd *
   if (BFD_IS_R2 (abfd))    if (BFD_IS_R2 (abfd))
     {      {
       howto_tbl = elf_nios2_r2_howto_table_rel;        howto_tbl = elf_nios2_r2_howto_table_rel;
       howto_tbl_size = (int) (sizeof (elf_nios2_r2_howto_table_rel)        howto_tbl_size = (int) ARRAY_SIZE (elf_nios2_r2_howto_table_rel);
                               / sizeof (elf_nios2_r2_howto_table_rel[0]));  
     }      }
   else    else
     {      {
       howto_tbl = elf_nios2_r1_howto_table_rel;        howto_tbl = elf_nios2_r1_howto_table_rel;
       howto_tbl_size = (int) (sizeof (elf_nios2_r1_howto_table_rel)        howto_tbl_size = (int) ARRAY_SIZE (elf_nios2_r1_howto_table_rel);
                               / sizeof (elf_nios2_r1_howto_table_rel[0]));  
     }      }
   
   for (i = 0; i < howto_tbl_size; i++)    for (i = 0; i < howto_tbl_size; i++)
     if (howto_tbl[i].name && strcasecmp (howto_tbl[i].name, r_name) == 0)      if (howto_tbl[i].name && strcasecmp (howto_tbl[i].name, r_name) == 0)
       return howto_tbl + i;        return howto_tbl + i;
   
   return NULL;    return NULL;
 }  }
   
 /* Implement elf_info_to_howto:  /* Implement elf_info_to_howto:
    Given a ELF32 relocation, fill in a arelent structure.  */     Given a ELF32 relocation, fill in a arelent structure.  */
 static void  
   static bfd_boolean
 nios2_elf32_info_to_howto (bfd *abfd, arelent *cache_ptr,  nios2_elf32_info_to_howto (bfd *abfd, arelent *cache_ptr,
                            Elf_Internal_Rela *dst)                             Elf_Internal_Rela *dst)
 {  {
   unsigned int r_type;    unsigned int r_type;
   
   r_type = ELF32_R_TYPE (dst->r_info);    r_type = ELF32_R_TYPE (dst->r_info);
   cache_ptr->howto = lookup_howto (r_type, abfd);    if ((cache_ptr->howto = lookup_howto (r_type, abfd)) == NULL)
       {
         /* xgettext:c-format */
         _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
                             abfd, r_type);
         bfd_set_error (bfd_error_bad_value);
         return FALSE;
       }
     return TRUE;
 }  }
   
 /* Return the base VMA address which should be subtracted from real addresses  /* Return the base VMA address which should be subtracted from real addresses
Line 3712  nios2_elf32_relocate_section (bfd *outpu
Line 3701  nios2_elf32_relocate_section (bfd *outpu
   splt = htab->root.splt;    splt = htab->root.splt;
   local_got_offsets = elf_local_got_offsets (input_bfd);    local_got_offsets = elf_local_got_offsets (input_bfd);
   
   if (elf32_nios2_hash_table (info)->h_gp_got == NULL)    if (htab->h_gp_got == NULL)
     got_base = 0;      got_base = 0;
   else    else
     got_base = elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value;      got_base = htab->h_gp_got->root.u.def.value;
   
   for (rel = relocs; rel < relend; rel++)    for (rel = relocs; rel < relend; rel++)
     {      {
Line 3771  nios2_elf32_relocate_section (bfd *outpu
Line 3760  nios2_elf32_relocate_section (bfd *outpu
   
       if (howto)        if (howto)
         {          {
             bfd_boolean resolved_to_zero;
   
             resolved_to_zero = (h != NULL
                                 && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
           switch (howto->type)            switch (howto->type)
             {              {
             case R_NIOS2_HI16:              case R_NIOS2_HI16:
Line 3845  nios2_elf32_relocate_section (bfd *outpu
Line 3838  nios2_elf32_relocate_section (bfd *outpu
                     {                      {
                       if (h)                        if (h)
                         name = h->root.root.string;                          name = h->root.root.string;
                       format = _("Unable to reach %s (at 0x%08x) from the "                        /* xgettext:c-format */
                         format = _("unable to reach %s (at 0x%08x) from the "
                                  "global pointer (at 0x%08x) because the "                                   "global pointer (at 0x%08x) because the "
                                  "offset (%d) is out of the allowed range, "                                   "offset (%d) is out of the allowed range, "
                                  "-32678 to 32767.\n" );                                   "-32678 to 32767\n" );
                       sprintf (msgbuf, format, name, symbol_address, gp,                        sprintf (msgbuf, format, name, symbol_address, gp,
                                (signed)relocation);                                 (signed)relocation);
                       msg = msgbuf;                        msg = msgbuf;
Line 3996  nios2_elf32_relocate_section (bfd *outpu
Line 3990  nios2_elf32_relocate_section (bfd *outpu
   
                   off = h->got.offset;                    off = h->got.offset;
                   BFD_ASSERT (off != (bfd_vma) -1);                    BFD_ASSERT (off != (bfd_vma) -1);
                   dyn = elf_hash_table (info)->dynamic_sections_created;                    dyn = htab->root.dynamic_sections_created;
                   if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,                    if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
                                                          bfd_link_pic (info),                                                           bfd_link_pic (info),
                                                          h)                                                           h)
                       || (bfd_link_pic (info)                        || (bfd_link_pic (info)
                           && SYMBOL_REFERENCES_LOCAL (info, h))                            && SYMBOL_REFERENCES_LOCAL (info, h))
                       || (ELF_ST_VISIBILITY (h->other)                        || ((ELF_ST_VISIBILITY (h->other)
                              || resolved_to_zero)
                           && h->root.type == bfd_link_hash_undefweak))                            && h->root.type == bfd_link_hash_undefweak))
                     {                      {
                       /* This is actually a static link, or it is a -Bsymbolic                        /* This is actually a static link, or it is a -Bsymbolic
Line 4256  nios2_elf32_relocate_section (bfd *outpu
Line 4251  nios2_elf32_relocate_section (bfd *outpu
   
                     if ((bfd_link_pic (info) || indx != 0)                      if ((bfd_link_pic (info) || indx != 0)
                         && (h == NULL                          && (h == NULL
                             || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT                              || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
                                   && !resolved_to_zero)
                             || h->root.type != bfd_link_hash_undefweak))                              || h->root.type != bfd_link_hash_undefweak))
                       {                        {
                         need_relocs = TRUE;                          need_relocs = TRUE;
Line 4365  nios2_elf32_relocate_section (bfd *outpu
Line 4361  nios2_elf32_relocate_section (bfd *outpu
             case R_NIOS2_TLS_LE16:              case R_NIOS2_TLS_LE16:
               if (bfd_link_dll (info))                if (bfd_link_dll (info))
                 {                  {
                   (*_bfd_error_handler)                    _bfd_error_handler
                     (_("%B(%A+0x%lx): R_NIOS2_TLS_LE16 relocation not "                      /* xgettext:c-format */
                       (_("%pB(%pA+%#" PRIx64 "): %s relocation not "
                        "permitted in shared object"),                         "permitted in shared object"),
                      input_bfd, input_section,                       input_bfd, input_section,
                      (long) rel->r_offset, howto->name);                       (uint64_t) rel->r_offset, howto->name);
                   return FALSE;                    return FALSE;
                 }                  }
               else                else
Line 4384  nios2_elf32_relocate_section (bfd *outpu
Line 4381  nios2_elf32_relocate_section (bfd *outpu
               if (bfd_link_pic (info)                if (bfd_link_pic (info)
                   && (input_section->flags & SEC_ALLOC) != 0                    && (input_section->flags & SEC_ALLOC) != 0
                   && (h == NULL                    && (h == NULL
                       || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT                        || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
                             && !resolved_to_zero)
                       || h->root.type != bfd_link_hash_undefweak))                        || h->root.type != bfd_link_hash_undefweak))
                 {                  {
                   Elf_Internal_Rela outrel;                    Elf_Internal_Rela outrel;
Line 4577  create_got_section (bfd *dynobj, struct 
Line 4575  create_got_section (bfd *dynobj, struct 
      points to the base of the GOT while _gp_got may include a bias.  */       points to the base of the GOT while _gp_got may include a bias.  */
   h = _bfd_elf_define_linkage_sym (dynobj, info, htab->root.sgotplt,    h = _bfd_elf_define_linkage_sym (dynobj, info, htab->root.sgotplt,
                                    "_gp_got");                                     "_gp_got");
   elf32_nios2_hash_table (info)->h_gp_got = h;    htab->h_gp_got = h;
   if (h == NULL)    if (h == NULL)
     return FALSE;      return FALSE;
   
Line 4597  nios2_elf32_create_dynamic_sections (bfd
Line 4595  nios2_elf32_create_dynamic_sections (bfd
   if (!htab->root.sgot && !create_got_section (dynobj, info))    if (!htab->root.sgot && !create_got_section (dynobj, info))
     return FALSE;      return FALSE;
   
   _bfd_elf_create_dynamic_sections (dynobj, info);    if (!_bfd_elf_create_dynamic_sections (dynobj, info))
       return FALSE;
   
   /* In order for the two loads in a shared object .PLTresolve to share the    /* In order for the two loads in a shared object .PLTresolve to share the
      same %hiadj, the start of the PLT (as well as the GOT) must be aligned       same %hiadj, the start of the PLT (as well as the GOT) must be aligned
      to a 16-byte boundary.  This is because the addresses for these loads       to a 16-byte boundary.  This is because the addresses for these loads
      include the -(.plt+4) PIC correction.  */       include the -(.plt+4) PIC correction.  */
   if (!bfd_set_section_alignment (dynobj, htab->root.splt, 4))    return bfd_set_section_alignment (dynobj, htab->root.splt, 4);
     return FALSE;  
   
   htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");  
   if (!htab->sdynbss)  
     return FALSE;  
   if (!bfd_link_pic (info))  
     {  
       htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");  
       if (!htab->srelbss)  
         return FALSE;  
     }  
   
   return TRUE;  
 }  }
   
 /* Implement elf_backend_copy_indirect_symbol:  /* Implement elf_backend_copy_indirect_symbol:
Line 4635  nios2_elf32_copy_indirect_symbol (struct
Line 4621  nios2_elf32_copy_indirect_symbol (struct
     {      {
       if (edir->dyn_relocs != NULL)        if (edir->dyn_relocs != NULL)
         {          {
           struct elf32_nios2_dyn_relocs **pp;            struct elf_dyn_relocs **pp;
           struct elf32_nios2_dyn_relocs *p;            struct elf_dyn_relocs *p;
   
           /* Add reloc counts against the indirect sym to the direct sym            /* Add reloc counts against the indirect sym to the direct sym
              list.  Merge any entries against the same section.  */               list.  Merge any entries against the same section.  */
           for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )            for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
             {              {
               struct elf32_nios2_dyn_relocs *q;                struct elf_dyn_relocs *q;
   
               for (q = edir->dyn_relocs; q != NULL; q = q->next)                for (q = edir->dyn_relocs; q != NULL; q = q->next)
                 if (q->sec == p->sec)                  if (q->sec == p->sec)
Line 4703  static bfd_boolean
Line 4689  static bfd_boolean
 nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,  nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
                           asection *sec, const Elf_Internal_Rela *relocs)                            asection *sec, const Elf_Internal_Rela *relocs)
 {  {
   bfd *dynobj;  
   Elf_Internal_Shdr *symtab_hdr;    Elf_Internal_Shdr *symtab_hdr;
   struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;    struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
   const Elf_Internal_Rela *rel;    const Elf_Internal_Rela *rel;
   const Elf_Internal_Rela *rel_end;    const Elf_Internal_Rela *rel_end;
   struct elf32_nios2_link_hash_table *htab;    struct elf32_nios2_link_hash_table *htab;
   asection *sgot;  
   asection *srelgot;  
   asection *sreloc = NULL;    asection *sreloc = NULL;
   bfd_signed_vma *local_got_refcounts;    bfd_signed_vma *local_got_refcounts;
   
   if (bfd_link_relocatable (info))    if (bfd_link_relocatable (info))
     return TRUE;      return TRUE;
   
   dynobj = elf_hash_table (info)->dynobj;  
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;    symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);    sym_hashes = elf_sym_hashes (abfd);
   sym_hashes_end = (sym_hashes    sym_hashes_end = (sym_hashes
Line 4727  nios2_elf32_check_relocs (bfd *abfd, str
Line 4709  nios2_elf32_check_relocs (bfd *abfd, str
   local_got_refcounts = elf_local_got_refcounts (abfd);    local_got_refcounts = elf_local_got_refcounts (abfd);
   
   htab = elf32_nios2_hash_table (info);    htab = elf32_nios2_hash_table (info);
   sgot = htab->root.sgot;  
   srelgot = htab->root.srelgot;  
   
   rel_end = relocs + sec->reloc_count;    rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)    for (rel = relocs; rel < rel_end; rel++)
Line 4746  nios2_elf32_check_relocs (bfd *abfd, str
Line 4726  nios2_elf32_check_relocs (bfd *abfd, str
           while (h->root.type == bfd_link_hash_indirect            while (h->root.type == bfd_link_hash_indirect
                  || h->root.type == bfd_link_hash_warning)                   || h->root.type == bfd_link_hash_warning)
             h = (struct elf_link_hash_entry *) h->root.u.i.link;              h = (struct elf_link_hash_entry *) h->root.u.i.link;
   
           /* PR15323, ref flags aren't set for references in the same  
              object.  */  
           h->root.non_ir_ref = 1;  
         }          }
   
       r_type = ELF32_R_TYPE (rel->r_info);        r_type = ELF32_R_TYPE (rel->r_info);
Line 4787  nios2_elf32_check_relocs (bfd *abfd, str
Line 4763  nios2_elf32_check_relocs (bfd *abfd, str
                 break;                  break;
               }                }
   
             if (dynobj == NULL)  
               {  
                 /* Create the .got section.  */  
                 elf_hash_table (info)->dynobj = dynobj = abfd;  
                 nios2_elf32_create_dynamic_sections (dynobj, info);  
               }  
   
             if (sgot == NULL)  
               {  
                 sgot = htab->root.sgot;  
                 BFD_ASSERT (sgot != NULL);  
               }  
   
             if (srelgot == NULL  
                 && (h != NULL || bfd_link_pic (info)))  
               {  
                 srelgot = htab->root.srelgot;  
                 BFD_ASSERT (srelgot != NULL);  
               }  
   
             if (h != NULL)              if (h != NULL)
               {                {
                 struct elf32_nios2_link_hash_entry *eh                  struct elf32_nios2_link_hash_entry *eh
Line 4865  nios2_elf32_check_relocs (bfd *abfd, str
Line 4821  nios2_elf32_check_relocs (bfd *abfd, str
                   elf32_nios2_local_got_tls_type (abfd) [r_symndx] = tls_type;                    elf32_nios2_local_got_tls_type (abfd) [r_symndx] = tls_type;
               }                }
           }            }
           /* Fall through */          make_got:
         case R_NIOS2_TLS_LDM16:  
           if (r_type == R_NIOS2_TLS_LDM16)  
             htab->tls_ldm_got.refcount++;  
   
           if (htab->root.sgot == NULL)            if (htab->root.sgot == NULL)
             {              {
               if (htab->root.dynobj == NULL)                if (htab->root.dynobj == NULL)
Line 4879  nios2_elf32_check_relocs (bfd *abfd, str
Line 4831  nios2_elf32_check_relocs (bfd *abfd, str
             }              }
           break;            break;
   
           case R_NIOS2_TLS_LDM16:
             htab->tls_ldm_got.refcount++;
             goto make_got;
   
           /* This relocation describes the C++ object vtable hierarchy.            /* This relocation describes the C++ object vtable hierarchy.
              Reconstruct it for later use during GC.  */               Reconstruct it for later use during GC.  */
         case R_NIOS2_GNU_VTINHERIT:          case R_NIOS2_GNU_VTINHERIT:
Line 4926  nios2_elf32_check_relocs (bfd *abfd, str
Line 4882  nios2_elf32_check_relocs (bfd *abfd, str
                   || (h != NULL && ! h->needs_plt                    || (h != NULL && ! h->needs_plt
                       && (! SYMBOLIC_BIND (info, h) || ! h->def_regular))))                        && (! SYMBOLIC_BIND (info, h) || ! h->def_regular))))
             {              {
               struct elf32_nios2_dyn_relocs *p;                struct elf_dyn_relocs *p;
               struct elf32_nios2_dyn_relocs **head;                struct elf_dyn_relocs **head;
   
               /* When creating a shared object, we must copy these                /* When creating a shared object, we must copy these
                  reloc types into the output file.  We create a reloc                   reloc types into the output file.  We create a reloc
                  section in dynobj and make room for this reloc.  */                   section in dynobj and make room for this reloc.  */
               if (sreloc == NULL)                if (sreloc == NULL)
                 {                  {
                     if (htab->root.dynobj == NULL)
                       htab->root.dynobj = abfd;
   
                   sreloc = _bfd_elf_make_dynamic_reloc_section                    sreloc = _bfd_elf_make_dynamic_reloc_section
                     (sec, dynobj, 2, abfd, TRUE);                      (sec, htab->root.dynobj, 2, abfd, TRUE);
                   if (sreloc == NULL)                    if (sreloc == NULL)
                     return FALSE;                      return FALSE;
                 }                  }
Line 4964  nios2_elf32_check_relocs (bfd *abfd, str
Line 4923  nios2_elf32_check_relocs (bfd *abfd, str
                     s = sec;                      s = sec;
   
                   vpp = &elf_section_data (s)->local_dynrel;                    vpp = &elf_section_data (s)->local_dynrel;
                   head = (struct elf32_nios2_dyn_relocs **) vpp;                    head = (struct elf_dyn_relocs **) vpp;
                 }                  }
   
               p = *head;                p = *head;
               if (p == NULL || p->sec != sec)                if (p == NULL || p->sec != sec)
                 {                  {
                   bfd_size_type amt = sizeof *p;                    bfd_size_type amt = sizeof *p;
                   p = ((struct elf32_nios2_dyn_relocs *)                    p = ((struct elf_dyn_relocs *)
                        bfd_alloc (htab->root.dynobj, amt));                         bfd_alloc (htab->root.dynobj, amt));
                   if (p == NULL)                    if (p == NULL)
                     return FALSE;                      return FALSE;
Line 5013  nios2_elf32_gc_mark_hook (asection *sec,
Line 4972  nios2_elf32_gc_mark_hook (asection *sec,
   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);    return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 }  }
   
 /* Implement elf_backend_gc_sweep_hook:  
    Update the got entry reference counts for the section being removed.  */  
 static bfd_boolean  
 nios2_elf32_gc_sweep_hook (bfd *abfd,  
                            struct bfd_link_info *info,  
                            asection *sec,  
                            const Elf_Internal_Rela *relocs)  
 {  
   Elf_Internal_Shdr *symtab_hdr;  
   struct elf_link_hash_entry **sym_hashes;  
   bfd_signed_vma *local_got_refcounts;  
   const Elf_Internal_Rela *rel, *relend;  
   bfd *dynobj;  
   
   if (bfd_link_relocatable (info))  
     return TRUE;  
   
   elf_section_data (sec)->local_dynrel = NULL;  
   
   dynobj = elf_hash_table (info)->dynobj;  
   if (dynobj == NULL)  
     return TRUE;  
   
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;  
   sym_hashes = elf_sym_hashes (abfd);  
   local_got_refcounts = elf_local_got_refcounts (abfd);  
   
   relend = relocs + sec->reloc_count;  
   for (rel = relocs; rel < relend; rel++)  
     {  
       unsigned long r_symndx;  
       struct elf_link_hash_entry *h = NULL;  
       int r_type;  
   
       r_symndx = ELF32_R_SYM (rel->r_info);  
       if (r_symndx >= symtab_hdr->sh_info)  
         {  
           h = sym_hashes[r_symndx - symtab_hdr->sh_info];  
           while (h->root.type == bfd_link_hash_indirect  
                  || h->root.type == bfd_link_hash_warning)  
             h = (struct elf_link_hash_entry *) h->root.u.i.link;  
         }  
   
       r_type = ELF32_R_TYPE (rel->r_info);  
       switch (r_type)  
         {  
         case R_NIOS2_GOT16:  
         case R_NIOS2_GOT_LO:  
         case R_NIOS2_GOT_HA:  
         case R_NIOS2_CALL16:  
         case R_NIOS2_CALL_LO:  
         case R_NIOS2_CALL_HA:  
           if (h != NULL)  
             {  
               if (h->got.refcount > 0)  
                 --h->got.refcount;  
             }  
           else if (local_got_refcounts != NULL)  
             {  
               if (local_got_refcounts[r_symndx] > 0)  
                 --local_got_refcounts[r_symndx];  
             }  
           break;  
   
         case R_NIOS2_PCREL_LO:  
         case R_NIOS2_PCREL_HA:  
         case R_NIOS2_BFD_RELOC_32:  
         case R_NIOS2_CALL26:  
         case R_NIOS2_CALL26_NOAT:  
           if (h != NULL)  
             {  
               struct elf32_nios2_link_hash_entry *eh;  
               struct elf32_nios2_dyn_relocs **pp;  
               struct elf32_nios2_dyn_relocs *p;  
   
               eh = (struct elf32_nios2_link_hash_entry *) h;  
   
               if (h->plt.refcount > 0)  
                 --h->plt.refcount;  
   
               if (r_type == R_NIOS2_PCREL_LO || r_type == R_NIOS2_PCREL_HA  
                   || r_type == R_NIOS2_BFD_RELOC_32)  
                 {  
                   for (pp = &eh->dyn_relocs; (p = *pp) != NULL;  
                        pp = &p->next)  
                     if (p->sec == sec)  
                       {  
                         p->count -= 1;  
                         if (p->count == 0)  
                           *pp = p->next;  
                         break;  
                       }  
                 }  
             }  
           break;  
   
         default:  
           break;  
         }  
     }  
   
   return TRUE;  
 }  
   
 /* Implement elf_backend_finish_dynamic_symbols:  /* Implement elf_backend_finish_dynamic_symbols:
    Finish up dynamic symbol handling.  We set the contents of various     Finish up dynamic symbol handling.  We set the contents of various
    dynamic sections here.  */     dynamic sections here.  */
Line 5284  nios2_elf32_finish_dynamic_symbol (bfd *
Line 5139  nios2_elf32_finish_dynamic_symbol (bfd *
                   && (h->root.type == bfd_link_hash_defined                    && (h->root.type == bfd_link_hash_defined
                       || h->root.type == bfd_link_hash_defweak));                        || h->root.type == bfd_link_hash_defweak));
   
       s = htab->srelbss;  
       BFD_ASSERT (s != NULL);  
   
       rela.r_offset = (h->root.u.def.value        rela.r_offset = (h->root.u.def.value
                        + h->root.u.def.section->output_section->vma                         + h->root.u.def.section->output_section->vma
                        + h->root.u.def.section->output_offset);                         + h->root.u.def.section->output_offset);
       rela.r_info = ELF32_R_INFO (h->dynindx, R_NIOS2_COPY);        rela.r_info = ELF32_R_INFO (h->dynindx, R_NIOS2_COPY);
       rela.r_addend = 0;        rela.r_addend = 0;
         if (h->root.u.def.section == htab->root.sdynrelro)
           s = htab->root.sreldynrelro;
         else
           s = htab->root.srelbss;
         BFD_ASSERT (s != NULL);
       loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);        loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);        bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
     }      }
   
   /* Mark _DYNAMIC, _GLOBAL_OFFSET_TABLE_, and _gp_got as absolute.  */    /* Mark _DYNAMIC, _GLOBAL_OFFSET_TABLE_, and _gp_got as absolute.  */
   if (strcmp (h->root.root.string, "_DYNAMIC") == 0    if (strcmp (h->root.root.string, "_DYNAMIC") == 0
       || h == elf_hash_table (info)->hgot        || h == htab->root.hgot
       || h == elf32_nios2_hash_table (info)->h_gp_got)        || h == htab->h_gp_got)
     sym->st_shndx = SHN_ABS;      sym->st_shndx = SHN_ABS;
   
   return TRUE;    return TRUE;
Line 5310  static bfd_boolean
Line 5167  static bfd_boolean
 nios2_elf32_finish_dynamic_sections (bfd *output_bfd,  nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
                                      struct bfd_link_info *info)                                       struct bfd_link_info *info)
 {  {
   bfd *dynobj;  
   asection *sgotplt;    asection *sgotplt;
   asection *sdyn;    asection *sdyn;
   struct elf32_nios2_link_hash_table *htab;    struct elf32_nios2_link_hash_table *htab;
   
   htab = elf32_nios2_hash_table (info);    htab = elf32_nios2_hash_table (info);
   dynobj = elf_hash_table (info)->dynobj;  
   sgotplt = htab->root.sgotplt;    sgotplt = htab->root.sgotplt;
   BFD_ASSERT (sgotplt != NULL);    sdyn = NULL;
   sdyn = bfd_get_linker_section (dynobj, ".dynamic");  
   
   if (elf_hash_table (info)->dynamic_sections_created)    if (htab->root.dynamic_sections_created)
     {      {
       asection *splt;        asection *splt;
       Elf32_External_Dyn *dyncon, *dynconend;        Elf32_External_Dyn *dyncon, *dynconend;
   
       splt = htab->root.splt;        splt = htab->root.splt;
       BFD_ASSERT (splt != NULL && sdyn != NULL);        sdyn = bfd_get_linker_section (htab->root.dynobj, ".dynamic");
         BFD_ASSERT (splt != NULL && sdyn != NULL && sgotplt != NULL);
   
       dyncon = (Elf32_External_Dyn *) sdyn->contents;        dyncon = (Elf32_External_Dyn *) sdyn->contents;
       dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);        dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
Line 5336  nios2_elf32_finish_dynamic_sections (bfd
Line 5191  nios2_elf32_finish_dynamic_sections (bfd
           Elf_Internal_Dyn dyn;            Elf_Internal_Dyn dyn;
           asection *s;            asection *s;
   
           bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);            bfd_elf32_swap_dyn_in (htab->root.dynobj, dyncon, &dyn);
   
           switch (dyn.d_tag)            switch (dyn.d_tag)
             {              {
Line 5361  nios2_elf32_finish_dynamic_sections (bfd
Line 5216  nios2_elf32_finish_dynamic_sections (bfd
               bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);                bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
               break;                break;
   
             case DT_RELASZ:  
               /* The procedure linkage table relocs (DT_JMPREL) should  
                  not be included in the overall relocs (DT_RELA).  
                  Therefore, we override the DT_RELASZ entry here to  
                  make it not include the JMPREL relocs.  Since the  
                  linker script arranges for .rela.plt to follow all  
                  other relocation sections, we don't have to worry  
                  about changing the DT_RELA entry.  */  
               s = htab->root.srelplt;  
               if (s != NULL)  
                 dyn.d_un.d_val -= s->size;  
               bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);  
               break;  
   
             case DT_NIOS2_GP:              case DT_NIOS2_GP:
               s = htab->root.sgotplt;                s = htab->root.sgotplt;
               dyn.d_un.d_ptr                dyn.d_un.d_ptr
Line 5434  nios2_elf32_finish_dynamic_sections (bfd
Line 5275  nios2_elf32_finish_dynamic_sections (bfd
             }              }
         }          }
     }      }
   
   /* Fill in the first three entries in the global offset table.  */    /* Fill in the first three entries in the global offset table.  */
   if (sgotplt->size > 0)    if (sgotplt != NULL && sgotplt->size > 0)
     {      {
       if (sdyn == NULL)        if (sdyn == NULL)
         bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents);          bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents);
Line 5445  nios2_elf32_finish_dynamic_sections (bfd
Line 5287  nios2_elf32_finish_dynamic_sections (bfd
                     sgotplt->contents);                      sgotplt->contents);
       bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 4);        bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 4);
       bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 8);        bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 8);
     }  
   
   elf_section_data (sgotplt->output_section)->this_hdr.sh_entsize = 4;        if (sgotplt->output_section != bfd_abs_section_ptr)
           elf_section_data (sgotplt->output_section)->this_hdr.sh_entsize = 4;
       }
   
   return TRUE;    return TRUE;
 }  }
Line 5464  nios2_elf32_adjust_dynamic_symbol (struc
Line 5307  nios2_elf32_adjust_dynamic_symbol (struc
 {  {
   struct elf32_nios2_link_hash_table *htab;    struct elf32_nios2_link_hash_table *htab;
   bfd *dynobj;    bfd *dynobj;
   asection *s;    asection *s, *srel;
   unsigned align2;    unsigned align2;
   
   htab = elf32_nios2_hash_table (info);    htab = elf32_nios2_hash_table (info);
   dynobj = elf_hash_table (info)->dynobj;    dynobj = htab->root.dynobj;
   
   /* Make sure we know what is going on here.  */    /* Make sure we know what is going on here.  */
   BFD_ASSERT (dynobj != NULL    BFD_ASSERT (dynobj != NULL
               && (h->needs_plt                && (h->needs_plt
                   || h->u.weakdef != NULL                    || h->is_weakalias
                   || (h->def_dynamic                    || (h->def_dynamic
                       && h->ref_regular                        && h->ref_regular
                       && !h->def_regular)));                        && !h->def_regular)));
Line 5507  nios2_elf32_adjust_dynamic_symbol (struc
Line 5350  nios2_elf32_adjust_dynamic_symbol (struc
   /* If this is a weak symbol, and there is a real definition, the    /* If this is a weak symbol, and there is a real definition, the
      processor independent code will have arranged for us to see the       processor independent code will have arranged for us to see the
      real definition first, and we can just use the same value.  */       real definition first, and we can just use the same value.  */
   if (h->u.weakdef != NULL)    if (h->is_weakalias)
     {      {
       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined        struct elf_link_hash_entry *def = weakdef (h);
                   || h->u.weakdef->root.type == bfd_link_hash_defweak);        BFD_ASSERT (def->root.type == bfd_link_hash_defined);
       h->root.u.def.section = h->u.weakdef->root.u.def.section;        h->root.u.def.section = def->root.u.def.section;
       h->root.u.def.value = h->u.weakdef->root.u.def.value;        h->root.u.def.value = def->root.u.def.value;
       return TRUE;        return TRUE;
     }      }
   
Line 5532  nios2_elf32_adjust_dynamic_symbol (struc
Line 5375  nios2_elf32_adjust_dynamic_symbol (struc
   
   if (h->size == 0)    if (h->size == 0)
     {      {
       (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"),        _bfd_error_handler (_("dynamic variable `%s' is zero size"),
                              h->root.root.string);                            h->root.root.string);
       return TRUE;        return TRUE;
     }      }
   
Line 5546  nios2_elf32_adjust_dynamic_symbol (struc
Line 5389  nios2_elf32_adjust_dynamic_symbol (struc
      determine the address it must put in the global offset table, so       determine the address it must put in the global offset table, so
      both the dynamic object and the regular object will refer to the       both the dynamic object and the regular object will refer to the
      same memory location for the variable.  */       same memory location for the variable.  */
   s = htab->sdynbss;  
   BFD_ASSERT (s != NULL);  
   
   /* We must generate a R_NIOS2_COPY reloc to tell the dynamic linker to    /* We must generate a R_NIOS2_COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the       copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the       runtime process image.  We need to remember the offset into the
      .rela.bss section we are going to use.  */       .rela.bss section we are going to use.  */
     if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
       {
         s = htab->root.sdynrelro;
         srel = htab->root.sreldynrelro;
       }
     else
       {
         s = htab->root.sdynbss;
         srel = htab->root.srelbss;
       }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)    if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
     {      {
       asection *srel;  
   
       srel = htab->srelbss;  
       BFD_ASSERT (srel != NULL);  
       srel->size += sizeof (Elf32_External_Rela);        srel->size += sizeof (Elf32_External_Rela);
       h->needs_copy = 1;        h->needs_copy = 1;
     }      }
Line 5619  allocate_dynrelocs (struct elf_link_hash
Line 5465  allocate_dynrelocs (struct elf_link_hash
   struct bfd_link_info *info;    struct bfd_link_info *info;
   struct elf32_nios2_link_hash_table *htab;    struct elf32_nios2_link_hash_table *htab;
   struct elf32_nios2_link_hash_entry *eh;    struct elf32_nios2_link_hash_entry *eh;
   struct elf32_nios2_dyn_relocs *p;    struct elf_dyn_relocs *p;
   int use_plt;    int use_plt;
   
   if (h->root.type == bfd_link_hash_indirect)    if (h->root.type == bfd_link_hash_indirect)
Line 5775  allocate_dynrelocs (struct elf_link_hash
Line 5621  allocate_dynrelocs (struct elf_link_hash
       if (h->def_regular        if (h->def_regular
           && (h->forced_local || SYMBOLIC_BIND (info, h)))            && (h->forced_local || SYMBOLIC_BIND (info, h)))
         {          {
           struct elf32_nios2_dyn_relocs **pp;            struct elf_dyn_relocs **pp;
   
           for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )            for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
             {              {
Line 5793  allocate_dynrelocs (struct elf_link_hash
Line 5639  allocate_dynrelocs (struct elf_link_hash
       if (eh->dyn_relocs != NULL        if (eh->dyn_relocs != NULL
           && h->root.type == bfd_link_hash_undefweak)            && h->root.type == bfd_link_hash_undefweak)
         {          {
           if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)            if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
                 || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
             eh->dyn_relocs = NULL;              eh->dyn_relocs = NULL;
   
           /* Make sure undefined weak symbols are output as a dynamic            /* Make sure undefined weak symbols are output as a dynamic
Line 5852  nios2_elf32_size_dynamic_sections (bfd *
Line 5699  nios2_elf32_size_dynamic_sections (bfd *
 {  {
   bfd *dynobj;    bfd *dynobj;
   asection *s;    asection *s;
   bfd_boolean plt;  
   bfd_boolean got;  
   bfd_boolean relocs;    bfd_boolean relocs;
   bfd *ibfd;    bfd *ibfd;
   struct elf32_nios2_link_hash_table *htab;    struct elf32_nios2_link_hash_table *htab;
   
   htab = elf32_nios2_hash_table (info);    htab = elf32_nios2_hash_table (info);
   dynobj = elf_hash_table (info)->dynobj;    dynobj = htab->root.dynobj;
   BFD_ASSERT (dynobj != NULL);    BFD_ASSERT (dynobj != NULL);
   
   htab->res_n_size = 0;    htab->res_n_size = 0;
   if (elf_hash_table (info)->dynamic_sections_created)    if (htab->root.dynamic_sections_created)
     {      {
       /* Set the contents of the .interp section to the interpreter.  */        /* Set the contents of the .interp section to the interpreter.  */
       if (bfd_link_executable (info) && !info->nointerp)        if (bfd_link_executable (info) && !info->nointerp)
Line 5902  nios2_elf32_size_dynamic_sections (bfd *
Line 5747  nios2_elf32_size_dynamic_sections (bfd *
   
       for (s = ibfd->sections; s != NULL; s = s->next)        for (s = ibfd->sections; s != NULL; s = s->next)
         {          {
           struct elf32_nios2_dyn_relocs *p;            struct elf_dyn_relocs *p;
   
           for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)            for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
             {              {
Line 5971  nios2_elf32_size_dynamic_sections (bfd *
Line 5816  nios2_elf32_size_dynamic_sections (bfd *
      sym dynamic relocs.  */       sym dynamic relocs.  */
   elf_link_hash_traverse (& htab->root, allocate_dynrelocs, info);    elf_link_hash_traverse (& htab->root, allocate_dynrelocs, info);
   
   if (elf_hash_table (info)->dynamic_sections_created)    if (htab->root.dynamic_sections_created)
     {      {
       /* If the .got section is more than 0x8000 bytes, we add        /* If the .got section is more than 0x8000 bytes, we add
          0x8000 to the value of _gp_got, so that 16-bit relocations           0x8000 to the value of _gp_got, so that 16-bit relocations
          have a greater chance of working. */           have a greater chance of working. */
       if (htab->root.sgot->size >= 0x8000        if (htab->root.sgot->size >= 0x8000
           && elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value == 0)            && htab->h_gp_got->root.u.def.value == 0)
         elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value = 0x8000;          htab->h_gp_got->root.u.def.value = 0x8000;
     }      }
   
   /* The check_relocs and adjust_dynamic_symbol entry points have    /* The check_relocs and adjust_dynamic_symbol entry points have
      determined the sizes of the various dynamic sections.  Allocate       determined the sizes of the various dynamic sections.  Allocate
      memory for them.  */       memory for them.  */
   plt = FALSE;  
   got = FALSE;  
   relocs = FALSE;    relocs = FALSE;
   for (s = dynobj->sections; s != NULL; s = s->next)    for (s = dynobj->sections; s != NULL; s = s->next)
     {      {
Line 5998  nios2_elf32_size_dynamic_sections (bfd *
Line 5841  nios2_elf32_size_dynamic_sections (bfd *
          of the dynobj section names depend upon the input files.  */           of the dynobj section names depend upon the input files.  */
       name = bfd_get_section_name (dynobj, s);        name = bfd_get_section_name (dynobj, s);
   
       if (strcmp (name, ".plt") == 0)        if (CONST_STRNEQ (name, ".rela"))
         {  
           /* Remember whether there is a PLT.  */  
           plt = s->size != 0;  
   
           /* Correct for the number of res_N branches.  */  
           if (plt && !bfd_link_pic (info))  
             {  
               htab->res_n_size = (s->size-28) / 3;  
               s->size += htab->res_n_size;  
             }  
         }  
       else if (CONST_STRNEQ (name, ".rela"))  
         {          {
           if (s->size != 0)            if (s->size != 0)
             {              {
               relocs = TRUE;                if (s != htab->root.srelplt)
                   relocs = TRUE;
   
               /* We use the reloc_count field as a counter if we need                /* We use the reloc_count field as a counter if we need
                  to copy relocs into the output file.  */                   to copy relocs into the output file.  */
               s->reloc_count = 0;                s->reloc_count = 0;
             }              }
         }          }
       else if (CONST_STRNEQ (name, ".got"))        else if (s == htab->root.splt)
         got = s->size != 0;          {
       else if (strcmp (name, ".dynbss") != 0)            /* Correct for the number of res_N branches.  */
             if (s->size != 0 && !bfd_link_pic (info))
               {
                 htab->res_n_size = (s->size - 28) / 3;
                 s->size += htab->res_n_size;
               }
           }
         else if (s != htab->sbss
                  && s != htab->root.sgot
                  && s != htab->root.sgotplt
                  && s != htab->root.sdynbss
                  && s != htab->root.sdynrelro)
         /* It's not one of our sections, so don't allocate space.  */          /* It's not one of our sections, so don't allocate space.  */
         continue;          continue;
   
       if (s->size == 0)        if (s->size == 0)
         {          {
           /* If we don't need this section, strip it from the  
              output file.  This is mostly to handle .rela.bss and  
              .rela.plt.  We must create both sections in  
              create_dynamic_sections, because they must be created  
              before the linker maps input sections to output  
              sections.  The linker does that before  
              adjust_dynamic_symbol is called, and it is that  
              function which decides whether anything needs to go  
              into these sections.  */  
           s->flags |= SEC_EXCLUDE;            s->flags |= SEC_EXCLUDE;
           continue;            continue;
         }          }
Line 6046  nios2_elf32_size_dynamic_sections (bfd *
Line 5880  nios2_elf32_size_dynamic_sections (bfd *
         continue;          continue;
   
       /* Allocate memory for the section contents.  */        /* Allocate memory for the section contents.  */
       /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.  
          Unused entries should be reclaimed before the section's contents  
          are written out, but at the moment this does not happen.  Thus in  
          order to prevent writing out garbage, we initialize the section's  
          contents to zero.  */  
       s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);        s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
       if (s->contents == NULL)        if (s->contents == NULL)
         return FALSE;          return FALSE;
Line 6061  nios2_elf32_size_dynamic_sections (bfd *
Line 5890  nios2_elf32_size_dynamic_sections (bfd *
   if (htab->res_n_size)    if (htab->res_n_size)
     elf_link_hash_traverse (& htab->root, adjust_dynrelocs, info);      elf_link_hash_traverse (& htab->root, adjust_dynrelocs, info);
   
   if (elf_hash_table (info)->dynamic_sections_created)    if (htab->root.dynamic_sections_created)
     {      {
       /* Add some entries to the .dynamic section.  We fill in the        /* Add some entries to the .dynamic section.  We fill in the
          values later, in elf_nios2_finish_dynamic_sections, but we           values later, in elf_nios2_finish_dynamic_sections, but we
Line 6074  nios2_elf32_size_dynamic_sections (bfd *
Line 5903  nios2_elf32_size_dynamic_sections (bfd *
       if (!bfd_link_pic (info) && !add_dynamic_entry (DT_DEBUG, 0))        if (!bfd_link_pic (info) && !add_dynamic_entry (DT_DEBUG, 0))
         return FALSE;          return FALSE;
   
       if (got && !add_dynamic_entry (DT_PLTGOT, 0))        if (htab->root.sgotplt->size != 0
             && !add_dynamic_entry (DT_PLTGOT, 0))
         return FALSE;          return FALSE;
   
       if (plt        if (htab->root.splt->size != 0
           && (!add_dynamic_entry (DT_PLTRELSZ, 0)            && (!add_dynamic_entry (DT_PLTRELSZ, 0)
               || !add_dynamic_entry (DT_PLTREL, DT_RELA)                || !add_dynamic_entry (DT_PLTREL, DT_RELA)
               || !add_dynamic_entry (DT_JMPREL, 0)))                || !add_dynamic_entry (DT_JMPREL, 0)))
Line 6184  nios2_elf_add_symbol_hook (bfd *abfd,
Line 6014  nios2_elf_add_symbol_hook (bfd *abfd,
                            asection **secp,                             asection **secp,
                            bfd_vma *valp)                             bfd_vma *valp)
 {  {
   bfd *dynobj;  
   
   if (sym->st_shndx == SHN_COMMON    if (sym->st_shndx == SHN_COMMON
       && !bfd_link_relocatable (info)        && !bfd_link_relocatable (info)
       && sym->st_size <= elf_gp_size (abfd)        && sym->st_size <= elf_gp_size (abfd)
Line 6200  nios2_elf_add_symbol_hook (bfd *abfd,
Line 6028  nios2_elf_add_symbol_hook (bfd *abfd,
         {          {
           flagword flags = SEC_IS_COMMON | SEC_LINKER_CREATED;            flagword flags = SEC_IS_COMMON | SEC_LINKER_CREATED;
   
           dynobj = elf_hash_table (info)->dynobj;            if (htab->root.dynobj == NULL)
           if (!dynobj)              htab->root.dynobj = abfd;
             dynobj = abfd;  
   
           htab->sbss = bfd_make_section_anyway_with_flags (dynobj, ".sbss",            htab->sbss = bfd_make_section_anyway_with_flags (htab->root.dynobj,
                                                            flags);                                                             ".sbss", flags);
           if (htab->sbss == NULL)            if (htab->sbss == NULL)
             return FALSE;              return FALSE;
         }          }
Line 6272  const struct bfd_elf_special_section elf
Line 6099  const struct bfd_elf_special_section elf
 #define elf_backend_can_refcount        1  #define elf_backend_can_refcount        1
 #define elf_backend_plt_readonly        1  #define elf_backend_plt_readonly        1
 #define elf_backend_want_got_plt        1  #define elf_backend_want_got_plt        1
   #define elf_backend_want_dynrelro       1
 #define elf_backend_rela_normal         1  #define elf_backend_rela_normal         1
   #define elf_backend_dtrel_excludes_plt  1
   
 #define elf_backend_relocate_section      nios2_elf32_relocate_section  #define elf_backend_relocate_section      nios2_elf32_relocate_section
 #define elf_backend_section_flags         nios2_elf32_section_flags  #define elf_backend_section_flags         nios2_elf32_section_flags
Line 6280  const struct bfd_elf_special_section elf
Line 6109  const struct bfd_elf_special_section elf
 #define elf_backend_check_relocs          nios2_elf32_check_relocs  #define elf_backend_check_relocs          nios2_elf32_check_relocs
   
 #define elf_backend_gc_mark_hook          nios2_elf32_gc_mark_hook  #define elf_backend_gc_mark_hook          nios2_elf32_gc_mark_hook
 #define elf_backend_gc_sweep_hook         nios2_elf32_gc_sweep_hook  
 #define elf_backend_create_dynamic_sections \  #define elf_backend_create_dynamic_sections \
                                           nios2_elf32_create_dynamic_sections                                            nios2_elf32_create_dynamic_sections
 #define elf_backend_finish_dynamic_symbol nios2_elf32_finish_dynamic_symbol  #define elf_backend_finish_dynamic_symbol nios2_elf32_finish_dynamic_symbol

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

CVSweb <webmaster@jp.NetBSD.org>