Back to index

cell-binutils  2.17cvs20070401
sunos.c
Go to the documentation of this file.
00001 /* BFD backend for SunOS binaries.
00002    Copyright 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
00003    2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
00004    Written by Cygnus Support.
00005 
00006    This file is part of BFD, the Binary File Descriptor library.
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00021 
00022 #define TARGETNAME "a.out-sunos-big"
00023 
00024 /* Do not "beautify" the CONCAT* macro args.  Traditional C will not
00025    remove whitespace added here, and thus will fail to concatenate
00026    the tokens.  */
00027 #define MY(OP) CONCAT2 (sunos_big_,OP)
00028 
00029 #include "bfd.h"
00030 #include "bfdlink.h"
00031 #include "libaout.h"
00032 
00033 /* ??? Where should this go?  */
00034 #define MACHTYPE_OK(mtype) \
00035   (((mtype) == M_SPARC && bfd_lookup_arch (bfd_arch_sparc, 0) != NULL) \
00036    || ((mtype) == M_SPARCLET \
00037        && bfd_lookup_arch (bfd_arch_sparc, bfd_mach_sparc_sparclet) != NULL) \
00038    || ((mtype) == M_SPARCLITE_LE \
00039        && bfd_lookup_arch (bfd_arch_sparc, bfd_mach_sparc_sparclet) != NULL) \
00040    || (((mtype) == M_UNKNOWN || (mtype) == M_68010 || (mtype) == M_68020) \
00041        && bfd_lookup_arch (bfd_arch_m68k, 0) != NULL))
00042 
00043 #define MY_get_dynamic_symtab_upper_bound  sunos_get_dynamic_symtab_upper_bound
00044 #define MY_canonicalize_dynamic_symtab     sunos_canonicalize_dynamic_symtab
00045 #define MY_get_synthetic_symtab            _bfd_nodynamic_get_synthetic_symtab
00046 #define MY_get_dynamic_reloc_upper_bound   sunos_get_dynamic_reloc_upper_bound
00047 #define MY_canonicalize_dynamic_reloc      sunos_canonicalize_dynamic_reloc
00048 #define MY_bfd_link_hash_table_create      sunos_link_hash_table_create
00049 #define MY_add_dynamic_symbols             sunos_add_dynamic_symbols
00050 #define MY_add_one_symbol                  sunos_add_one_symbol
00051 #define MY_link_dynamic_object             sunos_link_dynamic_object
00052 #define MY_write_dynamic_symbol            sunos_write_dynamic_symbol
00053 #define MY_check_dynamic_reloc             sunos_check_dynamic_reloc
00054 #define MY_finish_dynamic_link             sunos_finish_dynamic_link
00055 
00056 static bfd_boolean sunos_add_dynamic_symbols            (bfd *, struct bfd_link_info *, struct external_nlist **, bfd_size_type *, char **);
00057 static bfd_boolean sunos_add_one_symbol                 (struct bfd_link_info *, bfd *, const char *, flagword, asection *, bfd_vma, const char *, bfd_boolean, bfd_boolean, struct bfd_link_hash_entry **);
00058 static bfd_boolean sunos_link_dynamic_object            (struct bfd_link_info *, bfd *);
00059 static bfd_boolean sunos_write_dynamic_symbol           (bfd *, struct bfd_link_info *, struct aout_link_hash_entry *);
00060 static bfd_boolean sunos_check_dynamic_reloc            (struct bfd_link_info *, bfd *, asection *, struct aout_link_hash_entry *, void *, bfd_byte *, bfd_boolean *, bfd_vma *);
00061 static bfd_boolean sunos_finish_dynamic_link            (bfd *, struct bfd_link_info *);
00062 static struct bfd_link_hash_table *sunos_link_hash_table_create  (bfd *);
00063 static long        sunos_get_dynamic_symtab_upper_bound (bfd *);
00064 static long        sunos_canonicalize_dynamic_symtab    (bfd *, asymbol **);
00065 static long        sunos_get_dynamic_reloc_upper_bound  (bfd *);
00066 static long        sunos_canonicalize_dynamic_reloc     (bfd *, arelent **, asymbol **);
00067 
00068 /* Include the usual a.out support.  */
00069 #include "aoutf1.h"
00070 
00071 /* The SunOS 4.1.4 /usr/include/locale.h defines valid as a macro.  */
00072 #undef valid
00073 
00074 /* SunOS shared library support.  We store a pointer to this structure
00075    in obj_aout_dynamic_info (abfd).  */
00076 
00077 struct sunos_dynamic_info
00078 {
00079   /* Whether we found any dynamic information.  */
00080   bfd_boolean valid;
00081   /* Dynamic information.  */
00082   struct internal_sun4_dynamic_link dyninfo;
00083   /* Number of dynamic symbols.  */
00084   unsigned long dynsym_count;
00085   /* Read in nlists for dynamic symbols.  */
00086   struct external_nlist *dynsym;
00087   /* asymbol structures for dynamic symbols.  */
00088   aout_symbol_type *canonical_dynsym;
00089   /* Read in dynamic string table.  */
00090   char *dynstr;
00091   /* Number of dynamic relocs.  */
00092   unsigned long dynrel_count;
00093   /* Read in dynamic relocs.  This may be reloc_std_external or
00094      reloc_ext_external.  */
00095   void * dynrel;
00096   /* arelent structures for dynamic relocs.  */
00097   arelent *canonical_dynrel;
00098 };
00099 
00100 /* The hash table of dynamic symbols is composed of two word entries.
00101    See include/aout/sun4.h for details.  */
00102 
00103 #define HASH_ENTRY_SIZE (2 * BYTES_IN_WORD)
00104 
00105 /* Read in the basic dynamic information.  This locates the __DYNAMIC
00106    structure and uses it to find the dynamic_link structure.  It
00107    creates and saves a sunos_dynamic_info structure.  If it can't find
00108    __DYNAMIC, it sets the valid field of the sunos_dynamic_info
00109    structure to FALSE to avoid doing this work again.  */
00110 
00111 static bfd_boolean
00112 sunos_read_dynamic_info (bfd *abfd)
00113 {
00114   struct sunos_dynamic_info *info;
00115   asection *dynsec;
00116   bfd_vma dynoff;
00117   struct external_sun4_dynamic dyninfo;
00118   unsigned long dynver;
00119   struct external_sun4_dynamic_link linkinfo;
00120   bfd_size_type amt;
00121 
00122   if (obj_aout_dynamic_info (abfd) != NULL)
00123     return TRUE;
00124 
00125   if ((abfd->flags & DYNAMIC) == 0)
00126     {
00127       bfd_set_error (bfd_error_invalid_operation);
00128       return FALSE;
00129     }
00130 
00131   amt = sizeof (struct sunos_dynamic_info);
00132   info = bfd_zalloc (abfd, amt);
00133   if (!info)
00134     return FALSE;
00135   info->valid = FALSE;
00136   info->dynsym = NULL;
00137   info->dynstr = NULL;
00138   info->canonical_dynsym = NULL;
00139   info->dynrel = NULL;
00140   info->canonical_dynrel = NULL;
00141   obj_aout_dynamic_info (abfd) = (void *) info;
00142 
00143   /* This code used to look for the __DYNAMIC symbol to locate the dynamic
00144      linking information.
00145      However this inhibits recovering the dynamic symbols from a
00146      stripped object file, so blindly assume that the dynamic linking
00147      information is located at the start of the data section.
00148      We could verify this assumption later by looking through the dynamic
00149      symbols for the __DYNAMIC symbol.  */
00150   if ((abfd->flags & DYNAMIC) == 0)
00151     return TRUE;
00152   if (! bfd_get_section_contents (abfd, obj_datasec (abfd), (void *) &dyninfo,
00153                               (file_ptr) 0,
00154                               (bfd_size_type) sizeof dyninfo))
00155     return TRUE;
00156 
00157   dynver = GET_WORD (abfd, dyninfo.ld_version);
00158   if (dynver != 2 && dynver != 3)
00159     return TRUE;
00160 
00161   dynoff = GET_WORD (abfd, dyninfo.ld);
00162 
00163   /* dynoff is a virtual address.  It is probably always in the .data
00164      section, but this code should work even if it moves.  */
00165   if (dynoff < bfd_get_section_vma (abfd, obj_datasec (abfd)))
00166     dynsec = obj_textsec (abfd);
00167   else
00168     dynsec = obj_datasec (abfd);
00169   dynoff -= bfd_get_section_vma (abfd, dynsec);
00170   if (dynoff > dynsec->size)
00171     return TRUE;
00172 
00173   /* This executable appears to be dynamically linked in a way that we
00174      can understand.  */
00175   if (! bfd_get_section_contents (abfd, dynsec, (void *) &linkinfo,
00176                               (file_ptr) dynoff,
00177                               (bfd_size_type) sizeof linkinfo))
00178     return TRUE;
00179 
00180   /* Swap in the dynamic link information.  */
00181   info->dyninfo.ld_loaded = GET_WORD (abfd, linkinfo.ld_loaded);
00182   info->dyninfo.ld_need = GET_WORD (abfd, linkinfo.ld_need);
00183   info->dyninfo.ld_rules = GET_WORD (abfd, linkinfo.ld_rules);
00184   info->dyninfo.ld_got = GET_WORD (abfd, linkinfo.ld_got);
00185   info->dyninfo.ld_plt = GET_WORD (abfd, linkinfo.ld_plt);
00186   info->dyninfo.ld_rel = GET_WORD (abfd, linkinfo.ld_rel);
00187   info->dyninfo.ld_hash = GET_WORD (abfd, linkinfo.ld_hash);
00188   info->dyninfo.ld_stab = GET_WORD (abfd, linkinfo.ld_stab);
00189   info->dyninfo.ld_stab_hash = GET_WORD (abfd, linkinfo.ld_stab_hash);
00190   info->dyninfo.ld_buckets = GET_WORD (abfd, linkinfo.ld_buckets);
00191   info->dyninfo.ld_symbols = GET_WORD (abfd, linkinfo.ld_symbols);
00192   info->dyninfo.ld_symb_size = GET_WORD (abfd, linkinfo.ld_symb_size);
00193   info->dyninfo.ld_text = GET_WORD (abfd, linkinfo.ld_text);
00194   info->dyninfo.ld_plt_sz = GET_WORD (abfd, linkinfo.ld_plt_sz);
00195 
00196   /* Reportedly the addresses need to be offset by the size of the
00197      exec header in an NMAGIC file.  */
00198   if (adata (abfd).magic == n_magic)
00199     {
00200       unsigned long exec_bytes_size = adata (abfd).exec_bytes_size;
00201 
00202       info->dyninfo.ld_need += exec_bytes_size;
00203       info->dyninfo.ld_rules += exec_bytes_size;
00204       info->dyninfo.ld_rel += exec_bytes_size;
00205       info->dyninfo.ld_hash += exec_bytes_size;
00206       info->dyninfo.ld_stab += exec_bytes_size;
00207       info->dyninfo.ld_symbols += exec_bytes_size;
00208     }
00209 
00210   /* The only way to get the size of the symbol information appears to
00211      be to determine the distance between it and the string table.  */
00212   info->dynsym_count = ((info->dyninfo.ld_symbols - info->dyninfo.ld_stab)
00213                      / EXTERNAL_NLIST_SIZE);
00214   BFD_ASSERT (info->dynsym_count * EXTERNAL_NLIST_SIZE
00215              == (unsigned long) (info->dyninfo.ld_symbols
00216                               - info->dyninfo.ld_stab));
00217 
00218   /* Similarly, the relocs end at the hash table.  */
00219   info->dynrel_count = ((info->dyninfo.ld_hash - info->dyninfo.ld_rel)
00220                      / obj_reloc_entry_size (abfd));
00221   BFD_ASSERT (info->dynrel_count * obj_reloc_entry_size (abfd)
00222              == (unsigned long) (info->dyninfo.ld_hash
00223                               - info->dyninfo.ld_rel));
00224 
00225   info->valid = TRUE;
00226 
00227   return TRUE;
00228 }
00229 
00230 /* Return the amount of memory required for the dynamic symbols.  */
00231 
00232 static long
00233 sunos_get_dynamic_symtab_upper_bound (bfd *abfd)
00234 {
00235   struct sunos_dynamic_info *info;
00236 
00237   if (! sunos_read_dynamic_info (abfd))
00238     return -1;
00239 
00240   info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
00241   if (! info->valid)
00242     {
00243       bfd_set_error (bfd_error_no_symbols);
00244       return -1;
00245     }
00246 
00247   return (info->dynsym_count + 1) * sizeof (asymbol *);
00248 }
00249 
00250 /* Read the external dynamic symbols.  */
00251 
00252 static bfd_boolean
00253 sunos_slurp_dynamic_symtab (bfd *abfd)
00254 {
00255   struct sunos_dynamic_info *info;
00256   bfd_size_type amt;
00257 
00258   /* Get the general dynamic information.  */
00259   if (obj_aout_dynamic_info (abfd) == NULL)
00260     {
00261       if (! sunos_read_dynamic_info (abfd))
00262          return FALSE;
00263     }
00264 
00265   info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
00266   if (! info->valid)
00267     {
00268       bfd_set_error (bfd_error_no_symbols);
00269       return FALSE;
00270     }
00271 
00272   /* Get the dynamic nlist structures.  */
00273   if (info->dynsym == NULL)
00274     {
00275       amt = (bfd_size_type) info->dynsym_count * EXTERNAL_NLIST_SIZE;
00276       info->dynsym = bfd_alloc (abfd, amt);
00277       if (info->dynsym == NULL && info->dynsym_count != 0)
00278        return FALSE;
00279       if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_stab, SEEK_SET) != 0
00280          || bfd_bread ((void *) info->dynsym, amt, abfd) != amt)
00281        {
00282          if (info->dynsym != NULL)
00283            {
00284              bfd_release (abfd, info->dynsym);
00285              info->dynsym = NULL;
00286            }
00287          return FALSE;
00288        }
00289     }
00290 
00291   /* Get the dynamic strings.  */
00292   if (info->dynstr == NULL)
00293     {
00294       amt = info->dyninfo.ld_symb_size;
00295       info->dynstr = bfd_alloc (abfd, amt);
00296       if (info->dynstr == NULL && info->dyninfo.ld_symb_size != 0)
00297        return FALSE;
00298       if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_symbols, SEEK_SET) != 0
00299          || bfd_bread ((void *) info->dynstr, amt, abfd) != amt)
00300        {
00301          if (info->dynstr != NULL)
00302            {
00303              bfd_release (abfd, info->dynstr);
00304              info->dynstr = NULL;
00305            }
00306          return FALSE;
00307        }
00308     }
00309 
00310   return TRUE;
00311 }
00312 
00313 /* Read in the dynamic symbols.  */
00314 
00315 static long
00316 sunos_canonicalize_dynamic_symtab (bfd *abfd, asymbol **storage)
00317 {
00318   struct sunos_dynamic_info *info;
00319   unsigned long i;
00320 
00321   if (! sunos_slurp_dynamic_symtab (abfd))
00322     return -1;
00323 
00324   info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
00325 
00326 #ifdef CHECK_DYNAMIC_HASH
00327   /* Check my understanding of the dynamic hash table by making sure
00328      that each symbol can be located in the hash table.  */
00329   {
00330     bfd_size_type table_size;
00331     bfd_byte *table;
00332     bfd_size_type i;
00333 
00334     if (info->dyninfo.ld_buckets > info->dynsym_count)
00335       abort ();
00336     table_size = info->dyninfo.ld_stab - info->dyninfo.ld_hash;
00337     table = bfd_malloc (table_size);
00338     if (table == NULL && table_size != 0)
00339       abort ();
00340     if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_hash, SEEK_SET) != 0
00341        || bfd_bread ((void *) table, table_size, abfd) != table_size)
00342       abort ();
00343     for (i = 0; i < info->dynsym_count; i++)
00344       {
00345        unsigned char *name;
00346        unsigned long hash;
00347 
00348        name = ((unsigned char *) info->dynstr
00349               + GET_WORD (abfd, info->dynsym[i].e_strx));
00350        hash = 0;
00351        while (*name != '\0')
00352          hash = (hash << 1) + *name++;
00353        hash &= 0x7fffffff;
00354        hash %= info->dyninfo.ld_buckets;
00355        while (GET_WORD (abfd, table + hash * HASH_ENTRY_SIZE) != i)
00356          {
00357            hash = GET_WORD (abfd,
00358                           table + hash * HASH_ENTRY_SIZE + BYTES_IN_WORD);
00359            if (hash == 0 || hash >= table_size / HASH_ENTRY_SIZE)
00360              abort ();
00361          }
00362       }
00363     free (table);
00364   }
00365 #endif /* CHECK_DYNAMIC_HASH */
00366 
00367   /* Get the asymbol structures corresponding to the dynamic nlist
00368      structures.  */
00369   if (info->canonical_dynsym == NULL)
00370     {
00371       bfd_size_type size;
00372       bfd_size_type strsize = info->dyninfo.ld_symb_size;
00373 
00374       size = (bfd_size_type) info->dynsym_count * sizeof (aout_symbol_type);
00375       info->canonical_dynsym = bfd_alloc (abfd, size);
00376       if (info->canonical_dynsym == NULL && info->dynsym_count != 0)
00377        return -1;
00378 
00379       if (! aout_32_translate_symbol_table (abfd, info->canonical_dynsym,
00380                                        info->dynsym,
00381                                        (bfd_size_type) info->dynsym_count,
00382                                        info->dynstr, strsize, TRUE))
00383        {
00384          if (info->canonical_dynsym != NULL)
00385            {
00386              bfd_release (abfd, info->canonical_dynsym);
00387              info->canonical_dynsym = NULL;
00388            }
00389          return -1;
00390        }
00391     }
00392 
00393   /* Return pointers to the dynamic asymbol structures.  */
00394   for (i = 0; i < info->dynsym_count; i++)
00395     *storage++ = (asymbol *) (info->canonical_dynsym + i);
00396   *storage = NULL;
00397 
00398   return info->dynsym_count;
00399 }
00400 
00401 /* Return the amount of memory required for the dynamic relocs.  */
00402 
00403 static long
00404 sunos_get_dynamic_reloc_upper_bound (bfd *abfd)
00405 {
00406   struct sunos_dynamic_info *info;
00407 
00408   if (! sunos_read_dynamic_info (abfd))
00409     return -1;
00410 
00411   info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
00412   if (! info->valid)
00413     {
00414       bfd_set_error (bfd_error_no_symbols);
00415       return -1;
00416     }
00417 
00418   return (info->dynrel_count + 1) * sizeof (arelent *);
00419 }
00420 
00421 /* Read in the dynamic relocs.  */
00422 
00423 static long
00424 sunos_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage, asymbol **syms)
00425 {
00426   struct sunos_dynamic_info *info;
00427   unsigned long i;
00428   bfd_size_type size;
00429 
00430   /* Get the general dynamic information.  */
00431   if (obj_aout_dynamic_info (abfd) == NULL)
00432     {
00433       if (! sunos_read_dynamic_info (abfd))
00434        return -1;
00435     }
00436 
00437   info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
00438   if (! info->valid)
00439     {
00440       bfd_set_error (bfd_error_no_symbols);
00441       return -1;
00442     }
00443 
00444   /* Get the dynamic reloc information.  */
00445   if (info->dynrel == NULL)
00446     {
00447       size = (bfd_size_type) info->dynrel_count * obj_reloc_entry_size (abfd);
00448       info->dynrel = bfd_alloc (abfd, size);
00449       if (info->dynrel == NULL && size != 0)
00450        return -1;
00451       if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_rel, SEEK_SET) != 0
00452          || bfd_bread ((void *) info->dynrel, size, abfd) != size)
00453        {
00454          if (info->dynrel != NULL)
00455            {
00456              bfd_release (abfd, info->dynrel);
00457              info->dynrel = NULL;
00458            }
00459          return -1;
00460        }
00461     }
00462 
00463   /* Get the arelent structures corresponding to the dynamic reloc
00464      information.  */
00465   if (info->canonical_dynrel == NULL)
00466     {
00467       arelent *to;
00468 
00469       size = (bfd_size_type) info->dynrel_count * sizeof (arelent);
00470       info->canonical_dynrel = bfd_alloc (abfd, size);
00471       if (info->canonical_dynrel == NULL && info->dynrel_count != 0)
00472        return -1;
00473 
00474       to = info->canonical_dynrel;
00475 
00476       if (obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE)
00477        {
00478          struct reloc_ext_external *p;
00479          struct reloc_ext_external *pend;
00480 
00481          p = (struct reloc_ext_external *) info->dynrel;
00482          pend = p + info->dynrel_count;
00483          for (; p < pend; p++, to++)
00484            NAME (aout, swap_ext_reloc_in) (abfd, p, to, syms,
00485                                        (bfd_size_type) info->dynsym_count);
00486        }
00487       else
00488        {
00489          struct reloc_std_external *p;
00490          struct reloc_std_external *pend;
00491 
00492          p = (struct reloc_std_external *) info->dynrel;
00493          pend = p + info->dynrel_count;
00494          for (; p < pend; p++, to++)
00495            NAME (aout, swap_std_reloc_in) (abfd, p, to, syms,
00496                                        (bfd_size_type) info->dynsym_count);
00497        }
00498     }
00499 
00500   /* Return pointers to the dynamic arelent structures.  */
00501   for (i = 0; i < info->dynrel_count; i++)
00502     *storage++ = info->canonical_dynrel + i;
00503   *storage = NULL;
00504 
00505   return info->dynrel_count;
00506 }
00507 
00508 /* Code to handle linking of SunOS shared libraries.  */
00509 
00510 /* A SPARC procedure linkage table entry is 12 bytes.  The first entry
00511    in the table is a jump which is filled in by the runtime linker.
00512    The remaining entries are branches back to the first entry,
00513    followed by an index into the relocation table encoded to look like
00514    a sethi of %g0.  */
00515 
00516 #define SPARC_PLT_ENTRY_SIZE (12)
00517 
00518 static const bfd_byte sparc_plt_first_entry[SPARC_PLT_ENTRY_SIZE] =
00519 {
00520   /* sethi %hi(0),%g1; address filled in by runtime linker.  */
00521   0x3, 0, 0, 0,
00522   /* jmp %g1; offset filled in by runtime linker.  */
00523   0x81, 0xc0, 0x60, 0,
00524   /* nop */
00525   0x1, 0, 0, 0
00526 };
00527 
00528 /* save %sp, -96, %sp */
00529 #define SPARC_PLT_ENTRY_WORD0 ((bfd_vma) 0x9de3bfa0)
00530 /* call; address filled in later.  */
00531 #define SPARC_PLT_ENTRY_WORD1 ((bfd_vma) 0x40000000)
00532 /* sethi; reloc index filled in later.  */
00533 #define SPARC_PLT_ENTRY_WORD2 ((bfd_vma) 0x01000000)
00534 
00535 /* This sequence is used when for the jump table entry to a defined
00536    symbol in a complete executable.  It is used when linking PIC
00537    compiled code which is not being put into a shared library.  */
00538 /* sethi <address to be filled in later>, %g1 */
00539 #define SPARC_PLT_PIC_WORD0 ((bfd_vma) 0x03000000)
00540 /* jmp %g1 + <address to be filled in later> */
00541 #define SPARC_PLT_PIC_WORD1 ((bfd_vma) 0x81c06000)
00542 /* nop */
00543 #define SPARC_PLT_PIC_WORD2 ((bfd_vma) 0x01000000)
00544 
00545 /* An m68k procedure linkage table entry is 8 bytes.  The first entry
00546    in the table is a jump which is filled in the by the runtime
00547    linker.  The remaining entries are branches back to the first
00548    entry, followed by a two byte index into the relocation table.  */
00549 
00550 #define M68K_PLT_ENTRY_SIZE (8)
00551 
00552 static const bfd_byte m68k_plt_first_entry[M68K_PLT_ENTRY_SIZE] =
00553 {
00554   /* jmps @# */
00555   0x4e, 0xf9,
00556   /* Filled in by runtime linker with a magic address.  */
00557   0, 0, 0, 0,
00558   /* Not used?  */
00559   0, 0
00560 };
00561 
00562 /* bsrl */
00563 #define M68K_PLT_ENTRY_WORD0 ((bfd_vma) 0x61ff)
00564 /* Remaining words filled in later.  */
00565 
00566 /* An entry in the SunOS linker hash table.  */
00567 
00568 struct sunos_link_hash_entry
00569 {
00570   struct aout_link_hash_entry root;
00571 
00572   /* If this is a dynamic symbol, this is its index into the dynamic
00573      symbol table.  This is initialized to -1.  As the linker looks at
00574      the input files, it changes this to -2 if it will be added to the
00575      dynamic symbol table.  After all the input files have been seen,
00576      the linker will know whether to build a dynamic symbol table; if
00577      it does build one, this becomes the index into the table.  */
00578   long dynindx;
00579 
00580   /* If this is a dynamic symbol, this is the index of the name in the
00581      dynamic symbol string table.  */
00582   long dynstr_index;
00583 
00584   /* The offset into the global offset table used for this symbol.  If
00585      the symbol does not require a GOT entry, this is 0.  */
00586   bfd_vma got_offset;
00587 
00588   /* The offset into the procedure linkage table used for this symbol.
00589      If the symbol does not require a PLT entry, this is 0.  */
00590   bfd_vma plt_offset;
00591 
00592   /* Some linker flags.  */
00593   unsigned char flags;
00594   /* Symbol is referenced by a regular object.  */
00595 #define SUNOS_REF_REGULAR 01
00596   /* Symbol is defined by a regular object.  */
00597 #define SUNOS_DEF_REGULAR 02
00598   /* Symbol is referenced by a dynamic object.  */
00599 #define SUNOS_REF_DYNAMIC 04
00600   /* Symbol is defined by a dynamic object.  */
00601 #define SUNOS_DEF_DYNAMIC 010
00602   /* Symbol is a constructor symbol in a regular object.  */
00603 #define SUNOS_CONSTRUCTOR 020
00604 };
00605 
00606 /* The SunOS linker hash table.  */
00607 
00608 struct sunos_link_hash_table
00609 {
00610   struct aout_link_hash_table root;
00611 
00612   /* The object which holds the dynamic sections.  */
00613   bfd *dynobj;
00614 
00615   /* Whether we have created the dynamic sections.  */
00616   bfd_boolean dynamic_sections_created;
00617 
00618   /* Whether we need the dynamic sections.  */
00619   bfd_boolean dynamic_sections_needed;
00620 
00621   /* Whether we need the .got table.  */
00622   bfd_boolean got_needed;
00623 
00624   /* The number of dynamic symbols.  */
00625   size_t dynsymcount;
00626 
00627   /* The number of buckets in the hash table.  */
00628   size_t bucketcount;
00629 
00630   /* The list of dynamic objects needed by dynamic objects included in
00631      the link.  */
00632   struct bfd_link_needed_list *needed;
00633 
00634   /* The offset of __GLOBAL_OFFSET_TABLE_ into the .got section.  */
00635   bfd_vma got_base;
00636 };
00637 
00638 /* Routine to create an entry in an SunOS link hash table.  */
00639 
00640 static struct bfd_hash_entry *
00641 sunos_link_hash_newfunc (struct bfd_hash_entry *entry,
00642                       struct bfd_hash_table *table,
00643                       const char *string)
00644 {
00645   struct sunos_link_hash_entry *ret = (struct sunos_link_hash_entry *) entry;
00646 
00647   /* Allocate the structure if it has not already been allocated by a
00648      subclass.  */
00649   if (ret ==  NULL)
00650     ret = bfd_hash_allocate (table, sizeof (* ret));
00651   if (ret == NULL)
00652     return NULL;
00653 
00654   /* Call the allocation method of the superclass.  */
00655   ret = ((struct sunos_link_hash_entry *)
00656         NAME (aout, link_hash_newfunc) ((struct bfd_hash_entry *) ret,
00657                                     table, string));
00658   if (ret != NULL)
00659     {
00660       /* Set local fields.  */
00661       ret->dynindx = -1;
00662       ret->dynstr_index = -1;
00663       ret->got_offset = 0;
00664       ret->plt_offset = 0;
00665       ret->flags = 0;
00666     }
00667 
00668   return (struct bfd_hash_entry *) ret;
00669 }
00670 
00671 /* Create a SunOS link hash table.  */
00672 
00673 static struct bfd_link_hash_table *
00674 sunos_link_hash_table_create (bfd *abfd)
00675 {
00676   struct sunos_link_hash_table *ret;
00677   bfd_size_type amt = sizeof (struct sunos_link_hash_table);
00678 
00679   ret = bfd_malloc (amt);
00680   if (ret ==  NULL)
00681     return NULL;
00682   if (!NAME (aout, link_hash_table_init) (&ret->root, abfd,
00683                                      sunos_link_hash_newfunc,
00684                                      sizeof (struct sunos_link_hash_entry)))
00685     {
00686       free (ret);
00687       return NULL;
00688     }
00689 
00690   ret->dynobj = NULL;
00691   ret->dynamic_sections_created = FALSE;
00692   ret->dynamic_sections_needed = FALSE;
00693   ret->got_needed = FALSE;
00694   ret->dynsymcount = 0;
00695   ret->bucketcount = 0;
00696   ret->needed = NULL;
00697   ret->got_base = 0;
00698 
00699   return &ret->root.root;
00700 }
00701 
00702 /* Look up an entry in an SunOS link hash table.  */
00703 
00704 #define sunos_link_hash_lookup(table, string, create, copy, follow) \
00705   ((struct sunos_link_hash_entry *) \
00706    aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\
00707                        (follow)))
00708 
00709 /* Traverse a SunOS link hash table.  */
00710 
00711 #define sunos_link_hash_traverse(table, func, info)                   \
00712   (aout_link_hash_traverse                                     \
00713    (&(table)->root,                                            \
00714     (bfd_boolean (*) (struct aout_link_hash_entry *, void *)) (func), \
00715     (info)))
00716 
00717 /* Get the SunOS link hash table from the info structure.  This is
00718    just a cast.  */
00719 
00720 #define sunos_hash_table(p) ((struct sunos_link_hash_table *) ((p)->hash))
00721 
00722 /* Create the dynamic sections needed if we are linking against a
00723    dynamic object, or if we are linking PIC compiled code.  ABFD is a
00724    bfd we can attach the dynamic sections to.  The linker script will
00725    look for these special sections names and put them in the right
00726    place in the output file.  See include/aout/sun4.h for more details
00727    of the dynamic linking information.  */
00728 
00729 static bfd_boolean
00730 sunos_create_dynamic_sections (bfd *abfd,
00731                             struct bfd_link_info *info,
00732                             bfd_boolean needed)
00733 {
00734   asection *s;
00735 
00736   if (! sunos_hash_table (info)->dynamic_sections_created)
00737     {
00738       flagword flags;
00739 
00740       sunos_hash_table (info)->dynobj = abfd;
00741 
00742       flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
00743               | SEC_LINKER_CREATED);
00744 
00745       /* The .dynamic section holds the basic dynamic information: the
00746         sun4_dynamic structure, the dynamic debugger information, and
00747         the sun4_dynamic_link structure.  */
00748       s = bfd_make_section_with_flags (abfd, ".dynamic", flags);
00749       if (s == NULL
00750          || ! bfd_set_section_alignment (abfd, s, 2))
00751        return FALSE;
00752 
00753       /* The .got section holds the global offset table.  The address
00754         is put in the ld_got field.  */
00755       s = bfd_make_section_with_flags (abfd, ".got", flags);
00756       if (s == NULL
00757          || ! bfd_set_section_alignment (abfd, s, 2))
00758        return FALSE;
00759 
00760       /* The .plt section holds the procedure linkage table.  The
00761         address is put in the ld_plt field.  */
00762       s = bfd_make_section_with_flags (abfd, ".plt", flags | SEC_CODE);
00763       if (s == NULL
00764          || ! bfd_set_section_alignment (abfd, s, 2))
00765        return FALSE;
00766 
00767       /* The .dynrel section holds the dynamic relocs.  The address is
00768         put in the ld_rel field.  */
00769       s = bfd_make_section_with_flags (abfd, ".dynrel", flags | SEC_READONLY);
00770       if (s == NULL
00771          || ! bfd_set_section_alignment (abfd, s, 2))
00772        return FALSE;
00773 
00774       /* The .hash section holds the dynamic hash table.  The address
00775         is put in the ld_hash field.  */
00776       s = bfd_make_section_with_flags (abfd, ".hash", flags | SEC_READONLY);
00777       if (s == NULL
00778          || ! bfd_set_section_alignment (abfd, s, 2))
00779        return FALSE;
00780 
00781       /* The .dynsym section holds the dynamic symbols.  The address
00782         is put in the ld_stab field.  */
00783       s = bfd_make_section_with_flags (abfd, ".dynsym", flags | SEC_READONLY);
00784       if (s == NULL
00785          || ! bfd_set_section_alignment (abfd, s, 2))
00786        return FALSE;
00787 
00788       /* The .dynstr section holds the dynamic symbol string table.
00789         The address is put in the ld_symbols field.  */
00790       s = bfd_make_section_with_flags (abfd, ".dynstr", flags | SEC_READONLY);
00791       if (s == NULL
00792          || ! bfd_set_section_alignment (abfd, s, 2))
00793        return FALSE;
00794 
00795       sunos_hash_table (info)->dynamic_sections_created = TRUE;
00796     }
00797 
00798   if ((needed && ! sunos_hash_table (info)->dynamic_sections_needed)
00799       || info->shared)
00800     {
00801       bfd *dynobj;
00802 
00803       dynobj = sunos_hash_table (info)->dynobj;
00804 
00805       s = bfd_get_section_by_name (dynobj, ".got");
00806       if (s->size == 0)
00807        s->size = BYTES_IN_WORD;
00808 
00809       sunos_hash_table (info)->dynamic_sections_needed = TRUE;
00810       sunos_hash_table (info)->got_needed = TRUE;
00811     }
00812 
00813   return TRUE;
00814 }
00815 
00816 /* Add dynamic symbols during a link.  This is called by the a.out
00817    backend linker for each object it encounters.  */
00818 
00819 static bfd_boolean
00820 sunos_add_dynamic_symbols (bfd *abfd,
00821                         struct bfd_link_info *info,
00822                         struct external_nlist **symsp,
00823                         bfd_size_type *sym_countp,
00824                         char **stringsp)
00825 {
00826   bfd *dynobj;
00827   struct sunos_dynamic_info *dinfo;
00828   unsigned long need;
00829 
00830   /* Make sure we have all the required sections.  */
00831   if (info->hash->creator == abfd->xvec)
00832     {
00833       if (! sunos_create_dynamic_sections (abfd, info,
00834                                       ((abfd->flags & DYNAMIC) != 0
00835                                        && !info->relocatable)))
00836        return FALSE;
00837     }
00838 
00839   /* There is nothing else to do for a normal object.  */
00840   if ((abfd->flags & DYNAMIC) == 0)
00841     return TRUE;
00842 
00843   dynobj = sunos_hash_table (info)->dynobj;
00844 
00845   /* We do not want to include the sections in a dynamic object in the
00846      output file.  We hack by simply clobbering the list of sections
00847      in the BFD.  This could be handled more cleanly by, say, a new
00848      section flag; the existing SEC_NEVER_LOAD flag is not the one we
00849      want, because that one still implies that the section takes up
00850      space in the output file.  If this is the first object we have
00851      seen, we must preserve the dynamic sections we just created.  */
00852   if (abfd != dynobj)
00853     abfd->sections = NULL;
00854   else
00855     {
00856       asection *s;
00857 
00858       for (s = abfd->sections; s != NULL; s = s->next)
00859        {
00860          if ((s->flags & SEC_LINKER_CREATED) == 0)
00861            bfd_section_list_remove (abfd, s);
00862        }
00863     }
00864 
00865   /* The native linker seems to just ignore dynamic objects when -r is
00866      used.  */
00867   if (info->relocatable)
00868     return TRUE;
00869 
00870   /* There's no hope of using a dynamic object which does not exactly
00871      match the format of the output file.  */
00872   if (info->hash->creator != abfd->xvec)
00873     {
00874       bfd_set_error (bfd_error_invalid_operation);
00875       return FALSE;
00876     }
00877 
00878   /* Make sure we have a .need and a .rules sections.  These are only
00879      needed if there really is a dynamic object in the link, so they
00880      are not added by sunos_create_dynamic_sections.  */
00881   if (bfd_get_section_by_name (dynobj, ".need") == NULL)
00882     {
00883       /* The .need section holds the list of names of shared objets
00884         which must be included at runtime.  The address of this
00885         section is put in the ld_need field.  */
00886       flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
00887                      | SEC_IN_MEMORY | SEC_READONLY);
00888       asection *s = bfd_make_section_with_flags (dynobj, ".need", flags);
00889       if (s == NULL
00890          || ! bfd_set_section_alignment (dynobj, s, 2))
00891        return FALSE;
00892     }
00893 
00894   if (bfd_get_section_by_name (dynobj, ".rules") == NULL)
00895     {
00896       /* The .rules section holds the path to search for shared
00897         objects.  The address of this section is put in the ld_rules
00898         field.  */
00899       flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
00900                      | SEC_IN_MEMORY | SEC_READONLY);
00901       asection *s = bfd_make_section_with_flags (dynobj, ".rules", flags);
00902       if (s == NULL
00903          || ! bfd_set_section_alignment (dynobj, s, 2))
00904        return FALSE;
00905     }
00906 
00907   /* Pick up the dynamic symbols and return them to the caller.  */
00908   if (! sunos_slurp_dynamic_symtab (abfd))
00909     return FALSE;
00910 
00911   dinfo = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
00912   *symsp = dinfo->dynsym;
00913   *sym_countp = dinfo->dynsym_count;
00914   *stringsp = dinfo->dynstr;
00915 
00916   /* Record information about any other objects needed by this one.  */
00917   need = dinfo->dyninfo.ld_need;
00918   while (need != 0)
00919     {
00920       bfd_byte buf[16];
00921       unsigned long name, flags;
00922       unsigned short major_vno, minor_vno;
00923       struct bfd_link_needed_list *needed, **pp;
00924       char *namebuf, *p;
00925       bfd_size_type alc;
00926       bfd_byte b;
00927       char *namecopy;
00928 
00929       if (bfd_seek (abfd, (file_ptr) need, SEEK_SET) != 0
00930          || bfd_bread (buf, (bfd_size_type) 16, abfd) != 16)
00931        return FALSE;
00932 
00933       /* For the format of an ld_need entry, see aout/sun4.h.  We
00934         should probably define structs for this manipulation.  */
00935       name = bfd_get_32 (abfd, buf);
00936       flags = bfd_get_32 (abfd, buf + 4);
00937       major_vno = (unsigned short) bfd_get_16 (abfd, buf + 8);
00938       minor_vno = (unsigned short) bfd_get_16 (abfd, buf + 10);
00939       need = bfd_get_32 (abfd, buf + 12);
00940 
00941       alc = sizeof (struct bfd_link_needed_list);
00942       needed = bfd_alloc (abfd, alc);
00943       if (needed == NULL)
00944        return FALSE;
00945       needed->by = abfd;
00946 
00947       /* We return the name as [-l]name[.maj][.min].  */
00948       alc = 30;
00949       namebuf = bfd_malloc (alc + 1);
00950       if (namebuf == NULL)
00951        return FALSE;
00952       p = namebuf;
00953 
00954       if ((flags & 0x80000000) != 0)
00955        {
00956          *p++ = '-';
00957          *p++ = 'l';
00958        }
00959       if (bfd_seek (abfd, (file_ptr) name, SEEK_SET) != 0)
00960        {
00961          free (namebuf);
00962          return FALSE;
00963        }
00964 
00965       do
00966        {
00967          if (bfd_bread (&b, (bfd_size_type) 1, abfd) != 1)
00968            {
00969              free (namebuf);
00970              return FALSE;
00971            }
00972 
00973          if ((bfd_size_type) (p - namebuf) >= alc)
00974            {
00975              char *n;
00976 
00977              alc *= 2;
00978              n = bfd_realloc (namebuf, alc + 1);
00979              if (n == NULL)
00980               {
00981                 free (namebuf);
00982                 return FALSE;
00983               }
00984              p = n + (p - namebuf);
00985              namebuf = n;
00986            }
00987 
00988          *p++ = b;
00989        }
00990       while (b != '\0');
00991 
00992       if (major_vno == 0)
00993        *p = '\0';
00994       else
00995        {
00996          char majbuf[30];
00997          char minbuf[30];
00998 
00999          sprintf (majbuf, ".%d", major_vno);
01000          if (minor_vno == 0)
01001            minbuf[0] = '\0';
01002          else
01003            sprintf (minbuf, ".%d", minor_vno);
01004 
01005          if ((p - namebuf) + strlen (majbuf) + strlen (minbuf) >= alc)
01006            {
01007              char *n;
01008 
01009              alc = (p - namebuf) + strlen (majbuf) + strlen (minbuf);
01010              n = bfd_realloc (namebuf, alc + 1);
01011              if (n == NULL)
01012               {
01013                 free (namebuf);
01014                 return FALSE;
01015               }
01016              p = n + (p - namebuf);
01017              namebuf = n;
01018            }
01019 
01020          strcpy (p, majbuf);
01021          strcat (p, minbuf);
01022        }
01023 
01024       namecopy = bfd_alloc (abfd, (bfd_size_type) strlen (namebuf) + 1);
01025       if (namecopy == NULL)
01026        {
01027          free (namebuf);
01028          return FALSE;
01029        }
01030       strcpy (namecopy, namebuf);
01031       free (namebuf);
01032       needed->name = namecopy;
01033 
01034       needed->next = NULL;
01035 
01036       for (pp = &sunos_hash_table (info)->needed;
01037           *pp != NULL;
01038           pp = &(*pp)->next)
01039        ;
01040       *pp = needed;
01041     }
01042 
01043   return TRUE;
01044 }
01045 
01046 /* Function to add a single symbol to the linker hash table.  This is
01047    a wrapper around _bfd_generic_link_add_one_symbol which handles the
01048    tweaking needed for dynamic linking support.  */
01049 
01050 static bfd_boolean
01051 sunos_add_one_symbol (struct bfd_link_info *info,
01052                     bfd *abfd,
01053                     const char *name,
01054                     flagword flags,
01055                     asection *section,
01056                     bfd_vma value,
01057                     const char *string,
01058                     bfd_boolean copy,
01059                     bfd_boolean collect,
01060                     struct bfd_link_hash_entry **hashp)
01061 {
01062   struct sunos_link_hash_entry *h;
01063   int new_flag;
01064 
01065   if ((flags & (BSF_INDIRECT | BSF_WARNING | BSF_CONSTRUCTOR)) != 0
01066       || ! bfd_is_und_section (section))
01067     h = sunos_link_hash_lookup (sunos_hash_table (info), name, TRUE, copy,
01068                             FALSE);
01069   else
01070     h = ((struct sunos_link_hash_entry *)
01071         bfd_wrapped_link_hash_lookup (abfd, info, name, TRUE, copy, FALSE));
01072   if (h == NULL)
01073     return FALSE;
01074 
01075   if (hashp != NULL)
01076     *hashp = (struct bfd_link_hash_entry *) h;
01077 
01078   /* Treat a common symbol in a dynamic object as defined in the .bss
01079      section of the dynamic object.  We don't want to allocate space
01080      for it in our process image.  */
01081   if ((abfd->flags & DYNAMIC) != 0
01082       && bfd_is_com_section (section))
01083     section = obj_bsssec (abfd);
01084 
01085   if (! bfd_is_und_section (section)
01086       && h->root.root.type != bfd_link_hash_new
01087       && h->root.root.type != bfd_link_hash_undefined
01088       && h->root.root.type != bfd_link_hash_defweak)
01089     {
01090       /* We are defining the symbol, and it is already defined.  This
01091         is a potential multiple definition error.  */
01092       if ((abfd->flags & DYNAMIC) != 0)
01093        {
01094          /* The definition we are adding is from a dynamic object.
01095             We do not want this new definition to override the
01096             existing definition, so we pretend it is just a
01097             reference.  */
01098          section = bfd_und_section_ptr;
01099        }
01100       else if (h->root.root.type == bfd_link_hash_defined
01101               && h->root.root.u.def.section->owner != NULL
01102               && (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0)
01103        {
01104          /* The existing definition is from a dynamic object.  We
01105             want to override it with the definition we just found.
01106             Clobber the existing definition.  */
01107          h->root.root.type = bfd_link_hash_undefined;
01108          h->root.root.u.undef.abfd = h->root.root.u.def.section->owner;
01109        }
01110       else if (h->root.root.type == bfd_link_hash_common
01111               && (h->root.root.u.c.p->section->owner->flags & DYNAMIC) != 0)
01112        {
01113          /* The existing definition is from a dynamic object.  We
01114             want to override it with the definition we just found.
01115             Clobber the existing definition.  We can't set it to new,
01116             because it is on the undefined list.  */
01117          h->root.root.type = bfd_link_hash_undefined;
01118          h->root.root.u.undef.abfd = h->root.root.u.c.p->section->owner;
01119        }
01120     }
01121 
01122   if ((abfd->flags & DYNAMIC) != 0
01123       && abfd->xvec == info->hash->creator
01124       && (h->flags & SUNOS_CONSTRUCTOR) != 0)
01125     /* The existing symbol is a constructor symbol, and this symbol
01126        is from a dynamic object.  A constructor symbol is actually a
01127        definition, although the type will be bfd_link_hash_undefined
01128        at this point.  We want to ignore the definition from the
01129        dynamic object.  */
01130     section = bfd_und_section_ptr;
01131   else if ((flags & BSF_CONSTRUCTOR) != 0
01132           && (abfd->flags & DYNAMIC) == 0
01133           && h->root.root.type == bfd_link_hash_defined
01134           && h->root.root.u.def.section->owner != NULL
01135           && (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0)
01136     /* The existing symbol is defined by a dynamic object, and this
01137        is a constructor symbol.  As above, we want to force the use
01138        of the constructor symbol from the regular object.  */
01139     h->root.root.type = bfd_link_hash_new;
01140 
01141   /* Do the usual procedure for adding a symbol.  */
01142   if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section,
01143                                      value, string, copy, collect,
01144                                      hashp))
01145     return FALSE;
01146 
01147   if (abfd->xvec == info->hash->creator)
01148     {
01149       /* Set a flag in the hash table entry indicating the type of
01150         reference or definition we just found.  Keep a count of the
01151         number of dynamic symbols we find.  A dynamic symbol is one
01152         which is referenced or defined by both a regular object and a
01153         shared object.  */
01154       if ((abfd->flags & DYNAMIC) == 0)
01155        {
01156          if (bfd_is_und_section (section))
01157            new_flag = SUNOS_REF_REGULAR;
01158          else
01159            new_flag = SUNOS_DEF_REGULAR;
01160        }
01161       else
01162        {
01163          if (bfd_is_und_section (section))
01164            new_flag = SUNOS_REF_DYNAMIC;
01165          else
01166            new_flag = SUNOS_DEF_DYNAMIC;
01167        }
01168       h->flags |= new_flag;
01169 
01170       if (h->dynindx == -1
01171          && (h->flags & (SUNOS_DEF_REGULAR | SUNOS_REF_REGULAR)) != 0)
01172        {
01173          ++sunos_hash_table (info)->dynsymcount;
01174          h->dynindx = -2;
01175        }
01176 
01177       if ((flags & BSF_CONSTRUCTOR) != 0
01178          && (abfd->flags & DYNAMIC) == 0)
01179        h->flags |= SUNOS_CONSTRUCTOR;
01180     }
01181 
01182   return TRUE;
01183 }
01184 
01185 extern const bfd_target MY (vec);
01186 
01187 /* Return the list of objects needed by BFD.  */
01188 
01189 struct bfd_link_needed_list *
01190 bfd_sunos_get_needed_list (bfd *abfd ATTRIBUTE_UNUSED,
01191                         struct bfd_link_info *info)
01192 {
01193   if (info->hash->creator != &MY (vec))
01194     return NULL;
01195   return sunos_hash_table (info)->needed;
01196 }
01197 
01198 /* Record an assignment made to a symbol by a linker script.  We need
01199    this in case some dynamic object refers to this symbol.  */
01200 
01201 bfd_boolean
01202 bfd_sunos_record_link_assignment (bfd *output_bfd,
01203                               struct bfd_link_info *info,
01204                               const char *name)
01205 {
01206   struct sunos_link_hash_entry *h;
01207 
01208   if (output_bfd->xvec != &MY(vec))
01209     return TRUE;
01210 
01211   /* This is called after we have examined all the input objects.  If
01212      the symbol does not exist, it merely means that no object refers
01213      to it, and we can just ignore it at this point.  */
01214   h = sunos_link_hash_lookup (sunos_hash_table (info), name,
01215                            FALSE, FALSE, FALSE);
01216   if (h == NULL)
01217     return TRUE;
01218 
01219   /* In a shared library, the __DYNAMIC symbol does not appear in the
01220      dynamic symbol table.  */
01221   if (! info->shared || strcmp (name, "__DYNAMIC") != 0)
01222     {
01223       h->flags |= SUNOS_DEF_REGULAR;
01224 
01225       if (h->dynindx == -1)
01226        {
01227          ++sunos_hash_table (info)->dynsymcount;
01228          h->dynindx = -2;
01229        }
01230     }
01231 
01232   return TRUE;
01233 }
01234 
01235 /* Scan the relocs for an input section using standard relocs.  We
01236    need to figure out what to do for each reloc against a dynamic
01237    symbol.  If the symbol is in the .text section, an entry is made in
01238    the procedure linkage table.  Note that this will do the wrong
01239    thing if the symbol is actually data; I don't think the Sun 3
01240    native linker handles this case correctly either.  If the symbol is
01241    not in the .text section, we must preserve the reloc as a dynamic
01242    reloc.  FIXME: We should also handle the PIC relocs here by
01243    building global offset table entries.  */
01244 
01245 static bfd_boolean
01246 sunos_scan_std_relocs (struct bfd_link_info *info,
01247                      bfd *abfd,
01248                      asection *sec ATTRIBUTE_UNUSED,
01249                      const struct reloc_std_external *relocs,
01250                      bfd_size_type rel_size)
01251 {
01252   bfd *dynobj;
01253   asection *splt = NULL;
01254   asection *srel = NULL;
01255   struct sunos_link_hash_entry **sym_hashes;
01256   const struct reloc_std_external *rel, *relend;
01257 
01258   /* We only know how to handle m68k plt entries.  */
01259   if (bfd_get_arch (abfd) != bfd_arch_m68k)
01260     {
01261       bfd_set_error (bfd_error_invalid_target);
01262       return FALSE;
01263     }
01264 
01265   dynobj = NULL;
01266 
01267   sym_hashes = (struct sunos_link_hash_entry **) obj_aout_sym_hashes (abfd);
01268 
01269   relend = relocs + rel_size / RELOC_STD_SIZE;
01270   for (rel = relocs; rel < relend; rel++)
01271     {
01272       int r_index;
01273       struct sunos_link_hash_entry *h;
01274 
01275       /* We only want relocs against external symbols.  */
01276       if (bfd_header_big_endian (abfd))
01277        {
01278          if ((rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG) == 0)
01279            continue;
01280        }
01281       else
01282        {
01283          if ((rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE) == 0)
01284            continue;
01285        }
01286 
01287       /* Get the symbol index.  */
01288       if (bfd_header_big_endian (abfd))
01289        r_index = ((rel->r_index[0] << 16)
01290                  | (rel->r_index[1] << 8)
01291                  | rel->r_index[2]);
01292       else
01293        r_index = ((rel->r_index[2] << 16)
01294                  | (rel->r_index[1] << 8)
01295                  | rel->r_index[0]);
01296 
01297       /* Get the hash table entry.  */
01298       h = sym_hashes[r_index];
01299       if (h == NULL)
01300        /* This should not normally happen, but it will in any case
01301           be caught in the relocation phase.  */
01302        continue;
01303 
01304       /* At this point common symbols have already been allocated, so
01305         we don't have to worry about them.  We need to consider that
01306         we may have already seen this symbol and marked it undefined;
01307         if the symbol is really undefined, then SUNOS_DEF_DYNAMIC
01308         will be zero.  */
01309       if (h->root.root.type != bfd_link_hash_defined
01310          && h->root.root.type != bfd_link_hash_defweak
01311          && h->root.root.type != bfd_link_hash_undefined)
01312        continue;
01313 
01314       if ((h->flags & SUNOS_DEF_DYNAMIC) == 0
01315          || (h->flags & SUNOS_DEF_REGULAR) != 0)
01316        continue;
01317 
01318       if (dynobj == NULL)
01319        {
01320          asection *sgot;
01321 
01322          if (! sunos_create_dynamic_sections (abfd, info, FALSE))
01323            return FALSE;
01324          dynobj = sunos_hash_table (info)->dynobj;
01325          splt = bfd_get_section_by_name (dynobj, ".plt");
01326          srel = bfd_get_section_by_name (dynobj, ".dynrel");
01327          BFD_ASSERT (splt != NULL && srel != NULL);
01328 
01329          sgot = bfd_get_section_by_name (dynobj, ".got");
01330          BFD_ASSERT (sgot != NULL);
01331          if (sgot->size == 0)
01332            sgot->size = BYTES_IN_WORD;
01333          sunos_hash_table (info)->got_needed = TRUE;
01334        }
01335 
01336       BFD_ASSERT ((h->flags & SUNOS_REF_REGULAR) != 0);
01337       BFD_ASSERT (h->plt_offset != 0
01338                 || ((h->root.root.type == bfd_link_hash_defined
01339                      || h->root.root.type == bfd_link_hash_defweak)
01340                     ? (h->root.root.u.def.section->owner->flags
01341                       & DYNAMIC) != 0
01342                     : (h->root.root.u.undef.abfd->flags & DYNAMIC) != 0));
01343 
01344       /* This reloc is against a symbol defined only by a dynamic
01345         object.  */
01346       if (h->root.root.type == bfd_link_hash_undefined)
01347        /* Presumably this symbol was marked as being undefined by
01348           an earlier reloc.  */
01349        srel->size += RELOC_STD_SIZE;
01350       else if ((h->root.root.u.def.section->flags & SEC_CODE) == 0)
01351        {
01352          bfd *sub;
01353 
01354          /* This reloc is not in the .text section.  It must be
01355             copied into the dynamic relocs.  We mark the symbol as
01356             being undefined.  */
01357          srel->size += RELOC_STD_SIZE;
01358          sub = h->root.root.u.def.section->owner;
01359          h->root.root.type = bfd_link_hash_undefined;
01360          h->root.root.u.undef.abfd = sub;
01361        }
01362       else
01363        {
01364          /* This symbol is in the .text section.  We must give it an
01365             entry in the procedure linkage table, if we have not
01366             already done so.  We change the definition of the symbol
01367             to the .plt section; this will cause relocs against it to
01368             be handled correctly.  */
01369          if (h->plt_offset == 0)
01370            {
01371              if (splt->size == 0)
01372               splt->size = M68K_PLT_ENTRY_SIZE;
01373              h->plt_offset = splt->size;
01374 
01375              if ((h->flags & SUNOS_DEF_REGULAR) == 0)
01376               {
01377                 h->root.root.u.def.section = splt;
01378                 h->root.root.u.def.value = splt->size;
01379               }
01380 
01381              splt->size += M68K_PLT_ENTRY_SIZE;
01382 
01383              /* We may also need a dynamic reloc entry.  */
01384              if ((h->flags & SUNOS_DEF_REGULAR) == 0)
01385               srel->size += RELOC_STD_SIZE;
01386            }
01387        }
01388     }
01389 
01390   return TRUE;
01391 }
01392 
01393 /* Scan the relocs for an input section using extended relocs.  We
01394    need to figure out what to do for each reloc against a dynamic
01395    symbol.  If the reloc is a WDISP30, and the symbol is in the .text
01396    section, an entry is made in the procedure linkage table.
01397    Otherwise, we must preserve the reloc as a dynamic reloc.  */
01398 
01399 static bfd_boolean
01400 sunos_scan_ext_relocs (struct bfd_link_info *info,
01401                      bfd *abfd,
01402                      asection *sec ATTRIBUTE_UNUSED,
01403                      const struct reloc_ext_external *relocs,
01404                      bfd_size_type rel_size)
01405 {
01406   bfd *dynobj;
01407   struct sunos_link_hash_entry **sym_hashes;
01408   const struct reloc_ext_external *rel, *relend;
01409   asection *splt = NULL;
01410   asection *sgot = NULL;
01411   asection *srel = NULL;
01412   bfd_size_type amt;
01413 
01414   /* We only know how to handle SPARC plt entries.  */
01415   if (bfd_get_arch (abfd) != bfd_arch_sparc)
01416     {
01417       bfd_set_error (bfd_error_invalid_target);
01418       return FALSE;
01419     }
01420 
01421   dynobj = NULL;
01422 
01423   sym_hashes = (struct sunos_link_hash_entry **) obj_aout_sym_hashes (abfd);
01424 
01425   relend = relocs + rel_size / RELOC_EXT_SIZE;
01426   for (rel = relocs; rel < relend; rel++)
01427     {
01428       unsigned int r_index;
01429       int r_extern;
01430       int r_type;
01431       struct sunos_link_hash_entry *h = NULL;
01432 
01433       /* Swap in the reloc information.  */
01434       if (bfd_header_big_endian (abfd))
01435        {
01436          r_index = ((rel->r_index[0] << 16)
01437                    | (rel->r_index[1] << 8)
01438                    | rel->r_index[2]);
01439          r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
01440          r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
01441                   >> RELOC_EXT_BITS_TYPE_SH_BIG);
01442        }
01443       else
01444        {
01445          r_index = ((rel->r_index[2] << 16)
01446                    | (rel->r_index[1] << 8)
01447                    | rel->r_index[0]);
01448          r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
01449          r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
01450                   >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
01451        }
01452 
01453       if (r_extern)
01454        {
01455          h = sym_hashes[r_index];
01456          if (h == NULL)
01457            {
01458              /* This should not normally happen, but it will in any
01459                case be caught in the relocation phase.  */
01460              continue;
01461            }
01462        }
01463 
01464       /* If this is a base relative reloc, we need to make an entry in
01465         the .got section.  */
01466       if (r_type == RELOC_BASE10
01467          || r_type == RELOC_BASE13
01468          || r_type == RELOC_BASE22)
01469        {
01470          if (dynobj == NULL)
01471            {
01472              if (! sunos_create_dynamic_sections (abfd, info, FALSE))
01473               return FALSE;
01474              dynobj = sunos_hash_table (info)->dynobj;
01475              splt = bfd_get_section_by_name (dynobj, ".plt");
01476              sgot = bfd_get_section_by_name (dynobj, ".got");
01477              srel = bfd_get_section_by_name (dynobj, ".dynrel");
01478              BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
01479 
01480              /* Make sure we have an initial entry in the .got table.  */
01481              if (sgot->size == 0)
01482               sgot->size = BYTES_IN_WORD;
01483              sunos_hash_table (info)->got_needed = TRUE;
01484            }
01485 
01486          if (r_extern)
01487            {
01488              if (h->got_offset != 0)
01489               continue;
01490 
01491              h->got_offset = sgot->size;
01492            }
01493          else
01494            {
01495              if (r_index >= bfd_get_symcount (abfd))
01496               /* This is abnormal, but should be caught in the
01497                  relocation phase.  */
01498               continue;
01499 
01500              if (adata (abfd).local_got_offsets == NULL)
01501               {
01502                 amt = bfd_get_symcount (abfd);
01503                 amt *= sizeof (bfd_vma);
01504                 adata (abfd).local_got_offsets = bfd_zalloc (abfd, amt);
01505                 if (adata (abfd).local_got_offsets == NULL)
01506                   return FALSE;
01507               }
01508 
01509              if (adata (abfd).local_got_offsets[r_index] != 0)
01510               continue;
01511 
01512              adata (abfd).local_got_offsets[r_index] = sgot->size;
01513            }
01514 
01515          sgot->size += BYTES_IN_WORD;
01516 
01517          /* If we are making a shared library, or if the symbol is
01518             defined by a dynamic object, we will need a dynamic reloc
01519             entry.  */
01520          if (info->shared
01521              || (h != NULL
01522                 && (h->flags & SUNOS_DEF_DYNAMIC) != 0
01523                 && (h->flags & SUNOS_DEF_REGULAR) == 0))
01524            srel->size += RELOC_EXT_SIZE;
01525 
01526          continue;
01527        }
01528 
01529       /* Otherwise, we are only interested in relocs against symbols
01530         defined in dynamic objects but not in regular objects.  We
01531         only need to consider relocs against external symbols.  */
01532       if (! r_extern)
01533        {
01534          /* But, if we are creating a shared library, we need to
01535             generate an absolute reloc.  */
01536          if (info->shared)
01537            {
01538              if (dynobj == NULL)
01539               {
01540                 if (! sunos_create_dynamic_sections (abfd, info, TRUE))
01541                   return FALSE;
01542                 dynobj = sunos_hash_table (info)->dynobj;
01543                 splt = bfd_get_section_by_name (dynobj, ".plt");
01544                 sgot = bfd_get_section_by_name (dynobj, ".got");
01545                 srel = bfd_get_section_by_name (dynobj, ".dynrel");
01546                 BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
01547               }
01548 
01549              srel->size += RELOC_EXT_SIZE;
01550            }
01551 
01552          continue;
01553        }
01554 
01555       /* At this point common symbols have already been allocated, so
01556         we don't have to worry about them.  We need to consider that
01557         we may have already seen this symbol and marked it undefined;
01558         if the symbol is really undefined, then SUNOS_DEF_DYNAMIC
01559         will be zero.  */
01560       if (h->root.root.type != bfd_link_hash_defined
01561          && h->root.root.type != bfd_link_hash_defweak
01562          && h->root.root.type != bfd_link_hash_undefined)
01563        continue;
01564 
01565       if (r_type != RELOC_JMP_TBL
01566          && ! info->shared
01567          && ((h->flags & SUNOS_DEF_DYNAMIC) == 0
01568              || (h->flags & SUNOS_DEF_REGULAR) != 0))
01569        continue;
01570 
01571       if (r_type == RELOC_JMP_TBL
01572          && ! info->shared
01573          && (h->flags & SUNOS_DEF_DYNAMIC) == 0
01574          && (h->flags & SUNOS_DEF_REGULAR) == 0)
01575        {
01576          /* This symbol is apparently undefined.  Don't do anything
01577             here; just let the relocation routine report an undefined
01578             symbol.  */
01579          continue;
01580        }
01581 
01582       if (strcmp (h->root.root.root.string, "__GLOBAL_OFFSET_TABLE_") == 0)
01583        continue;
01584 
01585       if (dynobj == NULL)
01586        {
01587          if (! sunos_create_dynamic_sections (abfd, info, FALSE))
01588            return FALSE;
01589          dynobj = sunos_hash_table (info)->dynobj;
01590          splt = bfd_get_section_by_name (dynobj, ".plt");
01591          sgot = bfd_get_section_by_name (dynobj, ".got");
01592          srel = bfd_get_section_by_name (dynobj, ".dynrel");
01593          BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
01594 
01595          /* Make sure we have an initial entry in the .got table.  */
01596          if (sgot->size == 0)
01597            sgot->size = BYTES_IN_WORD;
01598          sunos_hash_table (info)->got_needed = TRUE;
01599        }
01600 
01601       BFD_ASSERT (r_type == RELOC_JMP_TBL
01602                 || info->shared
01603                 || (h->flags & SUNOS_REF_REGULAR) != 0);
01604       BFD_ASSERT (r_type == RELOC_JMP_TBL
01605                 || info->shared
01606                 || h->plt_offset != 0
01607                 || ((h->root.root.type == bfd_link_hash_defined
01608                      || h->root.root.type == bfd_link_hash_defweak)
01609                     ? (h->root.root.u.def.section->owner->flags
01610                       & DYNAMIC) != 0
01611                     : (h->root.root.u.undef.abfd->flags & DYNAMIC) != 0));
01612 
01613       /* This reloc is against a symbol defined only by a dynamic
01614         object, or it is a jump table reloc from PIC compiled code.  */
01615 
01616       if (r_type != RELOC_JMP_TBL
01617          && h->root.root.type == bfd_link_hash_undefined)
01618        /* Presumably this symbol was marked as being undefined by
01619           an earlier reloc.  */
01620        srel->size += RELOC_EXT_SIZE;
01621 
01622       else if (r_type != RELOC_JMP_TBL
01623               && (h->root.root.u.def.section->flags & SEC_CODE) == 0)
01624        {
01625          bfd *sub;
01626 
01627          /* This reloc is not in the .text section.  It must be
01628             copied into the dynamic relocs.  We mark the symbol as
01629             being undefined.  */
01630          srel->size += RELOC_EXT_SIZE;
01631          if ((h->flags & SUNOS_DEF_REGULAR) == 0)
01632            {
01633              sub = h->root.root.u.def.section->owner;
01634              h->root.root.type = bfd_link_hash_undefined;
01635              h->root.root.u.undef.abfd = sub;
01636            }
01637        }
01638       else
01639        {
01640          /* This symbol is in the .text section.  We must give it an
01641             entry in the procedure linkage table, if we have not
01642             already done so.  We change the definition of the symbol
01643             to the .plt section; this will cause relocs against it to
01644             be handled correctly.  */
01645          if (h->plt_offset == 0)
01646            {
01647              if (splt->size == 0)
01648               splt->size = SPARC_PLT_ENTRY_SIZE;
01649              h->plt_offset = splt->size;
01650 
01651              if ((h->flags & SUNOS_DEF_REGULAR) == 0)
01652               {
01653                 if (h->root.root.type == bfd_link_hash_undefined)
01654                   h->root.root.type = bfd_link_hash_defined;
01655                 h->root.root.u.def.section = splt;
01656                 h->root.root.u.def.value = splt->size;
01657               }
01658 
01659              splt->size += SPARC_PLT_ENTRY_SIZE;
01660 
01661              /* We will also need a dynamic reloc entry, unless this
01662                is a JMP_TBL reloc produced by linking PIC compiled
01663                code, and we are not making a shared library.  */
01664              if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0)
01665               srel->size += RELOC_EXT_SIZE;
01666            }
01667 
01668          /* If we are creating a shared library, we need to copy over
01669             any reloc other than a jump table reloc.  */
01670          if (info->shared && r_type != RELOC_JMP_TBL)
01671            srel->size += RELOC_EXT_SIZE;
01672        }
01673     }
01674 
01675   return TRUE;
01676 }
01677 
01678 /* Scan the relocs for an input section.  */
01679 
01680 static bfd_boolean
01681 sunos_scan_relocs (struct bfd_link_info *info,
01682                  bfd *abfd,
01683                  asection *sec,
01684                  bfd_size_type rel_size)
01685 {
01686   void * relocs;
01687   void * free_relocs = NULL;
01688 
01689   if (rel_size == 0)
01690     return TRUE;
01691 
01692   if (! info->keep_memory)
01693     relocs = free_relocs = bfd_malloc (rel_size);
01694   else
01695     {
01696       struct aout_section_data_struct *n;
01697       bfd_size_type amt = sizeof (struct aout_section_data_struct);
01698 
01699       n = bfd_alloc (abfd, amt);
01700       if (n == NULL)
01701        relocs = NULL;
01702       else
01703        {
01704          set_aout_section_data (sec, n);
01705          relocs = bfd_malloc (rel_size);
01706          aout_section_data (sec)->relocs = relocs;
01707        }
01708     }
01709   if (relocs == NULL)
01710     return FALSE;
01711 
01712   if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0
01713       || bfd_bread (relocs, rel_size, abfd) != rel_size)
01714     goto error_return;
01715 
01716   if (obj_reloc_entry_size (abfd) == RELOC_STD_SIZE)
01717     {
01718       if (! sunos_scan_std_relocs (info, abfd, sec,
01719                                (struct reloc_std_external *) relocs,
01720                                rel_size))
01721        goto error_return;
01722     }
01723   else
01724     {
01725       if (! sunos_scan_ext_relocs (info, abfd, sec,
01726                                (struct reloc_ext_external *) relocs,
01727                                rel_size))
01728        goto error_return;
01729     }
01730 
01731   if (free_relocs != NULL)
01732     free (free_relocs);
01733 
01734   return TRUE;
01735 
01736  error_return:
01737   if (free_relocs != NULL)
01738     free (free_relocs);
01739   return FALSE;
01740 }
01741 
01742 /* Build the hash table of dynamic symbols, and to mark as written all
01743    symbols from dynamic objects which we do not plan to write out.  */
01744 
01745 static bfd_boolean
01746 sunos_scan_dynamic_symbol (struct sunos_link_hash_entry *h, void * data)
01747 {
01748   struct bfd_link_info *info = (struct bfd_link_info *) data;
01749 
01750   if (h->root.root.type == bfd_link_hash_warning)
01751     h = (struct sunos_link_hash_entry *) h->root.root.u.i.link;
01752 
01753   /* Set the written flag for symbols we do not want to write out as
01754      part of the regular symbol table.  This is all symbols which are
01755      not defined in a regular object file.  For some reason symbols
01756      which are referenced by a regular object and defined by a dynamic
01757      object do not seem to show up in the regular symbol table.  It is
01758      possible for a symbol to have only SUNOS_REF_REGULAR set here, it
01759      is an undefined symbol which was turned into a common symbol
01760      because it was found in an archive object which was not included
01761      in the link.  */
01762   if ((h->flags & SUNOS_DEF_REGULAR) == 0
01763       && (h->flags & SUNOS_DEF_DYNAMIC) != 0
01764       && strcmp (h->root.root.root.string, "__DYNAMIC") != 0)
01765     h->root.written = TRUE;
01766 
01767   /* If this symbol is defined by a dynamic object and referenced by a
01768      regular object, see whether we gave it a reasonable value while
01769      scanning the relocs.  */
01770   if ((h->flags & SUNOS_DEF_REGULAR) == 0
01771       && (h->flags & SUNOS_DEF_DYNAMIC) != 0
01772       && (h->flags & SUNOS_REF_REGULAR) != 0)
01773     {
01774       if ((h->root.root.type == bfd_link_hash_defined
01775           || h->root.root.type == bfd_link_hash_defweak)
01776          && ((h->root.root.u.def.section->owner->flags & DYNAMIC) != 0)
01777          && h->root.root.u.def.section->output_section == NULL)
01778        {
01779          bfd *sub;
01780 
01781          /* This symbol is currently defined in a dynamic section
01782             which is not being put into the output file.  This
01783             implies that there is no reloc against the symbol.  I'm
01784             not sure why this case would ever occur.  In any case, we
01785             change the symbol to be undefined.  */
01786          sub = h->root.root.u.def.section->owner;
01787          h->root.root.type = bfd_link_hash_undefined;
01788          h->root.root.u.undef.abfd = sub;
01789        }
01790     }
01791 
01792   /* If this symbol is defined or referenced by a regular file, add it
01793      to the dynamic symbols.  */
01794   if ((h->flags & (SUNOS_DEF_REGULAR | SUNOS_REF_REGULAR)) != 0)
01795     {
01796       asection *s;
01797       size_t len;
01798       bfd_byte *contents;
01799       unsigned char *name;
01800       unsigned long hash;
01801       bfd *dynobj;
01802 
01803       BFD_ASSERT (h->dynindx == -2);
01804 
01805       dynobj = sunos_hash_table (info)->dynobj;
01806 
01807       h->dynindx = sunos_hash_table (info)->dynsymcount;
01808       ++sunos_hash_table (info)->dynsymcount;
01809 
01810       len = strlen (h->root.root.root.string);
01811 
01812       /* We don't bother to construct a BFD hash table for the strings
01813         which are the names of the dynamic symbols.  Using a hash
01814         table for the regular symbols is beneficial, because the
01815         regular symbols includes the debugging symbols, which have
01816         long names and are often duplicated in several object files.
01817         There are no debugging symbols in the dynamic symbols.  */
01818       s = bfd_get_section_by_name (dynobj, ".dynstr");
01819       BFD_ASSERT (s != NULL);
01820       contents = bfd_realloc (s->contents, s->size + len + 1);
01821       if (contents == NULL)
01822        return FALSE;
01823       s->contents = contents;
01824 
01825       h->dynstr_index = s->size;
01826       strcpy ((char *) contents + s->size, h->root.root.root.string);
01827       s->size += len + 1;
01828 
01829       /* Add it to the dynamic hash table.  */
01830       name = (unsigned char *) h->root.root.root.string;
01831       hash = 0;
01832       while (*name != '\0')
01833        hash = (hash << 1) + *name++;
01834       hash &= 0x7fffffff;
01835       hash %= sunos_hash_table (info)->bucketcount;
01836 
01837       s = bfd_get_section_by_name (dynobj, ".hash");
01838       BFD_ASSERT (s != NULL);
01839 
01840       if (GET_SWORD (dynobj, s->contents + hash * HASH_ENTRY_SIZE) == -1)
01841        PUT_WORD (dynobj, h->dynindx, s->contents + hash * HASH_ENTRY_SIZE);
01842       else
01843        {
01844          bfd_vma next;
01845 
01846          next = GET_WORD (dynobj,
01847                         (s->contents
01848                          + hash * HASH_ENTRY_SIZE
01849                          + BYTES_IN_WORD));
01850          PUT_WORD (dynobj, s->size / HASH_ENTRY_SIZE,
01851                   s->contents + hash * HASH_ENTRY_SIZE + BYTES_IN_WORD);
01852          PUT_WORD (dynobj, h->dynindx, s->contents + s->size);
01853          PUT_WORD (dynobj, next, s->contents + s->size + BYTES_IN_WORD);
01854          s->size += HASH_ENTRY_SIZE;
01855        }
01856     }
01857 
01858   return TRUE;
01859 }
01860 
01861 /* Set up the sizes and contents of the dynamic sections created in
01862    sunos_add_dynamic_symbols.  This is called by the SunOS linker
01863    emulation before_allocation routine.  We must set the sizes of the
01864    sections before the linker sets the addresses of the various
01865    sections.  This unfortunately requires reading all the relocs so
01866    that we can work out which ones need to become dynamic relocs.  If
01867    info->keep_memory is TRUE, we keep the relocs in memory; otherwise,
01868    we discard them, and will read them again later.  */
01869 
01870 bfd_boolean
01871 bfd_sunos_size_dynamic_sections (bfd *output_bfd,
01872                              struct bfd_link_info *info,
01873                              asection **sdynptr,
01874                              asection **sneedptr,
01875                              asection **srulesptr)
01876 {
01877   bfd *dynobj;
01878   bfd_size_type dynsymcount;
01879   struct sunos_link_hash_entry *h;
01880   asection *s;
01881   size_t bucketcount;
01882   bfd_size_type hashalloc;
01883   size_t i;
01884   bfd *sub;
01885 
01886   *sdynptr = NULL;
01887   *sneedptr = NULL;
01888   *srulesptr = NULL;
01889 
01890   if (info->relocatable)
01891     return TRUE;
01892 
01893   if (output_bfd->xvec != &MY(vec))
01894     return TRUE;
01895 
01896   /* Look through all the input BFD's and read their relocs.  It would
01897      be better if we didn't have to do this, but there is no other way
01898      to determine the number of dynamic relocs we need, and, more
01899      importantly, there is no other way to know which symbols should
01900      get an entry in the procedure linkage table.  */
01901   for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
01902     {
01903       if ((sub->flags & DYNAMIC) == 0
01904          && sub->xvec == output_bfd->xvec)
01905        {
01906          if (! sunos_scan_relocs (info, sub, obj_textsec (sub),
01907                                exec_hdr (sub)->a_trsize)
01908              || ! sunos_scan_relocs (info, sub, obj_datasec (sub),
01909                                   exec_hdr (sub)->a_drsize))
01910            return FALSE;
01911        }
01912     }
01913 
01914   dynobj = sunos_hash_table (info)->dynobj;
01915   dynsymcount = sunos_hash_table (info)->dynsymcount;
01916 
01917   /* If there were no dynamic objects in the link, and we don't need
01918      to build a global offset table, there is nothing to do here.  */
01919   if (! sunos_hash_table (info)->dynamic_sections_needed
01920       && ! sunos_hash_table (info)->got_needed)
01921     return TRUE;
01922 
01923   /* If __GLOBAL_OFFSET_TABLE_ was mentioned, define it.  */
01924   h = sunos_link_hash_lookup (sunos_hash_table (info),
01925                            "__GLOBAL_OFFSET_TABLE_", FALSE, FALSE, FALSE);
01926   if (h != NULL && (h->flags & SUNOS_REF_REGULAR) != 0)
01927     {
01928       h->flags |= SUNOS_DEF_REGULAR;
01929       if (h->dynindx == -1)
01930        {
01931          ++sunos_hash_table (info)->dynsymcount;
01932          h->dynindx = -2;
01933        }
01934       h->root.root.type = bfd_link_hash_defined;
01935       h->root.root.u.def.section = bfd_get_section_by_name (dynobj, ".got");
01936 
01937       /* If the .got section is more than 0x1000 bytes, we set
01938         __GLOBAL_OFFSET_TABLE_ to be 0x1000 bytes into the section,
01939         so that 13 bit relocations have a greater chance of working.  */
01940       s = bfd_get_section_by_name (dynobj, ".got");
01941       BFD_ASSERT (s != NULL);
01942       if (s->size >= 0x1000)
01943        h->root.root.u.def.value = 0x1000;
01944       else
01945        h->root.root.u.def.value = 0;
01946 
01947       sunos_hash_table (info)->got_base = h->root.root.u.def.value;
01948     }
01949 
01950   /* If there are any shared objects in the link, then we need to set
01951      up the dynamic linking information.  */
01952   if (sunos_hash_table (info)->dynamic_sections_needed)
01953     {
01954       *sdynptr = bfd_get_section_by_name (dynobj, ".dynamic");
01955 
01956       /* The .dynamic section is always the same size.  */
01957       s = *sdynptr;
01958       BFD_ASSERT (s != NULL);
01959       s->size = (sizeof (struct external_sun4_dynamic)
01960                     + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE
01961                     + sizeof (struct external_sun4_dynamic_link));
01962 
01963       /* Set the size of the .dynsym and .hash sections.  We counted
01964         the number of dynamic symbols as we read the input files.  We
01965         will build the dynamic symbol table (.dynsym) and the hash
01966         table (.hash) when we build the final symbol table, because
01967         until then we do not know the correct value to give the
01968         symbols.  We build the dynamic symbol string table (.dynstr)
01969         in a traversal of the symbol table using
01970         sunos_scan_dynamic_symbol.  */
01971       s = bfd_get_section_by_name (dynobj, ".dynsym");
01972       BFD_ASSERT (s != NULL);
01973       s->size = dynsymcount * sizeof (struct external_nlist);
01974       s->contents = bfd_alloc (output_bfd, s->size);
01975       if (s->contents == NULL && s->size != 0)
01976        return FALSE;
01977 
01978       /* The number of buckets is just the number of symbols divided
01979         by four.  To compute the final size of the hash table, we
01980         must actually compute the hash table.  Normally we need
01981         exactly as many entries in the hash table as there are
01982         dynamic symbols, but if some of the buckets are not used we
01983         will need additional entries.  In the worst case, every
01984         symbol will hash to the same bucket, and we will need
01985         BUCKETCOUNT - 1 extra entries.  */
01986       if (dynsymcount >= 4)
01987        bucketcount = dynsymcount / 4;
01988       else if (dynsymcount > 0)
01989        bucketcount = dynsymcount;
01990       else
01991        bucketcount = 1;
01992       s = bfd_get_section_by_name (dynobj, ".hash");
01993       BFD_ASSERT (s != NULL);
01994       hashalloc = (dynsymcount + bucketcount - 1) * HASH_ENTRY_SIZE;
01995       s->contents = bfd_zalloc (dynobj, hashalloc);
01996       if (s->contents == NULL && dynsymcount > 0)
01997        return FALSE;
01998       for (i = 0; i < bucketcount; i++)
01999        PUT_WORD (output_bfd, (bfd_vma) -1, s->contents + i * HASH_ENTRY_SIZE);
02000       s->size = bucketcount * HASH_ENTRY_SIZE;
02001 
02002       sunos_hash_table (info)->bucketcount = bucketcount;
02003 
02004       /* Scan all the symbols, place them in the dynamic symbol table,
02005         and build the dynamic hash table.  We reuse dynsymcount as a
02006         counter for the number of symbols we have added so far.  */
02007       sunos_hash_table (info)->dynsymcount = 0;
02008       sunos_link_hash_traverse (sunos_hash_table (info),
02009                             sunos_scan_dynamic_symbol,
02010                             (void *) info);
02011       BFD_ASSERT (sunos_hash_table (info)->dynsymcount == dynsymcount);
02012 
02013       /* The SunOS native linker seems to align the total size of the
02014         symbol strings to a multiple of 8.  I don't know if this is
02015         important, but it can't hurt much.  */
02016       s = bfd_get_section_by_name (dynobj, ".dynstr");
02017       BFD_ASSERT (s != NULL);
02018       if ((s->size & 7) != 0)
02019        {
02020          bfd_size_type add;
02021          bfd_byte *contents;
02022 
02023          add = 8 - (s->size & 7);
02024          contents = bfd_realloc (s->contents, s->size + add);
02025          if (contents == NULL)
02026            return FALSE;
02027          memset (contents + s->size, 0, (size_t) add);
02028          s->contents = contents;
02029          s->size += add;
02030        }
02031     }
02032 
02033   /* Now that we have worked out the sizes of the procedure linkage
02034      table and the dynamic relocs, allocate storage for them.  */
02035   s = bfd_get_section_by_name (dynobj, ".plt");
02036   BFD_ASSERT (s != NULL);
02037   if (s->size != 0)
02038     {
02039       s->contents = bfd_alloc (dynobj, s->size);
02040       if (s->contents == NULL)
02041        return FALSE;
02042 
02043       /* Fill in the first entry in the table.  */
02044       switch (bfd_get_arch (dynobj))
02045        {
02046        case bfd_arch_sparc:
02047          memcpy (s->contents, sparc_plt_first_entry, SPARC_PLT_ENTRY_SIZE);
02048          break;
02049 
02050        case bfd_arch_m68k:
02051          memcpy (s->contents, m68k_plt_first_entry, M68K_PLT_ENTRY_SIZE);
02052          break;
02053 
02054        default:
02055          abort ();
02056        }
02057     }
02058 
02059   s = bfd_get_section_by_name (dynobj, ".dynrel");
02060   if (s->size != 0)
02061     {
02062       s->contents = bfd_alloc (dynobj, s->size);
02063       if (s->contents == NULL)
02064        return FALSE;
02065     }
02066   /* We use the reloc_count field to keep track of how many of the
02067      relocs we have output so far.  */
02068   s->reloc_count = 0;
02069 
02070   /* Make space for the global offset table.  */
02071   s = bfd_get_section_by_name (dynobj, ".got");
02072   s->contents = bfd_alloc (dynobj, s->size);
02073   if (s->contents == NULL)
02074     return FALSE;
02075 
02076   *sneedptr = bfd_get_section_by_name (dynobj, ".need");
02077   *srulesptr = bfd_get_section_by_name (dynobj, ".rules");
02078 
02079   return TRUE;
02080 }
02081 
02082 /* Link a dynamic object.  We actually don't have anything to do at
02083    this point.  This entry point exists to prevent the regular linker
02084    code from doing anything with the object.  */
02085 
02086 static bfd_boolean
02087 sunos_link_dynamic_object (struct bfd_link_info *info ATTRIBUTE_UNUSED,
02088                         bfd *abfd ATTRIBUTE_UNUSED)
02089 {
02090   return TRUE;
02091 }
02092 
02093 /* Write out a dynamic symbol.  This is called by the final traversal
02094    over the symbol table.  */
02095 
02096 static bfd_boolean
02097 sunos_write_dynamic_symbol (bfd *output_bfd,
02098                          struct bfd_link_info *info,
02099                          struct aout_link_hash_entry *harg)
02100 {
02101   struct sunos_link_hash_entry *h = (struct sunos_link_hash_entry *) harg;
02102   int type;
02103   bfd_vma val;
02104   asection *s;
02105   struct external_nlist *outsym;
02106 
02107   /* If this symbol is in the procedure linkage table, fill in the
02108      table entry.  */
02109   if (h->plt_offset != 0)
02110     {
02111       bfd *dynobj;
02112       asection *splt;
02113       bfd_byte *p;
02114       bfd_vma r_address;
02115 
02116       dynobj = sunos_hash_table (info)->dynobj;
02117       splt = bfd_get_section_by_name (dynobj, ".plt");
02118       p = splt->contents + h->plt_offset;
02119 
02120       s = bfd_get_section_by_name (dynobj, ".dynrel");
02121 
02122       r_address = (splt->output_section->vma
02123                  + splt->output_offset
02124                  + h->plt_offset);
02125 
02126       switch (bfd_get_arch (output_bfd))
02127        {
02128        case bfd_arch_sparc:
02129          if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0)
02130            {
02131              bfd_put_32 (output_bfd, SPARC_PLT_ENTRY_WORD0, p);
02132              bfd_put_32 (output_bfd,
02133                        (SPARC_PLT_ENTRY_WORD1
02134                         + (((- (h->plt_offset + 4) >> 2)
02135                             & 0x3fffffff))),
02136                        p + 4);
02137              bfd_put_32 (output_bfd, SPARC_PLT_ENTRY_WORD2 + s->reloc_count,
02138                        p + 8);
02139            }
02140          else
02141            {
02142              val = (h->root.root.u.def.section->output_section->vma
02143                    + h->root.root.u.def.section->output_offset
02144                    + h->root.root.u.def.value);
02145              bfd_put_32 (output_bfd,
02146                        SPARC_PLT_PIC_WORD0 + ((val >> 10) & 0x3fffff),
02147                        p);
02148              bfd_put_32 (output_bfd,
02149                        SPARC_PLT_PIC_WORD1 + (val & 0x3ff),
02150                        p + 4);
02151              bfd_put_32 (output_bfd, SPARC_PLT_PIC_WORD2, p + 8);
02152            }
02153          break;
02154 
02155        case bfd_arch_m68k:
02156          if (! info->shared && (h->flags & SUNOS_DEF_REGULAR) != 0)
02157            abort ();
02158          bfd_put_16 (output_bfd, M68K_PLT_ENTRY_WORD0, p);
02159          bfd_put_32 (output_bfd, (- (h->plt_offset + 2)), p + 2);
02160          bfd_put_16 (output_bfd, (bfd_vma) s->reloc_count, p + 6);
02161          r_address += 2;
02162          break;
02163 
02164        default:
02165          abort ();
02166        }
02167 
02168       /* We also need to add a jump table reloc, unless this is the
02169         result of a JMP_TBL reloc from PIC compiled code.  */
02170       if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0)
02171        {
02172          BFD_ASSERT (h->dynindx >= 0);
02173          BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj)
02174                     < s->size);
02175          p = s->contents + s->reloc_count * obj_reloc_entry_size (output_bfd);
02176          if (obj_reloc_entry_size (output_bfd) == RELOC_STD_SIZE)
02177            {
02178              struct reloc_std_external *srel;
02179 
02180              srel = (struct reloc_std_external *) p;
02181              PUT_WORD (output_bfd, r_address, srel->r_address);
02182              if (bfd_header_big_endian (output_bfd))
02183               {
02184                 srel->r_index[0] = (bfd_byte) (h->dynindx >> 16);
02185                 srel->r_index[1] = (bfd_byte) (h->dynindx >> 8);
02186                 srel->r_index[2] = (bfd_byte) (h->dynindx);
02187                 srel->r_type[0] = (RELOC_STD_BITS_EXTERN_BIG
02188                                  | RELOC_STD_BITS_JMPTABLE_BIG);
02189               }
02190              else
02191               {
02192                 srel->r_index[2] = (bfd_byte) (h->dynindx >> 16);
02193                 srel->r_index[1] = (bfd_byte) (h->dynindx >> 8);
02194                 srel->r_index[0] = (bfd_byte)h->dynindx;
02195                 srel->r_type[0] = (RELOC_STD_BITS_EXTERN_LITTLE
02196                                  | RELOC_STD_BITS_JMPTABLE_LITTLE);
02197               }
02198            }
02199          else
02200            {
02201              struct reloc_ext_external *erel;
02202 
02203              erel = (struct reloc_ext_external *) p;
02204              PUT_WORD (output_bfd, r_address, erel->r_address);
02205              if (bfd_header_big_endian (output_bfd))
02206               {
02207                 erel->r_index[0] = (bfd_byte) (h->dynindx >> 16);
02208                 erel->r_index[1] = (bfd_byte) (h->dynindx >> 8);
02209                 erel->r_index[2] = (bfd_byte)h->dynindx;
02210                 erel->r_type[0] =
02211                   (RELOC_EXT_BITS_EXTERN_BIG
02212                    | (RELOC_JMP_SLOT << RELOC_EXT_BITS_TYPE_SH_BIG));
02213               }
02214              else
02215               {
02216                 erel->r_index[2] = (bfd_byte) (h->dynindx >> 16);
02217                 erel->r_index[1] = (bfd_byte) (h->dynindx >> 8);
02218                 erel->r_index[0] = (bfd_byte)h->dynindx;
02219                 erel->r_type[0] =
02220                   (RELOC_EXT_BITS_EXTERN_LITTLE
02221                    | (RELOC_JMP_SLOT << RELOC_EXT_BITS_TYPE_SH_LITTLE));
02222               }
02223              PUT_WORD (output_bfd, (bfd_vma) 0, erel->r_addend);
02224            }
02225 
02226          ++s->reloc_count;
02227        }
02228     }
02229 
02230   /* If this is not a dynamic symbol, we don't have to do anything
02231      else.  We only check this after handling the PLT entry, because
02232      we can have a PLT entry for a nondynamic symbol when linking PIC
02233      compiled code from a regular object.  */
02234   if (h->dynindx < 0)
02235     return TRUE;
02236 
02237   switch (h->root.root.type)
02238     {
02239     default:
02240     case bfd_link_hash_new:
02241       abort ();
02242       /* Avoid variable not initialized warnings.  */
02243       return TRUE;
02244     case bfd_link_hash_undefined:
02245       type = N_UNDF | N_EXT;
02246       val = 0;
02247       break;
02248     case bfd_link_hash_defined:
02249     case bfd_link_hash_defweak:
02250       {
02251        asection *sec;
02252        asection *output_section;
02253 
02254        sec = h->root.root.u.def.section;
02255        output_section = sec->output_section;
02256        BFD_ASSERT (bfd_is_abs_section (output_section)
02257                   || output_section->owner == output_bfd);
02258        if (h->plt_offset != 0
02259            && (h->flags & SUNOS_DEF_REGULAR) == 0)
02260          {
02261            type = N_UNDF | N_EXT;
02262            val = 0;
02263          }
02264        else
02265          {
02266            if (output_section == obj_textsec (output_bfd))
02267              type = (h->root.root.type == bfd_link_hash_defined
02268                     ? N_TEXT
02269                     : N_WEAKT);
02270            else if (output_section == obj_datasec (output_bfd))
02271              type = (h->root.root.type == bfd_link_hash_defined
02272                     ? N_DATA
02273                     : N_WEAKD);
02274            else if (output_section == obj_bsssec (output_bfd))
02275              type = (h->root.root.type == bfd_link_hash_defined
02276                     ? N_BSS
02277                     : N_WEAKB);
02278            else
02279              type = (h->root.root.type == bfd_link_hash_defined
02280                     ? N_ABS
02281                     : N_WEAKA);
02282            type |= N_EXT;
02283            val = (h->root.root.u.def.value
02284                  + output_section->vma
02285                  + sec->output_offset);
02286          }
02287       }
02288       break;
02289     case bfd_link_hash_common:
02290       type = N_UNDF | N_EXT;
02291       val = h->root.root.u.c.size;
02292       break;
02293     case bfd_link_hash_undefweak:
02294       type = N_WEAKU;
02295       val = 0;
02296       break;
02297     case bfd_link_hash_indirect:
02298     case bfd_link_hash_warning:
02299       /* FIXME: Ignore these for now.  The circumstances under which
02300         they should be written out are not clear to me.  */
02301       return TRUE;
02302     }
02303 
02304   s = bfd_get_section_by_name (sunos_hash_table (info)->dynobj, ".dynsym");
02305   BFD_ASSERT (s != NULL);
02306   outsym = ((struct external_nlist *)
02307            (s->contents + h->dynindx * EXTERNAL_NLIST_SIZE));
02308 
02309   H_PUT_8 (output_bfd, type, outsym->e_type);
02310   H_PUT_8 (output_bfd, 0, outsym->e_other);
02311 
02312   /* FIXME: The native linker doesn't use 0 for desc.  It seems to use
02313      one less than the desc value in the shared library, although that
02314      seems unlikely.  */
02315   H_PUT_16 (output_bfd, 0, outsym->e_desc);
02316 
02317   PUT_WORD (output_bfd, h->dynstr_index, outsym->e_strx);
02318   PUT_WORD (output_bfd, val, outsym->e_value);
02319 
02320   return TRUE;
02321 }
02322 
02323 /* This is called for each reloc against an external symbol.  If this
02324    is a reloc which are are going to copy as a dynamic reloc, then
02325    copy it over, and tell the caller to not bother processing this
02326    reloc.  */
02327 
02328 static bfd_boolean
02329 sunos_check_dynamic_reloc (struct bfd_link_info *info,
02330                         bfd *input_bfd,
02331                         asection *input_section,
02332                         struct aout_link_hash_entry *harg,
02333                         void * reloc,
02334                         bfd_byte *contents ATTRIBUTE_UNUSED,
02335                         bfd_boolean *skip,
02336                         bfd_vma *relocationp)
02337 {
02338   struct sunos_link_hash_entry *h = (struct sunos_link_hash_entry *) harg;
02339   bfd *dynobj;
02340   bfd_boolean baserel;
02341   bfd_boolean jmptbl;
02342   bfd_boolean pcrel;
02343   asection *s;
02344   bfd_byte *p;
02345   long indx;
02346 
02347   *skip = FALSE;
02348 
02349   dynobj = sunos_hash_table (info)->dynobj;
02350 
02351   if (h != NULL
02352       && h->plt_offset != 0
02353       && (info->shared
02354          || (h->flags & SUNOS_DEF_REGULAR) == 0))
02355     {
02356       asection *splt;
02357 
02358       /* Redirect the relocation to the PLT entry.  */
02359       splt = bfd_get_section_by_name (dynobj, ".plt");
02360       *relocationp = (splt->output_section->vma
02361                     + splt->output_offset
02362                     + h->plt_offset);
02363     }
02364 
02365   if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
02366     {
02367       struct reloc_std_external *srel;
02368 
02369       srel = (struct reloc_std_external *) reloc;
02370       if (bfd_header_big_endian (input_bfd))
02371        {
02372          baserel = (0 != (srel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
02373          jmptbl = (0 != (srel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
02374          pcrel = (0 != (srel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
02375        }
02376       else
02377        {
02378          baserel = (0 != (srel->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
02379          jmptbl = (0 != (srel->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
02380          pcrel = (0 != (srel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
02381        }
02382     }
02383   else
02384     {
02385       struct reloc_ext_external *erel;
02386       int r_type;
02387 
02388       erel = (struct reloc_ext_external *) reloc;
02389       if (bfd_header_big_endian (input_bfd))
02390        r_type = ((erel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
02391                 >> RELOC_EXT_BITS_TYPE_SH_BIG);
02392       else
02393        r_type = ((erel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
02394                 >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
02395       baserel = (r_type == RELOC_BASE10
02396                || r_type == RELOC_BASE13
02397                || r_type == RELOC_BASE22);
02398       jmptbl = r_type == RELOC_JMP_TBL;
02399       pcrel = (r_type == RELOC_DISP8
02400               || r_type == RELOC_DISP16
02401               || r_type == RELOC_DISP32
02402               || r_type == RELOC_WDISP30
02403               || r_type == RELOC_WDISP22);
02404       /* We don't consider the PC10 and PC22 types to be PC relative,
02405         because they are pcrel_offset.  */
02406     }
02407 
02408   if (baserel)
02409     {
02410       bfd_vma *got_offsetp;
02411       asection *sgot;
02412 
02413       if (h != NULL)
02414        got_offsetp = &h->got_offset;
02415       else if (adata (input_bfd).local_got_offsets == NULL)
02416        got_offsetp = NULL;
02417       else
02418        {
02419          struct reloc_std_external *srel;
02420          int r_index;
02421 
02422          srel = (struct reloc_std_external *) reloc;
02423          if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
02424            {
02425              if (bfd_header_big_endian (input_bfd))
02426               r_index = ((srel->r_index[0] << 16)
02427                         | (srel->r_index[1] << 8)
02428                         | srel->r_index[2]);
02429              else
02430               r_index = ((srel->r_index[2] << 16)
02431                         | (srel->r_index[1] << 8)
02432                         | srel->r_index[0]);
02433            }
02434          else
02435            {
02436              struct reloc_ext_external *erel;
02437 
02438              erel = (struct reloc_ext_external *) reloc;
02439              if (bfd_header_big_endian (input_bfd))
02440               r_index = ((erel->r_index[0] << 16)
02441                         | (erel->r_index[1] << 8)
02442                         | erel->r_index[2]);
02443              else
02444               r_index = ((erel->r_index[2] << 16)
02445                         | (erel->r_index[1] << 8)
02446                         | erel->r_index[0]);
02447            }
02448 
02449          got_offsetp = adata (input_bfd).local_got_offsets + r_index;
02450        }
02451 
02452       BFD_ASSERT (got_offsetp != NULL && *got_offsetp != 0);
02453 
02454       sgot = bfd_get_section_by_name (dynobj, ".got");
02455 
02456       /* We set the least significant bit to indicate whether we have
02457         already initialized the GOT entry.  */
02458       if ((*got_offsetp & 1) == 0)
02459        {
02460          if (h == NULL
02461              || (! info->shared
02462                 && ((h->flags & SUNOS_DEF_DYNAMIC) == 0
02463                     || (h->flags & SUNOS_DEF_REGULAR) != 0)))
02464            PUT_WORD (dynobj, *relocationp, sgot->contents + *got_offsetp);
02465          else
02466            PUT_WORD (dynobj, 0, sgot->contents + *got_offsetp);
02467 
02468          if (info->shared
02469              || (h != NULL
02470                 && (h->flags & SUNOS_DEF_DYNAMIC) != 0
02471                 && (h->flags & SUNOS_DEF_REGULAR) == 0))
02472            {
02473              /* We need to create a GLOB_DAT or 32 reloc to tell the
02474                dynamic linker to fill in this entry in the table.  */
02475 
02476              s = bfd_get_section_by_name (dynobj, ".dynrel");
02477              BFD_ASSERT (s != NULL);
02478              BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj)
02479                        < s->size);
02480 
02481              p = (s->contents
02482                  + s->reloc_count * obj_reloc_entry_size (dynobj));
02483 
02484              if (h != NULL)
02485               indx = h->dynindx;
02486              else
02487               indx = 0;
02488 
02489              if (obj_reloc_entry_size (dynobj) == RELOC_STD_SIZE)
02490               {
02491                 struct reloc_std_external *srel;
02492 
02493                 srel = (struct reloc_std_external *) p;
02494                 PUT_WORD (dynobj,
02495                          (*got_offsetp
02496                           + sgot->output_section->vma
02497                           + sgot->output_offset),
02498                          srel->r_address);
02499                 if (bfd_header_big_endian (dynobj))
02500                   {
02501                     srel->r_index[0] = (bfd_byte) (indx >> 16);
02502                     srel->r_index[1] = (bfd_byte) (indx >> 8);
02503                     srel->r_index[2] = (bfd_byte)indx;
02504                     if (h == NULL)
02505                      srel->r_type[0] = 2 << RELOC_STD_BITS_LENGTH_SH_BIG;
02506                     else
02507                      srel->r_type[0] =
02508                        (RELOC_STD_BITS_EXTERN_BIG
02509                         | RELOC_STD_BITS_BASEREL_BIG
02510                         | RELOC_STD_BITS_RELATIVE_BIG
02511                         | (2 << RELOC_STD_BITS_LENGTH_SH_BIG));
02512                   }
02513                 else
02514                   {
02515                     srel->r_index[2] = (bfd_byte) (indx >> 16);
02516                     srel->r_index[1] = (bfd_byte) (indx >> 8);
02517                     srel->r_index[0] = (bfd_byte)indx;
02518                     if (h == NULL)
02519                      srel->r_type[0] = 2 << RELOC_STD_BITS_LENGTH_SH_LITTLE;
02520                     else
02521                      srel->r_type[0] =
02522                        (RELOC_STD_BITS_EXTERN_LITTLE
02523                         | RELOC_STD_BITS_BASEREL_LITTLE
02524                         | RELOC_STD_BITS_RELATIVE_LITTLE
02525                         | (2 << RELOC_STD_BITS_LENGTH_SH_LITTLE));
02526                   }
02527               }
02528              else
02529               {
02530                 struct reloc_ext_external *erel;
02531 
02532                 erel = (struct reloc_ext_external *) p;
02533                 PUT_WORD (dynobj,
02534                          (*got_offsetp
02535                           + sgot->output_section->vma
02536                           + sgot->output_offset),
02537                          erel->r_address);
02538                 if (bfd_header_big_endian (dynobj))
02539                   {
02540                     erel->r_index[0] = (bfd_byte) (indx >> 16);
02541                     erel->r_index[1] = (bfd_byte) (indx >> 8);
02542                     erel->r_index[2] = (bfd_byte)indx;
02543                     if (h == NULL)
02544                      erel->r_type[0] =
02545                        RELOC_32 << RELOC_EXT_BITS_TYPE_SH_BIG;
02546                     else
02547                      erel->r_type[0] =
02548                        (RELOC_EXT_BITS_EXTERN_BIG
02549                         | (RELOC_GLOB_DAT << RELOC_EXT_BITS_TYPE_SH_BIG));
02550                   }
02551                 else
02552                   {
02553                     erel->r_index[2] = (bfd_byte) (indx >> 16);
02554                     erel->r_index[1] = (bfd_byte) (indx >> 8);
02555                     erel->r_index[0] = (bfd_byte)indx;
02556                     if (h == NULL)
02557                      erel->r_type[0] =
02558                        RELOC_32 << RELOC_EXT_BITS_TYPE_SH_LITTLE;
02559                     else
02560                      erel->r_type[0] =
02561                        (RELOC_EXT_BITS_EXTERN_LITTLE
02562                         | (RELOC_GLOB_DAT
02563                            << RELOC_EXT_BITS_TYPE_SH_LITTLE));
02564                   }
02565                 PUT_WORD (dynobj, 0, erel->r_addend);
02566               }
02567 
02568              ++s->reloc_count;
02569            }
02570 
02571          *got_offsetp |= 1;
02572        }
02573 
02574       *relocationp = (sgot->vma
02575                     + (*got_offsetp &~ (bfd_vma) 1)
02576                     - sunos_hash_table (info)->got_base);
02577 
02578       /* There is nothing else to do for a base relative reloc.  */
02579       return TRUE;
02580     }
02581 
02582   if (! sunos_hash_table (info)->dynamic_sections_needed)
02583     return TRUE;
02584   if (! info->shared)
02585     {
02586       if (h == NULL
02587          || h->dynindx == -1
02588          || h->root.root.type != bfd_link_hash_undefined
02589          || (h->flags & SUNOS_DEF_REGULAR) != 0
02590          || (h->flags & SUNOS_DEF_DYNAMIC) == 0
02591          || (h->root.root.u.undef.abfd->flags & DYNAMIC) == 0)
02592        return TRUE;
02593     }
02594   else
02595     {
02596       if (h != NULL
02597          && (h->dynindx == -1
02598              || jmptbl
02599              || strcmp (h->root.root.root.string,
02600                       "__GLOBAL_OFFSET_TABLE_") == 0))
02601        return TRUE;
02602     }
02603 
02604   /* It looks like this is a reloc we are supposed to copy.  */
02605 
02606   s = bfd_get_section_by_name (dynobj, ".dynrel");
02607   BFD_ASSERT (s != NULL);
02608   BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) < s->size);
02609 
02610   p = s->contents + s->reloc_count * obj_reloc_entry_size (dynobj);
02611 
02612   /* Copy the reloc over.  */
02613   memcpy (p, reloc, obj_reloc_entry_size (dynobj));
02614 
02615   if (h != NULL)
02616     indx = h->dynindx;
02617   else
02618     indx = 0;
02619 
02620   /* Adjust the address and symbol index.  */
02621   if (obj_reloc_entry_size (dynobj) == RELOC_STD_SIZE)
02622     {
02623       struct reloc_std_external *srel;
02624 
02625       srel = (struct reloc_std_external *) p;
02626       PUT_WORD (dynobj,
02627               (GET_WORD (dynobj, srel->r_address)
02628                + input_section->output_section->vma
02629                + input_section->output_offset),
02630               srel->r_address);
02631       if (bfd_header_big_endian (dynobj))
02632        {
02633          srel->r_index[0] = (bfd_byte) (indx >> 16);
02634          srel->r_index[1] = (bfd_byte) (indx >> 8);
02635          srel->r_index[2] = (bfd_byte)indx;
02636        }
02637       else
02638        {
02639          srel->r_index[2] = (bfd_byte) (indx >> 16);
02640          srel->r_index[1] = (bfd_byte) (indx >> 8);
02641          srel->r_index[0] = (bfd_byte)indx;
02642        }
02643       /* FIXME: We may have to change the addend for a PC relative
02644         reloc.  */
02645     }
02646   else
02647     {
02648       struct reloc_ext_external *erel;
02649 
02650       erel = (struct reloc_ext_external *) p;
02651       PUT_WORD (dynobj,
02652               (GET_WORD (dynobj, erel->r_address)
02653                + input_section->output_section->vma
02654                + input_section->output_offset),
02655               erel->r_address);
02656       if (bfd_header_big_endian (dynobj))
02657        {
02658          erel->r_index[0] = (bfd_byte) (indx >> 16);
02659          erel->r_index[1] = (bfd_byte) (indx >> 8);
02660          erel->r_index[2] = (bfd_byte)indx;
02661        }
02662       else
02663        {
02664          erel->r_index[2] = (bfd_byte) (indx >> 16);
02665          erel->r_index[1] = (bfd_byte) (indx >> 8);
02666          erel->r_index[0] = (bfd_byte)indx;
02667        }
02668       if (pcrel && h != NULL)
02669        {
02670          /* Adjust the addend for the change in address.  */
02671          PUT_WORD (dynobj,
02672                   (GET_WORD (dynobj, erel->r_addend)
02673                    - (input_section->output_section->vma
02674                      + input_section->output_offset
02675                      - input_section->vma)),
02676                   erel->r_addend);
02677        }
02678     }
02679 
02680   ++s->reloc_count;
02681 
02682   if (h != NULL)
02683     *skip = TRUE;
02684 
02685   return TRUE;
02686 }
02687 
02688 /* Finish up the dynamic linking information.  */
02689 
02690 static bfd_boolean
02691 sunos_finish_dynamic_link (bfd *abfd, struct bfd_link_info *info)
02692 {
02693   bfd *dynobj;
02694   asection *o;
02695   asection *s;
02696   asection *sdyn;
02697 
02698   if (! sunos_hash_table (info)->dynamic_sections_needed
02699       && ! sunos_hash_table (info)->got_needed)
02700     return TRUE;
02701 
02702   dynobj = sunos_hash_table (info)->dynobj;
02703 
02704   sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
02705   BFD_ASSERT (sdyn != NULL);
02706 
02707   /* Finish up the .need section.  The linker emulation code filled it
02708      in, but with offsets from the start of the section instead of
02709      real addresses.  Now that we know the section location, we can
02710      fill in the final values.  */
02711   s = bfd_get_section_by_name (dynobj, ".need");
02712   if (s != NULL && s->size != 0)
02713     {
02714       file_ptr filepos;
02715       bfd_byte *p;
02716 
02717       filepos = s->output_section->filepos + s->output_offset;
02718       p = s->contents;
02719       while (1)
02720        {
02721          bfd_vma val;
02722 
02723          PUT_WORD (dynobj, GET_WORD (dynobj, p) + filepos, p);
02724          val = GET_WORD (dynobj, p + 12);
02725          if (val == 0)
02726            break;
02727          PUT_WORD (dynobj, val + filepos, p + 12);
02728          p += 16;
02729        }
02730     }
02731 
02732   /* The first entry in the .got section is the address of the
02733      dynamic information, unless this is a shared library.  */
02734   s = bfd_get_section_by_name (dynobj, ".got");
02735   BFD_ASSERT (s != NULL);
02736   if (info->shared || sdyn->size == 0)
02737     PUT_WORD (dynobj, 0, s->contents);
02738   else
02739     PUT_WORD (dynobj, sdyn->output_section->vma + sdyn->output_offset,
02740              s->contents);
02741 
02742   for (o = dynobj->sections; o != NULL; o = o->next)
02743     {
02744       if ((o->flags & SEC_HAS_CONTENTS) != 0
02745          && o->contents != NULL)
02746        {
02747          BFD_ASSERT (o->output_section != NULL
02748                     && o->output_section->owner == abfd);
02749          if (! bfd_set_section_contents (abfd, o->output_section,
02750                                      o->contents,
02751                                      (file_ptr) o->output_offset,
02752                                      o->size))
02753            return FALSE;
02754        }
02755     }
02756 
02757   if (sdyn->size > 0)
02758     {
02759       struct external_sun4_dynamic esd;
02760       struct external_sun4_dynamic_link esdl;
02761       file_ptr pos;
02762 
02763       /* Finish up the dynamic link information.  */
02764       PUT_WORD (dynobj, (bfd_vma) 3, esd.ld_version);
02765       PUT_WORD (dynobj,
02766               sdyn->output_section->vma + sdyn->output_offset + sizeof esd,
02767               esd.ldd);
02768       PUT_WORD (dynobj,
02769               (sdyn->output_section->vma
02770                + sdyn->output_offset
02771                + sizeof esd
02772                + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE),
02773               esd.ld);
02774 
02775       if (! bfd_set_section_contents (abfd, sdyn->output_section, &esd,
02776                                   (file_ptr) sdyn->output_offset,
02777                                   (bfd_size_type) sizeof esd))
02778        return FALSE;
02779 
02780       PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_loaded);
02781 
02782       s = bfd_get_section_by_name (dynobj, ".need");
02783       if (s == NULL || s->size == 0)
02784        PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_need);
02785       else
02786        PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
02787                 esdl.ld_need);
02788 
02789       s = bfd_get_section_by_name (dynobj, ".rules");
02790       if (s == NULL || s->size == 0)
02791        PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_rules);
02792       else
02793        PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
02794                 esdl.ld_rules);
02795 
02796       s = bfd_get_section_by_name (dynobj, ".got");
02797       BFD_ASSERT (s != NULL);
02798       PUT_WORD (dynobj, s->output_section->vma + s->output_offset,
02799               esdl.ld_got);
02800 
02801       s = bfd_get_section_by_name (dynobj, ".plt");
02802       BFD_ASSERT (s != NULL);
02803       PUT_WORD (dynobj, s->output_section->vma + s->output_offset,
02804               esdl.ld_plt);
02805       PUT_WORD (dynobj, s->size, esdl.ld_plt_sz);
02806 
02807       s = bfd_get_section_by_name (dynobj, ".dynrel");
02808       BFD_ASSERT (s != NULL);
02809       BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj)
02810                 == s->size);
02811       PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
02812               esdl.ld_rel);
02813 
02814       s = bfd_get_section_by_name (dynobj, ".hash");
02815       BFD_ASSERT (s != NULL);
02816       PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
02817               esdl.ld_hash);
02818 
02819       s = bfd_get_section_by_name (dynobj, ".dynsym");
02820       BFD_ASSERT (s != NULL);
02821       PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
02822               esdl.ld_stab);
02823 
02824       PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_stab_hash);
02825 
02826       PUT_WORD (dynobj, (bfd_vma) sunos_hash_table (info)->bucketcount,
02827               esdl.ld_buckets);
02828 
02829       s = bfd_get_section_by_name (dynobj, ".dynstr");
02830       BFD_ASSERT (s != NULL);
02831       PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
02832               esdl.ld_symbols);
02833       PUT_WORD (dynobj, s->size, esdl.ld_symb_size);
02834 
02835       /* The size of the text area is the size of the .text section
02836         rounded up to a page boundary.  FIXME: Should the page size be
02837         conditional on something?  */
02838       PUT_WORD (dynobj,
02839               BFD_ALIGN (obj_textsec (abfd)->size, 0x2000),
02840               esdl.ld_text);
02841 
02842       pos = sdyn->output_offset;
02843       pos += sizeof esd + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE;
02844       if (! bfd_set_section_contents (abfd, sdyn->output_section, &esdl,
02845                                   pos, (bfd_size_type) sizeof esdl))
02846        return FALSE;
02847 
02848       abfd->flags |= DYNAMIC;
02849     }
02850 
02851   return TRUE;
02852 }